From eb0d219253def186f2701ae64f875809ea1857e7 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 15:50:43 -0700 Subject: [PATCH 01/34] Added the Decorator class --- packages/flame/lib/src/decorator.dart | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 packages/flame/lib/src/decorator.dart diff --git a/packages/flame/lib/src/decorator.dart b/packages/flame/lib/src/decorator.dart new file mode 100644 index 00000000000..9ded9cb84ac --- /dev/null +++ b/packages/flame/lib/src/decorator.dart @@ -0,0 +1,26 @@ +import 'dart:ui'; + +import 'package:flame/src/paint_decorator.dart'; + +/// [Decorator] is an abstract class that encapsulates a particular visual +/// effect that should apply to drawing commands wrapped by this class. +/// +/// The simplest way to apply a [Decorator] to a component is to override its +/// `renderTree` method like this: +/// ```dart +/// @override +/// void renderTree(Canvas canvas) { +/// decorator.apply(super.renderTree, canvas); +/// } +/// ``` +/// +/// The following implementations are available: +/// - [PaintDecorator] +abstract class Decorator { + /// Applies visual effect while [draw]ing on the [canvas]. + /// + /// A no-op decorator would simply call `draw(canvas)`. Any other non-trivial + /// decorator can transform the canvas before drawing, or perform any other + /// adjustment. + void apply(void Function(Canvas) draw, Canvas canvas); +} From 7f7a3c0d17dc8fb4d41abebbccddc0e6be0bc36f Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 15:51:27 -0700 Subject: [PATCH 02/34] Added PaintDecorator --- packages/flame/lib/src/paint_decorator.dart | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 packages/flame/lib/src/paint_decorator.dart diff --git a/packages/flame/lib/src/paint_decorator.dart b/packages/flame/lib/src/paint_decorator.dart new file mode 100644 index 00000000000..d1f7e619f1a --- /dev/null +++ b/packages/flame/lib/src/paint_decorator.dart @@ -0,0 +1,32 @@ +import 'dart:ui'; + +import 'package:flame/src/decorator.dart'; + +/// [PaintDecorator] applies a paint filter to a group of drawing operations. +/// +/// Specifically, the following flavors are available: +/// - +class PaintDecorator extends Decorator { + final _paint = Paint(); + + void addBlur(double amount, [double? amountY]) { + _paint.imageFilter = + ImageFilter.blur(sigmaX: amount, sigmaY: amountY ?? amount); + } + + void addTint(Color color) { + _paint.colorFilter = ColorFilter.mode(color, BlendMode.srcATop); + } + + void addDesaturation({double opacity = 1.0}) { + _paint.blendMode = BlendMode.luminosity; + _paint.color = Color.fromARGB((255 * opacity).toInt(), 0, 0, 0); + } + + @override + void apply(void Function(Canvas) draw, Canvas canvas) { + canvas.saveLayer(null, _paint); + draw(canvas); + canvas.restore(); + } +} From bd4ec466a490ab73b6dd66a3c80ea87a21c0bf4e Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 20:38:32 -0700 Subject: [PATCH 03/34] define constructors for PaintDecorator --- packages/flame/lib/src/paint_decorator.dart | 33 ++++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/flame/lib/src/paint_decorator.dart b/packages/flame/lib/src/paint_decorator.dart index d1f7e619f1a..df002a44010 100644 --- a/packages/flame/lib/src/paint_decorator.dart +++ b/packages/flame/lib/src/paint_decorator.dart @@ -4,23 +4,34 @@ import 'package:flame/src/decorator.dart'; /// [PaintDecorator] applies a paint filter to a group of drawing operations. /// -/// Specifically, the following flavors are available: -/// - +/// Specifically, the following filters are available: +/// - [PaintDecorator.blur] adds Gaussian blur to the image, as if your vision +/// became blurry and out of focus; +/// - [PaintDecorator.tinted] tints the picture with the specified color, as if +/// looking through a colored glass; +/// - [PaintDecorator.grayscale] removes all color from the picture, as if it +/// was a black-and-white photo. class PaintDecorator extends Decorator { - final _paint = Paint(); - - void addBlur(double amount, [double? amountY]) { - _paint.imageFilter = - ImageFilter.blur(sigmaX: amount, sigmaY: amountY ?? amount); + PaintDecorator.blur(double amount, [double? amountY]) { + addBlur(amount, amountY ?? amount); } - void addTint(Color color) { + PaintDecorator.tinted(Color color) { _paint.colorFilter = ColorFilter.mode(color, BlendMode.srcATop); } - void addDesaturation({double opacity = 1.0}) { - _paint.blendMode = BlendMode.luminosity; - _paint.color = Color.fromARGB((255 * opacity).toInt(), 0, 0, 0); + PaintDecorator.grayscale({double opacity = 1.0}) { + _paint.colorFilter = ColorFilter.mode( + Color.fromARGB((255 * opacity).toInt(), 0, 0, 0), + BlendMode.luminosity, + ); + } + + final _paint = Paint(); + + void addBlur(double amount, [double? amountY]) { + _paint.imageFilter = + ImageFilter.blur(sigmaX: amount, sigmaY: amountY ?? amount); } @override From cd9e3a7aa2eaf09de46279f432f502b65baf9e29 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 20:45:33 -0700 Subject: [PATCH 04/34] added export file --- packages/flame/lib/rendering.dart | 2 ++ packages/flame/lib/src/{ => rendering}/decorator.dart | 2 +- packages/flame/lib/src/{ => rendering}/paint_decorator.dart | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 packages/flame/lib/rendering.dart rename packages/flame/lib/src/{ => rendering}/decorator.dart (93%) rename packages/flame/lib/src/{ => rendering}/paint_decorator.dart (96%) diff --git a/packages/flame/lib/rendering.dart b/packages/flame/lib/rendering.dart new file mode 100644 index 00000000000..057934c9391 --- /dev/null +++ b/packages/flame/lib/rendering.dart @@ -0,0 +1,2 @@ +export 'src/rendering/decorator.dart' show Decorator; +export 'src/rendering/paint_decorator.dart' show PaintDecorator; diff --git a/packages/flame/lib/src/decorator.dart b/packages/flame/lib/src/rendering/decorator.dart similarity index 93% rename from packages/flame/lib/src/decorator.dart rename to packages/flame/lib/src/rendering/decorator.dart index 9ded9cb84ac..52e8a266c74 100644 --- a/packages/flame/lib/src/decorator.dart +++ b/packages/flame/lib/src/rendering/decorator.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:flame/src/paint_decorator.dart'; +import 'package:flame/src/rendering/paint_decorator.dart'; /// [Decorator] is an abstract class that encapsulates a particular visual /// effect that should apply to drawing commands wrapped by this class. diff --git a/packages/flame/lib/src/paint_decorator.dart b/packages/flame/lib/src/rendering/paint_decorator.dart similarity index 96% rename from packages/flame/lib/src/paint_decorator.dart rename to packages/flame/lib/src/rendering/paint_decorator.dart index df002a44010..28f59427a9f 100644 --- a/packages/flame/lib/src/paint_decorator.dart +++ b/packages/flame/lib/src/rendering/paint_decorator.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:flame/src/decorator.dart'; +import 'package:flame/src/rendering/decorator.dart'; /// [PaintDecorator] applies a paint filter to a group of drawing operations. /// From 7cfbcd7d9b7a3b79a950e247151f5afd4ecabb1d Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 20:54:35 -0700 Subject: [PATCH 05/34] wip --- .../test/rendering/paint_decorator_test.dart | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 packages/flame/test/rendering/paint_decorator_test.dart diff --git a/packages/flame/test/rendering/paint_decorator_test.dart b/packages/flame/test/rendering/paint_decorator_test.dart new file mode 100644 index 00000000000..b56e07ca89b --- /dev/null +++ b/packages/flame/test/rendering/paint_decorator_test.dart @@ -0,0 +1,29 @@ + +import 'package:flame/game.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('PaintDecorator', () { + + testWidgets('nnnn', (tester) async { + await tester.pumpWidget(Center( + child: SizedBox( + height: 100, + width: 80, + child: RepaintBoundary(child: GameWidget(game: MyGame())) + ))); + await tester.pump(); + expect(find.byType(GameWidget), findsOneWidget); + await expectLater( + find.byType(GameWidget), + matchesGoldenFile('nnn.png'), + ); + }); + }); +} + +class MyGame extends FlameGame { + @override + Color backgroundColor() => const Color(0xffff0000); +} From 4e243dad6328491cfbdde775fb96c6688e56cea1 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 21:22:53 -0700 Subject: [PATCH 06/34] feat: Added size parameter for testGolden() --- packages/flame_test/lib/src/test_golden.dart | 24 ++++++++++++++---- packages/flame_test/test/golden_test.dart | 12 +++++++++ .../flame_test/test/golden_test_small.png | Bin 0 -> 905 bytes 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 packages/flame_test/test/golden_test_small.png diff --git a/packages/flame_test/lib/src/test_golden.dart b/packages/flame_test/lib/src/test_golden.dart index c14ee75a5c7..70138b7a7f3 100644 --- a/packages/flame_test/lib/src/test_golden.dart +++ b/packages/flame_test/lib/src/test_golden.dart @@ -1,4 +1,5 @@ import 'package:flame/game.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:meta/meta.dart'; @@ -23,11 +24,16 @@ import 'package:meta/meta.dart'; /// necessary game components, and possibly advancing the game clock. As a /// convenience, we will run `await game.ready()` before rendering, to ensure /// that all components that might be pending are properly mounted. +/// +/// The [size] parameter controls the size of the "device" on which the game +/// widget is rendered, if omitted it defaults to 2400x1800. This size will be +/// equal to the canvas size of the game. @isTest void testGolden( String testName, PrepareGameFunction testBody, { required String goldenFile, + Vector2? size, FlameGame? game, bool skip = false, }) { @@ -35,19 +41,27 @@ void testGolden( testName, (tester) async { final gameInstance = game ?? FlameGame(); + const myKey = ValueKey('golden-widget'); await tester.runAsync(() async { - await tester.pumpWidget(GameWidget(game: gameInstance)); + Widget widget = GameWidget(key: myKey, game: gameInstance); + if (size != null) { + widget = Center( + child: SizedBox( + width: size.x, + height: size.y, + child: RepaintBoundary(child: widget), + ), + ); + } + await tester.pumpWidget(widget); await tester.pump(); await testBody(gameInstance); await gameInstance.ready(); await tester.pump(); }); - await expectLater( - find.byWidgetPredicate((widget) => widget is GameWidget), - matchesGoldenFile(goldenFile), - ); + await expectLater(find.byKey(myKey), matchesGoldenFile(goldenFile)); }, skip: skip, ); diff --git a/packages/flame_test/test/golden_test.dart b/packages/flame_test/test/golden_test.dart index 2b10e587420..f802fa1b03c 100644 --- a/packages/flame_test/test/golden_test.dart +++ b/packages/flame_test/test/golden_test.dart @@ -38,6 +38,18 @@ void main() { goldenFile: 'golden_test.png', ); + testGolden( + 'Same test, but with smaller size', + (game) async { + final paint = Paint()..color = Colors.white; + game.add( + CircleComponent(radius: 10, position: Vector2.all(100), paint: paint), + ); + }, + size: Vector2(200, 200), + goldenFile: 'golden_test_small.png', + ); + testGolden( 'skipped test', (game) async {}, diff --git a/packages/flame_test/test/golden_test_small.png b/packages/flame_test/test/golden_test_small.png new file mode 100644 index 0000000000000000000000000000000000000000..d9db6958ee5513cae19f3940d2cf3d00c73b5964 GIT binary patch literal 905 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_owhPZ!6KiaBp@AM}+@lyJRRIK_66&@z_k21_q6PGOPV!R)VD@<2yv3ClrW z7n#4!wS8Z(F5kU-cgy|v z%PZ$C&z!ZaGaF_1?ega49_HU*9)11m zd}d3z{=@OdTXTTYr>CXRWejO^?-X%sErH|NfKB>#pYg z`Wbe}ZO@)PKIZ1;>DAZXzI_`xuXOF6=9mq4^UQy>==&>3Z(jFWZGP!mmQ9B3hZ85C z-xbDmQ{uhCZR0=XXTSYE_tEv?u5~ag)Basa36`#F*lS$BX2(ok`vZ12(v<{{-vs)n z`|RgG;r5f)yndB@wSGqarTrbLk;^LQ+5ee-d-?L^2gT#m8XZ2^4u>StBLC#)${PV| SS3d`4Ck9VfKbLh*2~7YkD=PN@ literal 0 HcmV?d00001 From e10e8a5d2d99076b3545999e89174688799a00c7 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 21:27:41 -0700 Subject: [PATCH 07/34] rename key --- packages/flame_test/lib/src/test_golden.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flame_test/lib/src/test_golden.dart b/packages/flame_test/lib/src/test_golden.dart index 70138b7a7f3..5d5832261d1 100644 --- a/packages/flame_test/lib/src/test_golden.dart +++ b/packages/flame_test/lib/src/test_golden.dart @@ -41,7 +41,7 @@ void testGolden( testName, (tester) async { final gameInstance = game ?? FlameGame(); - const myKey = ValueKey('golden-widget'); + const myKey = ValueKey('game-instance'); await tester.runAsync(() async { Widget widget = GameWidget(key: myKey, game: gameInstance); From 416192e5f337e4d5872d1f75e418e7b6d3eb5fc7 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 21:28:02 -0700 Subject: [PATCH 08/34] format --- packages/flame_test/lib/src/test_golden.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/flame_test/lib/src/test_golden.dart b/packages/flame_test/lib/src/test_golden.dart index 5d5832261d1..846f5772f96 100644 --- a/packages/flame_test/lib/src/test_golden.dart +++ b/packages/flame_test/lib/src/test_golden.dart @@ -50,7 +50,9 @@ void testGolden( child: SizedBox( width: size.x, height: size.y, - child: RepaintBoundary(child: widget), + child: RepaintBoundary( + child: widget, + ), ), ); } From 2cb25247f2ce254343564a4e31ba3b73df43a879 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 21:28:30 -0700 Subject: [PATCH 09/34] format --- packages/flame_test/lib/src/test_golden.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/flame_test/lib/src/test_golden.dart b/packages/flame_test/lib/src/test_golden.dart index 846f5772f96..19bf55b7039 100644 --- a/packages/flame_test/lib/src/test_golden.dart +++ b/packages/flame_test/lib/src/test_golden.dart @@ -63,7 +63,10 @@ void testGolden( await tester.pump(); }); - await expectLater(find.byKey(myKey), matchesGoldenFile(goldenFile)); + await expectLater( + find.byKey(myKey), + matchesGoldenFile(goldenFile), + ); }, skip: skip, ); From 6a1529848a686989c562c4527ad848bb5cf67ed8 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 22:46:16 -0700 Subject: [PATCH 10/34] added tests --- .../lib/src/rendering/paint_decorator.dart | 6 +- .../flame/test/_resources/zz_guitarre.png | Bin 0 -> 19766 bytes .../test/rendering/paint_decorator_test.dart | 100 ++++++++++++++---- 3 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 packages/flame/test/_resources/zz_guitarre.png diff --git a/packages/flame/lib/src/rendering/paint_decorator.dart b/packages/flame/lib/src/rendering/paint_decorator.dart index 28f59427a9f..8fb7a0a0799 100644 --- a/packages/flame/lib/src/rendering/paint_decorator.dart +++ b/packages/flame/lib/src/rendering/paint_decorator.dart @@ -21,10 +21,8 @@ class PaintDecorator extends Decorator { } PaintDecorator.grayscale({double opacity = 1.0}) { - _paint.colorFilter = ColorFilter.mode( - Color.fromARGB((255 * opacity).toInt(), 0, 0, 0), - BlendMode.luminosity, - ); + _paint.color = Color.fromARGB((255 * opacity).toInt(), 0, 0, 0); + _paint.blendMode = BlendMode.luminosity; } final _paint = Paint(); diff --git a/packages/flame/test/_resources/zz_guitarre.png b/packages/flame/test/_resources/zz_guitarre.png new file mode 100644 index 0000000000000000000000000000000000000000..e3f78bd5c46f026c757ebcb321abc51158f46000 GIT binary patch literal 19766 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, findsOneWidget); - await expectLater( - find.byType(GameWidget), - matchesGoldenFile('nnn.png'), - ); - }); + testGolden( + 'tint effect', + (game) async { + final image = await loadImage('zz_guitarre.png'); + game.addAll([ + SpriteComponent(sprite: Sprite(image)), + _DecoratedSprite( + sprite: Sprite(image), + decorator: PaintDecorator.tinted(const Color(0x8800FF00)), + position: Vector2(100, 0), + ), + _DecoratedSprite( + sprite: Sprite(image), + decorator: PaintDecorator.tinted(const Color(0x880000FF)), + position: Vector2(200, 0), + ), + _DecoratedSprite( + sprite: Sprite(image), + decorator: PaintDecorator.tinted(const Color(0xAAFFFFFF)), + position: Vector2(300, 0), + ), + ]); + }, + size: Vector2(400, 300), + goldenFile: '../_goldens/paint_decorator_tinted.png', + ); }); } -class MyGame extends FlameGame { +class _DecoratedSprite extends SpriteComponent { + _DecoratedSprite({super.sprite, super.position, required this.decorator}); + final Decorator decorator; + @override - Color backgroundColor() => const Color(0xffff0000); + void renderTree(Canvas canvas) { + decorator.apply(super.renderTree, canvas); + } } From f7b23b6ce168804038c6c4f16bc6d0a16d7719f9 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 22:50:51 -0700 Subject: [PATCH 11/34] one more test --- .../test/_goldens/paint_decorator_blur.png | Bin 0 -> 47764 bytes .../_goldens/paint_decorator_grayscale.png | Bin 0 -> 54810 bytes .../paint_decorator_grayscale_blur.png | Bin 0 -> 20982 bytes .../test/_goldens/paint_decorator_tinted.png | Bin 0 -> 40556 bytes .../test/rendering/paint_decorator_test.dart | 18 ++++++++++++++++++ 5 files changed, 18 insertions(+) create mode 100644 packages/flame/test/_goldens/paint_decorator_blur.png create mode 100644 packages/flame/test/_goldens/paint_decorator_grayscale.png create mode 100644 packages/flame/test/_goldens/paint_decorator_grayscale_blur.png create mode 100644 packages/flame/test/_goldens/paint_decorator_tinted.png diff --git a/packages/flame/test/_goldens/paint_decorator_blur.png b/packages/flame/test/_goldens/paint_decorator_blur.png new file mode 100644 index 0000000000000000000000000000000000000000..37a1bb0982ece36c029741281eca9a6122274340 GIT binary patch literal 47764 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 z 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 literal 0 HcmV?d00001 diff --git a/packages/flame/test/_goldens/paint_decorator_grayscale.png b/packages/flame/test/_goldens/paint_decorator_grayscale.png new file mode 100644 index 0000000000000000000000000000000000000000..f2beca2c1f9a8241016d21ce83e1a6d93100f616 GIT binary patch literal 54810 zcmYJ4by!qi)bEGx?hXZMkQR{;5QzbaVW=Slq*I!qL%Ks61qPX+q(fR-=>h2y=>}=M z=l9kq`s|k*K{^)&+qu4S~NG@o|Bl6~9)V z1HUld>#Dv4RgE(50B^A0zf{x52VQV|>u3;&9i*nLsPCJ%->z22rRL50mnA9s`Iu|a zGuzEKOK2Em38YrvYJ&R+n_h(+iv#1cbx4YF^1I2fS0wzE%@bPu**jTwkHiEYJ3VHw zd^~|mUW6?^ht*1$VU(Yd?HY8s>?X)5yB_hO?ZZI3`$~Y(#b}+cRL_Tvfe&u~*00=s zFxgLNI9m~(ow|{5jV90kxz1^xxG!Ova>3}DTMz49cQRf6-{lZ1)-?AseHT8)1Kr|)t3^C7CW?609YzE5xiOba)#W5sg5RAC z{90L2MWHb%mOk!fF2g8aS_B8Pg?ED#$xWN2o6fm7IIwZU6=$GJlW1MgYN4xW=pJ&i zaFw$218)$Op3|f6oxM0_R({|~>YdiyYp=3@LQ`{d42R3@alm)1Hx|sx%d?OxG;cBl zxh;ft^wt{+h%hFIFq2YXWBfULwl3Y_^3`RBrEJq9Myo8`yN!ecdtEvzy$Sa*R3!nc z0yUl4T(6v!{84G$N2CvLd!24#fXqFya4m{Biggx(2-bMkQm^dJ{3y|inU(deIHRRZ z{`&9V*jrm$vx1VKrv0Xzs$8(HI`Idk`UPiT%6@FU7od&XqutBwzy@ZDJc^@721@CTYC)g~LV&=N&C~vvPcJ;^1tRh!USKU)4-wC+I56Qagz^hfIt<)#4M?{$%8$S$m z;LW5vY;qigQ!m*ypH5psa4`DxttR>Ub9x1G4ob{mBCLJRp2BtFvgT`^2fhYVbDRVN zs`>oBx1l_-BDp^mlz}m(cBp}2Tvs~!Jp9BEpJAS;%~n6^fu~{Y3QY?*$-l;c8;!7x zj*E*ksq7W3)O;E3M1e!W5zC3sQDZ9PT1G7OnjfPAfwvCE_(0!^Zd}B{}7q z*VtFzvV;UFh_^XzO~X)Yitby{?4l(Xtk*I%z+wX))zp-pshL^F!oe=B zCya<5}JIc1gbj&zs`Ekg^(ZHn!K=42{;B&2dHK3u~SyDdT{?9xk%6%0C82ClE4jgF2o zg3m@~s$9x7-IY%eMm3{dEvw_okx4qJ_|z-u-2Y%s;CHw`uh@aaw(uH{BZ zY(uc4s-)b{(!hK{{Ev_NgI_BVlUp}Jl_PGa`puVYVdsP1WolQoA2(n`*8{<6;G%hR>T$UjW0jl)jzjT`tm;msUINK z!*>!FXgh-W`geP+;>OUEzP*tExx$UZrM7-wOL|~A0NZ+FdmCSO*pWe6vNE9=t?;*zIbAAPy;_Dv;rYvOBqpaF=m$oqkiQ;*_|zT zJXNkUC`{vyx6S=c7XlscO; z>`kj9nhh8;t?ZxGO(2tRzM`s}5PK4|R|j^njpQK~*{eHmTA{RFp2d@t3deeU> zxjMRpUN!;}g}GYtg-`kU%mHBypAd(nqAwXa?R)c4#ubicjyDtqt5%3 zo>+u6sdC37xwO%36-BgyCbeaG=K7Y^)p)MSSkP031*Q27R{s9aa^y}AcoK~41WzIF zBj^7Oe`uPYU*j7UhR@!})A?akc-3w*j?dyiE^ILVB-86fAE{y~EBoCr>TND_hmxt# z*+!pW?Z~ye!ALUVR`^c#A5gP)X$OH*UAxHW=vtO$A0M9t^T^orrSRGzW1*~!56YeV z=J35i54}@&z2B=q0J*vEsDrsDdr|!zYUTB$+N&dQSigV5S@yM!)f)z$L3&c%%9wj# zR-kcxF6;GS&S)fiAFkWu5K@Yur~6hW5rYWa3?~bk>{t7#T?3zi+|n7V4b6098E6BYrKMUTR2u*^k&DrLapL3}j5P8($79Mw@!v%zT+w=>3T6f*U2`ONnQUE;Ph zAeOTe4(Lx{hf2xrx>2GRg=0^%HAS*D)!jAW)Pp&i+|e8K=J1oghM^AL)}j1WaArc9 z3@8W72j<;gmBFo{zT?IH2W&6gq+bG_iJYH<$?uM2ASSKVc&kaQcTN|7H|AvQBRLI7 ze#rS%WAWvzp3y#i5SQz%o}g5sV6QXR4ps}$VkWR+SZ7mxewCfK5ghk(ps;zL6*>G; zr2$9GT{5ykO@YSJ7pAUV9P~ol|L+Qp0-CxSPz6%1%N8xBoUxz7Ql4A5GF2K7X&1CcKZOQxOdEeLOJBkDFX1BGed%ZzBFl$qf*-@N|<`U5nm7v#H>D z{_mTC9%QakEYR?K>Cf`I+`HE0>8#dt%G=x9$QNIIWrlGzX0025t>CDHW9brip)l z(I{!clrF+wpkBut5&PC%J0re=3>nF5LoP}cvs4h(N@CRHtT*g*ub!S#wzaj*P5Kuq zzG?Alg8}mLThKk@+4VPrRxpV-^qHXr zr`i2IJZdRgob4CpZ`urmfv7anNzOUdjCHa58l$e2En-%2R_Cw*lquCL>N|}#Kx092 zlJK@cA;rEi!Q;7~xRf#UQ~JZ@`6-osDI1?saXgImr9A&+JZa@zv#CC%Dpc1N+`IU= z3)%ZVt!P*!D=W+Q?#kU>X5hP0CzL708;FT7W)PcAeGAymwY_a>;UDARdp0emZ)Nfs zds}>YF1_0lM2IW@8s>iHtGR%D&i!c4%hkH%V$)WOwxW+Bf4N8>P{G$aEb|51u&TR5 z_mRq>h>*qRsxhI?B&iYo_S*6wS5Tc;zZN-7y*~0ztg9#WH#_&^9;q;)Kf3ElnVT7r z9oADWTtSEB%2v#H<4D{p6qdZoETCf1?zg9TV_VHWM`qr-U4}8Ikh;uE&^u zC~8R&*h!S5ed)v>qa0|nM!5Pn+`YdOYzbJGdHuSDv zx2W+G1#TmEzvI`y6*6eVpVg~!vs>cPwQ38c2x=*Aq?`2&@+L`9VRS68yi0r>+qr8d zQqy}pe`86os1~s&cB%^A%gE?DIy*d=?1Y?HC zOuICF?d)_-*M`9fC#YRySvRh(egzoYW_-Jae=_K^Pc>Kz(8H^N3^&G3i+@@lQ*0B2 z9pXNAelJ(JBAw8SSlK|8_z1G?QiGPwuBsD!<$C`soPLmg2!h(Bc|pP|AoG-TEx+q9 z@ZY}{o31S_$BO1#?b-?MlzvH^eLOz#5z|D$9rDRy4D%O((p}mzX#tKi|HrRG35*`O zce^0Vm7DTC^U?|9EK`zTJ(gds!b?vI;kq)IAI>&+ws*=y>lO~yug|t{!mq(2m1id; zZ3L%3kHE!X(u$i2b=ensZIhcE>XLDb^Yg>F)47IGT|X;K*!<}>|5z+w*TO+rM+=C0lkWE$Zg1zBEn?lw*BDBy<*cU*C%^+LraBVMf{L-S*f z_=2EduQTBYLwkx|kCyM&qC=xmbwie^F)JS|@i}|u=8QItKF%7AN-5%+w-R_%SQ#I^>R ztCePrl_V8vz^h%FZ^|VIl79BA99y~76yYt!ngodB_Nk6T(aytjm?xFB9$N%zl25On zn|x)*lMqF@0&#d56pU(o*@HGFpDZ}|G{`tw()Tp-_WptRxuRitW$otXKWX{luJn@W zrxLB|AiBLgY_1}Hg$b>=kgxbBD zWC+SsCv=UO{zSV#I_XKd`bL_z+*b!`O)ORln}CsHX&{fTT=h$hA6>Se)*<`L`CRhF zb6AsIjcwbt9^Tc>8Dp(Yqy(aCi41oD-Q?}#(@u7WzJ}p#w-P95Pk^VYyxNwGqjqIl zKnD3f1<}AbmBuqZF*B7LFP*P2Q&V$k2Yx*AX$U2JsE8lF=K8{XlxvCi&+}V?e7h{a zec8FZ;!Q@x{mv<+s^Q}ndPS5wS1yhFY*9=>PFnfiHtTHI7*V}zuNJx> zQ+%~`ye|u}iCyN~KQ$9oy{lC9E1JF6WOw4jywhI5lU9i@6r|%~|AZxORRCfhc>3^j z(~q*>o8TcA!O62$8Cv05-*#mi4)bhKMk&}lb-Eto?yTI8wAD)) zZ8WbJfe)5vnf!Phi{1j{{Hz|cn97K{L5f|6DD-Z?Dfz~(D_vSeJG7l zZ+F;=mM_%RQ-y?7+fG7z8GB zsJZd!9RRgM(gu?)q=M)tk*+JS*ggyslq zCTT19T;U-?;hVqcz++b*cmLpP`v%$M3`g()kr!V#(jBS6J6XhIoJ;|L46J#ubrGqabn(|viHn{DCBxh4>2y5Z14l~e+*fj znT^flfMOTURZvg>EE4glm)XB(8_0Ie%$)~?8@$4Qc33V68|lfy_SQxQq!QKY-p2aS z6n!BjqboE(MFRT(TM@*|B_u4Izz^C>mDzpeD&}P^nb9!cYPq!3oI5VFNKG;ao-V>x z3^A+Dy5I$~Xx9M&HR`m(nxCHo`{w?kpH_FVL}uMXpRvUx+uE&5?uzMtkUC2J&golF zyZrY{|N9>&=6QwoYd2X zQ$|yPNM^oCke(6BLl6`C{{GkcdsctAo*|7{nZN@sV_T9;D_=*#;Yw#xczC!#d=v| z>06??KkZF=v@#9CBYxu- z{*06J@C8N5EDVJzkv_UMZ2DXCC(`hXH<_mb&e?n+|-+Myaf!?LH5d%Wu z;KbQGezs95;nloP<#L`rFM?&`Ou`n^K+EdP~+UzZ2-K>vGv zn8%5ETIVSM!%OWCz$umg+SElc1=!q5vAAk%`N_v|T}Fwbj&TaG@0zBZ7uPZ#h03?d zHie0)vzb0Hcfe~uZWv-zQ0r%S6QIS7-(2<8J}YnSw~P*!oKs3tHhT3dG}A+)Cw*iY zV#ZapNm$+Hs6b}S%q0DO0?~z*!IGy~>m`%_ZXv?c40RUSeU#R!rKKf`rN1;b`_ub} z7LW_1I4_wEXpHAVL6E~LH|X3N>;j~%{A*!>Ur>2mir%XflEJ#-HqDJ9(afD^ z^dSoa1q1}l@aB6d+_YZQkV>2=y0d(@VIaokVk(FHt*%X(ck`t2Xdu{JKDw-~aGKrO z%PE>%*dVHkJ+$fS>fH%%P;<1wQLtY;^0~Q6IA0VnyZHAm$nwvpP^#^R9D``kw}h-_ zO)`fWVYQrBaj_Qag}UPRLB9^xd~nkUyP)193e5GRQ{BDzd4?*#deV1iFlz}dE9COD z@1tO7hH9~2C=mdR_+A}b4z1wU7^K+C71DL!U%1^^KyWHNFAol!WrOaT|AyG6mARO* z`RGYMw5hc^Sg0ri#XQim;0j)#B|(MIOeq-RUG2G_{~h1Ei1)L5`2aaZ4Zt#X>&F0` z!T`{g4Fg6nW<~4juz^A2gQBybJFMR2wp?k>_6XUf?jyXU=kE45HvH`-am=wf7_p6q znLKE42K!EF{(S`Vi|Bjspd4Gy-5vUlazIpT|I0c1aA?zu?69(rFGjHAQ%W9Jq$ii( zhG5>!xW)dvy~CEzG3V|AdwBPu1N_Cd4w3NbFx3r0f&TCnjpY_3#DOQvkXA~=u+-kD z)GpPpkF?%}zA#jUj4q1fKjo%5QZ(%L)zBLEJ8BT|;f0J$4_r>l0n6zwf;@7Ets^$M zTIjL*-+uq|Z3?;DeKDYA(y04twkWTGztMlvPL? zvoXVtJ$l66&Vslhge}vQb*a6kRtq2CxdUSM^$8!u-^l`qN zh>mj>AHE!3pNbwTFucA$)4~h(5qYKh1*6bBXMQ;qZz_;h`($$1Som`Bt7&Jyo8S1$ zHn+Yx>gLJbTZeQ{_LJka-qd?a5WvC_(`pq+2Fz4@j*G~hNdxx-Y7mOzo4wbXr%Ycs z9$9VqOD5MsQB>?v?8e4BqN(3mn_i*(p#N4A69fB%*-p+6ufccWkWwAD27;x^sU7{p z1c-{)N1~w7$F@-Jn|=!TSUB`hk(~CzzMZ zOprF_^D8_poaX|fZ24)GkFj%EOPJFMis%UMRC_6w(H|OWz1TGPY_VNaEGN@a_ntSnO8+^v7rGFm}DtM-31QeH>fk7N5(~KOg(emI~%w3 z+l(U(_V_RR?_!D-LNQ+qS7Y_89A2En?dX7XIrF`-UUR?N`D!$$-yu-M*O}VMW@cug z_G5XtMi8r%ohUv031LyF2sO}Mh&maQVYwT&h!(<=*4zw5);A9vGQhN`UA4m2Gn{70W1G`G zPZ|1zSFheQI<#D4RziF``G52C>%7IaFbUk6f?j{y%7fRx?YIy73AX>b8*7-oDZqIBkd*s*XJ7_gwe2t@y{bD)NsK%ePHaE)PBc4 z_+_XXrd+N$C%4gzF>e&%>#qm&JUAwIHMW7n$&Oz?ha3l_F?fd$8cEvt;12SI&~}{; z4@1e!k@7@?wU~mc0Vkz0`ITgLH81#^f;y9I#|n%(3zjOcN868H}Jb1xK1?DHdz=&omjz0ono8IHN4nqDrl{+CCkZC6~)#MB(14 zbC|~?pVE_YD&&>mceFz4HB{rnk8ml_-LhT$)(*ASq_7U6J?!zFQ_Em{9g!@4q~Z!T zA<_4)0rxzosiN=>fspjR1EY)H8m^F!u|ZF7!3oPg^ArygGqeu_bipubA=P177@Cfb z1Rb-4!k&B27m^_x{W2sl=bQHp?-95-dIjRj;sRsr5r-%mE?q6KX8mU zmAXUN=gWMN5y)OxlTd-5d`GStrHpLD4qgX)de$d4n>pLD6rfJE5*F{fG7in~H*l)< zPp-ufVQ@X@7)t zWe5uBh(?~>U7v-q1=|Axn&<=Kw7J840nxnM%zSuQTP}KXk}n6pIkz989ZAQ7c9<&E z4FB9b+^hb8O7mvv07p7EEtKL=eS__&CQnZYHP1&b8-UjWeRB^lR_2@x7HCmbQJ>1a z>m07Y<1(TVmUgBhpI+y){1TTSn0E?{@jziFgG+p1kIxlNQb>qt3a2;@D$Utv@l@En^T?X!yy5-N3c4gYu?fFWzt6Bb#CBsxCMk*^nt)uxfas4^8! zcCOL6TzUB0M6@8fZ7v6&^PqCa`F*(SCz17 z?B^`RxLT~aAZQ2NxvSHqQ>i}tr>g7Az#JbBsk=-JdcR06!HT&~eDaQkoi(Wc{oAnA zUa{3U-xwl>Ek-8XJWnn?+E*H=yDYo@$A-#N)g4yPHR98kXqwQXpc?E7iVi8}wO%v2 zZ%$vjYI)eks>>IN*6M5g?~iK~7}&Ex>AbKP@d*Yjnt_9O`1?mk|2ZIVq+pvPm+!uw z)CXR)MK25=`^quJ+(d1{j}}|fSfjz;NJ%tXurvB}-4N&ZyK5Locx` zNIADxwko8@RF|`Y4~LzlnHeScAmNTn@au8z-CABG5hj>gCFMfIM`hPA7x8+?8OzXX zcWx$1(?#gfgV&cBf5Q)D-GfVa6=XkJ3wZ@-9_U^;-?b`V4NMVyo*pg#R%(;lBF11f zWayEnm(C$bPW9&L_h)e%qF>hS5*WUwVX8B(ah~KEk$zcEfUOk3mlw)+va!~3pJW`^7g9;CMWFO zEc6qBVfNnvPW47--@p4tyouV`E$huat;64+9DvEfymm*L+L2%tRL?DGgcn{!D+&hA zDySm*5@{I?sMoT1h~F2z4lrgT3eyN&qLgmuC8<)?2oiT}`-64f!qF)lZ32zr_BEgo z^ALVO29V5C7Y?yjeMdQ1Xa@&3%nsmHet)BXnyk#8O`D1>my{))ts z%_awzO|3>YeFo}x^w9S*2*imdajQ+_K6d)`iwo!xy>_AJ^$*FjmVJH@e<0{G#zdlK zr9FUdYG;~3Tm8SrDqz#uVsP@Z!LrC_^}wKZ;W@nd{QK3RJF_jjBT$_JMAi3XJyK6A zBQsTLrLl*bD)^5JH*2FbLfpyH;1dGR;>8a;aZ$#`J)6ei!(VciFs7{edA@3;hfkI! zHAQ-zE2`DAy+cE4f_|_z#O>kL5nrzi?nSOhkgEsCwQ0f3TMg0`2+Q6*clU3rjcmB! z0Enm#H4Sa}ulYOVwC6qaL?dBws%w81H^-yDuSPZxBhJp4UbGqOxnjr)V`2>rb_@U4 z@3pTZvQ98<9b!f9sRW!~klh(MTSCsq{+S8W+AI9Fh+ELvAvi97>Fgk~;F%tKxJdp` zv(!@^uezNqGFZGBYB;B7CR_?ftryGYeKn<*Hwzw4N~?SEvBwmn*@HxAxP5A8b)s0c zG;}=uZ(pCvP*v%!;~1@08PFgN>l_+f%ESvCZn!+x5X~yXuh&#iXBYM}L-@CJbq(lO zkFQe@nIhjSF`L(t9Lt@+@$5hUR@g$?lc?;%rC#LAoX%|n-8#ZI(h43gpx5PE+0o?K z7=JG>0h@vY7Kb@`5m`rvEL>r+wVu!p`Dn~SM5KVkmb0`QnO5NX?8|#G*a2Gd3*<#^ zP)zC$zXbga$mNAA8R%V_gGvKp!g&`G%f-{^Cl+TvR-Ye}Z8QjI^d zZU!xncT)hf&$xXPMT0SZIB2UflcD_hS}wJ;{SzUX)2!d2>aZZU!f!l9`5mug%j!6` zf_$s0RLeRyea)fdXVw8aEj{JDuOu2ip4rZ&>3{SWC@J2`9?Ah{`zIfD!Dh{Uj=bCc z>%!Wff%RmA?2wLbNOipzO$!J6cQqo!8vWZ<=5)a-@GgT>4PK6j!NW4(!FhWh_tBZB z|Gg6}wajIlzCUl4To&r&6CKi*Iz;p+>qJc0{eD3{^X#~p&lGTL_L3`-Ph;u|$p<29 z)DZwiHLJE=l5IeC1kU%iTEaJ~mB8UBnR$K{FpJ^Ay9VRsE&i%0 z)nC?jsoMDI-CDHWMJb|@QkbYPwr3jzobWnyzwqVl&|iFk`~57)v5|m#>S1Vx^$!87 z?u?K(_{6y374HFi>9)5Fei*x}Y1lZa7KZzfLN;Z(*w_R!4Q}bQcZ?`;rmJ{P80rUX zNux*ubES~@V~);>6V$Jbv(Eq0&WF(WY$!wtSpHZm z-;WYa5~6spkW~~O6dWO1jg5Q)dSbY4C?sZ4dbR;5Y&^h9xnN@QQM0TsG=5}El#~5i z{GwPYQil@<+_D=J&NL)p%nN7+_Pw?ZjKfBgEBIH<;w^TyC!BAGMU6yWCy80=-#okG z4SD>=LAtuMXcK%gm^UdBcJgDmU_W6|!UD}8j_RmLH=&REFAXY=tg71rjDktZU})*U z`)TganudnR@|h|pcQB)X*HLlzq>ua-KPN=mMsv)^uQT9MD5{qOaK;hBox@qR$I7r~ zC0O}j=0!G>dB5s;a&e&@vgeQ7O;6UPg*2O*d!j5qVq7G?6Iy#zr|ow=Q|zd&ryet5 z7h!3O$lu&bsH_WI-jkJ>n9uv~IYVo02Gz1CoUx8$$thhI3&vyfpn{bLf4r z36*#Q30Rm!1s8H5MeJdZ}Q-Fb&p7g`=iId)# zdce3t1L4#V>UZfb?3m%sG`ygEIT|0}qS^1Jzt^cRLl6|G`62MQwSG#u-1NC2i$~z& z@^b4XSxXk;I5+I4bCa6|2UE6(Cd+66Zz>{)JGScij;>(B_b6JSR3rJ`a-#z zXvB0fya!Zodzaw2FFSHuTyGrMf9v@Z>VwPl0826I2e-xV8;>&#!&uMbcef4@Mw%*P zpd~!_$z3pWjINLumWwDS9jpaPq!h{1gY#K*5QduH;nC4-Y_9}~aym%~(2H1dkuuqw zI|ms;H7qd=5F&Se;*1=`N_*2ct=eMg5qjy~?GneBaCV*$zQT^ltQ@D@ zDl&c=#FEP+e9R*~iQSSdrluHgUD4UuxUV9~Ig3P>=v8&HGp2Bgj!(qNMvOy6)#qaA zL<(K0Az!BYx_u)~eDf;*=&;a8kqL|$4%HTBHicNH5ZDg)B38k>k+fxNddJGI>mlTP zaLmTnC5%sS-n_M#Bt2o~@bS*^mD{_Oo&^8|cE_n1d7kd?@9H}Ct7_L1jyRTle{f&f>kdXRRWJeAkl%8%7xeohK=(-3QqJi2A z@1>GsRvPeQK^@kV^z_SuXNF444IU(=Y-as~f(o47Yqj!Wbc2L6+iSQ7TyE)>Onle2 zJtFeYo7JnQ-G%W_@brR;-dC}#=Us@0xzPE%qr%Sjp3%v+7CxT-E%+vuGd(!Vnp-I| zSP$_gUX@pvH})a<_1{l}@k@HkzysLI=;;3Ys&e<|dU*wWMHyIN zSTRIP97n!_UV89lcYdF`jShQ!n+-*&K&XIFB7t{Q_{<$5|L+3Fc-P1oi*n#8ZJbJD zPiE~Tskt*nB|6|+5@YH3ULYUyi_R)|*0Wsh=_mywPRxrLC*BhYjuX0Y z4BU3Pzn6bc);Ednt_I}0RV>YNVr`&yc=qAy5?U$^dWlt!tx_CO9=U>Ph&Z~k<#VLj z5Hf29XAs^i55KChcw|Lriz%Z#L`a*ZSPOm*;d&Ah=3Y)>m;L+qlm@eAwhYOvxFrfb z+(-+=J>c-qKpdU$@dn$!W{V?>;SZHm^`TFwc+S!O5^7*lnT?a?#)NoelL)cc@q+l= zz9U?Y99~b*nrpVDNDiC_u>umD^WOP6b+vh?5cs6IOPoxv4D8fOQmFy)sxn}n-BeTN za$9;_S={c?hr(>zHJan0)Om-JE*x{L7V#`?D3^{UMByi_#&njn7Lr!HzEo8cL;O0x z;duC4lvGfJc{~_OqOCZT^0)>+1cyQyH@2P-INq?2prbuW59x@G(+lIX7YuHt{URdx zrI_OW+03z4Jhl@?5$NiT*}Cuq5MGtp-7ZI2_74x&0mjq~_#UI`;^L@()-9H0|4h|E zKH&mo+&4?c8BTnmiE4c0UK{&1rviC7ie8&Vd(N%P~#sC(U|ba`M3QA*D$qFJ(zm1KrArP^rF?IHl`yq1&B~8u!)M6&hvEEW4DPyp_fr>seJwzCSB>Q)&$JcU_Wb0{7&Igmzh6_zJ8&s4W=_3TJ|YQ`c^x012S z4$h;ujM{1)i=D2wYz_h8bT*gH{aMWo=W$!(S^h}iJk1ljV_4Sti}qc6t}*g^xhucSDOB$MWj1GZVHKnL zaU-dFG$k!Yq}_#%j7_%7Q?fU1%xv{+%zXXsR20Xqg+oSLRIQ1)wwW@%+c=JD)chPV}3ojz2m9L+L`nLi+?POhaw^3{nTqvrq z5Eoq=n3uB{4nCw2)bFhYif6vW-&NrZlY3?vQhY z45iVYZOUI*=Rd_6M%d!idg`_dubcQc!6*5WT zJUF@xq>s&9${S-_c;A$s8sS;bnZ2>IG#wN234D|N^W6;Bc@@U%&_X^2_?ZP~;9ULQ z@{<>Os&6M{wr_=T6hnY}-`LoAX)57HNzuPy{jYh)Ggf=byDwo2W@9lq-7GVPP@F-A zr=XU+Wb%i(&Kv)>#B}T6jr+@ZDZny1iA;AqzJ!jxQr`oPE4g`kTFbs0xcD?RU1a2= zP^skAbGsh^xwIofw*lK`q_ zzVB*c<4;1(Sx7~Qu=Zx~N&_Ol>mqb(cIpK_8a$m7R+33&fScGoUf*YbNBSlDOP+ha zE^#JH>c`LIhIu8D`8CsM0(^-q9rSg_QQ7@^>>hzEul&*=(FbPG-anum6cg z*Iwxyx?)<-b)}dE00e_AN#P|29a!aMpZQx&wKwnB(xrEb)IZU7BxL*u)^&wWEfHpt z6Iu{tk9-dDY&jR#f0rHmBp1^&>ZYM{g;D@c?#Ny&d0@ooX7Naib{oM)%6A7y6IG4=v*CcLo;i)8UzZL;w9_tH# z{qh)5492DCZ(3V_Q1&|cOxOzQ8Ui*B={VK0$609Y7_0lZg2r3$Msa7xOaPSYLcRk{3VytlvL4#mhZ^FT#+{tLl(Vr6j({&G!bQ`G>kAH^<{z zbYv;qel>Qa^e^oJ-VQAZ(mKMM*Kblp*(sUYUM_-L>>rJvEY9!OA_Wne;gS>@%#+NP z$hP6|L2OgeyhplCE@k0Ka(CSS9Vpg9K|rk)(PwbImcvvxeUFjCp9h~};pQ^{mx=`} zFGqCK2aOmR=BCBHIMqu_>re>5mi`$Mz%Od!CZS7pv{htBKMs_O^OLXZ!{P>@p zWU0-E2vwjN(vq0Fv%LB4k@@(>h{?69volTRc-y>%UeO#^+Ng>7a`lIaB_}9E=BB#* za9U`cyFik#mmKI;0FBQ6O2XZlrPhOOvh#7qTnokyWgJB}eMnyVmQu%QP zYA1;V&h#Y&UC-Rb|hCIUpR_GQC@=i<@GbUGT$ z{ZIXY@?%svuEuX0ogd!>2C@ENS4HX?vm+Y#cos3K5hQ8{52SJzucVVT&TZnG-Y`-B zac|BMFy_8)AqEjD$-<98_d#Uxw{v4|p73}>gqK<^&xf~sbM-~TP47gism+io)_;xT z3rWsy!?+7W)q*Y4{|@&}Nf;iR7w&W*>Bhvp${cH)YUfUmZbY{j@is>rJP>G@!x4*( z?C_Z@QwiV)2Mhy%z4@fB@Sb>JU;u|nn5{Bn=%*yhCW>W|x;geU{?txAtuWJ(%+#o) zXaj#5?#N@JPAPj*uVB`(X>O-RBSMQg1P%CcM3=RwBDD&j%=zr=kn;(=D_-J8{>`oW zQi)aVr?2{QzyGfn00#e^(TKch0S-NfNuun*nS!R4 zvB}}6-;MZHqVHDeA6@e1=<5s}_>@`2_mJnD=wrO5cs~NtBG@O7cqt&${JFN`x?Qp1 z#}UD=gtyqC>QNp+2uP%^RY_Nr{#ER$+cVLjgDPtCNT>9afIQXbzHBNmSIQjgnl^Fo9Bn#etj`(4@C{*b@~5JJXrn% zmAD@`0w3rtp~54xMoOtxd8I~+SB@UVassv(+9yw*^na^%C~Q*qH81cgUpSa?pn{TA zfo_)_@^%{mLPSUY=dz>G0by(NZ#c=Ll`om={4>8LYj5CTrZzwsV{898%@EbGe?QV3 z;FZ?F4?PX&?#hsB$b?bq{^se&zkA%Njqx%4{{VhLfxabhl}pK{PDr8~#Ch5xoi_{s zQqzI@R9@2&b)=~H7oy%SSkL9VGb zAJT1|OzHCbAP7o(U@19FGI2Nkp7W?Pm8gg1`|t41&Iam&ASl?{42MHJefref?#uL_`hSkFrHX2oa3Vf8ni^WeMhgxMYMi4~!PY?Dm3&RXk8JTlI)Tpgc6C3$sEqI=} z^f#M6D`q+mD+|AB>w{?!qZ7y+@Teq}tyC&oDNRiS1&P8GU?I758j&O=dtL4ak!|phwIe=_NCumE%M0XscDd_->FZzrx^?9se|8NHihQ*szJtCR zIF!+4l?|1ih7NYr)Su2@*YfZwLcYBMPe%xWe!rg_CaxXfqNlrDF45_93e$lqUrD

{RZ1A2Zxtr!rL3#;dhVGPWveN5LFo%#bGi2vQ2bPCe z0RM8Qjo<&#TeO$?(a`ET*x$#~Cr{CCwKBY#X&wnIJZaBa@fW}~cjM2Qd>);FX<%@L z<(>GGCr|MB@nh>bUOITO0UGrsU5BbV4DP0;<9OOGdn}Vy%lA^6t}4wK5m^tIRUHH$ z)Z#eK4wlu+V1IufPo6wMtJSg&_NHeW_^pa(dR{fG9wrC^FAa*V?y6+*m4lP5Q|F*v zm%${Psl076+v=%`KM|FVsdD92N?F>;T=5ci>snf2m zgM8aI_t$^x_WdR|{l3n5jrzwZ=hJGnN?JtUGOrsh16b;}Fj$uSv;kD}SHEg1s?+J< z(Sry09ieD4w{Hv zr71y{kHR#f16Y-Sm(Y1oA@03kiH_170cDVdJYRo2>EOMyIsWF)&mbg^0|bG<{@yMg zJ$i&*x0`{ZIv`7xZ=qZ@kmVxZj?nb1+&Y~O9zJ}CM~@z5UnDjlrN`yGZGdZ4vhnD4 zyP2(w4Gh_~aM0zntqe5f#RSm!lv1zPtF&!UgS$G&*EARgL4duzJv@5!$Y@`(Dv(;G zPSyceYRB=(WKu95uglYv&vnSgCyJtiU7z~(Y4Jr_*tM$oaObO;go0uW!FuCydKqQJrZ*U1P8FR3K}W4W{eV zLuP}e50WPEq~DpsDRH~)4&HnG7!P-M@j<-AkZ)6-T^1&skzu<7BFeN?Tq2T`f+*%L zkr<6@nnj+h01%PHEQ%3@00PRkS|AMsk#29L!ss?wHXx<{>U^?$N-v-l0QbaPlRejF z@#=on4)94g#CKnvL`S<*(uts*SauT>7L zolXbuz4smt4i3=o_X~DJJ}-V1I5ClJ>dR$|rP5F~7y1;TE{6?hRcWL2ytwkF$5nO- zF8O(W<2W`R?V)(>>g~!CWZA-+!ntT2Ko*7}rqd|~gMsz9P=wzgx+lZ~H=r|i**VwbU%z$l0@X~iW#m1&g}@KM;1 zYqKn}bIlhK%;2jMXeHPEXko1by?%Z$X<`3zf$zLJLw^yM;t3(Jy|sn+pFc;p+fHO< zAPWYNRY=PMvUF+^ToEOEF+G3&9NXL5g)c&%!NJsV=wbB@M>&sGUOXvfY0oJW&~bqv zpLjNK=1N0_9}EVS9iO7bVu2tCvZ+8loDc$ATU&Vk{CNi4Tmzd6j9kUw$HCRs)>d{9 zwyrI4)xQm-n9^yI)Sgp%8ZOY}YWqB#ZyXoMsyYIOlhR_@_Q4`bw5?lPTSo2JIv}f# zzi${tYS((Tip{2_t4i-G-UXhX@5hC2yK=>;3aj7OohEdFGNR-|K-c6q*$z@nq=rhy zfL+R^JfP=p3S70q2v46pNz}Rk9xUcKh!a+d)Hf6ng7l&3t* zFp4p5#RYJrR{kMKgwQtxE!keV@}Yng2Va!Cl{8))Xc6!rT$({niXu4(`r~m2ApsvB zUEt~QWwwRN+52cm5je;ymltJ`_4EtnNUBA+$<o2D!%GKl{eHhxW~OHVn9t`BLS$1@CIez3 z!f-gmvuDq;`f&j$7s#@eu}_#PQsIRVn9XJx2o8dv_Qs+v|5XRbsyL=iJx#y9GFG|U z+J!BxIsi-UPh^{#QheL(Hnz65y!L4FE%Qx*7p}Qh&$d3O4s9B6*??dj8S1qAy7jgS zz;el=-uYE*vV6kiQ-szl2VeOhp1bCFg3t;hJbL&rS>6o7P{#ORc>$qmV-jGIBByLb z=Yo(EuqfQ4G*-5&5KU>am@zydF&r0&vE5o?tDR`DC}8p`4OKQZm;f#c(n<>w4NsP! zei^0{iSZ+*(Na@_1ua)VKmgorEf69u=C1&P@+rg9knmUC0R33v`>#$gn=ip_((?F( z$#{gvkKaQ(ijsOE23jev^K1(T($eSQQ3hVNj#{TGaP=^4S3vTTsns|(&{8#UsIa=9 zZ3T^uPgR(1x0~(S?Am_8bg%gM7`y8{xDAnBP8?L4G+3_Z<#GujL^kDN%C`{7`F)Qc zKQ0-*y9Q?$xT`AbRosP0Hn`+=V_aT6eOJ4($z6x)#E+uLxb=stEM5F<{=R&5H(kqF zl`l0IR!yU|+igszQ|BTPSDNeAjSs15L0&(ue#w<)o#!Tq11z8NtfH!RSCx+LUI$m)e3F@Y-V7PP6){9Ymk;itVsEA{krj&Hs_XJLwVTS5rz?rh`U{dHTb#SOH&-vJugesMzfswhLTkV*8P4z+s45brp|K} z)d^3OfJ@%y)q7Zn$EMnS6;IpA0IqkSZW?uY>F#yyu&UBk{!tW_jsaVj)XZMtDkW}s zF5m+q93CFx&fy(|L70Y@_;7KKPPXNOIibXlp$Hv_Xh0?b9I~MJ%51F+8*r9Z5~j&0 z?GFHS1Btu6We#?N{I{TC3aD%&#Whq)#&pwE4${CiVJ1zNuG!++uGIZ*G%o^33&@fL z{G<~CBAHVC z5I8(M#Npv#;mfw)?-!n3gNo0<;`>6mIvrDbQ50b`8fE?_4U!2o=^7{=#|F4u(~Uem zQ#jjp4W|4r7K<#tI{wENHV6Xj@9*RA@X&jTqz=ehr2|xPhQnb7eifOtE;jk9WU4zT z*CAE*rZio^NpI_>_Fo0Ge1V!8uy}YE$l`mfnN|$yX$}Sh42MH&8P&;0Q$$1slK@4o z(*Sh&nr!QJNtJz7+O~F61!7D*Txr?*=DO2_Dt;9(^xDQ_=p43P6n1)FA=;;j&crdOanjFY&S+;37qlTZfRY87{G2J@k)8QN(9N_NVyQSkmRL82nfHpNe_v2~T1zWBa zUM9bGyPZuBng%fwP_h9iJ)b76m_AinHMOYxeF2uzV5vNYVOZK5i<9cG^LAw(B5+2yHGTGX=DId0QuJ^>2wmyZar>Bc@r_V-JW!Dr{*l@jW4!n1aRFQrfRC5w7*ni)4`LT%L>f~rok%zMWI`%{ z#hsC*Eeq~^Ls1YSpAsa^O}D2q0mH&{Cn;m444{$v)d3gNUX?Uu0@!aY zOL;I(krLrJ5O~oJviRRVy1=uOi$ZznWz~uj8@kD4lDH9N?LY;xl_6!}%jD`HZ1R$Y1rSe0iU$E3wl{u~6l z@=jEoCL}5zxnql?Z0LBqGKDkU^L*OEyLjnt%7(`Tu5?XF{Hki1IBcT=FX$I^A5rC;vYFzF`1lW(y{8<lt{(6sdg?ioM(pc2nnqK=&%jFv|`NN z04#*SNhnf)DiI2aU;X(pqBt&u=Wz&0NAc|0Gjuzh3{xxMq|z(22_1B;I1uueNu4jq zrwY_dG9Hhepi1%3L6iw>nZSz>!t1O-)8L@f?(VKJpL%>BO_L2Y@#9iV;dDMG&=rPZ zY2}=&Q{?;0sLn{wr(R}RyJ80AzJok}US|MMyR`Fmq3TV2vAX24`MCg~Pd@7oxP0ZO ziJy(X3k=!bp{jVcyqexOn|!8c)n;6z(%9PCvWBgjzONrAA?)W1n)d1QrK)ySM@FBt zTq{58wksDOpZCG#UZ)&Q<>aFQBcj@SWSQhDrBnu2`7ghZ!VnMcKS00N&j;&tjJY4r zaYrul(52}!Yz#i8zLAH0TsiR)KP2-u`MJzA}&PNXBc&$#j#AzQsSen z%VKHh=~4=EI3vKG2X=6y%HyY+uvP#}B3YR<0GtcL>qr!UTQ8RQ z==cJo(&nSu%0f!^2HM}>M;K&l2Q^I;2m-G&(tzSr4(F$KKd<7EwJXc{bL)UC zSDE$ueIsZGU_3*yDxE6O#r=GyC4AEy3Z-e=yPgjp192cZ zj!LZvT^D54X$Sg>K~A=hH5b3CcD0I}K56OND^p*+Zd!H2xMZj!lWB2Fa04m{ z2niu1LMj6dH3g^_MHY^+fdmeF3mo*~3;+=eOd502Wi*wyj(9jf!?dD4jYtG=;fy6LKK(dkH6G_}8VI-y9E|AXvuy((xYY_Z8vt?*WIls~ zNp2U|(!=TH6$F8o{e`L%Q(34T(0z`lI5;@Srg}|v(KNMMEewalY{28~%9Qsy^`^`1 zJ2)yie2&CXVRa*FS9|u6%O$G|Jehc#WbxHtxyVNgq}uXuILxN2uYzo+8gQ9xem?C= zk5k9phgAF1H`lGARnzpzuMfzw_0y}!Qbp?Hk%Q$r`DZp*sqlr1N|+%K0uLTM$X6c8 zqW0r~Twp@QBWDWJWeRWvrNq+knngNSO{Mpt0753OqHOSY9FN2OKH9oOsO?vk?aifw zEF$RTnmro;l}!Lrd_|T_o=5#WL#ExLfY1toSt~Z?TQ36wa2yDnhLo4100wc4Z=RfE zw2Vvfi5CulUbl<;_w&`E#4@cwmsUhMFOL_6lhE3g{?)+`OjhAdQzb5gcUz~X?yJ6* zO*@yH{0ZWS1)GJ02=?3rZKiHNe5gq&v(1kP<6ICZ<-(*9U= z%Ev^mfow9FWNGQ`%4L7%%U=(p*ICs->muH+6lk}}{h3Ohja#8U)P1u5j!`N2G*}xP}SMSKHmWNm6Wi%RP+8JAV z07~+j1}Gm;n2&m#3+GP3f7QZG7vHzQ2+!zD?dLa^MX`D|otwF*onOmg>b zr-Mh29;JhNac6Xrz&4gRq;z^v5Gas2u*#0cq2e@|34r8?4NC1KDS4J8(Ge0|AxqPN z3T&t;Kp0p8fFOzYMstkXOK@!&WdMk6j;gq5WvRf0^)eT#*}&$C1YxNg*b@)|_}-f{w75nlE6d_0q#)q_{Ril=-M)1oSBFdkL?>-m znJ7#y{lH}2p}RVEm4*w5=rXyCos}$AhTQyIJJ(fJJ|=lxepPWyWykOJW$`@Ex?HX; zDs(X8GBQ<*8GOpXMYizD_?f6YwJD{{@~yW?Ur<#gi@Mi=C?}u2uZXB{uANKXrpOm) z>29`_t3G7Y5EHpKAJt_TkH=QKs3yvZubj2{SFJv)+pbKsN?biWfA5#6B%^M*MJOHNck>D**tr z8ZAc4Fr*8u0BEYc5&ct_cp2mjV3<2p9y3s z8!B7bxXR6>#d4LCq9}^+`0-=wRH2>+n;bUTR9)CW3#XRv-~5P@x}@!!wd;v=XgPBqW}U=h*G%K#&NlEzteJsQ*Ql!-#8HRwiiW_b;|>jTa_#>fWZB$ z&gJ7IM6waA@ASl`2jwc#^IOM&+V-xgXV*SWI(0f7=TzaUWl(hnCt!c)*Dd>1-VvR6 z8Anl6Ya5N5K)kNqQajL~K9WPs<4W*o!qsA0SFS<+1bHJEjw49YDh@6jBEtr(PHwRXU9!LEpFu!MF2D6A-CqxvLVq9bI%J1MO6UdrT5LKRgeejo2$ zV%(7h5JN;pqjqBHr7D~Bl4iLIVKsLhq^rW&NO)0jNJ7T z>Ulcqp07$&ZYG&kyV~2^b514s3|Pvo*XtS2gwyx%vYqE=1Ch3l*;XI?-p5eel%LUP zWVI9HGU(~)ey%ip+f@~B6A!&@_{wH`cYSw8SMRd=ICG`pLqz1Iz0%vd+Ku)J001BW zNkl1ZS?Ou0t*@2q+rz%-EI5nlmsl-(W zT>V}zJ6JIQ(&xgd(I#-E?xn@u0IIT@QQ#$$gU}9uc3{$4l?~q| zkWUe2c}h`K3WT4`=Qx7@%N{mJ$qv5Q{ zkli&fng$}>O?BX=m&F9E)L`B3_i=c5SW4F=htD)Z)c{09l`H*po+gk-l&>aoffAjk zo<9z5tIjCYc}=I&0@z-)!{+u%E(3CI)2HXdm44Nr&VTi-ELO>jYiox8pSw5fwIoT- z#6FL++&%Bj%*x8js_Lz}*)5V1Nnu9Pyy!)vA2tFs4}#t#LC{l^BIk*0f`lFjLJ|ZF zF&v2ynmxT#S6A24U6ob2-u<5aoCw!LgvGJ2FyG>wo0*gW=iUfk%*{PK+`lk4H+S`w zO(wgPekEnm$`9FKh5EnzX=fDrp2yza-d40&9FY4+zC*tH#e{1-d`qbz;sC)1u3ULz z)7%E=^1YuSkmX84lxm9=tMO+`giKh_d|djFIXXP7K$UHQD@yyj*`fwaYps-B11Qp3 zQ7+Byie~MMS$WkcshR$GP}CZ%di72ky))YH7x=HgGbs;sb^q#e&(Uj4MxJ)uKfuY|lQqCm zs?n&rV}Ln1ISG2DHpa9Zc7}kJ%k_bj#q~0AU=ZU7axfU+2S50Mb2(6!=Nm**(!1&u zGk|My@~?BPZ0*2QpS@eJ*Q>QyA-RE4>qLght~4>UySs~>ot>a#SU$nT0xQ>j%*03< zte8GU>F?japERLtlVbZ7PpeKa5j*O9Wol_8(DAkBU@-8WQV{zbwFy-t=~Ing$2_x? ze$@rU7-L$8g@@$W7Tp%uN-5XZuTnmO$gComu3}&R5tOh1R9ng2iFKz)n`6GUbL36!eV6fBMcG?;RCu07LT8ku*$B zqiL_S2J!)?TB}6}5ISi<&GYN`N<;ms@l`P>jLw&KwsQ{{7~s2$1@7m$w`vrYWd?6Q zc!1rV9R@gjv8V)^@?gE46~PR5iP<`jpg8jlzQ`;>PmR9>i^d6_9= zf=jdPd*?RoS1I*L3hd3tV-#r_*p8n|;K_nNiBE<<^&kOWl?d$%qlI&xu7QLviG+@gp>+4|-D{jV$a(rS zX_Ai%u!PEwNvD;g@zOk+YiGj|g+ML=EPe=dXi_{lIB4xCO&Lu2a*#&ENApvrrE@)( zl(y&hu>&}rtLNhz1ME`!RV>8-sFX=ddnbK>N!knYzN!%|8~gbBD0a79>~SiaJQrVE zhe+E2C-aBi(QVK+`sFtJvy>^8VwR0Fni3^jV+_9ejc*_`StGtNiB_HZpJlU#k$7t| zH)y(N5X*rL%}NEtOm%Nn;YtAa_Rb3OpyE17_5Wxm#~(dh;Am$J%%p8tN}05@ws*C!G5R6WzGrsl&YiB+sNeArX*P_pfMt{C74v>&S*E^=K5+Fa zY1@FwRYoYji$>5_PHlrl|I44jyN@1WcXzL;&EUSKs>%4SS>aKiITtNU5RmLN;=(b}HEX-PunbCp&0tM}D7pNvOGM^Vc_bhxw3?|T-hZKm-B z5TzOANBg*BqA;JlA(^_=C#9~N@R4$A<;Y!`p|T0M#-!yG`+-0*$uKE*h)2rgP84#& zYE0V!uqIzuS++?jeKJM9P`@Hd-HbwGoU6Q=8!xVxWq9}9_Zr#|=_Q@$_j`+a!sbB9 z)DydD1B)8W7#3y(xLSh^yGC{3s+vc;IWi75gktD}lO_J>odpJ@J!?2QHEVYaSOXdE z3#$QY=w2cU*&q<%Ep+0!H@w~iywC(y2IysA?i8Bh^6LRCdRf(}#G%$rjibRk#R~7O zmWp^yki~)Ad+)th4l0J?{2e~aGQ9ilyWRo- z>R9|vZ?OhT^1t+T<*~;y61-$s+j0>QBLPcGES&5VIPBB0G3#gp;H~`}|Kgi-9Fotg z8bF!0=Bfr>rdfUq{3vZ9(Txj$N%W(oTQ_jK43@TMXeqC~^N+LKGX-|BZo~3yL&Ms@ z)XyU88T?_sz(5034%*w@#od#W0IXWm@$s>DXBi(f2;{h40N=|YK^fqFnY0&!JjZKv zczB2pKKP*FCEQhRY?&dD6*KW{gJOBnGC(c*bJ-%hmQaEQBi?>d*hTzq}ctZTp6cE3t3SCd0)?~px_q<+62r9J2A zV<%hR?m;P^)~{R?GiLYzY?fu-GxW54Zz|y0q)*1?GbZg=CIH?Yg~HJ&02n-Y>#g#k ziKQn1wJ$6K;Kbzh@?Z^+oIuK`0H$_2S}$1%P*v5_wgrWO#kUU@EmNlbL4kky-3cBX zRJ#VH#-=KtWHuGJs@qijH>MrdO6LP#GE9bhLD^a@XDY2$R@L3q3F+_p;TTx#qdXW} zU4A8C$(9X2$QL*%az(s0=%VYlAH2QR00L{Rnli{dc<>-z$Rd z(65X0Rz9wTD72)@<%-!M8Uv)dk~YC-S$WJ-s`34sPO1IMHzsS8+NS`wePxT&-tI0A zkB*!efTOK%_Ey->3IU|hv}Y2)r~#<7Wh?rD@+vM4Y#DA1@ZSEaG2!=3f&c2eQ@nep zXxe!((AEH11O&N^U<_Tr$_t7*rj6iX3|lg-lkvZ0`}6?pqFCEtQF}`pH@1AcYk+^g znn5F1cRV^eY}ra_#Lor`5pAn>fg^1RMJ`(rNzDr7(}){!%O$5Q%kYCA{GfKp-~$w? zFEmj~`j|;5wY*Rs?gc$mSKi*eUeCLPr_s^TQB=R`_xsUC$aMA~Q7njY0WR5Ip?(FR z<>1j6gZuaId+n}Va>Y_=KMe6m&9`Yme}jrwcjXX z)PhtEh9K!*Z1Xs;VE=-sxqijDFEJpHF*qh2ty{#J5*z$g8ZF%rEJ#)>E zsBK^W=lK+WYY$LVyGKbpN@iFXOsS^7dvX`!$wX}*>bNH-Ctintoc8zkYxTSj#Blyu zmbE+_b1&pYQPlY~&*Yq!wYEIiobmph-}xOpeE6{OHAw&Yjz$WTK#>2}$aS1UY*E=+)zaE{XJ-eqS@WaN)n9;e zBHZ2G#d5jyrb}HOlzk@zUbKFt#mBbkU@*XRO2?k9J=llJj*%}mZjGgWJbLSX?{yzyqV(RYFG`Y$rQ10t9ysyN_odT{x{mR8ZMh<%ac6N50N8xM=u0k@r zY2@lpp?2l-N-Sxb%zE@PFtvlbI+4TH8UXHPIgWdId!lAu&|4EYP=l+M7Ry!vmF5Z- zKtTx{WXnI_y|aMXGx($Tm)IMu%j51Aj1kv-X^<+%|EpzH@m8djS|~1ZC|p+0m0k@l zg)yL}GnM(j#SSb^vgQT=6eynw+ih9bhu#07o#P7(Me%J_n?czT_YV$mu)mM1>uXiy zR=@HP9~`s^(Dj1Qy{5%--G}Jjy?YoAhxpdFzSXeDaP6G)O}?D?y-S0`<22HE_$Vg5 zODiUi$&rJ%)Rs|QC?CZi9UWmlp9f_n9tQ^pI5;@K)zy_6KNt+6mxwgyl>9p8S#hE| z@w)r8hMe~H_G$p>+AZnpL$^7RrS_{BitV4Nc6!v_J3Bj=OeRrfQok7t2F|{ivOFj! z;#i>N;|GK_)Ebf2O#_gzKx)&zbsPO>Qwo7;!2K~<6h$lC#fQciuK8+w9`5b#VxLsl zwmFRxm?65`D{!Y*IBl<-JM!qB*zxNEfHg4Imc>_-e~G!u082orS{j1^{@|@S_TI|s z9fLpxt}2aJ(~&6Fz^dkjwf2h2#QJ)jz}32ebXuG%z1Am89vsvr5f;<9%ISFwGh z3vD`CrcBl@&95w9Yj2lk+|?fae!m7-T6rW(tlXjJY2PQ8HeVI6(n#{$ zHsFc{?lE=K+MB>qtlV0^saE*PN$lX@pd5sF!Qww%-^+3w_lpWhndUMSCC*UUUYRwp zvLc?eFt)U@;y?@5mRc;@x>#wuEbJO&!Qh?!6=wZGb7vq-c`fX%U<^ys{NJdcK~q*L zPNs#Dj-wKu-lf^nc()Zs&CFI~YfDgRfrr_$##10r$rD=xZL)ks&MP%rDi_!b zO^&fZ32?=C$!X7p16o-gZIdTkkx-rb{eHa*O4>G%CL+ZNq|_E^ zgRif>eUra7@w-U2q2wP6tU}kf1-82I4yBLrd**r;WdFi72fk-OyGgSwYiTH`ucUl@ zNMIPs8|qg+yGD%{5ntAPoxsXPv7m9A6at%}kL;9>7T$L#PyGqi@Aq-UjV(Qlc2MA6 zKS#e;&D*t&lWE#p(J~yc-Z98jL5`-aDd@(*vgZ#gUlGyntXhqo!8gZuQVVf!$M2Ep)$2{Qzpb1pwg9M`jso6YvY6l zc!{t4IFWsGFc`Fql6~^fLA@@36+_y45PDuQjq;6vZxJe4VGPlhXPGC ziYfEdK&Y@Vs{-g%oy!2_&O)ZGGNl|GJk{;a0T*vA4rq)BlX0$VuzM{`OQQ+H(&r3i zmb(Udv_;=oe51c)&%`u9B`jbH_L#YCmH`F;zKsQT>>g%pnNW(uupRaf4$7S@Vn$7!71enY6NFWZ`*zU`xx>WdN3PNf4x6 z6OlI3rNQED%85^q`}_O2yu54-S{j(6`vdA%0$>>v?`4}b92%&R^@#0DyuCG`#p@9Q z4I1CuoD_Nc#`L!ozC^C&VpkuRKBs(bCV3FRn$2e3cY^1k1Dqu&O9fay&0FfYr15us z45jufmt1cOrHo%GJblL(#h8ppz!V~>{j4F+?(QyjcXsMI8Or}kEbN&AZw-ZpMDG6M z8Z4g90Ig$j*uAMez$YC9c1XodVP`O>*|xw-gAIr-om;>Xi<9Z*wv_&{H3nSAndk+uOrYj0N= zEzP88o?QJZ#r}#WV6EOUZRo47E59s9UdzGV2lBf1Cm*@W+a`Y^4RCXk9_}@u;(Jci zw^Do;x%y9v{S~FxC>C6~#vmE*;~z`6(T}!G+w7OVaXltpOA{j559=OA4isA?CU0X5 z?(_=W>*Zy712&P{<}x9b;{qZ4-md=}&{qmz>!mBZwi9A9Sppk{g(=GNjj6yC<6l4uHPml%jvPKVyK_tlNRLG1+k0q8Ua@ zg?CWk9pw0;Dq)?yDKxLzojZ5%^5x5h*v@_>$QV=GUr~A&Ad>6q+DpQL1CJvh!42QF zuWBAf%Z0v4S*uShg_e?H)9|#u2~NwuTCIWxo$@R{1cXwO9i+rT@ ztJot?jM43{xcu^(=hgVd*ky6@E$RBenUA`b>*Kd=t(Gwcd7h&v3RUYw*YYekSvT2M z(&h~)Kh8AYMZS7yyAM-9nrrzf23*C4YjyWg%<}&~1#-O)e2F;J7AdYaTT+X0}|G6Izgle<|%()&#ZjI#2>LYA^<(3stwEt>=}RnS@gMIjn(a-? ze;H739;h=`Tm*34GZy!3j$Q%qA*%uAM1Ahuxzp;l0F`TCm%MttUabWS zspyHcewA{j9AAEl0avM$rnYpY4cd~5qVQ^NwD4{BD_1$&0$KDiqlHs>Qp2saCFSAi zWLxvHS@e?dAGgQi@paX#Z2*s$uT!2j#U?8DrRS7tbH&4W-l8b#4GJ0vJ3KsWoa4va zLVn?Ka4MfWIg;)7`&cfQUb(p)mh4w4N2G8AY9COR?c|#vH`QYCeil=1N?ATxQ)nBL zEw886uZF{+3Nq!p<^o#$njE;sY8y0XoT(ZtDYLAH>t2%YS@{5_i+n&l7Wio&5^oBH z0G70cay^fb)>ihz7;0&-_V#wyUaGYme7-go_xpL<<2tvc;(&{o${#VTytJ1SHfgXJ zqOlgHa@Amssdv5AAZsliFe`w(fEi}s_^Kv`3XBZbz>j4WudVA{jieBNUXs7$A%K)i z6SlGyz#^FhF8q&n7BIakLsoSpQx$4Wd6;%xKT$@32EV(=aZnVvvOR$Zn-w4&OuGPq z5rDNrMZgUX_~1ki@{EbIyP|x)0nYW6CV`f3P+qN8D2l>+u9rsIB*Fh{>0K0)$2U0h zdu?LpnmWnL7=z>EW7Y2$rPW+vaPZ2@qe(Rcus9#Cu}bx_?J{uJ`iP8+i3i*hnr{Hl z^SsWNI*6xGmwpw)BPK8Zc+n`dJQ$Ll$GZTQ@7>{Aj?j)XnKx#MFjNN_?*lclK#T8^ z-e$kr2H<{GlrlyDI)Eoi)nHNI04jiWuwU--;^M3^M^mHKGr*&rRh7WBK$hX)N&>1( z`ELO_r_i9nG{lQQl)>7oI{}YE#9NeWS+fGz%b>QcY5Z%08j-G1aa6)JfRa)O1!*8k z0ZdLiE^0U1Oj}q}8@XFi&~cXId&8w;dA0(FFl#MV&D$uJ^T7RHj-$NXZfM%QL8WrX z;3)t&59@UeO0?V12duOmY}$WqQ0Fg+1Xmm&$ozSpW4T;<&-RL0x^cyCOUo5I0BVD{ z?~8CS7}U#j5~#>F<;#XN(aE-<19wyGu&8eU@!BgYSEdj39iC3+b1k{L%J!wR)*{by zuc376@=z+p^sAV>E|)np7&@(yAu*|~u`g;(Ge7TC`$?wTAK0Pfw2l4 z<0~YX(!iDGJWg9SbPY~)PXK^?op4|vU#Qt^);OKsSCDd0>4=~|kYu#_@mmkFh>zuP1iz>= zX*78xppr{lz*>tX0hX^`U9?SIz}7ajT8qU3i^ZZ5X05Fq#q#azzKMm}js|$H#o`+d z$RAdyjug+ep(*xPT3Xp>Vt|zv=L(~6uGw=vhmaP_MP0wfQ+RK}lY@3`Vlu|m%Y$8j zil)^9p!&n&@<`$UD@B79(vWlkSFZTbGND$l(9-N}(`|hS5V_1cjA!Vg+-|Y|7-=* z{6a*A%-qPG$megWmcs$Eq=tnPU(TX<`Qq|C+<6&3P@ZxRv?o1Rd&}p#TrQL9 zq|t3mXq$pKV@zZ71SdK-FZ6Ll<%Zgnhl9gB?;YDtUQ#V!Cl$&nqVt*JMN+Bky~Tr@}nS)7ki)MPS` zrZr>N)|ShIOEF&Um;&G3UEyS4>t|s2VcV!&X^==6*4n@v<+HP<1YSK>-s`&SXMbqkTQw7+-t;4 z?4fX(CT1C33+I~TH-&u9HH9>QWz2dfX{bCNr+pYn-tvsW5Y&fON&;T!UB_}fz1DKxWae#mu#bfX}ipz|Casuea7yATI1HY!2K-8 zSsv*%yZY}k2(POr21s&ZsevLn8EWT$`Lq)}jF(II6h;~qd6bUSV#%FPoIkIh+CC2O z<|A!lG+k#nTWudtC~B)cYqZo}wYLs?l_K`88LKE2L=~-FBdNWq6{A+nv}&emuTa#c zwPMsN?|DAFKDsWsP1}ofeb)Y14PB zIjHiCk<8R#_((Lf7Rt=)T|l#|O& z1Yd9OixGM`)>+&QgI$t`98<=1J%2)!_}vFRlpvGW&gRL%6-nbCsPrjG=uOBK8O2)6 zBuLM!{qPSaz8U2v6|$4Um0ZMLF8kwdF%c5NUirLl?{WOOx1hOUaP^*w3K9VB_} zB`CkRFWY%^+M{b5-ivtlZ020=sul0FLQ7{(kk?`zQW(~dd89+x%9L! zoPUBA?Uez$Y9HkbaXQ226E7rMc-C6)mrWbsS=@GYZ<^MpjXF)1xbxZGqSnvyYHB%w z*Tf8e|G+_;mWn3lhd!H)a+{K_Yn~qGOq7(`ML!4V7>EO+NSN4&o3K(0xGuPJ^D8IE zDoBmCL`%fHrniCOIMevv3vkqs@ccoe=`}%VlrgAI%`c zEkuz9B8Yg$%M66!Py=+F@6k+1u_(IL3;%N&D!f}~EKoWu?aM%LTLPmL6Kt~%*|5}^ zY=jhEUn*#`E!}s=m3}1b33G}0F54#DbZSNC;ABy4@t)+dLqw_m7A$l09p@9vcddaL zYN9k0b&IBu=eUPX9_EyNABQ-mSlu#NvN4&Sj!U>5Iu;_qjz~n}|t8F0kZh(hWollm129qw7 zfbtAs|3#U}L6ICH1)zM|DZTZfOs(j^D{^kaStA#RYraGgG*h!LKRyqogXI7iCG_TwsZedAF7 zfPgh=?-_W0)vyh=&PIl!M6b`^s~u{zKEyS?6NRfC}p@t3v8{E{Wvkh3+6 zlbZ+ek$8b;vk6WM@O!pTXV%ZP2+c$(5q(&qao9GSOWoH>CG5g7ENAM^BA}3?Hkd_6 z!O*oAKJP+a2q{XNwR%O6U@rQ6O}8oAsUNAZQpN6!r(vbx)NZ|QtZQ!tq{YVf;!vc* z5YPXzk=xs?B1HNWmX2cb_xoO1qIQ%aD_Ltoe zXYl!{j^8RbHbI|lM|ECM=v%)_EMJebh*`Cl5A9YFwF8P}_vCe=Q-||wCQb~su}jtu z-M95e8wNc|L(`|qF+t=yT)lkZ3`T=D>?y5%Ot|$IMj|8#`ybU_rGt`9WmtN6uElHx z5wYo}CtU97-Mh$(y9WwddGt(zns|E{qrC4!A)g@0_=t1g@lngE<;tnWt8)m(jJzg5 zD(NZu*b;0BNpB|?vXC^nd#yC4G-D!pC!=AKdso7`eX3DizC`~p+H?7>t-bxf-mliFHt!+H&p)TzXHdTYfbde~ ziM0nhfy4s)CK%J565TaR!2mGv-Mr27>7a0^Q$xabx2RxTkzdjS=*MMP7<5-?UYgtZ z;|S3}8U4{1W42gX^(dqu%-4NJ!m^qfZ6~{&${7Ibx%G@}Ht`&@?qsR+@3PaD6G|@p zOzlLGbqy3r?^M?uAxS}>S+@~)gLI&L<`z@CCv0C+p~e`P2gJH|S?mi-z2NWxhvxRM ze;nsoD2*N$q`b3F9&aHzIdl|Fs)9_T2>I}ZIbKyR^VhGgfXrv>!)~Lr(P=hT_1+VG zNni7B-#c)HUv@I^RUII?1OKEmWpX0#TpUUQxtEfyek!m!#1BcdWfnDVVw)b|T7K|G z(R_>pKa&u9>18>iCJ$uj>rVjDh<*V9^tU=#4@=ea@?sAO3laq=^K3x6Y056Csoo%C zkm(R;mpp#T{_t9}8A6-m9c6qmRd$ZVy5#O19Mt`ijJl4+Eu7RBiPYnz0u&y5bUJ>* z%12Zz>s-qDHz`viXOy7Tj6zSFXTZ%{6ov(15V?W~h&EZ+Ei_JUt~gZHfv2NAt@fwb zgy=+@w|^`>AI_Oga(sIkCUx8JO^z`LG4jDhxOE)E zNd4;Ys5A|mah#6=n##*2Dn8qCpF4NL@ck)O-i62J=H{Sj-6+dWm!C~Gc@4YHul4($ zD^}AFCj~86RSlbbG4)dHhbx??W#y;4vg&5z6Tl0N^9TfS7?hL1rt5UvS*xjMhoDZ1 zCG4Mw8P$wj%2$&#?Qkyds7GPTGVefCB9s@45=d)N8pcY)$`@!K)00GlzrStX`VtC- zP@Zx|hEg8C|ePHq^!4XqMIX7(TJcL;+sLnbrxZ+ zbmxXZsw`yky>7fT@M3F*6iNoSV!egTravA_*nI@7wt!-hnp34ZKYF9@%~8hg6AZ}B zqxw-u+bs5*@j!fghrzCS{kMFg!CwvUi{%s$+7B0gmQ8at*`e_-RlWi7xLjCC!0Il; z_lS}i&8MU-fnzJk?$i@@_tuo!!5JD)w0p&@F{e4kPd!bV-^yoQ53x<=5TLT-jb58t zoN$IWS@u@6OFBtZOL4@g(YrrwZ60#uWN_xb0lg(*;Rn)~`3WDm77B@iKQAWMI6 zpO8OKbnNof7ibL5xi4U^Nn~tuQQemur4V#;@|1H45ZL`qVk$kY9GA~CMeXZyC4$IZ!)NK}$_Yv=?Z8bFJCX+267VWOoqF(<`Fs2_UqFY?F-9<#M zGGYroU__Jn)AibeQ6msE#K1f=5e)0fIN6U8t=Zx`p!7XgeSyF%Y)@n8aloi z+!bsopVH3vc*ixqmq!QNLTSIYnmLrcqe&9&S%8>X`fCsis_-)5`pIPG)hPwvOI7^l zI=@ChoK?m*a%44y?;V(pZry0dYRXc-Of1dfU|iRpwih9fCDu*vToOxZLJ;YPzNc{` z5D2L~5sG^iNh@MVL_=Yet2+Qkk~=dn1{s4ciN1sBAfb!acLh~T?OJ!V*H&vv6x(Ia zn5bQYL%Sg@Esjw@0K^^88mn+Yr^!T|)U8Ge-xUj<#*PGFfB~c9iJ=FS`Uw(IHe{c` z$EA{^mf^66MLk9a%*@Q3ZOC@NFD@=t$iMQd;|*!&Q=B9kruuRSRYKzfpM}AGKP+^9?0p41ZOSinulfI&lA>8*(J|&|OB~BIH-{bkb zN8wa(hZhb~Jwa5h_E~8`x1XcO-9eQ1%}XP}-wfnT!~&(&HHaGE(gSUS4za{9?CGzm zSZs9RUA~F2@%O3omI&I92$oa@vUY#^W;+O)QvxNpo}cc2=+nK1(^{JzKIoBR6W-+~ z+;#D1dG49kSTg(N`w34QA2})NtSMjygS_MVnFU~I(;urAO|Ex7A1%~>k`q_-NxAu` zR%$o1HQ2KtQtZwJ2=RN_i|Nqjoys@@=|u8N^q*if46c*fRO(YLnpRkQw3X9y`D)?ggoK={~ z0K)WKf00t;y~{%dr)5GzqZLO~g`O2@&uAQYdU4S~=(4Ek-Z-oC2cPn%fd;=w*#aJ8 zVWKo<^ns=!5yuaeO-QP>>l6i67?OLZ?JdhD^Q6Wh%+z)qc|Y0($aBL_N8u$ z&MMb-@ki196bU#47^$IXeai_T)m5S zCW|ipR*uMZR9PM$Z$0bKiTh`CYkEI?M=np$P%A3y(Ld9!H#suD(X$_oh29P|rEbiS z1^7(Q7_Hd&S>lY8Y*P5D+NwDcS=((@q{>Je$V@!yHHhjw;hhvQf6^bZ3hM`nAm>` zja*@0swI!kz27w8X<^|yg19OI2(B!@iXuY>YsUK2inV=4N$)d-C?_(L;^(=t(Y(#n zp=oHQbR4D32kd|iA)!Q?m7Bc*C3P=)JOv;Ycq@h*rX7{;$|A_ZEMsYC;=<15#q2t7 z-!|Y&d)@x|${kQp3d0`V>%uv263Qv%wd5xo=UnwtVCE;40yx&3jzk#a`%*o&94GMOrL)h84#?>}cvRu?DFGi6MzihQ`G{4th@j4#NWA}b zITwfieFQP3kC^%VA)aNKXLC<_U}c5~nl!nLE8-kvxX_3bFsFpxp)vd}qBp6qw7S`)Q>Alw^s-pc-1ts(wCxdpU8kHtc{Balj zEK8VD$_|vcNNuw5myCo>vCKy9m9)Dz;NR*F3b`_W>hIrt)Rw&;v9l%#oHMOO*|-F! zD?Zg)bG}QlE4JZFIt;c(>S_)K6n@kWpI;tA{wTHZEiGSvq`yj&>O&`@&%f`{ zoZdU{5n|?o-^Ob8C*DdeEhNo}5|Bf=d=%JmofDwv0k0izh6N^Y))R52HMLr7qotll<@S~BYWKHB94;TT!)|<9+5KFIGi|M z)wI5_7owZhPi2*>P0N1=yPXYGi; zk2!mCyxDvYACk13s2^9p^Gdk{`O4p|crW)ObJL<`3-s?* zoe)wLre({hx%?jGZjs^%jt^A0R6U<9xu)Kb%z#>6wo{N$j*Imy%J?b>cbJ=N2JYJeUZOxuxZU=qP8gByXH2$7_vK&G&2I= z+E8r~gcK!X-E_yd(<*&nH@03D45UcrMo#PeepNpSf^0Hi8pJ*IO(}0v*o*X4Q4qN+ zQ;asCQ`0)h@0XU5mj*^Akb(So6L~ReX9Lgs_M?gX(-p}>K{3QJOnhJNxDIj0I8Z)- zwx+M;ls7R30XcI*QB7rWmmQT9iereyFf6+*Z_GY(MVc1vm%?zerD`2<5H6{E&L=TPd13W zz0us}!BfuQznzL5sxdoX!DinNZM*!NE@?V->Q}2s#Ar_s4$3KWgZ6 zI}6)hlVjo`_#FmnWlo%?+!;``V4-J+`+-JN`wo{F%1X7tR+b8no>3g7PgU)>Vdb2R zJU(mbJ`}XyJDye~m$yU4R8sww>exJ=|N1paM7)wOx-YfBJ=AkVFsLEdGJ)gp{=+81 zCF$FYnhwNj^=3g8db;dM!-Cz?_GP3Y^93{D z>fpOIoxyC~9)|l*#y50^_-mU&6JeYcsN<|@snc^=Dagb*#b;P_=d~INGBtz!`bqb# z2C2!HREBM?areKH-=~s(NKrV0J+pbRdz3nfiQs_<1jjn&8S%u(^!9z9#UI9^R);Ge zl6W6^iu@@dFsGe#YbTbcshqczbU8#_bLDG7BV2T8`oWOW-Io@FvpXX&^w$7|nx4Ue z*K+KYp4ad_C4*F%?Q(b(3Ku*3K5Zt}_R;x0{pr0uZ>*Z)`Z`h)jnLCl+&T*6{o-}o z{(LA^(!*|WT-EHmx#U#TUm;5bo~5l{Sn)D1bcYFsJTuChJ^heX4Hcbn8^JXRYu(tu zbysIhZJ`YleN3F|A&Y02`0cdpaEjicp!qcq)e4J6dgtgqG6QbkDIy3k?=`72t(<(C zx>a86DJ{W}VHL%?-&cTm~9R{3*?S+NC&{n?AGs|(|w=SF^kG-EV+FizA zn0$orHNAhjPAC`AnRah4sP(%47!I7ed+rv+k_%Y6l&PL z>MCp0MXI`@d;I;`4-UqA%<`}T%#;ed^VmPfdbq@OZQtk5pUt{gSVfpV)QX8BlN~2I z;=b4jO^}Gg`3A=E-aIW$&5I)Zmnd?h!&V6HiJ2{*zJFIZ0Owd9jytOtr>|zUTF)2F zgMOg?W;E`%Slo4oNsSu(#hu8w9R7S62hPE+HyD^(u_~kGV*gE(@V@LTw$+xz^d=-k zKsqY;!YCKi(9@uF;&0Y|s9?_JRni^ao+jnY(p-2mUNM7Zmc5kN(=5GzJ4J-P#V}Pj zi8V8*Lj)9>L6|0}=7D(q;%Avxf5EmX#X8<;7?S>=_B@nl|KW$&@Jw)ZFVN4a=W5n|MM*L@z3+W#(|&4V=3y`}E`j4#p_ zWfY(030~NYUyNf*`F5NN31LkKqb0w9=hAZ~Gz(YzsKH}D+KVu*+;yK|{}?sU3Wy-` zHfwCY)UQ4#0Pt9Sn-??|7w#?F1!Z@?h=uQD85y$y@O&e6a6 zd#b)%EZG@ZBR<%hGpEFS7`2JB5NiDL{+8ZxKIZXl>vIs3>ATU#L@9z^(Ky+3k+jUO zm<`4tGf?{+?oI_?@ryLx;ks&(S3-;Q82VkA$sh`y*dkHisZUPre-OhAB(V&mk}N}n z^@CxAN0EVOk8W$vhb0l;g8r`s5Q(qargwT;C7wS5bPWL}`q`|2_a!o4W!+wJxLJ#p zzo7d-hO%BCL;@wXNL>nI!g43WnYDtcNUx5wZ(rBN`=pZg4&~`52V4|aJ`4OJ-jh;G zdnS_stVN^T8j)mEn>X?`i>W@) z0UH=CzLPZoBQn1)+;+ZWU;ZaR9}{-94A*aU?2Ls z-W4j@@V$c+ySZQ8#d&Z(gsg=u5}2bnNnSR5XNGE5KXbd?NV`SG5%w}Lu(ZvEKaSw& ze1W{~5mwm-Y>3p}km1uYpmhtBFhYzN6PmMr#L?UL4)F9mR{PR4mG7pKuLx%3sNOB2 z!MvWpn8xvG5!R^9mPtg*wc-b}$*N%;&gWgn9eIVOMA}tTm1C+qcY;3D`pUG4vM`6y zhQTI$-mr2OywNJRIlAcz7D*%?S{q?<)jP`jlXQD4#UX^V6by3!?hQ8v)>a{8pzvc@+oY4zuTBg@7`s3^ld&?Nb1buZRVGm z3H8UJrZ+7ZFZ9>--~?-M{?lhblUkksf@yzR-OP(T9ak5-nxb-?a9>@Hz6$gu#UO5T zY^q!OW{CKr>&rDlpX@j5&{4kK%EMnBa{JFie6andOsTN2Rr6{}MiH?p5IG1{PG_y( zH>;=uKD#grL<>`hZeV^AR`-NqNR!S!h9*98L67&AJs5hDBf*>c34^dP(+E+H#L3mw z1FlUfC<>bA!R0aI&8Q`zWmzM-EZC^@>4eiA8BM!p;hvuXHZ0qF*yhbgXDvy+m&%t$ zs!@Cg0LW+Pt17uT5@5c*qj4`gVK(Z|_416mW=VNnXir3#hLHL5R)?hNXMVm6<9EM- z_-5d{*x!T%>`yL|Ojwiq7thxH-vcqRBfKBZ% zqnEi~Yn?ErWHhf%7!ucR?XPSeopwWnI}W+wPwAjDg#C65KVzoLtMn1XC}Y(eJ6`mK z*=>96-4{;N9a#y7{sDK^m+51u?pNX}3d#pEI$8NTnv;Ux9xVQyR->rh znua)wVyYti_zx_9zLO2xq2>pTxIvqi%GdPi*Yxp zuTxVD1_lN>QPXpCEP$iq4P20s0{!(q*VsURZTv>m_<(xcO*v;LMv7afotD5{R17E3 zPV^W`b4gU~uF!h=Huh!ID|eEf2PZ}RzJY=3C&e19N=z7nAxe4xg=YB_yW-piVe4SF z75J9l?TKHNv5=(hed${|$o&OP++e)6PETONZ6&N-5;-w|+t?;%9lN8}6_r0|;K^37 z92ogmADgltd^nr;roRtNtUa(ad>Z(YL=~ z64o{qVA<*zIcty{j?WnIIEOZ!nv9j((E{t$gLaD8>f{-41Lh$qc@A;nt3%BaTq zt=%92MasRgzMmyV-w!6$j{&h-lCU1Hr*eI;CQkp`&@o!DPDmm8_>~HcwmzYu=8Vej zq+>m1d%L2=&cah7*8q5hZsky*%XrGDp`ob@rzK1iwU1bzP{PmveZdvTW=Rb7pIC8W zg+7wiSjyCSP9MFKr%vmx5{7-7JqmS0dPl)VG)`sbYR@2yD`K@xmk^8hG8V6=zlLSM zsBWUXF@I9?Z2NqjNaM4>Dam8>3K8M*Q9Rhb5_-Zq@Wx-P#|i$yx-2cw02~yErZOsx z6wX8-^TGUjqz!Qdb;Qj`a7f6X#9T)4Ti;q?#LKSaGM(jY8}XHbO9i(A7PQ?(VhO#X z|I|JTLpay{UW(tgWLPvxvanamUmbLx$o!-Mbb@{~D4(4Zh-`r5vAyc^*y6720E)xcBKboy`?3a|KbNW-$bIMYcdd`F^~4G_;aUU@kT7+ zm;BM+g8#_4a`8a($nAUO?gx%#lc5|h?Y~3r;Oy)5?HL4%vF-f*E?gbJ?$SQ}Nh)*X z;CP3Ynrc6tPWhfEynlvJ4~fZp{)G9^Q+xMppUjiKx`cXtMlGEjQn4#$=iU0W6P2%zekn=V zm3Pd+XU%9hA|?@cP^p|f>>D1Q1n9F*h}t?jzWJl8!4Q!wNsQ;(gvJ>k`x2I;>euX( z&_b}N`*Sozc#>D0sz5FnD0E0rM|#!URd&6O=2J<1pYS#e8&O_f{%lVXpw1{4q|sZg zTubN4^915g>YD`$rRMY8+aGeYsPJ4WBPYzp&!Fx5 z9aOg2lj@JZq{${Lej=RSsZ_AVmTGWP4h23FZI8>5zi zh$&A5yP%FOEeC?h6|%}A7493}oraWE86~^-vFVs|IyvdEmDzwE-=zv_UcPV@{7bzR zFWzOXwcche;S8Bc+|jhGowY00*H4pu*m`q?+wJ`abhcPIh`v7klc`WZxDF2t4_~|; zpIg$%lyPGnVr+YmBBQHYJGgTB?6te5G&99cWL_+`F-w;iHHgn(n+THFc3ROci;pLF zy;Kgrl54BcEdKCvxrCD5xJ;COhpqMgE zbRA*Aw>&8*M65vk)nClb!~QcTb4VlSAixWECfmfO|Gl7&*yU z6&&Li3B^Hwz9IT{)kv)eD5Gw@$c%h8|DF_rg*PFze?gZeDCO-xtyIM@q&n z34?}NOcx)l2=Z(dofU|cSc|K^yqAKSx>Xo87fZcaKX?6X5oTLdGUhf3k)*og&RcSt zHk4yf4)llVgx{SvpwpRey6M&1%UMemac>B=RyKnDjz77X9dn4nIAU z9jJj0Z=;D++L?LEN$2IleXpn^`OH}d=gouO#Zsi*|7~=mcT%+{q@VVS__s2Kon;vV zdQ3B*0Kcn0Ve*R4=8M?c|fSs6%84pxJYGAe3=Am0w9(qK@wQ;r?*0|YK z)(NM}w`)thcJIo~hzmGNsH*#!nB>9JK6Xm|+gn*Wl|AIl*29w4-W~N3e|S z+t78#M{tZF`oGC5OW4H z0y9Fh4(6`V1A!$}bwR=*R&ba3WrunHKG4C(@J6Ub^B2w3Dr$g)5xf10pt^|vV4}bK zsdqer(X(;j;Mmf_<~Xv1nP#2f1*#FmijC|eL~$MQrdKUyOLIAJ4W=+wQGW#M6i7b- z#Gw0J)zI2owdu{Pzn=APrVKNBKJ2x5;tj7wT}opr|C~RYCE&b1#cr+I$T2+qHR%YH z*Y?%R=R5*&F+Oppd*mgraxDNKm6jL`g`Ov?P1%codhi4phVT@R2b)SNO%wN#8@PUTAi<9Zn<#zv7e!GlG=b<@zV8 zutOB?Hp?eUJxs`dhR!nQ7&>w3wiVr$D5KdR#1?A zWL`ATW)8Cuza2MyWtC*ZTjxJjPqcX3nsnDJ<1_$>WiCm6l%P8zT6=i^%c;&dFeCmL z8L?{jbt~uoz^?T8m!xgXxoyYfU=OlZsP(9HO6vKoX6FuanrJmsGB^LjL{hfoeqd*+ z0sp?b>X?wE8grI>_TVwjeXEM8_uOrMnFrx`sUuu#BySVJohKk!)=?F(iyu|VH7K@z z*g8-Op1O*K5?Vv!o2RJT2^eQuS9C(z8Yuypo;6!B%d60oTjF-Yhri1W5B3g!`fC zkcpt0MNjmK{IA8Zd*WvokjP@_G4 zOSv;Oil41wlN-%}&pF)#kw44ZZ0+g-a)ZNl5kUWKuVY~w_;9Qlqbpczbir(E^Wfo} zUGUxf8!2;D(hRn7VfQfOA!ohq+s2A4%NG}~?{%B5#d?b~OMTUjdYb*LO>bqM`1yRv ze7eXQk7ltx<^1D+Cc1`udQ!VnFcoTroD+{aVPRWayOr&!r|YjsPrhCKX^Ta!4)L}+ z+zF_N{6G)CcQj=w6a$h^;CcuQd?eI@$qfmX|cGGTu{Q=jZYn-go52*&&ey%lo#cG&|y=vo!ZdnA@Z35%f5 zbe5J%5=29q1+0WscUk&zfvp^^sN+n7& z`V#@*7+PWUp3|Dn_P(fvv3jONX%(sWvUg35A^8DEE}ib$f%!`n^!p$$t47MvLqYgd zv)g>b1-v~ce!#PRM2ztnjXlHkN{d+j>iLOj#SjUI5W)<@`@cIJZ;jL>GxA+e1Hc#F zp2pC@d7^aZ@OJ@S7gA>*cVc5Ee!OmRU@-Ie>}8c*8hJl>#oD1O2)ht6Qm(AjC2XD| z#QzRCa}Rd0=KkQGv-Y$lQ2h8@S|tqV$f|*ERa$J56$Q7hWg2(IJ7US#%Q;)HE5t)8 zXqbyTU2fHNeL>s}Uz#?yP`aJOWNpVrIT`uh{Lx;@FLCm%l=<4AoU}@8e2a!a!HFrpO$49#z=wxFz2iQd55qu?ivqw1 z-~^=d8qa(*MaEc0Y>}T!<@>M-(u&d8vNgW9`})0p@~gM!L&wpVh(&9AeZ(ArkZ|!V zR7+J-yk*5L?~~mm>Wh?Zv;Y!rmvC{ivn(if@QcZAbH>ICOf1!JR1CgguB=MH-yMYK0-8Fi<+uhtsctl zRK29zA*eRKs6ogwfJ%p^1C1ACQt+ifhxUmk%iOVzwe@{KSN4gY?E8z)jP_Q-jL%|O zm-uLA(`TB&OU>XLXgbFV(H1spVq5C9g&dhZ7=r}vFgAXJDt}wBXC&{oVKeLKxEi&! z`)rbow&)_O7)x1n{{X8AwNKcVE6zR!9mpTS*lhl7_jW=e(|T`7?j{gx!wDG7KnLsC zhgTch4>fz+CxCt~OT~T!)&Or@TE8${o>miS?gH_DK& zfW10T1?r)euN)dv+kLG7*?$h)Rgw8@r4cL5(g62Ms1Zdi3gbx^VhlQJ2HR5Di6kKi zYLM@lW4)H8e-bf-5u*yb@YF-Z z>%^OSG+bYQwh`Wf+cSLx$D4lvv!Lc*;PiJ>AGtT38J*Kse}f}p6k~S!mAhR{eVbrz zmqcDKe&^4ibgr%azouy(aEd*=S{baHw$*1OziPJ&Z`y1Q3fpN7rf zBJ&|TXca-ju382kAj)t3xV2`&&kEer0G0mkn`0+o&!|^X@!HfkducY$TRc&;zUptI zQM`~e_%PDU_7dOz_5S%#+=s&6;x;3-TdI?Y&>(rqhUst09NE@#sQWgK5n9e<*hQ;eSPs8MvW20_lzG$scsdG}>T|j6^ zG+}y{7G1R+(<77(L-&G&N5zKLAM5AQJH4tPH5q5f?Crj3y!CyWpgZi4w!1UBR9)LJ zU!@m#vRR|1V>!b=RXT;GMeyfR>?@F#fOt5$;=x8J$w#2?C-;E!cxWov4GFp1gTg7Q0pbpF_LT;{Z`?SBd~Pn4Sg2BO~<1&gX#tD0!CKYnlpdrmwpP5!i(0g`AQ*g0PgFe)vcYJwz_qnJ2SFeIBGJz~!Aid6G*ODVfKIXc7B2Jgi@%UzEnxc2TOsEtu>%<=@$AGMm+J-co|Q7o0~8WpD(299XUE zlBOGy!a!hI4;SLQ-c-E_*}Zf5c|^q%?a`{AHL_XrnHr#9EqAUzy0VbRIr1gy2bT=c zKm5>}o{g(rJK^(pcL9~kq#|;pNt#=0!O(cy2f;IV4@_A0E=j@S zl%85!Rqba3;QMw3pA&S4pWdqCiIv7|e~Qglxr;*9Tc&l({Z1OEkw1Dbg}UJu=icWa zUQ}OHS$f`;@8fEZ-C6)?z-#Wp^8{8&KtYwIJqaNRucjWD3_Wwc!dJ%{=2NCH5vhb- zu;+*Uqp!`%1GeJ+WX_qiU;o{dUV;TN6aIxJn7Vu8B{PV-N1E`Zokjin875z7!R6q` z@BY=-op&$(b)uf9p^fdSIAEWJDD=C;V7zo<7UpnF;))|-r!|20Dq~cw};SpDw{Y0;_-}C%?y__8=%t?cC>cTylmf zWSLXtXRoAe@N2*K`QaDxcoDg9y;5K;WG`J21ArMwXSc^E{D^HI>3+MhgkmE=EH|(Z zv7YwKz}V(IaQI$iM$ky4*>`Wv8uq*q%XmZ8fAoN+*45SZ40w!MR*a-F+$vI}D1hHF zF)`UXZOwj>KRv$;F4Mau5q9tCsSymRt@HaH?c06=tHkOiIaO87XY>F#Y9;@oLdcJj z1lX}H$`<&RTPf{N%7)4glZh@Qo?s&Z8vV0I>ZgYo0{9>-i8JC_0Oe{zFMf913*rn{ zeqzfh`TYlFKqNo^FQb)5@PvLeJge4vP_s?eH-j6RX$|jtkX-gNHH#lLoXT1YhDSzo zJP&Vt# zV+H^$HBh0x)%u-nMHlhKTLl5>@0%m$w*w~YL zZ=#tEFz4vli9M+lC{yxnT+MfanOIlNMk976Fy+{2MFQ1Tbul zc_5h_!Iv%;9ZUV~P^v<*bZ9yIxed%YEDR*>0#9>c1fmR7E^c#1TuFpqt#Y=o4|P!$ z6^jA+jo@_2yBr*aGrz%F+18H4c+n7_G&?47x)tQ3E){x3b%OPVBj8*O;4N)aCZIMz z?l^G74wz)rDje9TVt+VQHLJIL@w8grkqLR*r)wAdDQD364RBb@&d#pMkwAYSj^7%b z6S%%kO9lwagTo1KmDl59O%N3T;a%Nc52UcOvtSj=r)Z!MKpGP3pBjaA*eCt0yE++D zR8Ggn_6!+dTLM0UM?^!<1~-+jevYVqL5kVl+}AqBuj^i|Fm+=9G`i&^jq(;j7!?S_ z0MmY={yb3wRh!0Km!?p7MqDB)1{;Ep5@~t->Z+B`Ok(Sqz!%1o*x1?Ht^iwSk6}1I z%_{KfqYhx;KTYmc4)>ue@rp9;8gM#?Mj0ZHyRJGS&=}=%UoH{W$2>5RW0jCJ>b^aWE_j<_Wb=_^RP903{(58OMuIZ%E zb7Gc8I~yCQ^Q5TzD(@p6^7yJj=04^>6b9n#>AKM@EzjO;T3)}}ZHsC}o;&CCEs^v| z70?SVnR427=rWpz6|Q-fR(Ur{K1^3>l&qcr1&5Pf{fz(yz{}6Ib+3u8o!Um-qy#Ug zeoz7VPK#lGf5s3$y|)X{ML+emw%6cdtJa5wcqjZNW`u9Ol*+bCeW*9Tyt}m(lYeub zzsh-Y$Z7Z9u1K^IB5eO1cepb)_Mv50noOA~Pn3}cN}Hb*WOXG&K^wI6qM7@f*Td>`#RdIp$6!*QMQIVTc2%pfOLH7vo|>dim0 zo1>f4Tc6FBkL!iTjDG-WqyQuIpD)qhpY~q{k9wqr=<;f|nv>n)b9pBhUvTrRwrY%H zB;pn-;<6S8I4_&5n z2nw(I@7M%(Jf`U*?Dl{s zIkuk|XTsy}q+K^|@1ryI<=BYO=$q3er7!2h*@~pJW09yvrIW3(dw=%!rVl0TA286IH#$o=)Z4A2I+P5V zR9ckf+Hrqlqe+`rgM21 zkPpL?hF?tNca0U~zRSrcaIuk!`b+cghQ+#*%KxN2K0dx6Q_UQwfFaOHIl02q&K#*M zs;Kn+U9u|Dyw1j4d(MbrXwycB5?~IfV3CFXrQR8mHkf@ixqPGpof`w=8Rs>g{bra` z^~>jYS@V~??oF1z0G{>p9L1~s#aSa$@)EcJD?f4-$J8Kwr36*x6-~G@An_?oIJ#df z;#~J??SX1Yjkk*N`>Ps;r;*{^$v{u)_V56>d4Bjw`lLuTBy4weVo5Py96Y6}N*aW?Sw;L2GpJE8 z?%w|JgO)}pVyBZ#iYtMYd!+5bD~Y_Onn#uW0FZDYx4HgXlKz7i!o6m1{>uu6CMRD6 z-4Vw;D?SRMZSKfd1R0W@Ar5-@3gW4UM&4sS}BeHnBT+Bo|1xCo! z+1cY|dfz||O*z@ea!#vE{H#6ANfnEaXAl{8lU*k{8JQ$mqT`p}9kMG#xZ<&dtt}y$bwCgIvQ*1)R&| zWV2ySRJu(7sg@;!;Cc3^?3@?5BZ}NncTLw9c7}iw4Or17u>7bw54x6_uEOL5N!Obi zzi94h&+RF^ItF%G7P2RP5_P_H#j>|`wnnp$2)Ki+K`-`w9F0qjD_+LZz3s%2MXHQr zV2@S*u$`?9ovmfd)Lzehu?~DdZ?EQsN|`CnXwBfrGG1T|X#@6$L`h^!_UYR5^M%$+ zY?-FD$LH0)ZWXR@lE8W5!`Sw8HG@itNpxY49?X1AL3i9SL&PJgI(dU;;NkI;-(fDH z*7)ge&PP|wKI#X@gmStK>ymRhm|dN2(GaM)-SBEcZ^8#=Ss!a{&eb>G30?_u+_1FQ zV1E8*Rv!ml{-(A&g0a77OV5;jSx^KWt1>dlX_Fp&(6xQJry~* zZg86Jd7d4NE%CBlL5xFm@(leNf8{=87FDbdeCp{V9_X8F5x+B*xC(u#vAmBpT`HcTOetN3H~1wci|Tt3zoM|?q0={YM8$dI z=Dii@sVG*>sK=wrov_?aGG83>-dW#>MEs+wI&^p_udS_(o>_9Lva14}gj?Ne1p9XK z&&CHhjME#NX9$Ln`EB{WzP?M&32wrWizXt8YVq1~PnUoABaFI;(sNKt}pGW6zR4xTrF7%@(VyUpA;PH42XMYeF;eNQyQGGLdGGu`IY?2Q*_LF_Z+|D zoW5&f4l;ILtR96F;b0hy*Pq{xdRa=nCnrJX(<2N(sO&Ld<*nA``F@glsijcqQpbfl zpM6Q)(c0i+SptC|#2$nFl7n(cgB9m2`_#*Eh`7PT%6R6#VwUR$zkX!^QwPkDJDcvf z7K$fc3aZ&U?0Vcmq6@jx;)pUK9i6%AEW+MvgT^E|6qPxt5fyJ-*Q^^n_|GgtW(a?} zDtNYNb@^Stx1L7%auo=1PjApe#TNy0hao{c{*gC*dbSRf^YqfiM*Q zv2J6W@OsF#Y>hQF+xhNeBYEQhUC7*1{SH)3j$smLsXg7|RN2zW$8)yUL3u_9;&_8X zI@5!#mzHkt=%AXJnbC*fqNb8{?_eS*oi7;W)u$V?d!m}!oxmQZ>Ua^lE~p&NQVwRT zy5s7?O0ILhVPlR;e0CJ0MpVzpQFmP2UD54X->?FriDJ0|^zPE);^Nd4+9y|xf#l5_ z)xNEE?PaokQ-S?m7>qaj>kSTu&xSWZ1@h3!ij(=YP5A!fgcCPWq@PSrLj2y2`B1NS zD&k?X(}SWDIB951&8)?#tfHNRp8oWjxhj{Sp!UK>B}HUX51Wr4w3N#0UYQlNV%?egYk zS!()N@s>qV*`$`Yg(&A6&!s_uzYQ}D7=>iRXWT?t=~$U)-XPlT8;kUqDbrHimRDA8 zR+#j&<8sizBkA>a{U}erBCty6ZXVTcF}C?2dp$`@b%I?Fwc);C(zt|;`C>RL`g}e^ zfseR2!!+3-Y+3N^olp!Q{Mg-}cHbRT+??G#id~ZBwJcmzDLF{nA;5S$I3CUQr%DH% z9WDKA4D@{*;l>M0a&&aG9WZ_jsT{9e6mOGF(yvN3 zE9tTignw7zW-1k5D*Gip?ddLlTkd1L`lo*}PCOrGq$v72#HWw+db;svB$Z!h16Ev? zC70M=Pd&h7`C(pKR6jR9#&zoS+aK*-)IQmP#l9a&6?aREkmys|?U(*b$%o6iU#O^sH$ z+7#)h6O#1?x4-b*hLL{ljjgySL?YfzSl`awPRQ;$jLN>{yD-jZKCoKWJP4py_u1)j zqEMl|!ID6nL1mE7jo!j4aS7$Ate3dr z2cY2_NN6p^$^E*@!Eni#KTXE=C9K*O#@hlmA9S6E*LlZ)%r1M38gL=5aT0xRS#_|ng85UPBOT!eZ!JZ)@AR}clEYV&aV|_earCr5|0h1 zr1KO1jMPVLm5w6E`|AYa2dl-cx%Rhlao?t=8Nd6cVFTl#BFS_6>(lVY02CwFt@7I1 z9~&YsIezT+Z@=@{VRl2L4!e?L;p;k zxH?;ylT2N&rVSs>7jdZaSrNFb3R29T_$*)x?%JO9#EX5 zSdoQ_D!HDhu>~?jw^dXIfdgb@WJFg_D3X^=Xd{uTf%|I+KR@u+|EbbMJiMgj0TlYz zRRQ{wXtnDdgl#OgU=$=`+X&mhZ~;N#4TZebyqVMd%W3(EIwG1P$)86_SQpMZ9&Ba{ zMftRgccAe8@4Nm7HGxNs69N8?#f*W4?{Y(jh;45wZ6RI%FooPf5em52Gmh}wEVjJc zpCe&Ee99cmZK@_?FU}X0HGKs+93DPC^8+kn-bDI*UM6KKf?G#d*K@9oy6I#`+opoM z*Uqqb)`?9v{X)SgPzf;qlqX_pNaQ(|%Vcq}3dq71fgpcm&_ndPK7@(TNP0a=0u5q} zZ_e_yVkpFuds!2@fsQz&spmZTfj*~m(+-8k575|NyP_KM{GIBbri4}%KCBi!iSq)r zy;1miQ^x$}xpMzu2?urXbaPUCi+vRvLj+)4^1bV`#ti~>j&ee=ltUrrE3xmx5lAxP zUaq234kduG&El4_Y`wj|I2{gSa_;Gln!w?9fQn{>zDtqK6ir%P4ZMC{#$WVSp9n(t z)D&-`#%mpsQMOZzAQkL}CGO1x^U+~z;$_S8(l@WH+BQ+k`#(rtQ&Trf8R}Zi%tRA! zvRa6H_)B$5ip*y;qZhxe>_^|&H2Uc#7sV_v-;*e)bbhjX7^Ko*DS0_zDQ4uxI(I`q z%B;{Rwz~R`h^T04N{V$*5Zr~?$rBh8partWHw7~>GmngoMU0XINLSyT-Z6p@v>S=!}A)naW^>j8_u%D8Po|4mNPw(qq=n%2xPRK0OXt;MhRg_)Q z!}o4q97&=%ZSbGFAFh3hWgYP8AbJ6T%X`d{f%0KH2Z!j;P;%g>l$DihXEq>w9Zc=_ zpiqF>dhIGrghK)X(h3W2fS`=E$O@aiog~CYN431ZF3iouc`3Pg4!5vaukCd&u&$Z*#KCK4+ zp@Bjbr%X2;LZNysn>KdCz1G>`tsld!YdT6_^>4ijZ&jf^4ZRg`%B~_;Yat7_2uhxS zMk2T!sCyP&?To_J%tZP7D%mGeSezvytBOVLpg&RD#PIi3P`p7vg)qJ#Ol0TeTnlTx z8XO$l83a}vnrpFnaO_z>QwzWKw?IQLDG~wX+_SX%FGdU0Qvi&T&`lrJ{<O3?XN6)Ftvt`^kH!bz1Mjg4;>9WrAd?C^g%il!;Z+R3XE(GpciR6Ig4RRB^>MG<=MDk~i}OqL4?^yBZhWu@0G?EkxTka}PZ z4iJBDk>R=a|2L<-Wi|QV&!}|O=_LLefGSKxkP7{GC@PBk$!rwb|6PTC>^)IUv-Yf3 Twn%$R20ogP^wdfpScm-|)^sw# literal 0 HcmV?d00001 diff --git a/packages/flame/test/_goldens/paint_decorator_grayscale_blur.png b/packages/flame/test/_goldens/paint_decorator_grayscale_blur.png new file mode 100644 index 0000000000000000000000000000000000000000..bdd1f9a7828206ac9693435700408d80fbdedea4 GIT binary patch literal 20982 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 literal 0 HcmV?d00001 diff --git a/packages/flame/test/rendering/paint_decorator_test.dart b/packages/flame/test/rendering/paint_decorator_test.dart index 149c7df3962..563c14913e1 100644 --- a/packages/flame/test/rendering/paint_decorator_test.dart +++ b/packages/flame/test/rendering/paint_decorator_test.dart @@ -79,6 +79,24 @@ void main() { size: Vector2(400, 300), goldenFile: '../_goldens/paint_decorator_tinted.png', ); + + + testGolden( + 'grayscale with blur', + (game) async { + final image = await loadImage('zz_guitarre.png'); + game.addAll([ + SpriteComponent(sprite: Sprite(image)), + _DecoratedSprite( + sprite: Sprite(image), + decorator: PaintDecorator.grayscale()..addBlur(3), + position: Vector2(100, 0), + ), + ]); + }, + size: Vector2(200, 300), + goldenFile: '../_goldens/paint_decorator_grayscale_blur.png', + ); }); } From 180a616404f817f5653c40f1dfd5c382eb4d7c6f Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 2 Jul 2022 22:55:48 -0700 Subject: [PATCH 12/34] update last test --- .../_goldens/paint_decorator_grayscale_blur.png | Bin 20982 -> 0 bytes .../test/_goldens/paint_decorator_with_blur.png | Bin 0 -> 41449 bytes .../test/rendering/paint_decorator_test.dart | 13 +++++++++---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 packages/flame/test/_goldens/paint_decorator_grayscale_blur.png create mode 100644 packages/flame/test/_goldens/paint_decorator_with_blur.png diff --git a/packages/flame/test/_goldens/paint_decorator_grayscale_blur.png b/packages/flame/test/_goldens/paint_decorator_grayscale_blur.png deleted file mode 100644 index bdd1f9a7828206ac9693435700408d80fbdedea4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20982 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 Date: Mon, 4 Jul 2022 13:35:47 +0100 Subject: [PATCH 13/34] feat: New colours to pallete.dart (#1783) added 20 new colors and the colors are in alphabetical order. --- packages/flame/lib/src/palette.dart | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/packages/flame/lib/src/palette.dart b/packages/flame/lib/src/palette.dart index 45d72fba4a9..a84aedd379e 100644 --- a/packages/flame/lib/src/palette.dart +++ b/packages/flame/lib/src/palette.dart @@ -31,4 +31,24 @@ class BasicPalette { static const PaletteEntry green = PaletteEntry(Color(0xFF00FF00)); static const PaletteEntry blue = PaletteEntry(Color(0xFF0000FF)); static const PaletteEntry magenta = PaletteEntry(Color(0xFFFF00FF)); + static const PaletteEntry brown = PaletteEntry(Color(0xFFA52A2A)); + static const PaletteEntry cyan = PaletteEntry(Color(0xFF00FFFF)); + static const PaletteEntry darkBlue = PaletteEntry(Color(0xFF000080)); + static const PaletteEntry darkGray = PaletteEntry(Color(0xFFA9A9A9)); + static const PaletteEntry darkGreen = PaletteEntry(Color(0xFF006400)); + static const PaletteEntry darkPink = PaletteEntry(Color(0xFFFFC0CB)); + static const PaletteEntry darkRed = PaletteEntry(Color(0xFFB22222)); + static const PaletteEntry gray = PaletteEntry(Color(0xFF808080)); + static const PaletteEntry lime = PaletteEntry(Color(0xFF32CD32)); + static const PaletteEntry lightBlue = PaletteEntry(Color(0xFF00BFFF)); + static const PaletteEntry lightGreen = PaletteEntry(Color(0xFF7CFC00)); + static const PaletteEntry lightGray = PaletteEntry(Color(0xFFD3D3D3)); + static const PaletteEntry lightOrange = PaletteEntry(Color(0xFFFF8C00)); + static const PaletteEntry lightPink = PaletteEntry(Color(0xFFFFB6C1)); + static const PaletteEntry lightRed = PaletteEntry(Color(0xFFFFA07A)); + static const PaletteEntry orange = PaletteEntry(Color(0xFFFFA500)); + static const PaletteEntry pink = PaletteEntry(Color(0xFFFF69B4)); + static const PaletteEntry purple = PaletteEntry(Color(0xFF800080)); + static const PaletteEntry teal = PaletteEntry(Color(0xFF008080)); + static const PaletteEntry yellow = PaletteEntry(Color(0xFFFFFF00)); } From 9d7b4467f49079f6d8b3f49adb5e6fd731946afa Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Thu, 7 Jul 2022 11:42:20 -0700 Subject: [PATCH 14/34] perf!: Game.images/assets are now same as Flame.images/assets by default (#1775) The caches Game.images and Game.assets now coincide with the static caches Flame.images and Flame.assets by default. This aims to avoid the situation where the same image (asset) may be loaded twice into two separate caches without the user noticing. --- packages/flame/lib/src/game/game.dart | 12 ++++++++++-- packages/flame/test/cache/images_test.dart | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/flame/lib/src/game/game.dart b/packages/flame/lib/src/game/game.dart index e2408695325..43d35dd2492 100644 --- a/packages/flame/lib/src/game/game.dart +++ b/packages/flame/lib/src/game/game.dart @@ -1,6 +1,7 @@ import 'package:flame/cache.dart'; import 'package:flame/components.dart'; import 'package:flame/extensions.dart'; +import 'package:flame/src/flame.dart'; import 'package:flame/src/game/game_render_box.dart'; import 'package:flame/src/game/projector.dart'; import 'package:flutter/rendering.dart'; @@ -15,8 +16,15 @@ import 'package:meta/meta.dart'; /// Methods [update] and [render] need to be implemented in order to connect /// your class with the internal game loop. abstract class Game { - final images = Images(); - final assets = AssetsCache(); + /// The cache of all images loaded into the game. This defaults to the global + /// [Flame.images] cache, but you can replace it with a new cache instance if + /// needed. + Images images = Flame.images; + + /// The cache of all (non-image) assets loaded into the game. This defaults to + /// the global [Flame.assets] cache, but you can replace this with another + /// instance if needed. + AssetsCache assets = Flame.assets; /// This should update the state of the game. void update(double dt); diff --git a/packages/flame/test/cache/images_test.dart b/packages/flame/test/cache/images_test.dart index 2ecf2b160f4..9604db3ee13 100644 --- a/packages/flame/test/cache/images_test.dart +++ b/packages/flame/test/cache/images_test.dart @@ -2,6 +2,7 @@ import 'dart:ui'; import 'package:collection/collection.dart'; import 'package:flame/cache.dart'; +import 'package:flame/flame.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -81,6 +82,7 @@ void main() { testWithFlameGame( 'prefix on game.images can be changed', (game) async { + game.images = Images(); expect(game.images.prefix, 'assets/images/'); game.images.prefix = 'assets/pictures/'; expect(game.images.prefix, 'assets/pictures/'); @@ -89,6 +91,21 @@ void main() { }, ); + testWithFlameGame( + 'Game.images is same as Flame.images', + (game) async { + expect(game.images, equals(Flame.images)); + + final img = _MockImage(); + game.images.add('my image', img); + expect(Flame.images.containsKey('my image'), isTrue); + + game.images = Images(); + game.images.add('new image', img); + expect(Flame.images.containsKey('new image'), isFalse); + }, + ); + test('throws when setting an invalid prefix', () { final images = Images(); expect( From 81193c9bf3a0cc1c5d8dfe4e8cfe7d2e82bbf6ce Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Fri, 8 Jul 2022 10:33:19 +0200 Subject: [PATCH 15/34] fix: Correct the imports for the padracing -> dartpad script (#1786) After a previous update to padracing I forgot to update the script that turns it into a file that can be put into DartPad. --- examples/games/padracing/lib/main.dart | 2 +- examples/games/padracing/scripts/merge_files.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 examples/games/padracing/scripts/merge_files.sh diff --git a/examples/games/padracing/lib/main.dart b/examples/games/padracing/lib/main.dart index ad099e4d6d3..67b71714546 100644 --- a/examples/games/padracing/lib/main.dart +++ b/examples/games/padracing/lib/main.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide Image, Gradient; import 'package:padracing/padracing_widget.dart'; void main() { diff --git a/examples/games/padracing/scripts/merge_files.sh b/examples/games/padracing/scripts/merge_files.sh old mode 100644 new mode 100755 index 787c49a7dd9..74bc8766eba --- a/examples/games/padracing/scripts/merge_files.sh +++ b/examples/games/padracing/scripts/merge_files.sh @@ -14,7 +14,7 @@ cat $(ls | grep -v 'main.dart' | grep -v 'padracing_game.dart') >> $OUTPUT/main. cd $OUTPUT grep import < main.dart > imports.dart grep -v import < main.dart > tmp.dart -LC_COLLATE=c sort -u imports.dart | grep : > imports_tmp.dart +LC_COLLATE=c sort -u imports.dart | grep -v padracing > imports_tmp.dart cat imports_tmp.dart tmp.dart > main.dart rm tmp.dart imports_tmp.dart imports.dart echo '//ignore_for_file: avoid_web_libraries_in_flutter' >> main.dart From 4082a6add87e9a8601cd2a00d0dc3daa056977b4 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Fri, 8 Jul 2022 13:41:14 +0200 Subject: [PATCH 16/34] chore(release): publish packages (#1789) * chore(release): publish packages - flame@1.2.1 - flame_audio@1.3.0 - flame_test@1.6.0 - flame_bloc@1.6.0 - flame_fire_atlas@1.2.0 - flame_flare@1.3.0 - flame_forge2d@0.12.1 - flame_lint@0.1.1 - flame_oxygen@0.1.4 - flame_rive@1.5.0 - flame_svg@1.4.0 - flame_tiled@1.6.0 * Update packages/flame/CHANGELOG.md --- CHANGELOG.md | 121 ++++++++++++++++++ doc/flame/examples/pubspec.yaml | 4 +- doc/tutorials/klondike/app/pubspec.yaml | 5 +- examples/games/padracing/pubspec.yaml | 4 +- examples/games/trex/pubspec.yaml | 5 +- examples/pubspec.yaml | 9 +- packages/flame/CHANGELOG.md | 25 ++++ packages/flame/example/pubspec.yaml | 4 +- packages/flame/pubspec.yaml | 6 +- packages/flame_audio/CHANGELOG.md | 7 + packages/flame_audio/example/pubspec.yaml | 7 +- packages/flame_audio/pubspec.yaml | 6 +- packages/flame_bloc/CHANGELOG.md | 7 + packages/flame_bloc/example/pubspec.yaml | 4 +- packages/flame_bloc/pubspec.yaml | 8 +- packages/flame_fire_atlas/CHANGELOG.md | 6 + .../flame_fire_atlas/example/pubspec.yaml | 6 +- packages/flame_fire_atlas/pubspec.yaml | 6 +- packages/flame_flare/CHANGELOG.md | 6 + packages/flame_flare/example/pubspec.yaml | 7 +- packages/flame_flare/pubspec.yaml | 6 +- packages/flame_forge2d/CHANGELOG.md | 5 + packages/flame_forge2d/example/pubspec.yaml | 2 +- packages/flame_forge2d/pubspec.yaml | 8 +- packages/flame_lint/CHANGELOG.md | 11 ++ packages/flame_lint/pubspec.yaml | 2 +- packages/flame_oxygen/CHANGELOG.md | 6 + packages/flame_oxygen/example/pubspec.yaml | 7 +- packages/flame_oxygen/pubspec.yaml | 6 +- packages/flame_rive/CHANGELOG.md | 6 + packages/flame_rive/example/pubspec.yaml | 6 +- packages/flame_rive/pubspec.yaml | 6 +- packages/flame_svg/CHANGELOG.md | 5 + packages/flame_svg/example/pubspec.yaml | 6 +- packages/flame_svg/pubspec.yaml | 6 +- packages/flame_test/CHANGELOG.md | 9 ++ packages/flame_test/example/pubspec.yaml | 6 +- packages/flame_test/pubspec.yaml | 6 +- packages/flame_tiled/CHANGELOG.md | 6 + packages/flame_tiled/example/pubspec.yaml | 7 +- packages/flame_tiled/pubspec.yaml | 6 +- tutorials/space_shooter/pubspec.yaml | 4 +- 42 files changed, 299 insertions(+), 86 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f874525a95..dc1c8e9fa09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,127 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 2022-07-08 + +### Changes + +--- + +Packages with breaking changes: + + - [`flame` - `v1.2.1`](#flame---v121) + - [`flame_audio` - `v1.3.0`](#flame_audio---v130) + - [`flame_test` - `v1.6.0`](#flame_test---v160) + +Packages with other changes: + + - [`flame_bloc` - `v1.6.0`](#flame_bloc---v160) + - [`flame_fire_atlas` - `v1.2.0`](#flame_fire_atlas---v120) + - [`flame_flare` - `v1.3.0`](#flame_flare---v130) + - [`flame_forge2d` - `v0.12.1`](#flame_forge2d---v0121) + - [`flame_lint` - `v0.1.1`](#flame_lint---v011) + - [`flame_oxygen` - `v0.1.4`](#flame_oxygen---v014) + - [`flame_rive` - `v1.5.0`](#flame_rive---v150) + - [`flame_svg` - `v1.4.0`](#flame_svg---v140) + - [`flame_tiled` - `v1.6.0`](#flame_tiled---v160) + +--- + +#### `flame` - `v1.2.1` + + - **REFACTOR**: Game is now a class, not a mixin ([#1751](https://github.com/flame-engine/flame/issues/1751)). ([5225a4eb](https://github.com/flame-engine/flame/commit/5225a4ebd55a21f5709ccab9a1e24c728b2747ed)) + - **REFACTOR**: Use new "super"-constructors in ShapeComponents ([#1752](https://github.com/flame-engine/flame/issues/1752)). ([b69e8d85](https://github.com/flame-engine/flame/commit/b69e8d85c77346081d1fc5a2ee5cbf9c204a9edf)) + - **PERF**: Avoid unnecessary copy in AssetsCache.readBinaryFile ([#1749](https://github.com/flame-engine/flame/issues/1749)). ([7e79638d](https://github.com/flame-engine/flame/commit/7e79638dd577cb07d55402d4e862de08ce832b85)) + - **FIX**: Specify size for the SpriteWidget ([#1760](https://github.com/flame-engine/flame/issues/1760)). ([82f75fcb](https://github.com/flame-engine/flame/commit/82f75fcb57c8185a7138ee6ceb9082a418099df8)) + - **FIX**: SpriteAnimationWidget can now be update animation safely ([#1738](https://github.com/flame-engine/flame/issues/1738)). ([eb070195](https://github.com/flame-engine/flame/commit/eb0701951c165576fac1f540c8860e560a8961e6)) + - **FIX**: Overlays can now be properly added during onLoad ([#1759](https://github.com/flame-engine/flame/issues/1759)). ([9f35b154](https://github.com/flame-engine/flame/commit/9f35b15420bea9ac5eeeddc245484b854e8eed38)) + - **FIX**: Camera incorrect follow with zoom and world boundaries. ([c1756177](https://github.com/flame-engine/flame/commit/c175617714e2f15f4379ed8ea412c7cb8bfa1842)) + - **FIX**: Correct key events in GameWidget.controller ([#1745](https://github.com/flame-engine/flame/issues/1745)). ([01ed2ec9](https://github.com/flame-engine/flame/commit/01ed2ec967ee29c946c967786eec6bf7cc6ec958)) + - **FIX**: World component can now be queried with `componentsAtPoint` ([#1739](https://github.com/flame-engine/flame/issues/1739)). ([f750d705](https://github.com/flame-engine/flame/commit/f750d705d14dd0ba95d550b2b8a320201a96584b)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FIX**: ButtonComponent behavior when the engine is paused ([#1726](https://github.com/flame-engine/flame/issues/1726)). ([197e63d6](https://github.com/flame-engine/flame/commit/197e63d69e2a4c6779e49b918d05a60447ce9462)) + - **FIX**: Add missing paint arguments on shapes ([#1727](https://github.com/flame-engine/flame/issues/1727)). ([e59f3428](https://github.com/flame-engine/flame/commit/e59f3428469e4298d812bb665171679df8895daf)) + - **FIX**: Merge basic and advanced gesture detectors ([#1718](https://github.com/flame-engine/flame/issues/1718)). ([f08f8e12](https://github.com/flame-engine/flame/commit/f08f8e12f5322c7bea1491908f06b350e13c14b7)) + - **FEAT**: New colours to pallete.dart ([#1783](https://github.com/flame-engine/flame/issues/1783)). ([85cd60e1](https://github.com/flame-engine/flame/commit/85cd60e16c7b4dafdf1823bf85a7ae8a50fd05f2)) + - **FEAT**: Added TextFormatter classes ([#1720](https://github.com/flame-engine/flame/issues/1720)). ([c44272be](https://github.com/flame-engine/flame/commit/c44272be45eadfabc8f03ef250eb663e59ef2aab)) + - **FEAT**: Drag events that dispatch using componentsAtPoint ([#1715](https://github.com/flame-engine/flame/issues/1715)). ([10669c12](https://github.com/flame-engine/flame/commit/10669c12702a3a82fcf5be9161107dce4349a79f)) + - **FEAT**: add `HasAncestor` mixin ([#1711](https://github.com/flame-engine/flame/issues/1711)). ([987a44f4](https://github.com/flame-engine/flame/commit/987a44f441429534c743388b44e6d84b28e8f5ca)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: Klondike tutorial, part 4 ([#1740](https://github.com/flame-engine/flame/issues/1740)). ([02d0b71b](https://github.com/flame-engine/flame/commit/02d0b71b2379d12b36b53a76b6bcf5f4018ec9df)) + - **BREAKING** **REFACTOR**: Matcher closeToVector() now accepts Vector2 as an argument ([#1761](https://github.com/flame-engine/flame/issues/1761)). ([c5083501](https://github.com/flame-engine/flame/commit/c5083501d54023f04d3f09e3358bce039ade9a20)) + - **BREAKING** **PERF**: Game.images/assets are now same as Flame.images/assets by default ([#1775](https://github.com/flame-engine/flame/issues/1775)). ([0ccb0e2e](https://github.com/flame-engine/flame/commit/0ccb0e2ef525661830c7b4662662ba64fda830fe)) + +#### `flame_audio` - `v1.3.0` + + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **BREAKING** **FEAT**: Update flame_audio to AP 1.0.0 ([#1724](https://github.com/flame-engine/flame/issues/1724)). ([d6bf920d](https://github.com/flame-engine/flame/commit/d6bf920d28eea5f08adcba2601104271078e7a3d)) + +#### `flame_test` - `v1.6.0` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Added size parameter for testGolden() ([#1780](https://github.com/flame-engine/flame/issues/1780)). ([8e41d83e](https://github.com/flame-engine/flame/commit/8e41d83ea4e057e1a428f0456450d697351683bf)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **BREAKING** **REFACTOR**: Matcher closeToVector() now accepts Vector2 as an argument ([#1761](https://github.com/flame-engine/flame/issues/1761)). ([c5083501](https://github.com/flame-engine/flame/commit/c5083501d54023f04d3f09e3358bce039ade9a20)) + +#### `flame_bloc` - `v1.6.0` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Adding bloc getter to FlameBlocListenable mixin ([#1732](https://github.com/flame-engine/flame/issues/1732)). ([3d19caa3](https://github.com/flame-engine/flame/commit/3d19caa36dcb470b306b841ef9c03647a2f307d7)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: updating README to the new flame bloc version ([#1737](https://github.com/flame-engine/flame/issues/1737)). ([6a2356aa](https://github.com/flame-engine/flame/commit/6a2356aa5eba1696caa6f88ecfe8143c4ffdb507)) + +#### `flame_fire_atlas` - `v1.2.0` + + - **PERF**: Avoid unnecessary copy in AssetsCache.readBinaryFile ([#1749](https://github.com/flame-engine/flame/issues/1749)). ([7e79638d](https://github.com/flame-engine/flame/commit/7e79638dd577cb07d55402d4e862de08ce832b85)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + +#### `flame_flare` - `v1.3.0` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: Documenting how to write documentation ([#1721](https://github.com/flame-engine/flame/issues/1721)). ([ea354e3a](https://github.com/flame-engine/flame/commit/ea354e3a81e3810a8d2b9e3783d9833ae92349e0)) + +#### `flame_forge2d` - `v0.12.1` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + +#### `flame_lint` - `v0.1.1` + + - **REFACTOR**: Move to package imports ([#1625](https://github.com/flame-engine/flame/issues/1625)). ([843ddc36](https://github.com/flame-engine/flame/commit/843ddc36249272fcb518b44672e1012307dfa1b5)) + - **REFACTOR**: Add a few more rules to flame_lint, including use_key_in_widget_constructors ([#1248](https://github.com/flame-engine/flame/issues/1248)). ([bac6c8a4](https://github.com/flame-engine/flame/commit/bac6c8a4469f2c5c2926335f2f589eec9b1a5b5b)) + - **FIX**: Upgrade dartdoc (upgrade analyzer transitive dependency) ([#1630](https://github.com/flame-engine/flame/issues/1630)). ([6da8adb2](https://github.com/flame-engine/flame/commit/6da8adb28cffd8fcb43e6bf8a33aae22578f1b40)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **FEAT**: Add more lint rules ([#1703](https://github.com/flame-engine/flame/issues/1703)). ([49252f8e](https://github.com/flame-engine/flame/commit/49252f8ef29aa6b77144dcb97c24346f2f39380b)) + - **FEAT**: Add non_constant_identifier_names rule ([#1656](https://github.com/flame-engine/flame/issues/1656)). ([1b40de09](https://github.com/flame-engine/flame/commit/1b40de094f4e66be7622d077a6e18cecf1964dde)) + - **FEAT**: Bump to Flutter 2.10.0 ([#1617](https://github.com/flame-engine/flame/issues/1617)). ([beac9013](https://github.com/flame-engine/flame/commit/beac901313456cf0b39b6f4e6459f0feed183614)) + - **DOCS**: Fix various dartdoc warnings ([#1353](https://github.com/flame-engine/flame/issues/1353)). ([9f096053](https://github.com/flame-engine/flame/commit/9f096053fd3c8ebd52d301710625a187db09704f)) + +#### `flame_oxygen` - `v0.1.4` + + - **REFACTOR**: Game is now a class, not a mixin ([#1751](https://github.com/flame-engine/flame/issues/1751)). ([5225a4eb](https://github.com/flame-engine/flame/commit/5225a4ebd55a21f5709ccab9a1e24c728b2747ed)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + +#### `flame_rive` - `v1.5.0` + + - **FIX**: Flame_rive now can load Nested Artboards and update to 0.9.0 rive package ([#1741](https://github.com/flame-engine/flame/issues/1741)). ([82e4be96](https://github.com/flame-engine/flame/commit/82e4be96f3090908e95659a96006bf50fbb5b08c)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + +#### `flame_svg` - `v1.4.0` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + +#### `flame_tiled` - `v1.6.0` + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FIX**: tiled example size ([#1729](https://github.com/flame-engine/flame/issues/1729)). ([8306fc11](https://github.com/flame-engine/flame/commit/8306fc1104cb752ce71108abb3768f05ce1b1dac)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + + ## 2022-06-19 ### Changes diff --git a/doc/flame/examples/pubspec.yaml b/doc/flame/examples/pubspec.yaml index 10fdc4a261b..f888efa554b 100644 --- a/doc/flame/examples/pubspec.yaml +++ b/doc/flame/examples/pubspec.yaml @@ -8,9 +8,9 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 \ No newline at end of file diff --git a/doc/tutorials/klondike/app/pubspec.yaml b/doc/tutorials/klondike/app/pubspec.yaml index 0cc9cd27234..557bb09c818 100644 --- a/doc/tutorials/klondike/app/pubspec.yaml +++ b/doc/tutorials/klondike/app/pubspec.yaml @@ -7,13 +7,12 @@ environment: sdk: ^2.17.0 dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: assets: - assets/images/ diff --git a/examples/games/padracing/pubspec.yaml b/examples/games/padracing/pubspec.yaml index b066e2ac95f..0e73b28836f 100644 --- a/examples/games/padracing/pubspec.yaml +++ b/examples/games/padracing/pubspec.yaml @@ -7,7 +7,7 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flame_forge2d: ^0.11.0 flutter: sdk: flutter @@ -15,7 +15,7 @@ dependencies: url_launcher: ^6.1.2 dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/examples/games/trex/pubspec.yaml b/examples/games/trex/pubspec.yaml index 1d8141d3b6b..50a6ad93bce 100644 --- a/examples/games/trex/pubspec.yaml +++ b/examples/games/trex/pubspec.yaml @@ -10,13 +10,12 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: uses-material-design: true diff --git a/examples/pubspec.yaml b/examples/pubspec.yaml index cd41a6060e3..3dd72e48833 100644 --- a/examples/pubspec.yaml +++ b/examples/pubspec.yaml @@ -11,10 +11,10 @@ environment: dependencies: dashbook: 0.1.8 - flame: ^1.2.0 - flame_audio: ^1.2.0 + flame: ^1.2.1 + flame_audio: ^1.3.0 flame_forge2d: ^0.11.0 - flame_svg: ^1.3.0 + flame_svg: ^1.4.0 flutter: sdk: flutter google_fonts: ^2.3.2 @@ -24,8 +24,7 @@ dependencies: path: games/trex dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: uses-material-design: true diff --git a/packages/flame/CHANGELOG.md b/packages/flame/CHANGELOG.md index fe4ad0e4b80..c739a17cf0f 100644 --- a/packages/flame/CHANGELOG.md +++ b/packages/flame/CHANGELOG.md @@ -1,3 +1,28 @@ +## 1.2.1 + +> Note: This release has breaking changes. + + - **REFACTOR**: Game is now a class, not a mixin ([#1751](https://github.com/flame-engine/flame/issues/1751)). ([5225a4eb](https://github.com/flame-engine/flame/commit/5225a4ebd55a21f5709ccab9a1e24c728b2747ed)) + - **REFACTOR**: Use new "super"-constructors in ShapeComponents ([#1752](https://github.com/flame-engine/flame/issues/1752)). ([b69e8d85](https://github.com/flame-engine/flame/commit/b69e8d85c77346081d1fc5a2ee5cbf9c204a9edf)) + - **PERF**: Avoid unnecessary copy in AssetsCache.readBinaryFile ([#1749](https://github.com/flame-engine/flame/issues/1749)). ([7e79638d](https://github.com/flame-engine/flame/commit/7e79638dd577cb07d55402d4e862de08ce832b85)) + - **FIX**: Specify size for the SpriteWidget ([#1760](https://github.com/flame-engine/flame/issues/1760)). ([82f75fcb](https://github.com/flame-engine/flame/commit/82f75fcb57c8185a7138ee6ceb9082a418099df8)) + - **FIX**: SpriteAnimationWidget can now be update animation safely ([#1738](https://github.com/flame-engine/flame/issues/1738)). ([eb070195](https://github.com/flame-engine/flame/commit/eb0701951c165576fac1f540c8860e560a8961e6)) + - **FIX**: Overlays can now be properly added during onLoad ([#1759](https://github.com/flame-engine/flame/issues/1759)). ([9f35b154](https://github.com/flame-engine/flame/commit/9f35b15420bea9ac5eeeddc245484b854e8eed38)) + - **FIX**: Camera incorrect follow with zoom and world boundaries. ([c1756177](https://github.com/flame-engine/flame/commit/c175617714e2f15f4379ed8ea412c7cb8bfa1842)) + - **FIX**: Correct key events in GameWidget.controller ([#1745](https://github.com/flame-engine/flame/issues/1745)). ([01ed2ec9](https://github.com/flame-engine/flame/commit/01ed2ec967ee29c946c967786eec6bf7cc6ec958)) + - **FIX**: World component can now be queried with `componentsAtPoint` ([#1739](https://github.com/flame-engine/flame/issues/1739)). ([f750d705](https://github.com/flame-engine/flame/commit/f750d705d14dd0ba95d550b2b8a320201a96584b)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FIX**: ButtonComponent behavior when the engine is paused ([#1726](https://github.com/flame-engine/flame/issues/1726)). ([197e63d6](https://github.com/flame-engine/flame/commit/197e63d69e2a4c6779e49b918d05a60447ce9462)) + - **FIX**: Add missing paint arguments on shapes ([#1727](https://github.com/flame-engine/flame/issues/1727)). ([e59f3428](https://github.com/flame-engine/flame/commit/e59f3428469e4298d812bb665171679df8895daf)) + - **FIX**: Merge basic and advanced gesture detectors ([#1718](https://github.com/flame-engine/flame/issues/1718)). ([f08f8e12](https://github.com/flame-engine/flame/commit/f08f8e12f5322c7bea1491908f06b350e13c14b7)) + - **FEAT**: New colours to pallete.dart ([#1783](https://github.com/flame-engine/flame/issues/1783)). ([85cd60e1](https://github.com/flame-engine/flame/commit/85cd60e16c7b4dafdf1823bf85a7ae8a50fd05f2)) + - **FEAT**: Added TextFormatter classes ([#1720](https://github.com/flame-engine/flame/issues/1720)). ([c44272be](https://github.com/flame-engine/flame/commit/c44272be45eadfabc8f03ef250eb663e59ef2aab)) + - **FEAT**: Drag events that dispatch using componentsAtPoint ([#1715](https://github.com/flame-engine/flame/issues/1715)). ([10669c12](https://github.com/flame-engine/flame/commit/10669c12702a3a82fcf5be9161107dce4349a79f)) + - **FEAT**: add `HasAncestor` mixin ([#1711](https://github.com/flame-engine/flame/issues/1711)). ([987a44f4](https://github.com/flame-engine/flame/commit/987a44f441429534c743388b44e6d84b28e8f5ca)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: Klondike tutorial, part 4 ([#1740](https://github.com/flame-engine/flame/issues/1740)). ([02d0b71b](https://github.com/flame-engine/flame/commit/02d0b71b2379d12b36b53a76b6bcf5f4018ec9df)) + - **BREAKING** **PERF**: Game.images/assets are now same as Flame.images/assets by default ([#1775](https://github.com/flame-engine/flame/issues/1775)). ([0ccb0e2e](https://github.com/flame-engine/flame/commit/0ccb0e2ef525661830c7b4662662ba64fda830fe)) + ## 1.2.0 > Note: This release has breaking changes. diff --git a/packages/flame/example/pubspec.yaml b/packages/flame/example/pubspec.yaml index f37e8d5ae94..230376cc735 100644 --- a/packages/flame/example/pubspec.yaml +++ b/packages/flame/example/pubspec.yaml @@ -8,11 +8,11 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame/pubspec.yaml b/packages/flame/pubspec.yaml index 935f555d39c..4be9e770829 100644 --- a/packages/flame/pubspec.yaml +++ b/packages/flame/pubspec.yaml @@ -1,6 +1,6 @@ name: flame description: A minimalist Flutter game engine, provides a nice set of somewhat independent modules you can choose from. -version: 1.2.0 +version: 1.2.1 homepage: https://github.com/flame-engine/flame environment: @@ -18,8 +18,8 @@ dependencies: dev_dependencies: canvas_test: ^0.2.0 dartdoc: ^4.1.0 - flame_lint: ^0.0.1 - flame_test: ^1.5.0 + flame_lint: ^0.1.1 + flame_test: ^1.6.0 flutter_test: sdk: flutter mocktail: ^0.3.0 diff --git a/packages/flame_audio/CHANGELOG.md b/packages/flame_audio/CHANGELOG.md index 79a76c899ed..dade1d89710 100644 --- a/packages/flame_audio/CHANGELOG.md +++ b/packages/flame_audio/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.3.0 + +> Note: This release has breaking changes. + + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **BREAKING** **FEAT**: Update flame_audio to AP 1.0.0 ([#1724](https://github.com/flame-engine/flame/issues/1724)). ([d6bf920d](https://github.com/flame-engine/flame/commit/d6bf920d28eea5f08adcba2601104271078e7a3d)) + ## 1.2.0 > Note: This release has breaking changes. diff --git a/packages/flame_audio/example/pubspec.yaml b/packages/flame_audio/example/pubspec.yaml index 99bbfebade6..13d7ddc7e07 100644 --- a/packages/flame_audio/example/pubspec.yaml +++ b/packages/flame_audio/example/pubspec.yaml @@ -9,14 +9,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_audio: ^1.2.0 + flame: ^1.2.1 + flame_audio: ^1.3.0 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: assets: - assets/audio/music/bg_music.ogg diff --git a/packages/flame_audio/pubspec.yaml b/packages/flame_audio/pubspec.yaml index b6bcf65de6d..96bd58fed17 100644 --- a/packages/flame_audio/pubspec.yaml +++ b/packages/flame_audio/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_audio description: Audio support for the Flame game engine. This containst all audio related code will live in the future, using the audioplayers package. -version: 1.2.0 +version: 1.3.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_audio environment: @@ -9,11 +9,11 @@ environment: dependencies: audioplayers: ^1.0.1 - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter synchronized: ^3.0.0 dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 \ No newline at end of file diff --git a/packages/flame_bloc/CHANGELOG.md b/packages/flame_bloc/CHANGELOG.md index 502d4b31d96..8a342764056 100644 --- a/packages/flame_bloc/CHANGELOG.md +++ b/packages/flame_bloc/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.6.0 + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Adding bloc getter to FlameBlocListenable mixin ([#1732](https://github.com/flame-engine/flame/issues/1732)). ([3d19caa3](https://github.com/flame-engine/flame/commit/3d19caa36dcb470b306b841ef9c03647a2f307d7)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: updating README to the new flame bloc version ([#1737](https://github.com/flame-engine/flame/issues/1737)). ([6a2356aa](https://github.com/flame-engine/flame/commit/6a2356aa5eba1696caa6f88ecfe8143c4ffdb507)) + ## 1.5.0 - **REFACTOR**: Update and guarantee consistency on mocktail dev dependency version across repo ([#1701](https://github.com/flame-engine/flame/issues/1701)). ([f4a98878](https://github.com/flame-engine/flame/commit/f4a98878062dbd4fe8238a8b014e6be3e528c5d8)) diff --git a/packages/flame_bloc/example/pubspec.yaml b/packages/flame_bloc/example/pubspec.yaml index 374c6137f66..7024bc8b6a6 100644 --- a/packages/flame_bloc/example/pubspec.yaml +++ b/packages/flame_bloc/example/pubspec.yaml @@ -10,13 +10,13 @@ environment: dependencies: equatable: ^2.0.3 - flame_bloc: ^1.5.0 + flame_bloc: ^1.6.0 flutter: sdk: flutter flutter_bloc: ^8.0.1 dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_bloc/pubspec.yaml b/packages/flame_bloc/pubspec.yaml index c71ec9b82a6..3dd7878b426 100644 --- a/packages/flame_bloc/pubspec.yaml +++ b/packages/flame_bloc/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_bloc description: Bloc integration to Flame games -version: 1.5.0 +version: 1.6.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_bloc environment: @@ -9,7 +9,7 @@ environment: dependencies: bloc: ^8.0.2 - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter flutter_bloc: ^8.0.1 @@ -17,8 +17,8 @@ dependencies: dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 - flame_test: ^1.5.0 + flame_lint: ^0.1.1 + flame_test: ^1.6.0 flutter_lints: ^1.0.0 flutter_test: sdk: flutter diff --git a/packages/flame_fire_atlas/CHANGELOG.md b/packages/flame_fire_atlas/CHANGELOG.md index 483dd0bdb09..759afec3707 100644 --- a/packages/flame_fire_atlas/CHANGELOG.md +++ b/packages/flame_fire_atlas/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.2.0 + + - **PERF**: Avoid unnecessary copy in AssetsCache.readBinaryFile ([#1749](https://github.com/flame-engine/flame/issues/1749)). ([7e79638d](https://github.com/flame-engine/flame/commit/7e79638dd577cb07d55402d4e862de08ce832b85)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 1.1.0 - **REFACTOR**: Update and guarantee consistency on mocktail dev dependency version across repo ([#1701](https://github.com/flame-engine/flame/issues/1701)). ([f4a98878](https://github.com/flame-engine/flame/commit/f4a98878062dbd4fe8238a8b014e6be3e528c5d8)) diff --git a/packages/flame_fire_atlas/example/pubspec.yaml b/packages/flame_fire_atlas/example/pubspec.yaml index 122cc7e575f..0c3f27ead5e 100644 --- a/packages/flame_fire_atlas/example/pubspec.yaml +++ b/packages/flame_fire_atlas/example/pubspec.yaml @@ -9,13 +9,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_fire_atlas: ^1.1.0 + flame: ^1.2.1 + flame_fire_atlas: ^1.2.0 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_fire_atlas/pubspec.yaml b/packages/flame_fire_atlas/pubspec.yaml index 9977a34a5ce..8feaec6e8c2 100644 --- a/packages/flame_fire_atlas/pubspec.yaml +++ b/packages/flame_fire_atlas/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_fire_atlas description: Easy to use texture atlases for the flame engine created with the fire atlas editor -version: 1.1.0 +version: 1.2.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_fire_atlas environment: @@ -9,13 +9,13 @@ environment: dependencies: archive: ^3.1.5 - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter mocktail: ^0.3.0 diff --git a/packages/flame_flare/CHANGELOG.md b/packages/flame_flare/CHANGELOG.md index 0136f1a37e2..5529493857a 100644 --- a/packages/flame_flare/CHANGELOG.md +++ b/packages/flame_flare/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.3.0 + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **DOCS**: Documenting how to write documentation ([#1721](https://github.com/flame-engine/flame/issues/1721)). ([ea354e3a](https://github.com/flame-engine/flame/commit/ea354e3a81e3810a8d2b9e3783d9833ae92349e0)) + ## 1.2.0 - **REFACTOR**: Move to package imports ([#1625](https://github.com/flame-engine/flame/issues/1625)). ([843ddc36](https://github.com/flame-engine/flame/commit/843ddc36249272fcb518b44672e1012307dfa1b5)) diff --git a/packages/flame_flare/example/pubspec.yaml b/packages/flame_flare/example/pubspec.yaml index 066dd0ae1c4..50f1b9db24e 100644 --- a/packages/flame_flare/example/pubspec.yaml +++ b/packages/flame_flare/example/pubspec.yaml @@ -8,14 +8,13 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 - flame_flare: ^1.2.0 + flame: ^1.2.1 + flame_flare: ^1.3.0 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.1.0 - + flame_lint: ^0.1.1 flutter: assets: - assets/Bob_Minion.flr diff --git a/packages/flame_flare/pubspec.yaml b/packages/flame_flare/pubspec.yaml index 183729bd191..e47dcfbb167 100644 --- a/packages/flame_flare/pubspec.yaml +++ b/packages/flame_flare/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_flare description: This packages allows you to use flare animations into a Flame game. -version: 1.2.0 +version: 1.3.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_flare environment: @@ -8,11 +8,11 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flare_flutter: ^3.0.2 flutter: sdk: flutter dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 \ No newline at end of file diff --git a/packages/flame_forge2d/CHANGELOG.md b/packages/flame_forge2d/CHANGELOG.md index 849327bbd41..93c866a7a4f 100644 --- a/packages/flame_forge2d/CHANGELOG.md +++ b/packages/flame_forge2d/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.12.1 + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 0.12.0 > Note: This release has breaking changes. diff --git a/packages/flame_forge2d/example/pubspec.yaml b/packages/flame_forge2d/example/pubspec.yaml index c5b7b15e928..1f5023bd596 100644 --- a/packages/flame_forge2d/example/pubspec.yaml +++ b/packages/flame_forge2d/example/pubspec.yaml @@ -16,7 +16,7 @@ dependencies: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_forge2d/pubspec.yaml b/packages/flame_forge2d/pubspec.yaml index b38863a3d3f..73d45aec728 100644 --- a/packages/flame_forge2d/pubspec.yaml +++ b/packages/flame_forge2d/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_forge2d description: Forge2D (Box2D) support for the Flame game engine. This uses the forge2d package and provides wrappers and components to be used inside Flame. -version: 0.12.0 +version: 0.12.1 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_forge2d environment: @@ -8,15 +8,15 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter forge2d: ">=0.11.0 <0.12.0" dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 - flame_test: ^1.5.0 + flame_lint: ^0.1.1 + flame_test: ^1.6.0 flutter_test: sdk: flutter mocktail: ^0.3.0 diff --git a/packages/flame_lint/CHANGELOG.md b/packages/flame_lint/CHANGELOG.md index faa773c306a..6ba27fbc12b 100644 --- a/packages/flame_lint/CHANGELOG.md +++ b/packages/flame_lint/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.1.1 + + - **REFACTOR**: Move to package imports ([#1625](https://github.com/flame-engine/flame/issues/1625)). ([843ddc36](https://github.com/flame-engine/flame/commit/843ddc36249272fcb518b44672e1012307dfa1b5)) + - **REFACTOR**: Add a few more rules to flame_lint, including use_key_in_widget_constructors ([#1248](https://github.com/flame-engine/flame/issues/1248)). ([bac6c8a4](https://github.com/flame-engine/flame/commit/bac6c8a4469f2c5c2926335f2f589eec9b1a5b5b)) + - **FIX**: Upgrade dartdoc (upgrade analyzer transitive dependency) ([#1630](https://github.com/flame-engine/flame/issues/1630)). ([6da8adb2](https://github.com/flame-engine/flame/commit/6da8adb28cffd8fcb43e6bf8a33aae22578f1b40)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **FEAT**: Add more lint rules ([#1703](https://github.com/flame-engine/flame/issues/1703)). ([49252f8e](https://github.com/flame-engine/flame/commit/49252f8ef29aa6b77144dcb97c24346f2f39380b)) + - **FEAT**: Add non_constant_identifier_names rule ([#1656](https://github.com/flame-engine/flame/issues/1656)). ([1b40de09](https://github.com/flame-engine/flame/commit/1b40de094f4e66be7622d077a6e18cecf1964dde)) + - **FEAT**: Bump to Flutter 2.10.0 ([#1617](https://github.com/flame-engine/flame/issues/1617)). ([beac9013](https://github.com/flame-engine/flame/commit/beac901313456cf0b39b6f4e6459f0feed183614)) + - **DOCS**: Fix various dartdoc warnings ([#1353](https://github.com/flame-engine/flame/issues/1353)). ([9f096053](https://github.com/flame-engine/flame/commit/9f096053fd3c8ebd52d301710625a187db09704f)) + # CHANGELOG ## [0.1.0] diff --git a/packages/flame_lint/pubspec.yaml b/packages/flame_lint/pubspec.yaml index a95c2b5a685..be15b4517da 100644 --- a/packages/flame_lint/pubspec.yaml +++ b/packages/flame_lint/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_lint description: Flame lint package -version: 0.1.0 +version: 0.1.1 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_lint environment: diff --git a/packages/flame_oxygen/CHANGELOG.md b/packages/flame_oxygen/CHANGELOG.md index 26c5911e35e..5984491565e 100644 --- a/packages/flame_oxygen/CHANGELOG.md +++ b/packages/flame_oxygen/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.4 + + - **REFACTOR**: Game is now a class, not a mixin ([#1751](https://github.com/flame-engine/flame/issues/1751)). ([5225a4eb](https://github.com/flame-engine/flame/commit/5225a4ebd55a21f5709ccab9a1e24c728b2747ed)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 0.1.3 - **REFACTOR**: Move to package imports ([#1625](https://github.com/flame-engine/flame/issues/1625)). ([843ddc36](https://github.com/flame-engine/flame/commit/843ddc36249272fcb518b44672e1012307dfa1b5)) diff --git a/packages/flame_oxygen/example/pubspec.yaml b/packages/flame_oxygen/example/pubspec.yaml index f4f67512729..eacd1f59c8c 100644 --- a/packages/flame_oxygen/example/pubspec.yaml +++ b/packages/flame_oxygen/example/pubspec.yaml @@ -9,14 +9,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_oxygen: ^0.1.3 + flame: ^1.2.1 + flame_oxygen: ^0.1.4 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: uses-material-design: true assets: diff --git a/packages/flame_oxygen/pubspec.yaml b/packages/flame_oxygen/pubspec.yaml index d175d402f20..9336c2708f5 100644 --- a/packages/flame_oxygen/pubspec.yaml +++ b/packages/flame_oxygen/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_oxygen description: Integrate the Oxygen ECS with the Flame Engine. -version: 0.1.3 +version: 0.1.4 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_oxygen environment: @@ -8,11 +8,11 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter oxygen: ^0.2.0 dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 \ No newline at end of file diff --git a/packages/flame_rive/CHANGELOG.md b/packages/flame_rive/CHANGELOG.md index e1906861a97..926a4b73914 100644 --- a/packages/flame_rive/CHANGELOG.md +++ b/packages/flame_rive/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.5.0 + + - **FIX**: Flame_rive now can load Nested Artboards and update to 0.9.0 rive package ([#1741](https://github.com/flame-engine/flame/issues/1741)). ([82e4be96](https://github.com/flame-engine/flame/commit/82e4be96f3090908e95659a96006bf50fbb5b08c)) + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 1.4.0 - **FIX**: Flame_rive now can load Nested Artboards and update to 0.9.0 rive package ([#1741](https://github.com/flame-engine/flame/issues/1741)). ([82e4be96](https://github.com/flame-engine/flame/commit/82e4be96f3090908e95659a96006bf50fbb5b08c)) diff --git a/packages/flame_rive/example/pubspec.yaml b/packages/flame_rive/example/pubspec.yaml index 44556fc075e..7a8442e46f6 100644 --- a/packages/flame_rive/example/pubspec.yaml +++ b/packages/flame_rive/example/pubspec.yaml @@ -7,14 +7,14 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_rive: ^1.4.0 + flame: ^1.2.1 + flame_rive: ^1.5.0 flutter: sdk: flutter rive: 0.9.0 dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_rive/pubspec.yaml b/packages/flame_rive/pubspec.yaml index 0de494900cf..053614ee1fb 100644 --- a/packages/flame_rive/pubspec.yaml +++ b/packages/flame_rive/pubspec.yaml @@ -1,20 +1,20 @@ name: flame_rive description: Rive support for the Flame game engine. This uses the rive package and provides wrappers and components to be used inside Flame. homepage: https://github.com/flame-engine/flame -version: 1.4.0 +version: 1.5.0 environment: sdk: ">=2.17.0 <3.0.0" flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter rive: ^0.9.0 dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_svg/CHANGELOG.md b/packages/flame_svg/CHANGELOG.md index e988d984cd4..d45e9fc1732 100644 --- a/packages/flame_svg/CHANGELOG.md +++ b/packages/flame_svg/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.4.0 + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 1.3.0 - **REFACTOR**: Update and guarantee consistency on mocktail dev dependency version across repo ([#1701](https://github.com/flame-engine/flame/issues/1701)). ([f4a98878](https://github.com/flame-engine/flame/commit/f4a98878062dbd4fe8238a8b014e6be3e528c5d8)) diff --git a/packages/flame_svg/example/pubspec.yaml b/packages/flame_svg/example/pubspec.yaml index b17f09db04b..f7caf5614b4 100644 --- a/packages/flame_svg/example/pubspec.yaml +++ b/packages/flame_svg/example/pubspec.yaml @@ -9,13 +9,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_svg: ^1.3.0 + flame: ^1.2.1 + flame_svg: ^1.4.0 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_test: sdk: flutter diff --git a/packages/flame_svg/pubspec.yaml b/packages/flame_svg/pubspec.yaml index e9508b406c7..b48729d797c 100644 --- a/packages/flame_svg/pubspec.yaml +++ b/packages/flame_svg/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_svg description: Package to add SVG rendering support for the Flame game engine -version: 1.3.0 +version: 1.4.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_svg environment: @@ -8,13 +8,13 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter flutter_svg: ^1.0.3 dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 mocktail: ^0.3.0 test: ^1.17.12 diff --git a/packages/flame_test/CHANGELOG.md b/packages/flame_test/CHANGELOG.md index 698720bfc26..f4ce4106ea7 100644 --- a/packages/flame_test/CHANGELOG.md +++ b/packages/flame_test/CHANGELOG.md @@ -1,3 +1,12 @@ +## 1.6.0 + +> Note: This release has breaking changes. + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FEAT**: Added size parameter for testGolden() ([#1780](https://github.com/flame-engine/flame/issues/1780)). ([8e41d83e](https://github.com/flame-engine/flame/commit/8e41d83ea4e057e1a428f0456450d697351683bf)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + - **BREAKING** **REFACTOR**: Matcher closeToVector() now accepts Vector2 as an argument ([#1761](https://github.com/flame-engine/flame/issues/1761)). ([c5083501](https://github.com/flame-engine/flame/commit/c5083501d54023f04d3f09e3358bce039ade9a20)) + ## 1.5.0 - **FEAT**: Add more lint rules ([#1703](https://github.com/flame-engine/flame/issues/1703)). ([49252f8e](https://github.com/flame-engine/flame/commit/49252f8ef29aa6b77144dcb97c24346f2f39380b)) diff --git a/packages/flame_test/example/pubspec.yaml b/packages/flame_test/example/pubspec.yaml index 2ca3ad5e7bb..9d873d2656e 100644 --- a/packages/flame_test/example/pubspec.yaml +++ b/packages/flame_test/example/pubspec.yaml @@ -8,13 +8,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - flame_test: ^1.5.0 + flame_lint: ^0.1.1 + flame_test: ^1.6.0 flutter: assets: - assets/images/ diff --git a/packages/flame_test/pubspec.yaml b/packages/flame_test/pubspec.yaml index 94fdb967c6b..78951fa3136 100644 --- a/packages/flame_test/pubspec.yaml +++ b/packages/flame_test/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_test description: A package with classes to help testing applications using Flame -version: 1.5.0 +version: 1.6.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_test environment: @@ -8,7 +8,7 @@ environment: flutter: ">=3.0.0" dependencies: - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter flutter_test: @@ -19,4 +19,4 @@ dependencies: dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 \ No newline at end of file diff --git a/packages/flame_tiled/CHANGELOG.md b/packages/flame_tiled/CHANGELOG.md index 089a4df0575..72a8db4f648 100644 --- a/packages/flame_tiled/CHANGELOG.md +++ b/packages/flame_tiled/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.6.0 + + - **FIX**: Correct flutter constraint ([#1731](https://github.com/flame-engine/flame/issues/1731)). ([c7383843](https://github.com/flame-engine/flame/commit/c738384314a1a5c3695d1c3adaebcb59604df83a)) + - **FIX**: tiled example size ([#1729](https://github.com/flame-engine/flame/issues/1729)). ([8306fc11](https://github.com/flame-engine/flame/commit/8306fc1104cb752ce71108abb3768f05ce1b1dac)) + - **FEAT**: Move to Flutter 3.0.0 and Dart 2.17.0 ([#1713](https://github.com/flame-engine/flame/issues/1713)). ([2a41d0d6](https://github.com/flame-engine/flame/commit/2a41d0d683391194b7209c47bde91199ab7a663e)) + ## 1.5.0 - **REFACTOR**: Move to package imports ([#1625](https://github.com/flame-engine/flame/issues/1625)). ([843ddc36](https://github.com/flame-engine/flame/commit/843ddc36249272fcb518b44672e1012307dfa1b5)) diff --git a/packages/flame_tiled/example/pubspec.yaml b/packages/flame_tiled/example/pubspec.yaml index 774c78da2ab..60512535186 100644 --- a/packages/flame_tiled/example/pubspec.yaml +++ b/packages/flame_tiled/example/pubspec.yaml @@ -7,14 +7,13 @@ environment: sdk: ">=2.17.0 <3.0.0" dependencies: - flame: ^1.2.0 - flame_tiled: ^1.5.0 + flame: ^1.2.1 + flame_tiled: ^1.6.0 flutter: sdk: flutter dev_dependencies: - flame_lint: ^0.0.1 - + flame_lint: ^0.1.1 flutter: uses-material-design: true assets: diff --git a/packages/flame_tiled/pubspec.yaml b/packages/flame_tiled/pubspec.yaml index 5e025f3b81d..305a0e73422 100644 --- a/packages/flame_tiled/pubspec.yaml +++ b/packages/flame_tiled/pubspec.yaml @@ -1,6 +1,6 @@ name: flame_tiled description: Tiled support for the Flame game engine. This uses the tiled package and provides wrappers and components to be used inside Flame. -version: 1.5.0 +version: 1.6.0 homepage: https://github.com/flame-engine/flame/tree/main/packages/flame_tiled environment: @@ -9,7 +9,7 @@ environment: dependencies: collection: ^1.15.0 - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter meta: ^1.7.0 @@ -18,5 +18,5 @@ dependencies: dev_dependencies: dartdoc: ^4.1.0 - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 test: any diff --git a/tutorials/space_shooter/pubspec.yaml b/tutorials/space_shooter/pubspec.yaml index 7df0da62945..1e18128a19c 100644 --- a/tutorials/space_shooter/pubspec.yaml +++ b/tutorials/space_shooter/pubspec.yaml @@ -10,14 +10,14 @@ environment: dependencies: dashbook: ^0.1.5 - flame: ^1.2.0 + flame: ^1.2.1 flutter: sdk: flutter flutter_highlight: ^0.7.0 flutter_markdown: ^0.6.7 dev_dependencies: - flame_lint: ^0.0.1 + flame_lint: ^0.1.1 flutter_lints: ^1.0.0 flutter_test: sdk: flutter From e0b587c04ef5219afa3de05be8bacc88991c9914 Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Sat, 9 Jul 2022 20:00:07 +0200 Subject: [PATCH 17/34] feat: Add vector projection and inversion (#1787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adding projection, ìnvert and inverted to the vector extension. --- .../flame/lib/src/extensions/vector2.dart | 20 +++++++ .../flame/test/extensions/vector2_test.dart | 55 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/packages/flame/lib/src/extensions/vector2.dart b/packages/flame/lib/src/extensions/vector2.dart index 709d2adf9a0..52d11af15ac 100644 --- a/packages/flame/lib/src/extensions/vector2.dart +++ b/packages/flame/lib/src/extensions/vector2.dart @@ -80,6 +80,26 @@ extension Vector2Extension on Vector2 { } } + /// Project this onto [other]. + /// + /// [other] needs to have a length > 0; + /// If [out] is specified, it will be used to provide the result. + Vector2 projection(Vector2 other, {Vector2? out}) { + assert(other.length2 > 0, 'other needs to have a length > 0'); + final dotProduct = dot(other); + final result = (out?..setFrom(other)) ?? other.clone(); + return result..scale(dotProduct / other.length2); + } + + /// Inverts the vector. + void invert() { + x *= -1; + y *= -1; + } + + /// Returns the inverse of this vector. + Vector2 inverted() => Vector2(-x, -y); + /// Smoothly moves this [Vector2] in the direction [target] by a displacement /// given by a distance [ds] in that direction. /// diff --git a/packages/flame/test/extensions/vector2_test.dart b/packages/flame/test/extensions/vector2_test.dart index a733a338726..db19e383282 100644 --- a/packages/flame/test/extensions/vector2_test.dart +++ b/packages/flame/test/extensions/vector2_test.dart @@ -208,4 +208,59 @@ void main() { expectDouble(position.screenAngle(), math.pi / 2); }); }); + + group('projection', () { + test('Project onto longer vector', () { + final u = Vector2(5, 2); + final v = Vector2(10, 0); + final result = u.projection(v); + expect(result, Vector2(5, 0)); + }); + + test('Project onto shorter vector', () { + final u = Vector2(5, 2); + final v = Vector2(2, 0); + final result = u.projection(v); + expect(result, Vector2(5, 0)); + }); + + test('Project onto vector in other direction', () { + final u = Vector2(5, 2); + final v = Vector2(-10, 0); + final result = u.projection(v); + expect(result, Vector2(5, 0)); + }); + + test('Project onto vector with out', () { + final out = Vector2.zero(); + final u = Vector2(5, 2); + final v = Vector2(-10, 0); + final result = u.projection(v, out: out); + expect(result, Vector2(5, 0)); + expect(out, Vector2(5, 0)); + }); + + test('Project onto vector with out as sane return and argument', () { + var out = Vector2.zero(); + final u = Vector2(5, 2); + final v = Vector2(-10, 0); + out = u.projection(v, out: out); + expect(out, Vector2(5, 0)); + }); + }); + + group('inversion', () { + test('invert', () { + final v = Vector2.all(1); + v.invert(); + expect(v, Vector2.all(-1)); + }); + + test('inverted', () { + final v = Vector2.all(1); + final w = v.inverted(); + expect(v, Vector2.all(1)); + expect(w, Vector2.all(-1)); + }); + }); } From dda9d49afc50a1815f39df3c3e5d417f6e6cf10d Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Sat, 9 Jul 2022 21:58:16 +0200 Subject: [PATCH 18/34] feat: add `children` argument to `SpriteComponent.fromImage` (#1793) --- packages/flame/lib/src/components/sprite_component.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/flame/lib/src/components/sprite_component.dart b/packages/flame/lib/src/components/sprite_component.dart index 5a7e0b346e6..253675c407b 100644 --- a/packages/flame/lib/src/components/sprite_component.dart +++ b/packages/flame/lib/src/components/sprite_component.dart @@ -47,6 +47,7 @@ class SpriteComponent extends PositionComponent Vector2? scale, double? angle, Anchor? anchor, + Iterable? children, int? priority, }) : this( sprite: Sprite( @@ -60,6 +61,7 @@ class SpriteComponent extends PositionComponent scale: scale, angle: angle, anchor: anchor, + children: children, priority: priority, ); From 635d49c91e2b2ee7e88746c8275b40ce1337e8a9 Mon Sep 17 00:00:00 2001 From: Sai Rajendra Immadi Date: Tue, 12 Jul 2022 16:53:51 +0530 Subject: [PATCH 19/34] docs: replace images in README with absolute path (#1796) The images path under sponsors has a relative path from the repository, which are being changed to absolute path (starting with https) --- README.md | 4 ++-- i18n/README-ES.md | 2 +- i18n/README-JA.md | 2 +- i18n/README-PL.md | 4 ++-- i18n/README-RU.md | 4 ++-- i18n/README-ZH.md | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fa4b6498173..8a7f5f98f20 100644 --- a/README.md +++ b/README.md @@ -95,9 +95,9 @@ Flame officially provides bridge libraries to the following packages: The Flame Engine's top sponsors: -[![Very Good Ventures](/media/unicorn_two_toned.png)](https://verygood.ventures/) +[![Very Good Ventures](https://raw.githubusercontent.com/flame-engine/flame/main/media/unicorn_two_toned.png)](https://verygood.ventures/) -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) Want to sponsor Flame? Check our Patreon on the section below, or contact us on Discord. diff --git a/i18n/README-ES.md b/i18n/README-ES.md index 8716f3e53e4..4509c79370a 100644 --- a/i18n/README-ES.md +++ b/i18n/README-ES.md @@ -85,7 +85,7 @@ Por medio de estas librerías, serás capaz de acceder a componentes de Flame, h Top de patrocinadores del Flame Engine: -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) ¿Quieres patrocinar Flame? Mira nuestro Patreon en la siguiente sección, o contactanos en Discord. diff --git a/i18n/README-JA.md b/i18n/README-JA.md index 4f368bdef7a..2e8d4e444d8 100644 --- a/i18n/README-JA.md +++ b/i18n/README-JA.md @@ -83,7 +83,7 @@ Flame は公式に以下のパッケージのブリッジライブラリを提 Flame エンジンのトップスポンサーは以下の通りです: -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) Flame のスポンサーになることを希望する方は、以下のセクションにある私たちの Patreon か、または Discord で連絡してください。 diff --git a/i18n/README-PL.md b/i18n/README-PL.md index 79b93cad8fa..77dc691109d 100644 --- a/i18n/README-PL.md +++ b/i18n/README-PL.md @@ -88,9 +88,9 @@ Flame oficjalnie udostępnia biblioteki bridge do następujących pakietów: Top sponsorzy Flame Engine: -[![Very Good Ventures](/media/unicorn_two_toned.png)](https://verygood.ventures/) +[![Very Good Ventures](https://raw.githubusercontent.com/flame-engine/flame/main/media/unicorn_two_toned.png)](https://verygood.ventures/) -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) Chcesz sponsorować Flame? Sprawdź nasz Patreon w sekcji poniżej lub skontaktuj się z nami na Discordzie. diff --git a/i18n/README-RU.md b/i18n/README-RU.md index bbddc7334c6..7ff2971ca37 100644 --- a/i18n/README-RU.md +++ b/i18n/README-RU.md @@ -89,9 +89,9 @@ Flame официально предоставляет связанные биб Лучшие спонсоры движка Flame: -[![Very Good Ventures](/media/unicorn_two_toned.png)](https://verygood.ventures/) +[![Very Good Ventures](https://raw.githubusercontent.com/flame-engine/flame/main/media/unicorn_two_toned.png)](https://verygood.ventures/) -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) Хотите спонсировать Flame? Обратите внимание на наш Patreon в следующем разделе, или свяжитесь с нами через Discord. diff --git a/i18n/README-ZH.md b/i18n/README-ZH.md index c9c9fd42449..2c84f85c109 100644 --- a/i18n/README-ZH.md +++ b/i18n/README-ZH.md @@ -91,7 +91,7 @@ Flame 引擎的目的是为使用 Flutter 开发的游戏会遇到的常见问 Flame 引擎最大的赞助者: -[![Cypher Stack](/media/logo_cypherstack.png)](https://cypherstack.com/) +[![Cypher Stack](https://raw.githubusercontent.com/flame-engine/flame/main/media/logo_cypherstack.png)](https://cypherstack.com/) 如果你想要赞助 Flame,请查看下方的 Pateron 信息,或在 Discord 频道中联系我们。 From f303e3c136ee17ac7479bc24bfa0baaec8510f53 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Wed, 13 Jul 2022 00:19:07 -0700 Subject: [PATCH 20/34] Added HasDecorator mixin --- .../src/components/mixins/has_decorator.dart | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 packages/flame/lib/src/components/mixins/has_decorator.dart diff --git a/packages/flame/lib/src/components/mixins/has_decorator.dart b/packages/flame/lib/src/components/mixins/has_decorator.dart new file mode 100644 index 00000000000..46fcbadc713 --- /dev/null +++ b/packages/flame/lib/src/components/mixins/has_decorator.dart @@ -0,0 +1,27 @@ +import 'dart:ui'; + +import 'package:flame/src/components/component.dart'; +import 'package:flame/src/rendering/decorator.dart'; + +/// [HasDecorator] mixin adds a nullable [decorator] field to a Component. If +/// this field is set, it will apply the visual effect encapsulated in this +/// [Decorator] to the component. If the field is not set, then the component +/// will be rendered normally. +/// +/// Note that the decorator only affects visual rendering of a component, but +/// not its perceived size or shape from the point of view of tap events. +/// +/// See also: +/// - [Decorator] class for the list of available decorators. +mixin HasDecorator on Component { + Decorator? decorator; + + @override + void renderTree(Canvas canvas) { + if (decorator == null) { + super.renderTree(canvas); + } else { + decorator!.apply(super.renderTree, canvas); + } + } +} From c6966105baddac67ac57c458cccf4f7ef7c7475c Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Wed, 13 Jul 2022 00:41:54 -0700 Subject: [PATCH 21/34] added a test --- packages/flame/lib/components.dart | 1 + .../flame/test/_goldens/has_decorator_1.png | Bin 0 -> 2292 bytes .../components/mixins/has_decorator_test.dart | 43 ++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 packages/flame/test/_goldens/has_decorator_1.png create mode 100644 packages/flame/test/components/mixins/has_decorator_test.dart diff --git a/packages/flame/lib/components.dart b/packages/flame/lib/components.dart index 757d120fb20..522bcfab6c9 100644 --- a/packages/flame/lib/components.dart +++ b/packages/flame/lib/components.dart @@ -14,6 +14,7 @@ export 'src/components/mixins/component_viewport_margin.dart'; export 'src/components/mixins/draggable.dart'; export 'src/components/mixins/gesture_hitboxes.dart'; export 'src/components/mixins/has_ancestor.dart'; +export 'src/components/mixins/has_decorator.dart' show HasDecorator; export 'src/components/mixins/has_game_ref.dart'; export 'src/components/mixins/has_paint.dart'; export 'src/components/mixins/hoverable.dart'; diff --git a/packages/flame/test/_goldens/has_decorator_1.png b/packages/flame/test/_goldens/has_decorator_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d0db07248891cbc23e9998f9e802ac72f4359997 GIT binary patch literal 2292 zcmVPx#1am@3R0s$N2z&@+hyVZxo=HSORCt{2Tsw>#*A+dx!x?gZ{1b4vNJ`ngqO_4z z1Zf1-Hk8(YTNzj&286^&6$7pfxRoFkL7E`7tklw`47}U;19)R#K`uFe&hV2$xKEdF zhr{7-w42od21A0wnag|L{k;3`;~sz+-eC@VdwVNgKbvh&g{7_C=?a4ru(!7-j{W`p z3)gVvPp4DNW;1aRHX-O*6GBQR(dr2@k+#A_m@R4SoVD$QBQcs#~;0S1}DNW3>bz1+qPjC z1}w{huItcsU04daElvozDYA$#3=xJQJkNvg`{FDUlZTYG2_YgnA3lI$+w0syVB)$s zd-h}}#E>GnRgm&++eWoog>BogZCemR7DCpM7DKp|L{Wqw2;loZT-Sx`x)=_Ja9tO^ z?;{9;IcuT&q{@pm2x;ECkAsJY8xtX8;=1_p^G6uIc)peU$z+gQvTYmndL6Y|4UI+v z)oK-%Wx+5EVHp%Zva&25N61xqo`>OZh{0fh!C)YWA$PWn6a~PaSNW0eef$XyK0U;K zxxAseE@Ho2M&ozC2LO0SuQt9P1#eYV1sSzk4b5f~?RFdOb{nl$3ynqtwOS39Wx+H} zR4Nse%VnslDh{$1Iuu0_pHaNw$pCkCL?AyevXI<_D7KAX{_znyA3fMuQOjW6yanwS zU3mX~g;^Z0bq^w=R4SodF2giU)M_=fS}nBOZFD*vwA*de>va)B$W@Vba0}sc5=spC znMmLSazeOOWf77)%Q|>?h~~ZfYbj?P(6fI0{L#waB^RS8iijDuZKKg>2tu08CaTpc zOw+s&yt#`?yElJ5o6W?TXK+Ml79m6mCnuMMy!Y`Zg;<6R{r%Tj+p6x1$WT=kx~`*I ztqM2Q>2%O)wShT-)vKD$qnBy~m)EOA+iZR6nK z+arVUt3Uk(|2cY@J0<3^!!Qg~t5wwNbrCO2(-dULMZ`@&q)w+(sHzI!&AcT^5{yP8 zL{Wq&iV(-~95F)ntOsmkjmcMEAhHrH z%bFvDkIG#WLe@(1=(-NmG+~(yQoDV( zFo9P^mTa65vJ!drU6gfjnRuchuer$a?8*^h-MqE%Gd>#W$MZ5q(bmD`;_-w?NweDR z=X^UxR-z%V1k$;PtZEr(vdD{*a=i>#K!{>lg$lb0mdTbz$~I==n<8!LIBlS$5^@;> zIw4CoURO#x=$fLzpPeQTe}Cm%*8e+F2?TsYagQW`;{gnOE%u3!`C19+C$NZ$Yr#WWiru^C+nd0&L9X7 zhM`bEQC33FNo%O1uEr!umRksb*Ik63w{xNMV&Zu?d-i1Mbz~uN9M83Pk^(56?3xrg zZqNYneg8r?BVSivNXW!>arX4_&IDc+XHOq5T~p`ofh&O8JA)t)r0m*t$?h`<0wIU* z`-q|lqtPf|P$yg#E6Hmez2L2`JWhcFE15)DFT8_+C{ zG5Y>H(cbyC@WW?^xs!~v8WG=+!;5-!$lqNTeAb;LiHI4);Sl|PAH7}={eBRj}WUP0>~K)><+TEec2{y+bLpT7KJP&*KW2ZWEB=yZ5fsC!HMAW z4BC>wEu-J>!*QHBSCy9O!%kLaxA~T~kN&XnlJCUxaQ5`^ zTien`?VVS4OB=_VO`msHjxXWKF@`Um7q;n>va763pR{pjl}(@AN)~PUww;U&EEWi@#@jM@R}*t!HhsjQ>A6q*!84a*m7u O0000 Date: Fri, 15 Jul 2022 08:33:34 -0700 Subject: [PATCH 22/34] Added Flower class --- doc/flame/examples/lib/flower.dart | 53 ++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 doc/flame/examples/lib/flower.dart diff --git a/doc/flame/examples/lib/flower.dart b/doc/flame/examples/lib/flower.dart new file mode 100644 index 00000000000..121e2d31c71 --- /dev/null +++ b/doc/flame/examples/lib/flower.dart @@ -0,0 +1,53 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:flame/components.dart'; +import 'package:flame/experimental.dart'; + +const tau = 2 * pi; + +class Flower extends PositionComponent with TapCallbacks, HasDecorator { + Flower({required double size, void Function(Flower)? onTap, super.position}) + : _onTap = onTap, + super(size: Vector2.all(size), anchor: Anchor.center) { + final radius = size * 0.38; + _paths.add(_makePath(radius * 1.4, 6, -0.05, 0.8)); + _paths.add(_makePath(radius, 6, 0.25, 1.5)); + _paths.add(_makePath(radius * 0.8, 6, 0.3, 1.4)); + _paths.add(_makePath(radius * 0.55, 6, 0.2, 1.5)); + _paths.add(_makePath(radius * 0.1, 12, 0.1, 6)); + _paints.add(Paint()..color = const Color(0xff255910)); + _paints.add(Paint()..color = const Color(0xffee3f3f)); + _paints.add(Paint()..color = const Color(0xffffbd66)); + _paints.add(Paint()..color = const Color(0xfff6f370)); + _paints.add(Paint()..color = const Color(0xfffffff0)); + } + + final List _paths = []; + final List _paints = []; + final void Function(Flower)? _onTap; + + Path _makePath(double radius, int n, double sharpness, double f) { + final radius2 = radius * f; + final p0 = Vector2(radius, 0)..rotate(0); + final path = Path()..moveTo(p0.x, p0.y); + for (var i = 0; i < n; i++) { + final p1 = Vector2(radius2, 0)..rotate(tau / n * (i + sharpness)); + final p2 = Vector2(radius2, 0)..rotate(tau / n * (i + 1 - sharpness)); + final p3 = Vector2(radius, 0)..rotate(tau / n * (i + 1)); + path.cubicTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y); + } + path.close(); + return path.shift(Offset(width / 2, height / 2)); + } + + @override + void render(Canvas canvas) { + for (var i = 0; i < _paths.length; i++) { + canvas.drawPath(_paths[i], _paints[i]); + } + } + + @override + void onTapUp(TapUpEvent event) => _onTap?.call(this); +} From e8750a403f153967072f3f29b2f255da59a76d1b Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Fri, 15 Jul 2022 13:02:16 -0700 Subject: [PATCH 23/34] Added doc page for Decorators --- doc/_sphinx/extensions/flutter_app.css | 5 +- doc/_sphinx/extensions/flutter_app.py | 29 ++++- doc/_sphinx/theme/flames.css | 9 ++ doc/flame/examples/lib/decorator_blur.dart | 30 +++++ .../examples/lib/decorator_grayscale.dart | 32 ++++++ doc/flame/examples/lib/decorator_tinted.dart | 36 ++++++ doc/flame/examples/lib/flower.dart | 2 +- doc/flame/examples/lib/main.dart | 12 ++ doc/flame/rendering/decorators.md | 103 ++++++++++++++++++ doc/flame/rendering/rendering.md | 3 +- 10 files changed, 253 insertions(+), 8 deletions(-) create mode 100644 doc/flame/examples/lib/decorator_blur.dart create mode 100644 doc/flame/examples/lib/decorator_grayscale.dart create mode 100644 doc/flame/examples/lib/decorator_tinted.dart create mode 100644 doc/flame/rendering/decorators.md diff --git a/doc/_sphinx/extensions/flutter_app.css b/doc/_sphinx/extensions/flutter_app.css index 54af42ca36e..9743bfbf94d 100644 --- a/doc/_sphinx/extensions/flutter_app.css +++ b/doc/_sphinx/extensions/flutter_app.css @@ -127,6 +127,7 @@ button.flutter-app-button:after { .flutter-app-iframe { border: 1px solid #555; + display: block; height: 350px; width: 100%; } @@ -138,7 +139,6 @@ button.flutter-app-button:after { float: right; margin-left: 6pt; padding: 8px; - width: 280px; } .flutter-app-infobox button.flutter-app-iframe { @@ -148,8 +148,7 @@ button.flutter-app-button:after { .flutter-app-infobox button.flutter-app-button { float: right; font-size: 0.85em; - margin-bottom: 0; - margin-right: 0; + margin: 6px 0 0 0; min-height: 14pt; min-width: 50pt; } diff --git a/doc/_sphinx/extensions/flutter_app.py b/doc/_sphinx/extensions/flutter_app.py index bef8b948d9c..2d92b48adfb 100644 --- a/doc/_sphinx/extensions/flutter_app.py +++ b/doc/_sphinx/extensions/flutter_app.py @@ -52,6 +52,11 @@ class FlutterAppDirective(SphinxDirective): compiled. "infobox" - the content will be displayed as an infobox floating on the right-hand side of the page. + + :width: - override the default width of an iframe in widget/infobox modes. + + :height: - override the default height of an iframe in widget/infobox + modes. """ has_content = True required_arguments = 0 @@ -60,6 +65,8 @@ class FlutterAppDirective(SphinxDirective): 'sources': directives.unchanged, 'page': directives.unchanged, 'show': directives.unchanged, + 'width': directives.unchanged, + 'height': directives.unchanged, } # Static list of targets that were already compiled during the build COMPILED = [] @@ -89,7 +96,21 @@ def run(self): iframe_url = _doc_root() + self.html_dir + '/index.html?' + page result = [] if 'widget' in self.modes: - result.append(IFrame(src=iframe_url, classes=['flutter-app-iframe'])) + iframe = IFrame(src=iframe_url, classes=['flutter-app-iframe']) + result.append(iframe) + styles = [] + if self.options.get('width'): + width = self.options.get('width') + if width.isdigit(): + width += 'px' + styles.append("width: " + width) + if self.options.get('height'): + height = self.options.get('height') + if height.isdigit(): + height += 'px' + styles.append("height: " + height) + if styles: + iframe.attributes['style'] = '; '.join(styles) if 'popup' in self.modes: result.append(Button( '', @@ -237,8 +258,10 @@ def _doc_root(): class IFrame(nodes.Element, nodes.General): def visit(self, node): - self.body.append( - self.starttag(node, 'iframe', src=node.attributes['src'])) + attrs = {'src': node.attributes['src']} + if 'style' in node.attributes: + attrs['style'] = node.attributes['style'] + self.body.append(self.starttag(node, 'iframe', **attrs).strip()) def depart(self, _): self.body.append('') diff --git a/doc/_sphinx/theme/flames.css b/doc/_sphinx/theme/flames.css index 499eb87ba06..ca488f155e0 100644 --- a/doc/_sphinx/theme/flames.css +++ b/doc/_sphinx/theme/flames.css @@ -797,3 +797,12 @@ div.admonition.admonition-deprecated { --admonition-icon-color: #555; --admonition-title-background-color: #1c1c1c; } + + +pre, div[class*="highlight-"] { + clear: none; +} + +h1, h2, h3, h4, h5, h6 { + clear: both; +} diff --git a/doc/flame/examples/lib/decorator_blur.dart b/doc/flame/examples/lib/decorator_blur.dart new file mode 100644 index 00000000000..6f00dbb6566 --- /dev/null +++ b/doc/flame/examples/lib/decorator_blur.dart @@ -0,0 +1,30 @@ +import 'package:doc_flame_examples/flower.dart'; +import 'package:flame/experimental.dart'; +import 'package:flame/game.dart'; +import 'package:flame/rendering.dart'; + +class DecoratorBlurGame extends FlameGame with HasTappableComponents { + @override + Future onLoad() async { + var step = 0; + add( + Flower( + size: 100, + position: canvasSize / 2, + onTap: (flower) { + step++; + if (step == 1) { + flower.decorator = PaintDecorator.blur(3.0); + } else if (step == 2) { + flower.decorator = PaintDecorator.blur(5.0); + } else if (step == 3) { + flower.decorator = PaintDecorator.blur(0.0, 20.0); + } else { + flower.decorator = null; + step = 0; + } + }, + )..onTapUp(), + ); + } +} diff --git a/doc/flame/examples/lib/decorator_grayscale.dart b/doc/flame/examples/lib/decorator_grayscale.dart new file mode 100644 index 00000000000..9ed895c4d5c --- /dev/null +++ b/doc/flame/examples/lib/decorator_grayscale.dart @@ -0,0 +1,32 @@ +import 'package:doc_flame_examples/flower.dart'; +import 'package:flame/experimental.dart'; +import 'package:flame/game.dart'; +import 'package:flame/rendering.dart'; + +class DecoratorGrayscaleGame extends FlameGame with HasTappableComponents { + @override + Future onLoad() async { + var step = 0; + add( + Flower( + size: 100, + position: canvasSize / 2, + onTap: (flower) { + step++; + if (step == 1) { + flower.decorator = PaintDecorator.grayscale(); + } else if (step == 2) { + flower.decorator = PaintDecorator.grayscale(opacity: 0.5); + } else if (step == 3) { + flower.decorator = PaintDecorator.grayscale(opacity: 0.2); + } else if (step == 4) { + flower.decorator = PaintDecorator.grayscale(opacity: 0.1); + } else { + flower.decorator = null; + step = 0; + } + }, + )..onTapUp(), + ); + } +} diff --git a/doc/flame/examples/lib/decorator_tinted.dart b/doc/flame/examples/lib/decorator_tinted.dart new file mode 100644 index 00000000000..682d0611296 --- /dev/null +++ b/doc/flame/examples/lib/decorator_tinted.dart @@ -0,0 +1,36 @@ +import 'dart:ui'; + +import 'package:doc_flame_examples/flower.dart'; +import 'package:flame/experimental.dart'; +import 'package:flame/game.dart'; +import 'package:flame/rendering.dart'; + +class DecoratorTintedGame extends FlameGame with HasTappableComponents { + @override + Future onLoad() async { + var step = 0; + add( + Flower( + size: 100, + position: canvasSize / 2, + onTap: (flower) { + step++; + if (step == 1) { + flower.decorator = PaintDecorator.tinted(const Color(0x88FF0000)); + } else if (step == 2) { + flower.decorator = PaintDecorator.tinted(const Color(0x8800FF00)); + } else if (step == 3) { + flower.decorator = PaintDecorator.tinted(const Color(0x88000088)); + } else if (step == 4) { + flower.decorator = PaintDecorator.tinted(const Color(0x66FFFFFF)); + } else if (step == 5) { + flower.decorator = PaintDecorator.tinted(const Color(0xAA000000)); + } else { + flower.decorator = null; + step = 0; + } + }, + )..onTapUp(), + ); + } +} diff --git a/doc/flame/examples/lib/flower.dart b/doc/flame/examples/lib/flower.dart index 121e2d31c71..1e76a72b57a 100644 --- a/doc/flame/examples/lib/flower.dart +++ b/doc/flame/examples/lib/flower.dart @@ -49,5 +49,5 @@ class Flower extends PositionComponent with TapCallbacks, HasDecorator { } @override - void onTapUp(TapUpEvent event) => _onTap?.call(this); + void onTapUp([TapUpEvent? event]) => _onTap?.call(this); } diff --git a/doc/flame/examples/lib/main.dart b/doc/flame/examples/lib/main.dart index 76200327a96..1b4f30cd51b 100644 --- a/doc/flame/examples/lib/main.dart +++ b/doc/flame/examples/lib/main.dart @@ -1,5 +1,8 @@ import 'dart:html'; // ignore: avoid_web_libraries_in_flutter +import 'package:doc_flame_examples/decorator_blur.dart'; +import 'package:doc_flame_examples/decorator_grayscale.dart'; +import 'package:doc_flame_examples/decorator_tinted.dart'; import 'package:doc_flame_examples/drag_events.dart'; import 'package:doc_flame_examples/tap_events.dart'; import 'package:flame/game.dart'; @@ -18,6 +21,15 @@ void main() { case 'drag_events': game = DragEventsGame(); break; + case 'decorator_blur': + game = DecoratorBlurGame(); + break; + case 'decorator_grayscale': + game = DecoratorGrayscaleGame(); + break; + case 'decorator_tinted': + game = DecoratorTintedGame(); + break; } if (game != null) { runApp(GameWidget(game: game)); diff --git a/doc/flame/rendering/decorators.md b/doc/flame/rendering/decorators.md new file mode 100644 index 00000000000..f77b8c92ff7 --- /dev/null +++ b/doc/flame/rendering/decorators.md @@ -0,0 +1,103 @@ +# Decorators + +**Decorators** are classes that can encapsulate certain visual effects and then apply those visual +effects to a sequence of canvas drawing operations. Decorators are not [Component]s, but they can +be applied to components either manually or via the [HasDecorator] mixin. Likewise, decorators are +not [Effect]s, although they can be used to implement certain `Effect`s. + +There are a certain number of decorators available in Flame, and it is simple to add one's own if +necessary. We are planning to add shader-based decorators once Flutter fully supports them on the +web. + + +## Flame built-in decorators + +### PaintDecorator.blur + +```{flutter-app} +:sources: ../flame/examples +:page: decorator_blur +:show: widget code infobox +:width: 180 +:height: 160 +``` + +This decorator applies a Gaussian blur to the underlying component. The amount of blur can be +different in the X and Y direction, though this is not very common. + +```dart +final decorator = PaintDecorator.blur(3.0); +``` + +Possible uses: +- soft shadows; +- "out-of-focus" objects in the distance or very close to the camera; +- motion blur effects; +- deemphasize/obscure content when showing a popup dialog; +- blurred vision when the character is drunk. + + +### PaintDecorator.grayscale + +```{flutter-app} +:sources: ../flame/examples +:page: decorator_grayscale +:show: widget infobox +:width: 180 +:height: 160 +``` + +This decorator converts the underlying image into the shades of grey, as if it was a +black-and-white photograph. In addition, you can make the image semi-transparent to the desired +level of `opacity`. + +```dart +final decorator = PaintDecorator.grayscale(opacity: 0.5); +``` + +Possible uses: +- apply to an NPC to turn them into stone, or into a ghost! +- apply to a scene to indicate that it is a memory of the past; +- black-and-white photos. + + +### PaintDecorator.tinted + +```{flutter-app} +:sources: ../flame/examples +:page: decorator_tinted +:show: widget infobox +:width: 180 +:height: 160 +``` + +This decorator "tints" the underlying image with the specified color, as if watching it through a +colored glass. It is recommended that the `color` used by this decorator was semi-transparent, so +that you can see the details of the image below. + +```dart +final decorator = PaintDecorator.tinted(const Color(0xAAFF0000); +``` + +Possible uses: +- NPCs affected by certain types of magic; +- items/characters in the shadows can be tinted black; +- tint the scene red to show bloodlust, or that the character is low on health; +- tint green to show that the character is poisoned or sick; +- tint the scene deep blue during the night time; + + +## Using decorators + +### HasDecorator mixin + +This `Component` mixin adds the `decorator` property, which is initially `null`. If you set this +property to an actual `Decorator` object, then that decorator will apply its visual effect during +the rendering of the component. In order to remove this visual effect, simply set the `decorator` +property back to `null`. + + + +[Component]: ../../flame/components.md#component +[Effect]: ../../flame/effects.md +[HasDecorator]: #hasdecorator-mixin diff --git a/doc/flame/rendering/rendering.md b/doc/flame/rendering/rendering.md index 3bfbb8ea276..3bd0a430693 100644 --- a/doc/flame/rendering/rendering.md +++ b/doc/flame/rendering/rendering.md @@ -3,10 +3,11 @@ ```{eval-rst} .. toctree:: :hidden: - + Images, sprites and animations Text rendering Colors and palette Particles + Decorators Layers ``` From b24f67eeb8cdb58a563d383ec68c2758f0122c10 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sat, 16 Jul 2022 01:02:40 -0700 Subject: [PATCH 24/34] rename tinted->tint --- .../{decorator_tinted.dart => decorator_tint.dart} | 12 ++++++------ doc/flame/examples/lib/main.dart | 4 ++-- doc/flame/rendering/decorators.md | 8 ++++---- .../flame/lib/src/rendering/paint_decorator.dart | 4 ++-- .../flame/test/rendering/paint_decorator_test.dart | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) rename doc/flame/examples/lib/{decorator_tinted.dart => decorator_tint.dart} (58%) diff --git a/doc/flame/examples/lib/decorator_tinted.dart b/doc/flame/examples/lib/decorator_tint.dart similarity index 58% rename from doc/flame/examples/lib/decorator_tinted.dart rename to doc/flame/examples/lib/decorator_tint.dart index 682d0611296..06c188dd677 100644 --- a/doc/flame/examples/lib/decorator_tinted.dart +++ b/doc/flame/examples/lib/decorator_tint.dart @@ -5,7 +5,7 @@ import 'package:flame/experimental.dart'; import 'package:flame/game.dart'; import 'package:flame/rendering.dart'; -class DecoratorTintedGame extends FlameGame with HasTappableComponents { +class DecoratorTintGame extends FlameGame with HasTappableComponents { @override Future onLoad() async { var step = 0; @@ -16,15 +16,15 @@ class DecoratorTintedGame extends FlameGame with HasTappableComponents { onTap: (flower) { step++; if (step == 1) { - flower.decorator = PaintDecorator.tinted(const Color(0x88FF0000)); + flower.decorator = PaintDecorator.tint(const Color(0x88FF0000)); } else if (step == 2) { - flower.decorator = PaintDecorator.tinted(const Color(0x8800FF00)); + flower.decorator = PaintDecorator.tint(const Color(0x8800FF00)); } else if (step == 3) { - flower.decorator = PaintDecorator.tinted(const Color(0x88000088)); + flower.decorator = PaintDecorator.tint(const Color(0x88000088)); } else if (step == 4) { - flower.decorator = PaintDecorator.tinted(const Color(0x66FFFFFF)); + flower.decorator = PaintDecorator.tint(const Color(0x66FFFFFF)); } else if (step == 5) { - flower.decorator = PaintDecorator.tinted(const Color(0xAA000000)); + flower.decorator = PaintDecorator.tint(const Color(0xAA000000)); } else { flower.decorator = null; step = 0; diff --git a/doc/flame/examples/lib/main.dart b/doc/flame/examples/lib/main.dart index 1b4f30cd51b..10d6199835e 100644 --- a/doc/flame/examples/lib/main.dart +++ b/doc/flame/examples/lib/main.dart @@ -2,7 +2,7 @@ import 'dart:html'; // ignore: avoid_web_libraries_in_flutter import 'package:doc_flame_examples/decorator_blur.dart'; import 'package:doc_flame_examples/decorator_grayscale.dart'; -import 'package:doc_flame_examples/decorator_tinted.dart'; +import 'package:doc_flame_examples/decorator_tint.dart'; import 'package:doc_flame_examples/drag_events.dart'; import 'package:doc_flame_examples/tap_events.dart'; import 'package:flame/game.dart'; @@ -28,7 +28,7 @@ void main() { game = DecoratorGrayscaleGame(); break; case 'decorator_tinted': - game = DecoratorTintedGame(); + game = DecoratorTintGame(); break; } if (game != null) { diff --git a/doc/flame/rendering/decorators.md b/doc/flame/rendering/decorators.md index f77b8c92ff7..65f8ee0d919 100644 --- a/doc/flame/rendering/decorators.md +++ b/doc/flame/rendering/decorators.md @@ -61,22 +61,22 @@ Possible uses: - black-and-white photos. -### PaintDecorator.tinted +### PaintDecorator.tint ```{flutter-app} :sources: ../flame/examples -:page: decorator_tinted +:page: decorator_tint :show: widget infobox :width: 180 :height: 160 ``` -This decorator "tints" the underlying image with the specified color, as if watching it through a +This decorator *tints* the underlying image with the specified color, as if watching it through a colored glass. It is recommended that the `color` used by this decorator was semi-transparent, so that you can see the details of the image below. ```dart -final decorator = PaintDecorator.tinted(const Color(0xAAFF0000); +final decorator = PaintDecorator.tint(const Color(0xAAFF0000); ``` Possible uses: diff --git a/packages/flame/lib/src/rendering/paint_decorator.dart b/packages/flame/lib/src/rendering/paint_decorator.dart index 8fb7a0a0799..99535ea000c 100644 --- a/packages/flame/lib/src/rendering/paint_decorator.dart +++ b/packages/flame/lib/src/rendering/paint_decorator.dart @@ -7,7 +7,7 @@ import 'package:flame/src/rendering/decorator.dart'; /// Specifically, the following filters are available: /// - [PaintDecorator.blur] adds Gaussian blur to the image, as if your vision /// became blurry and out of focus; -/// - [PaintDecorator.tinted] tints the picture with the specified color, as if +/// - [PaintDecorator.tint] tints the picture with the specified color, as if /// looking through a colored glass; /// - [PaintDecorator.grayscale] removes all color from the picture, as if it /// was a black-and-white photo. @@ -16,7 +16,7 @@ class PaintDecorator extends Decorator { addBlur(amount, amountY ?? amount); } - PaintDecorator.tinted(Color color) { + PaintDecorator.tint(Color color) { _paint.colorFilter = ColorFilter.mode(color, BlendMode.srcATop); } diff --git a/packages/flame/test/rendering/paint_decorator_test.dart b/packages/flame/test/rendering/paint_decorator_test.dart index d11374d26ee..35fd567fd02 100644 --- a/packages/flame/test/rendering/paint_decorator_test.dart +++ b/packages/flame/test/rendering/paint_decorator_test.dart @@ -61,17 +61,17 @@ void main() { SpriteComponent(sprite: Sprite(image)), _DecoratedSprite( sprite: Sprite(image), - decorator: PaintDecorator.tinted(const Color(0x8800FF00)), + decorator: PaintDecorator.tint(const Color(0x8800FF00)), position: Vector2(100, 0), ), _DecoratedSprite( sprite: Sprite(image), - decorator: PaintDecorator.tinted(const Color(0x880000FF)), + decorator: PaintDecorator.tint(const Color(0x880000FF)), position: Vector2(200, 0), ), _DecoratedSprite( sprite: Sprite(image), - decorator: PaintDecorator.tinted(const Color(0xAAFFFFFF)), + decorator: PaintDecorator.tint(const Color(0xAAFFFFFF)), position: Vector2(300, 0), ), ]); @@ -94,7 +94,7 @@ void main() { ), _DecoratedSprite( sprite: Sprite(image), - decorator: PaintDecorator.tinted(color)..addBlur(3), + decorator: PaintDecorator.tint(color)..addBlur(3), position: Vector2(200, 0), ), ]); From f258849a3ada1825242e84ceb0e34cf86471fefd Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 15:05:12 -0700 Subject: [PATCH 25/34] copied Decorator class --- .../flame/lib/src/rendering/decorator.dart | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/flame/lib/src/rendering/decorator.dart diff --git a/packages/flame/lib/src/rendering/decorator.dart b/packages/flame/lib/src/rendering/decorator.dart new file mode 100644 index 00000000000..531357c7a00 --- /dev/null +++ b/packages/flame/lib/src/rendering/decorator.dart @@ -0,0 +1,23 @@ +import 'dart:ui'; + +/// [Decorator] is an abstract class that encapsulates a particular visual +/// effect that should apply to drawing commands wrapped by this class. +/// +/// The simplest way to apply a [Decorator] to a component is to override its +/// `renderTree` method like this: +/// ```dart +/// @override +/// void renderTree(Canvas canvas) { +/// decorator.apply(super.renderTree, canvas); +/// } +/// ``` +/// +/// The following implementations are available: +abstract class Decorator { + /// Applies visual effect while [draw]ing on the [canvas]. + /// + /// A no-op decorator would simply call `draw(canvas)`. Any other non-trivial + /// decorator can transform the canvas before drawing, or perform any other + /// adjustment. + void apply(void Function(Canvas) draw, Canvas canvas); +} From aa29e1af52c1aa94226aac1703fedde52b6ff271 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 15:06:17 -0700 Subject: [PATCH 26/34] copied HasDecorator mixin --- .../src/components/mixins/has_decorator.dart | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 packages/flame/lib/src/components/mixins/has_decorator.dart diff --git a/packages/flame/lib/src/components/mixins/has_decorator.dart b/packages/flame/lib/src/components/mixins/has_decorator.dart new file mode 100644 index 00000000000..46fcbadc713 --- /dev/null +++ b/packages/flame/lib/src/components/mixins/has_decorator.dart @@ -0,0 +1,27 @@ +import 'dart:ui'; + +import 'package:flame/src/components/component.dart'; +import 'package:flame/src/rendering/decorator.dart'; + +/// [HasDecorator] mixin adds a nullable [decorator] field to a Component. If +/// this field is set, it will apply the visual effect encapsulated in this +/// [Decorator] to the component. If the field is not set, then the component +/// will be rendered normally. +/// +/// Note that the decorator only affects visual rendering of a component, but +/// not its perceived size or shape from the point of view of tap events. +/// +/// See also: +/// - [Decorator] class for the list of available decorators. +mixin HasDecorator on Component { + Decorator? decorator; + + @override + void renderTree(Canvas canvas) { + if (decorator == null) { + super.renderTree(canvas); + } else { + decorator!.apply(super.renderTree, canvas); + } + } +} From 5ffcad3bd585b3887959177d650fb0549c77c932 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 16:09:37 -0700 Subject: [PATCH 27/34] Rotate3DDecorator --- .../lib/src/rendering/rotate3d_decorator.dart | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 packages/flame/lib/src/rendering/rotate3d_decorator.dart diff --git a/packages/flame/lib/src/rendering/rotate3d_decorator.dart b/packages/flame/lib/src/rendering/rotate3d_decorator.dart new file mode 100644 index 00000000000..e6f7acc9094 --- /dev/null +++ b/packages/flame/lib/src/rendering/rotate3d_decorator.dart @@ -0,0 +1,43 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:flame/src/rendering/decorator.dart'; +import 'package:vector_math/vector_math_64.dart'; + +class Rotate3DDecorator extends Decorator { + Rotate3DDecorator({ + Vector2? center, + this.angleX = 0.0, + this.angleY = 0.0, + this.angleZ = 0.0, + this.perspective = 0.001, + }) : center = center ?? Vector2.zero(); + + Vector2 center; + double angleX; + double angleY; + double angleZ; + double perspective; + + bool get isFlipped { + const tau = 2 * pi; + final phaseX = (angleX / tau - 0.25) % 1.0; + final phaseY = (angleY / tau - 0.25) % 1.0; + return (phaseX > 0.5) ^ (phaseY > 0.5); + } + + @override + void apply(void Function(Canvas) draw, Canvas canvas) { + canvas.save(); + canvas.translate(center.x, center.y); + final matrix = Matrix4.identity() + ..setEntry(3, 2, perspective) + ..rotateX(angleX) + ..rotateY(angleY) + ..rotateZ(angleZ) + ..translate(-center.x, -center.y); + canvas.transform(matrix.storage); + draw(canvas); + canvas.restore(); + } +} From 8982f78cb74287de98ba04b440f126ae685a76b3 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 16:10:35 -0700 Subject: [PATCH 28/34] export file --- packages/flame/lib/rendering.dart | 2 ++ packages/flame/lib/src/rendering/decorator.dart | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 packages/flame/lib/rendering.dart diff --git a/packages/flame/lib/rendering.dart b/packages/flame/lib/rendering.dart new file mode 100644 index 00000000000..7c30298c16d --- /dev/null +++ b/packages/flame/lib/rendering.dart @@ -0,0 +1,2 @@ +export 'src/rendering/decorator.dart' show Decorator; +export 'src/rendering/rotate3d_decorator.dart' show Rotate3DDecorator; diff --git a/packages/flame/lib/src/rendering/decorator.dart b/packages/flame/lib/src/rendering/decorator.dart index 531357c7a00..866013b22df 100644 --- a/packages/flame/lib/src/rendering/decorator.dart +++ b/packages/flame/lib/src/rendering/decorator.dart @@ -1,5 +1,7 @@ import 'dart:ui'; +import 'package:flame/src/rendering/rotate3d_decorator.dart'; + /// [Decorator] is an abstract class that encapsulates a particular visual /// effect that should apply to drawing commands wrapped by this class. /// @@ -13,6 +15,7 @@ import 'dart:ui'; /// ``` /// /// The following implementations are available: +/// - [Rotate3DDecorator] abstract class Decorator { /// Applies visual effect while [draw]ing on the [canvas]. /// From 1d147b544443ab371f9f97521a8e5c61c8d1943f Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 16:53:01 -0700 Subject: [PATCH 29/34] doc comments --- .../lib/src/rendering/rotate3d_decorator.dart | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/packages/flame/lib/src/rendering/rotate3d_decorator.dart b/packages/flame/lib/src/rendering/rotate3d_decorator.dart index e6f7acc9094..1ee0ee19316 100644 --- a/packages/flame/lib/src/rendering/rotate3d_decorator.dart +++ b/packages/flame/lib/src/rendering/rotate3d_decorator.dart @@ -4,6 +4,11 @@ import 'dart:ui'; import 'package:flame/src/rendering/decorator.dart'; import 'package:vector_math/vector_math_64.dart'; +/// [Rotate3DDecorator] treats the underlying component as if it was a flat +/// sheet of paper, and applies a 3D rotation to it. +/// +/// The angles of rotation can be changed dynamically, allowing you to rotate +/// the content continuously at the desired angular speeds. class Rotate3DDecorator extends Decorator { Rotate3DDecorator({ Vector2? center, @@ -13,12 +18,35 @@ class Rotate3DDecorator extends Decorator { this.perspective = 0.001, }) : center = center ?? Vector2.zero(); + /// The center of rotation, in the local coordinate space. For example, in + /// order to rotate the component around its anchor point, pass `center = + /// anchor * size`. Vector2 center; + + /// Angle of rotation around the X axis. This rotation is usually described as + /// "vertical". double angleX; + + /// Angle of rotation around the Y axis. This rotation is typically described + /// as "horizontal". double angleY; + + /// Angle of rotation around the Z axis. This is a regular "2D" rotation + /// because it occurs entirely inside the plane in which the component is + /// normally drawn. double angleZ; + + /// The strength of the perspective effect. In other words, how much the + /// elements that are "behind" the canvas are shrunk, and those in front of + /// it are expanded. double perspective; + /// Returns `true` if the component is currently being rendered from its + /// back side, and `false` if it shows the front side. + /// + /// The "front" side is the one displayed at `angleX = angleY = 0`, and the + /// "back" side is shows if the component is rotated 180º degree around either + /// the X or Y axis. bool get isFlipped { const tau = 2 * pi; final phaseX = (angleX / tau - 0.25) % 1.0; From 3f8c36d098e7c049f4052989f966fb6c5092b957 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 21:23:41 -0700 Subject: [PATCH 30/34] added tests --- packages/flame/lib/components.dart | 1 + .../lib/src/rendering/rotate3d_decorator.dart | 4 +- .../test/_goldens/rotate3d_decorator_1.png | Bin 0 -> 1515 bytes .../test/_goldens/rotate3d_decorator_2.png | Bin 0 -> 1404 bytes .../test/_goldens/rotate3d_decorator_3.png | Bin 0 -> 1499 bytes .../rendering/rotate3d_decorator_test.dart | 105 ++++++++++++++++++ 6 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 packages/flame/test/_goldens/rotate3d_decorator_1.png create mode 100644 packages/flame/test/_goldens/rotate3d_decorator_2.png create mode 100644 packages/flame/test/_goldens/rotate3d_decorator_3.png create mode 100644 packages/flame/test/rendering/rotate3d_decorator_test.dart diff --git a/packages/flame/lib/components.dart b/packages/flame/lib/components.dart index 757d120fb20..522bcfab6c9 100644 --- a/packages/flame/lib/components.dart +++ b/packages/flame/lib/components.dart @@ -14,6 +14,7 @@ export 'src/components/mixins/component_viewport_margin.dart'; export 'src/components/mixins/draggable.dart'; export 'src/components/mixins/gesture_hitboxes.dart'; export 'src/components/mixins/has_ancestor.dart'; +export 'src/components/mixins/has_decorator.dart' show HasDecorator; export 'src/components/mixins/has_game_ref.dart'; export 'src/components/mixins/has_paint.dart'; export 'src/components/mixins/hoverable.dart'; diff --git a/packages/flame/lib/src/rendering/rotate3d_decorator.dart b/packages/flame/lib/src/rendering/rotate3d_decorator.dart index 1ee0ee19316..bba660fa9cb 100644 --- a/packages/flame/lib/src/rendering/rotate3d_decorator.dart +++ b/packages/flame/lib/src/rendering/rotate3d_decorator.dart @@ -18,9 +18,7 @@ class Rotate3DDecorator extends Decorator { this.perspective = 0.001, }) : center = center ?? Vector2.zero(); - /// The center of rotation, in the local coordinate space. For example, in - /// order to rotate the component around its anchor point, pass `center = - /// anchor * size`. + /// The center of rotation, in the **parent** coordinate space. Vector2 center; /// Angle of rotation around the X axis. This rotation is usually described as diff --git a/packages/flame/test/_goldens/rotate3d_decorator_1.png b/packages/flame/test/_goldens/rotate3d_decorator_1.png new file mode 100644 index 0000000000000000000000000000000000000000..97b9998411dade4255f50d85f26d6885b19b9074 GIT binary patch literal 1515 zcmeAS@N?(olHy`uVBq!ia0vp^DL}k{gAGXjntk#ckYX$ja(7}_cTVOdki$~!8`!3c|q9tuJnlARtVBAOYO0s?gWlAD&#Z&ts1 z?jys%Xn6SA>V1rxcv>Zzoq8M)&&><9+U9~p6y8q7Et7iq5Rj`*cGVGpdX}81cA;-~EcX(1Ry{cN< zTJ!MUvE( zuzc%;%cAi`jhV0Y{dz+!Ul_g0(rr0>=j%-mZplSQ1X5q?pXyy#`N~8k%glA!n%R~w ztUTYSEO{HC=f3ONip2uol>fV5mnqeY{5tbx>jwXo&leoX*{sU_!0tr7;H25-oFca6 zsjHaJZJm>}^YW~enqNyS4`n@D#+#+Pyr83USMQZTy3_d$W>W9Yx#Y3uJ$9py82_2zdAk5$#0Zg)x#efK4aklpVY^G zPtTmod=Q||x}|7=(h>fzacMWa{wxW|<^uBc&EwNFj`(wJ-KIPxio<(a7~hq1wR{FA zx20sBvA3ymN|}>;^3ocCET^J-mw0bZ$lCPnYFdW z@88gV{*LpMysug1ja1p|P1*l( z?VojKmtMte%6q(gu73f0^vUn4#%HE?+0FX5pepw3^Yh1o81wR~*rT`ioc!g@n$RW5 z624Juv0h3O*Y6u`3>t=qMT!mmes`PoJcw#hKjtZ2s(AM1F7e4qhGA+~ylWdX#n_uz z4p{njyrdggnsk-1R8f>AmCbc^%Y&s~7PR^-Ikl*D%8S60 zObtd4>r~Qm0=>ixeoHS_*rAI4uj`+WxH(>!iOtVwI7NJ8E?~Y(&Avr&@oxk z*spu-vq4~s&Z)2_+1>NM9IHywd8Jj^m8xClGtukXpJl;sZq)j0Dm(r5TguH*Jy_T0S+RCL)ECZG%i#R=h&dEP>;|92d>4?~LskSr+ z&JEwB@-Q&$2uxN@<>~cf--?oEe9lgGPB>}g7NWRtz0X#UH>SH*NQdk{C2`yK{){Z4 z-6HOylZuYZaeu>EW(CwQmf>vHrMM`=C=WmCPZLylDR^SPJg~rK@O1TaS?83{1OWR0 BttbEh literal 0 HcmV?d00001 diff --git a/packages/flame/test/_goldens/rotate3d_decorator_2.png b/packages/flame/test/_goldens/rotate3d_decorator_2.png new file mode 100644 index 0000000000000000000000000000000000000000..88a1406804d80aaee7b72d89c4809dc0313e2eb6 GIT binary patch literal 1404 zcmeAS@N?(olHy`uVBq!ia0vp^DL}k{gAGXjntk#ckYX$ja(7}_cTVOdki$~!n7|{T;bAqO-a%0+e@aLQ|8YO*GcZ(&)YO}Bmd_gbBsGV6cUX# zRq`J=S0rG_r*zEmh((74yWnGmBpH{U=8i&qf>ZQ7+F$KyFVJ7gy-AAu`>uVC{~VNe z&OQ}$|8L{kfaf=5(>$8zyie}@n(^7}>kW_H{RX>kYlcq9Oh2BbbD>xDTBd*9w`upB z`LnfDxi3A5wc7J-4qxc5i)psECjItZ*|g^3BiZTfm6E#G7N3<`yE1OG-Q{^`?>g!U|wd^nxb9xC5wH{Z>8sDOy;U|c%3pcD^O8AV_x;DRjwOq4{!QD!%O%{ z`-=~yTYebL`r;|VVp^1yBI5tz<-dc?f9CA1c`<#C#Qi%Tg*JP%x)x1axl!Qw{4dHv z?%yN4XKALZN}12QzQ{?x??>U6Z|B~ZO74`rq@u2#arEN_zv4^iZmYohRE)tAfs>*E&PWK62|nA)Red3DEMU%kt37&hKt?&TxOtl(wlyrgMH z^9j7MM|?aFR+Y-4DGo^!E`?lIS!Nv{n|hD=$9_iTe~B*hnye(Zo;cBwy>XHJ{B zu<=aAzb1>03m%THo7JwuC-F&<_lLRcMgPUw=XEE~JTu|@m&*CSCclpkIl(z=VzBb! zgg;*&Jzspj_V1FPmOe>45&L)Ew-rKv zrj`9X(C{^5vsZD^9?w>rCb7p$KcvVD&yHNmx#=k5`UYkktptr@cO zrz|*rw05<^Vlhir$@*n-^`B?5{hYaAbI>e>*(;C#tgY>5Tz{Dlh_Wv(lFq%B5xZmC z`HW8)f8Bqz_im|v_5+wh6_SBDP2)wtQv+W4r{6Vv1sZ&-!sWef&4T;+La%}HP|1pW zuS$mdKI;Vst08|TitN;K2 literal 0 HcmV?d00001 diff --git a/packages/flame/test/_goldens/rotate3d_decorator_3.png b/packages/flame/test/_goldens/rotate3d_decorator_3.png new file mode 100644 index 0000000000000000000000000000000000000000..96490279518d5c371412160153ca5df37e48e08c GIT binary patch literal 1499 zcmbVMX;4#F6i(P0mPjOl$Rgo|H7Eo!DkD0ek01|`9c7>hE>T-bwG?WDpisz*1g7Od zB_dR;F_<7|qM!r;v4Rb1-7o<`F^GU93?(G2iqPjw`@?^2@65gDobTSV&fJd|6%m3r zvophBF!)f28G}j|x_`x)py#`)d$Xv(X2gVmm@AJQ)Tm*U0fxrm(3OK@6=E>Pa42(Y z9Q&7vD&I(lkX76iRVrQXnB+ZLmzE;meD=}*4?Y;N`KTz0wt8Rf%ge(QehIlBZuASB`uSRN!_$-lBT+r zO!@Jd$lacBj=n2aIjB9O!AfGF+~wEUS2RX_`^)XJN~xGwHaU$+2(9>!iJwHxzjGPViWZp-44Jvc0wQ zhF`R^3tHTVLC2NZE%uj8TJ3-);OS@Ko7n3?{_4?i)&&Q9db_2pk}W3aRLEEXe_jki zvC#C^j?2Z#T|vOplYh!0b8kZQ;j74);d?c;4UvNa%RUd$PbCVFZ^{dpp7Xn~I6#Op z=Vd+bw4*e`Ms}m&(rWK+vvfQ!z~>(&v&f?0ob2%KQ(#Vz!160PH*Tslrpps8<{~zd z<}&JYgsM_M?F{h;05tyHrP!i*$lWCl%B+cHt#Sw;H_x_x2hj(;0o2<(Gxh2g58o0PjEbItK-P#-NKc3ddh_nQFNs*NPyg@r440m8)-QW@a}I@0^`_DmRpnUt8eekV_+r^`D;qcrgay3tvXrlNP? zf}m+&c17~vN*$gGR-hI8Mv{X$QkWUd&z(1z=f+Pq}J0|*Jh+@+%DdIGB#y{C(yp&!BB`K?qc^0URVe)tQI`~ zU8@^(L@G13V?XXpTgC>t0=$rO} z*n3G-JOuX7(-KCiN`}C^*@tBjrCCR8XdK1qjJQKJ(~SIR$CN#@^77vH8iGON{*-It z)TAYyiL!P%*V_)58F6@~a_@eiJs7R5XgyZE(9*X(_vAJlW-(ire1Ki=u6JT!7=T~z z`iqi4h~B|lSg<%9*ltQSbRrt$n3g04xa#$`0jOuy_&4J?ZktC1wzO`}ZF$e(f%J5oR(dE2ts3#bx%YbR}@Od zX_pi3oC1@+gpro4YA;x(GrA2PTM2Y++j#R$z>MR5+eBxfSK|<0>GpqE>c4T?r>}EN YUUewKRPH|*pahKx4US-50r%wp1rdgsHvj+t literal 0 HcmV?d00001 diff --git a/packages/flame/test/rendering/rotate3d_decorator_test.dart b/packages/flame/test/rendering/rotate3d_decorator_test.dart new file mode 100644 index 00000000000..f404447acb0 --- /dev/null +++ b/packages/flame/test/rendering/rotate3d_decorator_test.dart @@ -0,0 +1,105 @@ +import 'dart:ui'; + +import 'package:flame/components.dart'; +import 'package:flame/rendering.dart'; +import 'package:flame/src/components/mixins/has_decorator.dart'; +import 'package:flame_test/flame_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('Rotate3DDecorator', () { + testGolden( + 'Rotation around X axis', + (game) async { + for (var angle = 0.0; angle <= 1.5; angle += 0.5) { + game.add( + DecoratedRectangle( + position: Vector2(20, 30), + size: Vector2(60, 100), + paint: Paint()..color = const Color(0x9dde0445), + decorator: Rotate3DDecorator( + center: Vector2(50, 80), + angleX: angle, + perspective: 0.005, + ), + ), + ); + } + }, + size: Vector2(100, 160), + goldenFile: '../_goldens/rotate3d_decorator_1.png', + ); + + testGolden( + 'Rotation around Y axis', + (game) async { + for (var angle = 0.0; angle <= 1.5; angle += 0.5) { + game.add( + DecoratedRectangle( + position: Vector2(20, 30), + size: Vector2(60, 100), + paint: Paint()..color = const Color(0x9dde0445), + decorator: Rotate3DDecorator( + center: Vector2(50, 80), + angleY: angle, + perspective: 0.005, + ), + ), + ); + } + }, + size: Vector2(100, 160), + goldenFile: '../_goldens/rotate3d_decorator_2.png', + ); + + testGolden( + 'Rotation around all axes', + (game) async { + game.add( + DecoratedRectangle( + position: Vector2(20, 30), + size: Vector2(60, 100), + paint: Paint()..color = const Color(0xff199f2b), + decorator: Rotate3DDecorator( + center: Vector2(50, 80), + angleX: 0.7, + angleY: 1.0, + angleZ: 0.5, + perspective: 0.005, + ), + ), + ); + }, + size: Vector2(100, 160), + goldenFile: '../_goldens/rotate3d_decorator_3.png', + ); + + test('isFlipped', () { + final decorator = Rotate3DDecorator(); + expect(decorator.isFlipped, false); + decorator.angleZ = 2.0; + expect(decorator.isFlipped, false); + decorator.angleX = 2.0; + expect(decorator.isFlipped, true); + decorator.angleY = 2.0; + expect(decorator.isFlipped, false); + decorator.angleY = -0.5; + expect(decorator.isFlipped, true); + decorator.angleY = -1.5; + expect(decorator.isFlipped, true); + decorator.angleY = -1.6; + expect(decorator.isFlipped, false); + }); + }); +} + +class DecoratedRectangle extends RectangleComponent with HasDecorator { + DecoratedRectangle({ + super.position, + super.size, + super.paint, + Decorator? decorator, + }) { + this.decorator = decorator; + } +} From 05d0eae30e1a044ddbffd4e89bbb9751be5448bf Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Sun, 17 Jul 2022 21:24:26 -0700 Subject: [PATCH 31/34] format --- .../rendering/rotate3d_decorator_test.dart | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/flame/test/rendering/rotate3d_decorator_test.dart b/packages/flame/test/rendering/rotate3d_decorator_test.dart index f404447acb0..4716c15fe7b 100644 --- a/packages/flame/test/rendering/rotate3d_decorator_test.dart +++ b/packages/flame/test/rendering/rotate3d_decorator_test.dart @@ -2,7 +2,6 @@ import 'dart:ui'; import 'package:flame/components.dart'; import 'package:flame/rendering.dart'; -import 'package:flame/src/components/mixins/has_decorator.dart'; import 'package:flame_test/flame_test.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -55,20 +54,20 @@ void main() { testGolden( 'Rotation around all axes', (game) async { - game.add( - DecoratedRectangle( - position: Vector2(20, 30), - size: Vector2(60, 100), - paint: Paint()..color = const Color(0xff199f2b), - decorator: Rotate3DDecorator( - center: Vector2(50, 80), - angleX: 0.7, - angleY: 1.0, - angleZ: 0.5, - perspective: 0.005, - ), + game.add( + DecoratedRectangle( + position: Vector2(20, 30), + size: Vector2(60, 100), + paint: Paint()..color = const Color(0xff199f2b), + decorator: Rotate3DDecorator( + center: Vector2(50, 80), + angleX: 0.7, + angleY: 1.0, + angleZ: 0.5, + perspective: 0.005, ), - ); + ), + ); }, size: Vector2(100, 160), goldenFile: '../_goldens/rotate3d_decorator_3.png', From 3f726d084a80e564f912a655b42a0e763e7e7a13 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Mon, 18 Jul 2022 01:12:31 -0700 Subject: [PATCH 32/34] doc page for Rotate3DDecorator --- .../examples/lib/decorator_rotate3d.dart | 39 +++++++++++++++++++ doc/flame/examples/lib/main.dart | 6 ++- doc/flame/rendering/decorators.md | 32 +++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 doc/flame/examples/lib/decorator_rotate3d.dart diff --git a/doc/flame/examples/lib/decorator_rotate3d.dart b/doc/flame/examples/lib/decorator_rotate3d.dart new file mode 100644 index 00000000000..ae32e037528 --- /dev/null +++ b/doc/flame/examples/lib/decorator_rotate3d.dart @@ -0,0 +1,39 @@ +import 'package:doc_flame_examples/flower.dart'; +import 'package:flame/experimental.dart'; +import 'package:flame/game.dart'; +import 'package:flame/rendering.dart'; + +class DecoratorRotate3DGame extends FlameGame with HasTappableComponents { + @override + Future onLoad() async { + print('DecoratorRotate3DGame onLoad'); + var step = 0; + add( + Flower( + size: 100, + position: canvasSize / 2, + onTap: (flower) { + step++; + final decorator = + (flower.decorator ??= Rotate3DDecorator()) as Rotate3DDecorator + ..center = flower.center + ..perspective = 0.01; + if (step == 1) { + decorator.angleY = -0.8; + } else if (step == 2) { + decorator.angleX = 1.0; + } else if (step == 3) { + decorator.angleZ = 0.2; + } else if (step == 4) { + decorator.angleX = 10; + } else if (step == 5) { + decorator.angleY = 2; + } else { + flower.decorator = null; + step = 0; + } + }, + )..onTapUp(), + ); + } +} diff --git a/doc/flame/examples/lib/main.dart b/doc/flame/examples/lib/main.dart index 10d6199835e..8f31b07859d 100644 --- a/doc/flame/examples/lib/main.dart +++ b/doc/flame/examples/lib/main.dart @@ -2,6 +2,7 @@ import 'dart:html'; // ignore: avoid_web_libraries_in_flutter import 'package:doc_flame_examples/decorator_blur.dart'; import 'package:doc_flame_examples/decorator_grayscale.dart'; +import 'package:doc_flame_examples/decorator_rotate3d.dart'; import 'package:doc_flame_examples/decorator_tint.dart'; import 'package:doc_flame_examples/drag_events.dart'; import 'package:doc_flame_examples/tap_events.dart'; @@ -27,7 +28,10 @@ void main() { case 'decorator_grayscale': game = DecoratorGrayscaleGame(); break; - case 'decorator_tinted': + case 'decorator_rotate3d': + game = DecoratorRotate3DGame(); + break; + case 'decorator_tint': game = DecoratorTintGame(); break; } diff --git a/doc/flame/rendering/decorators.md b/doc/flame/rendering/decorators.md index 65f8ee0d919..64619a2692a 100644 --- a/doc/flame/rendering/decorators.md +++ b/doc/flame/rendering/decorators.md @@ -87,6 +87,38 @@ Possible uses: - tint the scene deep blue during the night time; +### Rotate3DDecorator + +```{flutter-app} +:sources: ../flame/examples +:page: decorator_rotate3d +:show: widget infobox +:width: 180 +:height: 160 +``` + +This decorator applies a 3D rotation to the underlying component. You can specify the angles of the +rotation, as well as the pivot point and the amount of perspective distortion to apply. + +The decorator also supplies the `isFlipped` property, which allows you to determine whether the +component is currently being viewed from the front side or from the back. This is useful if you want +to draw a component whose appearance is different in the front and in the back. + +```dart +final decorator = Rotate3DDecorator( + center: component.center, + angleX: rotationAngle, + perspective: 0.002, +); +``` + +Possible uses: +- a card that can be flipped over; +- pages in a book; +- transitions between app routes; +- 3d falling particles such as snowflakes or leaves. + + ## Using decorators ### HasDecorator mixin From 127f0bf40a69015b918d9746d482b71d85add262 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Mon, 18 Jul 2022 10:07:50 -0700 Subject: [PATCH 33/34] format --- doc/flame/examples/lib/decorator_rotate3d.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/flame/examples/lib/decorator_rotate3d.dart b/doc/flame/examples/lib/decorator_rotate3d.dart index ae32e037528..3fdf7ea8aa6 100644 --- a/doc/flame/examples/lib/decorator_rotate3d.dart +++ b/doc/flame/examples/lib/decorator_rotate3d.dart @@ -6,7 +6,6 @@ import 'package:flame/rendering.dart'; class DecoratorRotate3DGame extends FlameGame with HasTappableComponents { @override Future onLoad() async { - print('DecoratorRotate3DGame onLoad'); var step = 0; add( Flower( @@ -16,8 +15,8 @@ class DecoratorRotate3DGame extends FlameGame with HasTappableComponents { step++; final decorator = (flower.decorator ??= Rotate3DDecorator()) as Rotate3DDecorator - ..center = flower.center - ..perspective = 0.01; + ..center = flower.center + ..perspective = 0.01; if (step == 1) { decorator.angleY = -0.8; } else if (step == 2) { From 834211f9d7e66c6877187d785d50d9450435e8c3 Mon Sep 17 00:00:00 2001 From: Pasha Stetsenko Date: Mon, 18 Jul 2022 10:16:48 -0700 Subject: [PATCH 34/34] minor refactor --- doc/flame/examples/lib/decorator_rotate3d.dart | 13 ++++++++----- doc/flame/examples/lib/flower.dart | 10 ++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/flame/examples/lib/decorator_rotate3d.dart b/doc/flame/examples/lib/decorator_rotate3d.dart index 3fdf7ea8aa6..e380dd11ce8 100644 --- a/doc/flame/examples/lib/decorator_rotate3d.dart +++ b/doc/flame/examples/lib/decorator_rotate3d.dart @@ -11,12 +11,12 @@ class DecoratorRotate3DGame extends FlameGame with HasTappableComponents { Flower( size: 100, position: canvasSize / 2, + decorator: Rotate3DDecorator() + ..center = canvasSize / 2 + ..perspective = 0.01, onTap: (flower) { step++; - final decorator = - (flower.decorator ??= Rotate3DDecorator()) as Rotate3DDecorator - ..center = flower.center - ..perspective = 0.01; + final decorator = flower.decorator! as Rotate3DDecorator; if (step == 1) { decorator.angleY = -0.8; } else if (step == 2) { @@ -28,7 +28,10 @@ class DecoratorRotate3DGame extends FlameGame with HasTappableComponents { } else if (step == 5) { decorator.angleY = 2; } else { - flower.decorator = null; + decorator + ..angleX = 0 + ..angleY = 0 + ..angleZ = 0; step = 0; } }, diff --git a/doc/flame/examples/lib/flower.dart b/doc/flame/examples/lib/flower.dart index 1e76a72b57a..7d6570b0db3 100644 --- a/doc/flame/examples/lib/flower.dart +++ b/doc/flame/examples/lib/flower.dart @@ -3,13 +3,19 @@ import 'dart:ui'; import 'package:flame/components.dart'; import 'package:flame/experimental.dart'; +import 'package:flame/rendering.dart'; const tau = 2 * pi; class Flower extends PositionComponent with TapCallbacks, HasDecorator { - Flower({required double size, void Function(Flower)? onTap, super.position}) - : _onTap = onTap, + Flower({ + required double size, + void Function(Flower)? onTap, + Decorator? decorator, + super.position, + }) : _onTap = onTap, super(size: Vector2.all(size), anchor: Anchor.center) { + this.decorator = decorator; final radius = size * 0.38; _paths.add(_makePath(radius * 1.4, 6, -0.05, 0.8)); _paths.add(_makePath(radius, 6, 0.25, 1.5));