diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj
index 3643e885c..58bafb3e0 100644
--- a/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj
+++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/DrawingCppTestApp.vcxproj
@@ -1,6 +1,6 @@
-
+
@@ -133,7 +133,8 @@
-
+
+
@@ -143,7 +144,8 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp b/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp
index 31315d8ac..dfbd303c7 100644
--- a/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp
+++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/WinMain.cpp
@@ -21,8 +21,7 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
auto controller{ winrt::DispatcherQueueController::CreateOnCurrentThread() };
auto queue = controller.DispatcherQueue();
- // Associating the AppWindow with the DispatcherQueue on which the ContentIsland is created
- // will ensure that the ContentIsland is Closed when the AppWindow closes.
+ // Associate the AppWindow's lifetime with the DispatcherQueue to automatically close on exit.
auto window = winrt::AppWindow::Create();
window.AssociateWithDispatcherQueue(queue);
window.Closing(
@@ -35,20 +34,21 @@ int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
window.Title(L"Drawing C++ TestApp");
window.Show();
- // Create the Island content in the window.
- auto compositor = winrt::Compositor();
- auto island = winrt::DrawingIsland(compositor).Island();
-
+#pragma region ...
// Create a ContentSiteBridge and connect the ContentIsland to it.
+ auto compositor = winrt::Compositor();
auto siteBridge = winrt::DesktopChildSiteBridge::Create(compositor, window.Id());
siteBridge.ResizePolicy(winrt::ContentSizePolicy::ResizeContentToParentWindow);
siteBridge.Show();
+
+ auto island = winrt::DrawingIsland(compositor).Island();
siteBridge.Connect(island);
// Move initial focus to the ContentIsland.
auto focusNavigationHost = winrt::InputFocusNavigationHost::GetForSiteBridge(siteBridge);
focusNavigationHost.NavigateFocus(winrt::FocusNavigationRequest::Create(
winrt::FocusNavigationReason::Programmatic));
+#pragma endregion
queue.RunEventLoop();
diff --git a/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config b/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config
index 02e8fb621..229c2d189 100644
--- a/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config
+++ b/Samples/Islands/DrawingIsland/DrawingCppTestApp/packages.config
@@ -1,6 +1,7 @@
+
-
+
\ No newline at end of file
diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj
index 13b109104..e34e270eb 100644
--- a/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj
+++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/DrawingCsTestApp.csproj
@@ -26,6 +26,10 @@
False
+
+
+
+
diff --git a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs
index 75f5cea3f..a9071b376 100644
--- a/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs
+++ b/Samples/Islands/DrawingIsland/DrawingCsTestApp/Program.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
+#region Using directives
using Microsoft.UI.Composition;
using Microsoft.UI.Content;
using Microsoft.UI.Dispatching;
@@ -8,55 +9,44 @@
using Microsoft.UI.Windowing;
using DrawingIslandComponents;
+#endregion
var controller = DispatcherQueueController.CreateOnCurrentThread();
var queue = controller.DispatcherQueue;
+// Associate the AppWindow's lifetime with the DispatcherQueue to automatically close on exit.
var window = AppWindow.Create();
window.AssociateWithDispatcherQueue(queue);
window.Closing +=(sender, args) =>
{
+ // Ensure the DispatcherQueue exits the event loop on close.
queue.EnqueueEventLoopExit();
};
window.Title = "Drawing C# .NET TestApp";
window.Show();
+#region ...
+// Create a ContentSiteBridge and connect Island content into it.
var compositor = new Compositor();
-
var siteBridge = DesktopChildSiteBridge.Create(compositor, window.Id);
siteBridge.ResizePolicy = ContentSizePolicy.ResizeContentToParentWindow;
siteBridge.Show();
-if (args.Contains("Lottie"))
-{
- // LottieIsland
- var lottie = LottieIslandScenario.CreateLottieIsland(compositor);
- siteBridge.Connect(lottie.Island);
-}
-else if (args.Contains("Duck"))
-{
- // SceneNodeIsland
- var island = DuckScenario.CreateIsland(compositor);
- siteBridge.Connect(island);
-}
-else if (args.Contains("Helmet"))
-{
- // SceneNodeIsland
- var island = HelmetScenario.CreateIsland(compositor);
- siteBridge.Connect(island);
-}
-else
-{
- // DrawingIsland
- var drawing = new DrawingIsland(compositor);
- siteBridge.Connect(drawing.Island);
-}
+var lottie = LottieIslandScenario.CreateLottieIsland(compositor);
+siteBridge.Connect(lottie.Island);
+
+#region ...
+//var island = HelmetScenario.CreateIsland(compositor);
+//siteBridge.Connect(island);
+
+#endregion
// Move initial focus to the island.
var focusNavigationHost = InputFocusNavigationHost.GetForSiteBridge(siteBridge);
focusNavigationHost.NavigateFocus(FocusNavigationRequest.Create(
FocusNavigationReason.Programmatic));
+#endregion
queue.RunEventLoop();
diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj
index 8fa5e8bb5..c817eed95 100644
--- a/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj
+++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/DrawingIslandComponents.vcxproj
@@ -1,6 +1,6 @@
-
+
@@ -171,7 +171,8 @@
-
+
+
@@ -182,7 +183,8 @@
-
-
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config b/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config
index c4397c325..8401faf51 100644
--- a/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config
+++ b/Samples/Islands/DrawingIsland/DrawingIslandComponents/packages.config
@@ -1,7 +1,8 @@
+
-
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/App.config b/Samples/Islands/WpfCalculator/CalculatorDemo/App.config
new file mode 100644
index 000000000..51fffc74b
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/App.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/App.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/App.cs
new file mode 100644
index 000000000..82f967ced
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/App.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Windows;
+
+namespace CalculatorDemo
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/App.xaml b/Samples/Islands/WpfCalculator/CalculatorDemo/App.xaml
new file mode 100644
index 000000000..cf39a75c8
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/App.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/App_Demo3.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/App_Demo3.cs
new file mode 100644
index 000000000..4de9aa9f2
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/App_Demo3.cs
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Windows;
+using Microsoft.UI.Dispatching;
+
+// Demo3_Step1_AddWasdk
+namespace CalculatorDemo
+{
+ public partial class App : Application
+ {
+ // Many WinAppSDK APIs require a DispatcherQueue to be running on the thread. We'll start
+ // one when the app starts up and shut it down when the app is finished.
+ protected override void OnStartup(StartupEventArgs e)
+ {
+ _dispatcherQueueController = DispatcherQueueController.CreateOnCurrentThread();
+ base.OnStartup(e);
+ }
+
+ protected override void OnExit(ExitEventArgs e)
+ {
+ base.OnExit(e);
+ _dispatcherQueueController?.ShutdownQueue();
+ _dispatcherQueueController = null;
+ }
+
+ DispatcherQueueController? _dispatcherQueueController;
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/CalculatorDemo.csproj b/Samples/Islands/WpfCalculator/CalculatorDemo/CalculatorDemo.csproj
new file mode 100644
index 000000000..0ed7d78dc
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/CalculatorDemo.csproj
@@ -0,0 +1,185 @@
+
+
+
+ net9.0-windows10.0.22621.0
+ true
+ false
+ x64;ARM64;x86
+
+
+ win-x64;win-x86;win-arm64
+
+
+ false
+ false
+ true
+
+
+ Debug
+ x64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}
+ WinExe
+ Properties
+ CalculatorDemo
+ CalculatorDemo
+ 512
+ 4
+ true
+ 10.0.17763.0
+ app.manifest
+
+
+ x86
+ true
+ portable
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ ARM64
+ true
+ portable
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x64
+ true
+ portable
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ x86
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ ARM64
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ x64
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ App.xaml
+ Code
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MainWindow.xaml
+ Code
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+ True
+ Settings.settings
+ True
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/HelmetScenario.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/HelmetScenario.cs
new file mode 100644
index 000000000..68b5799e8
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/HelmetScenario.cs
@@ -0,0 +1,155 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.Numerics;
+using System.Runtime.InteropServices;
+
+using Windows.Foundation;
+using Windows.Graphics;
+using Windows.Storage;
+using Windows.Storage.Streams;
+
+using Microsoft.Graphics.Canvas;
+using Microsoft.Graphics.Canvas.UI.Composition;
+using Microsoft.Graphics.DirectX;
+using Microsoft.UI.Composition;
+using Microsoft.UI.Composition.Scenes;
+using Microsoft.UI.Content;
+using System.Threading.Tasks;
+
+class HelmetScenario
+{
+ public static async Task CreateIsland(Compositor compositor)
+ {
+ var visual = await LoadScene_DamagedHelmet(compositor);
+
+ var island = ContentIsland.Create(visual);
+ return island;
+ }
+
+ private static async Task LoadScene_DamagedHelmet(Compositor compositor)
+ {
+ // Initialize Win2D, used for loading bitmaps.
+
+ var canvasDevice = new CanvasDevice();
+ var graphicsDevice = CanvasComposition.CreateCompositionGraphicsDevice(
+ compositor, canvasDevice);
+
+
+ // Create the Visuals and SceneNode structure, along with default rotation animations.
+
+ var sceneVisual = SceneVisual.Create(compositor);
+ sceneVisual.RelativeOffsetAdjustment = new Vector3(0.5f, 0.5f, 0.0f);
+
+ var worldNode = SceneNode.Create(compositor);
+ sceneVisual.Root = worldNode;
+
+ var rotateAngleAnimation = compositor.CreateScalarKeyFrameAnimation();
+ rotateAngleAnimation.InsertKeyFrame(0.0f, 0.0f);
+ rotateAngleAnimation.InsertKeyFrame(0.5f, 360.0f);
+ rotateAngleAnimation.InsertKeyFrame(1.0f, 0.0f);
+ rotateAngleAnimation.Duration = TimeSpan.FromSeconds(15);
+ rotateAngleAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
+ worldNode.Transform.RotationAxis = new Vector3(0, 1, 0);
+ worldNode.Transform.StartAnimation("RotationAngleInDegrees", rotateAngleAnimation);
+
+ var sceneNode0 = SceneNode.Create(compositor);
+ sceneNode0.Transform.Scale = new Vector3(350);
+ sceneNode0.Transform.Orientation = new Quaternion(0.70710683f, 0.0f, 0.0f, 0.70710683f);
+ worldNode.Children.Add(sceneNode0);
+
+ var sceneNodeForTheGLTFMesh0 = SceneNode.Create(compositor);
+ sceneNode0.Children.Add(sceneNodeForTheGLTFMesh0);
+
+
+ // Load all file data in parallel:
+ // - Although Scene Graph objects prefer a UI thread, Win2D can load and create the bitmaps
+ // on parallel background threads.
+
+ var vertexData = await SceneNodeCommon.LoadMemoryBufferFromUriAsync(
+ new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet6.bin"));
+
+ var normalData = await SceneNodeCommon.LoadMemoryBufferFromUriAsync(
+ new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet7.bin"));
+
+ var texCoordData = await SceneNodeCommon.LoadMemoryBufferFromUriAsync(
+ new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet8.bin"));
+
+ var indexData = await SceneNodeCommon.LoadMemoryBufferFromUriAsync(
+ new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet9.bin"));
+
+ //Task.WaitAll(
+ // vertexData, normalData, texCoordData, indexData);
+
+ var canvasBitmap0 = await CanvasBitmap.LoadAsync(
+ canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet1.bmp"));
+
+ var canvasBitmap1 = await CanvasBitmap.LoadAsync(
+ canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet2.bmp"));
+
+ var canvasBitmap2 = await CanvasBitmap.LoadAsync(
+ canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet3.bmp"));
+
+ var canvasBitmap3 = await CanvasBitmap.LoadAsync(
+ canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet4.bmp"));
+
+ var canvasBitmap4 = await CanvasBitmap.LoadAsync(
+ canvasDevice, new Uri("ms-appx:///Assets/SceneNode/DamagedHelmet5.bmp"));
+
+
+ // Generate mipmaps from the bitmaps, which are needed for 3D rendering.
+
+ var materialInput0 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap0);
+ var materialInput1 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap1);
+ var materialInput2 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap2);
+ var materialInput3 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap3);
+ var materialInput4 = SceneNodeCommon.LoadMipmapFromBitmap(graphicsDevice, canvasBitmap4);
+
+
+ // Copy loaded binary data into mesh: verticies, normals, ...
+
+ var mesh0 = SceneMesh.Create(compositor);
+ mesh0.PrimitiveTopology = DirectXPrimitiveTopology.TriangleList;
+ mesh0.FillMeshAttribute(SceneAttributeSemantic.Vertex, DirectXPixelFormat.R32G32B32Float, vertexData);
+ mesh0.FillMeshAttribute(SceneAttributeSemantic.Normal, DirectXPixelFormat.R32G32B32Float, normalData);
+ mesh0.FillMeshAttribute(SceneAttributeSemantic.TexCoord0, DirectXPixelFormat.R32G32Float, texCoordData);
+ mesh0.FillMeshAttribute(SceneAttributeSemantic.Index, DirectXPixelFormat.R16UInt, indexData);
+
+
+ // Initialize the material with different texture inputs (color, roughness, normals, ...)
+
+ var sceneMaterial0 = SceneMetallicRoughnessMaterial.Create(compositor);
+
+ var renderComponent0 = SceneMeshRendererComponent.Create(compositor);
+ renderComponent0.Mesh = mesh0;
+ renderComponent0.Material = sceneMaterial0;
+ sceneNodeForTheGLTFMesh0.Components.Add(renderComponent0);
+
+ sceneMaterial0.BaseColorFactor = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
+ sceneMaterial0.BaseColorInput = SceneNodeCommon.CreateMaterial(
+ compositor, materialInput0, renderComponent0, "BaseColorInput"); ;
+
+ sceneMaterial0.RoughnessFactor = 1.0f;
+ sceneMaterial0.MetallicFactor = 1.0f;
+ sceneMaterial0.MetallicRoughnessInput = SceneNodeCommon.CreateMaterial(
+ compositor, materialInput1, renderComponent0, "MetallicRoughnessInput");
+
+ sceneMaterial0.NormalScale = 1.0f;
+ sceneMaterial0.NormalInput = SceneNodeCommon.CreateMaterial(
+ compositor, materialInput2, renderComponent0, "NormalInput");
+
+ sceneMaterial0.OcclusionStrength = 1.0f;
+ sceneMaterial0.OcclusionInput = SceneNodeCommon.CreateMaterial(
+ compositor, materialInput3, renderComponent0, "OcclusionInput");
+
+ sceneMaterial0.AlphaMode = SceneAlphaMode.Opaque;
+ sceneMaterial0.IsDoubleSided = false;
+ sceneMaterial0.EmissiveFactor = new Vector3(1.0f, 1.0f, 1.0f);
+ sceneMaterial0.EmissiveInput = SceneNodeCommon.CreateMaterial(
+ compositor, materialInput4, renderComponent0, "EmissiveInput");
+
+ return sceneVisual;
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/MainWindow_Demo4_Extra.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/MainWindow_Demo4_Extra.cs
new file mode 100644
index 000000000..15ac7d4b9
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/MainWindow_Demo4_Extra.cs
@@ -0,0 +1,28 @@
+// // Copyright (c) Microsoft. All rights reserved.
+// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Windows;
+
+namespace CalculatorDemo
+{
+ public sealed partial class MainWindow : Window
+ {
+ private void CreateDrawingIslandMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ var wpfIslandHost = new WpfIslandHost(_compositor);
+ var drawingIsland = new DrawingIslandComponents.DrawingIsland(_compositor);
+
+ DisplayAreaBorder.Child = wpfIslandHost;
+ wpfIslandHost.DesktopChildSiteBridge.Connect(drawingIsland.Island);
+ }
+
+ private async void CreateSceneNodeIslandMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ var wpfIslandHost = new WpfIslandHost(_compositor);
+ var helmetIsland = await HelmetScenario.CreateIsland(_compositor);
+
+ DisplayAreaBorder.Child = wpfIslandHost;
+ wpfIslandHost.DesktopChildSiteBridge.Connect(helmetIsland);
+ }
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/SceneNodeCommon.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/SceneNodeCommon.cs
new file mode 100644
index 000000000..d18bc4d7e
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Extra/SceneNodeCommon.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.Storage.Streams;
+using Windows.Storage;
+using WinRT;
+using Microsoft.Graphics.Canvas.UI.Composition;
+using Microsoft.Graphics.Canvas;
+using Microsoft.Graphics.DirectX;
+using Microsoft.UI.Composition;
+using Microsoft.UI.Composition.Scenes;
+using Windows.Graphics;
+
+class SceneNodeCommon
+{
+ public static CompositionMipmapSurface LoadMipmapFromBitmap(
+ CompositionGraphicsDevice graphicsDevice, CanvasBitmap canvasBitmap)
+ {
+ var size = new SizeInt32(2048, 2048);
+ var mipmapSurface = graphicsDevice.CreateMipmapSurface(
+ size,
+ DirectXPixelFormat.B8G8R8A8UIntNormalized,
+ DirectXAlphaMode.Premultiplied);
+
+ var drawDestRect = new Rect(0, 0, size.Width, size.Height);
+ var drawSourceRect = new Rect(0, 0, size.Width, size.Height);
+ for (uint level = 0; level < mipmapSurface.LevelCount; ++level)
+ {
+ // Draw the image to the surface
+ var drawingSurface = mipmapSurface.GetDrawingSurfaceForLevel(level);
+
+ using (var session = CanvasComposition.CreateDrawingSession(drawingSurface))
+ {
+ session.Clear(Windows.UI.Color.FromArgb(0, 0, 0, 0));
+ session.DrawImage(canvasBitmap, drawDestRect, drawSourceRect);
+ }
+
+ drawDestRect = new Rect(0, 0, drawDestRect.Width / 2, drawDestRect.Height / 2);
+ }
+
+ return mipmapSurface;
+ }
+
+ public static SceneSurfaceMaterialInput CreateMaterial(
+ Compositor compositor,
+ CompositionMipmapSurface mipmap,
+ SceneMeshRendererComponent rendererComponent,
+ string mapping)
+ {
+ var materialInput = SceneSurfaceMaterialInput.Create(compositor);
+ materialInput.Surface = mipmap;
+ materialInput.BitmapInterpolationMode =
+ CompositionBitmapInterpolationMode.MagLinearMinLinearMipLinear;
+
+ materialInput.WrappingUMode = SceneWrappingMode.Repeat;
+ materialInput.WrappingVMode = SceneWrappingMode.Repeat;
+
+ rendererComponent.UVMappings[mapping] = SceneAttributeSemantic.TexCoord0;
+
+ return materialInput;
+ }
+
+ public static async Task LoadMemoryBufferFromUriAsync(Uri uri)
+ {
+ var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
+ var buffer = await FileIO.ReadBufferAsync(file);
+
+ return CopyToMemoryBuffer(buffer);
+ }
+
+ public static MemoryBuffer CopyToMemoryBuffer(IBuffer buffer)
+ {
+ var dataReader = DataReader.FromBuffer(buffer);
+
+ var memBuffer = new MemoryBuffer(buffer.Length);
+ var memBufferRef = memBuffer.CreateReference();
+ var memBufferByteAccess = memBufferRef.As();
+
+ unsafe
+ {
+ byte* bytes = null;
+ uint capacity;
+ memBufferByteAccess.GetBuffer(&bytes, &capacity);
+
+ for (int i = 0; i < capacity; ++i)
+ {
+ bytes[i] = dataReader.ReadByte();
+ }
+ }
+
+ return memBuffer;
+ }
+
+
+ public static MemoryBuffer CopyToMemoryBuffer(byte[] a)
+ {
+ MemoryBuffer mb = new MemoryBuffer((uint)a.Length);
+ var mbr = mb.CreateReference();
+ var mba = mbr.As();
+ unsafe
+ {
+ byte* bytes = null;
+ uint capacity;
+ mba.GetBuffer(&bytes, &capacity);
+ for (int i = 0; i < capacity; ++i)
+ {
+ bytes[i] = a[i];
+ }
+ }
+
+ return mb;
+ }
+
+
+
+ [ComImport,
+ Guid("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d"),
+ InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IMemoryBufferByteAccess
+ {
+ unsafe void GetBuffer(byte** bytes, uint* capacity);
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/LottieIslandScenario.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/LottieIslandScenario.cs
new file mode 100644
index 000000000..0e47e4dd9
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/LottieIslandScenario.cs
@@ -0,0 +1,38 @@
+using System;
+using Microsoft.UI.Composition;
+using CommunityToolkit.WinAppSDK.LottieIsland;
+using CommunityToolkit.WinAppSDK.LottieWinRT;
+
+// Demo4_Step1_LottieIsland
+class LottieIslandScenario
+{
+ public static LottieContentIsland CreateLottieIsland(Compositor compositor)
+ {
+ var lottieIsland = LottieContentIsland.Create(compositor);
+ var lottieVisualSource = LottieVisualSourceWinRT.CreateFromString(
+ "ms-appx:///Assets/LottieLogo1.json");
+
+ if (lottieVisualSource != null)
+ {
+ lottieVisualSource.AnimatedVisualInvalidated += (sender, args) =>
+ {
+ object? diagnostics = null;
+ IAnimatedVisualFrameworkless? animatedVisual =
+ lottieVisualSource.TryCreateAnimatedVisual(compositor, out diagnostics);
+
+ if (animatedVisual != null)
+ {
+ // This callback comes back on a different thread, so set the AnimatedVisual on
+ // the UI thread
+ compositor.DispatcherQueue.TryEnqueue(async () =>
+ {
+ lottieIsland.AnimatedVisual = animatedVisual;
+ await lottieIsland.PlayAsync(0, 1, true);
+ });
+ }
+ };
+ }
+
+ return lottieIsland;
+ }
+}
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.cs
new file mode 100644
index 000000000..c3b690bd2
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.cs
@@ -0,0 +1,449 @@
+// // Copyright (c) Microsoft. All rights reserved.
+// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Interop;
+using Windows.ApplicationModel.Contacts;
+
+namespace CalculatorDemo
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public sealed partial class MainWindow : Window
+ {
+ private static PaperTrail _paper;
+ private Operation _lastOper;
+ private string _lastVal;
+ private string _memVal;
+ public MainWindow()
+ {
+ InitializeComponent();
+ _paper = new PaperTrail(this);
+ ProcessKey('0');
+ EraseDisplay = true;
+ }
+
+ ///
+ /// Flag to erase or just add to current display flag
+ ///
+ private bool EraseDisplay { get; set; }
+
+ ///
+ /// Get/Set Memory cell value
+ ///
+ private double Memory
+ {
+ get
+ {
+ if (_memVal == string.Empty)
+ return 0.0;
+ return Convert.ToDouble(_memVal);
+ }
+ set { _memVal = value.ToString(CultureInfo.InvariantCulture); }
+ }
+
+ //Lats value entered
+ private string LastValue
+ {
+ get
+ {
+ if (_lastVal == string.Empty)
+ return "0";
+ return _lastVal;
+ }
+ set { _lastVal = value; }
+ }
+
+ //The current Calculator display
+ private string Display { get; set; }
+ // Sample event handler:
+ private void OnWindowKeyDown(object sender, TextCompositionEventArgs /*System.Windows.Input.KeyEventArgs*/ e)
+ {
+ var s = e.Text;
+ var c = (s.ToCharArray())[0];
+ e.Handled = true;
+
+ if ((c >= '0' && c <= '9') || c == '.' || c == '\b') // '\b' is backspace
+ {
+ ProcessKey(c);
+ return;
+ }
+ switch (c)
+ {
+ case '+':
+ ProcessOperation("BPlus");
+ break;
+ case '-':
+ ProcessOperation("BMinus");
+ break;
+ case '*':
+ ProcessOperation("BMultiply");
+ break;
+ case '/':
+ ProcessOperation("BDevide");
+ break;
+ case '%':
+ ProcessOperation("BPercent");
+ break;
+ case '=':
+ ProcessOperation("BEqual");
+ break;
+ }
+ }
+
+ private void DigitBtn_Click(object sender, RoutedEventArgs e)
+ {
+ var s = ((Button) sender).Content.ToString();
+
+ //char[] ids = ((Button)sender).ID.ToCharArray();
+ var ids = s.ToCharArray();
+ ProcessKey(ids[0]);
+ }
+
+ private void ProcessKey(char c)
+ {
+ if (EraseDisplay)
+ {
+ Display = string.Empty;
+ EraseDisplay = false;
+ }
+ AddToDisplay(c);
+ }
+
+ private void ProcessOperation(string s)
+ {
+ var d = 0.0;
+ switch (s)
+ {
+ case "BPM":
+ _lastOper = Operation.Negate;
+ LastValue = Display;
+ CalcResults();
+ LastValue = Display;
+ EraseDisplay = true;
+ _lastOper = Operation.None;
+ break;
+ case "BDevide":
+
+ if (EraseDisplay) //stil wait for a digit...
+ {
+ //stil wait for a digit...
+ _lastOper = Operation.Devide;
+ break;
+ }
+ CalcResults();
+ _lastOper = Operation.Devide;
+ LastValue = Display;
+ EraseDisplay = true;
+ break;
+ case "BMultiply":
+ if (EraseDisplay) //stil wait for a digit...
+ {
+ //stil wait for a digit...
+ _lastOper = Operation.Multiply;
+ break;
+ }
+ CalcResults();
+ _lastOper = Operation.Multiply;
+ LastValue = Display;
+ EraseDisplay = true;
+ break;
+ case "BMinus":
+ if (EraseDisplay) //stil wait for a digit...
+ {
+ //stil wait for a digit...
+ _lastOper = Operation.Subtract;
+ break;
+ }
+ CalcResults();
+ _lastOper = Operation.Subtract;
+ LastValue = Display;
+ EraseDisplay = true;
+ break;
+ case "BPlus":
+ if (EraseDisplay)
+ {
+ //stil wait for a digit...
+ _lastOper = Operation.Add;
+ break;
+ }
+ CalcResults();
+ _lastOper = Operation.Add;
+ LastValue = Display;
+ EraseDisplay = true;
+ break;
+ case "BEqual":
+ if (EraseDisplay) //stil wait for a digit...
+ break;
+ CalcResults();
+ EraseDisplay = true;
+ _lastOper = Operation.None;
+ LastValue = Display;
+ //val = Display;
+ break;
+ case "BSqrt":
+ _lastOper = Operation.Sqrt;
+ LastValue = Display;
+ CalcResults();
+ LastValue = Display;
+ EraseDisplay = true;
+ _lastOper = Operation.None;
+ break;
+ case "BPercent":
+ if (EraseDisplay) //stil wait for a digit...
+ {
+ //stil wait for a digit...
+ _lastOper = Operation.Percent;
+ break;
+ }
+ CalcResults();
+ _lastOper = Operation.Percent;
+ LastValue = Display;
+ EraseDisplay = true;
+ //LastOper = Operation.None;
+ break;
+ case "BOneOver":
+ _lastOper = Operation.OneX;
+ LastValue = Display;
+ CalcResults();
+ LastValue = Display;
+ EraseDisplay = true;
+ _lastOper = Operation.None;
+ break;
+ case "BC": //clear All
+ _lastOper = Operation.None;
+ Display = LastValue = string.Empty;
+ _paper.Clear();
+ UpdateDisplay();
+ break;
+ case "BCE": //clear entry
+ _lastOper = Operation.None;
+ Display = LastValue;
+ UpdateDisplay();
+ break;
+ case "BMemClear":
+ Memory = 0.0F;
+ DisplayMemory();
+ break;
+ case "BMemSave":
+ Memory = Convert.ToDouble(Display);
+ DisplayMemory();
+ EraseDisplay = true;
+ break;
+ case "BMemRecall":
+ Display = /*val =*/ Memory.ToString(CultureInfo.InvariantCulture);
+ UpdateDisplay();
+ //if (LastOper != Operation.None) //using MR is like entring a digit
+ EraseDisplay = false;
+ break;
+ case "BMemPlus":
+ d = Memory + Convert.ToDouble(Display);
+ Memory = d;
+ DisplayMemory();
+ EraseDisplay = true;
+ break;
+ }
+ }
+
+ private void OperBtn_Click(object sender, RoutedEventArgs e)
+ {
+ ProcessOperation(((Button) sender).Name.Replace("_c",""));
+ }
+
+ private double Calc(Operation lastOper)
+ {
+ var d = 0.0;
+
+
+ try
+ {
+ switch (lastOper)
+ {
+ case Operation.Devide:
+ _paper.AddArguments(LastValue + " / " + Display);
+ d = (Convert.ToDouble(LastValue)/Convert.ToDouble(Display));
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Add:
+ _paper.AddArguments(LastValue + " + " + Display);
+ d = Convert.ToDouble(LastValue) + Convert.ToDouble(Display);
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Multiply:
+ _paper.AddArguments(LastValue + " * " + Display);
+ d = Convert.ToDouble(LastValue)*Convert.ToDouble(Display);
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Percent:
+ //Note: this is different (but make more sense) then Windows calculator
+ _paper.AddArguments(LastValue + " % " + Display);
+ d = (Convert.ToDouble(LastValue)*Convert.ToDouble(Display))/100.0F;
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Subtract:
+ _paper.AddArguments(LastValue + " - " + Display);
+ d = Convert.ToDouble(LastValue) - Convert.ToDouble(Display);
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Sqrt:
+ _paper.AddArguments("Sqrt( " + LastValue + " )");
+ d = Math.Sqrt(Convert.ToDouble(LastValue));
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.OneX:
+ _paper.AddArguments("1 / " + LastValue);
+ d = 1.0F/Convert.ToDouble(LastValue);
+ CheckResult(d);
+ _paper.AddResult(d.ToString(CultureInfo.InvariantCulture));
+ break;
+ case Operation.Negate:
+ d = Convert.ToDouble(LastValue)*(-1.0F);
+ break;
+ }
+ }
+ catch
+ {
+ d = 0;
+ var parent = (Window) MyPanel.Parent;
+ _paper.AddResult("Error");
+ MessageBox.Show(parent, "Operation cannot be perfomed", parent.Title);
+ }
+
+ return d;
+ }
+
+ private void CheckResult(double d)
+ {
+ if (double.IsNegativeInfinity(d) || double.IsPositiveInfinity(d) || double.IsNaN(d))
+ throw new Exception("Illegal value");
+ }
+
+ private void DisplayMemory()
+ {
+ if (_memVal != string.Empty)
+ BMemBox.Text = "Memory: " + _memVal;
+ else
+ BMemBox.Text = "Memory: [empty]";
+ }
+
+ private void CalcResults()
+ {
+ double d;
+ if (_lastOper == Operation.None)
+ return;
+
+ d = Calc(_lastOper);
+ Display = d.ToString(CultureInfo.InvariantCulture);
+
+ UpdateDisplay();
+ }
+
+ private void UpdateDisplay()
+ {
+ DisplayBox.Text = Display == string.Empty ? "0" : Display;
+ }
+
+ private void AddToDisplay(char c)
+ {
+ if (c == '.')
+ {
+ if (Display.IndexOf('.', 0) >= 0) //already exists
+ return;
+ Display = Display + c;
+ }
+ else
+ {
+ if (c >= '0' && c <= '9')
+ {
+ Display = Display + c;
+ }
+ else if (c == '\b') //backspace ?
+ {
+ if (Display.Length <= 1)
+ Display = string.Empty;
+ else
+ {
+ var i = Display.Length;
+ Display = Display.Remove(i - 1, 1); //remove last char
+ }
+ }
+ }
+
+ UpdateDisplay();
+ }
+
+ private void OnMenuAbout(object sender, RoutedEventArgs e)
+ {
+ var parent = (Window) MyPanel.Parent;
+ MessageBox.Show(parent, parent.Title + " - By Jossef Goldberg ", parent.Title, MessageBoxButton.OK,
+ MessageBoxImage.Information);
+ }
+
+ private void OnMenuExit(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+
+ private void OnMenuStandard(object sender, RoutedEventArgs e)
+ {
+ //((MenuItem)ScientificMenu).IsChecked = false;
+ StandardMenu.IsChecked = true; //for now always Standard
+ }
+
+ private void OnMenuScientific(object sender, RoutedEventArgs e)
+ {
+ //((MenuItem)StandardMenu).IsChecked = false;
+ }
+
+ private enum Operation
+ {
+ None,
+ Devide,
+ Multiply,
+ Subtract,
+ Add,
+ Percent,
+ Sqrt,
+ OneX,
+ Negate
+ }
+
+ private class PaperTrail
+ {
+ private readonly MainWindow _window;
+ private string _args;
+
+ public PaperTrail(MainWindow window)
+ {
+ _window = window;
+ }
+
+ public void AddArguments(string a)
+ {
+ _args = a;
+ }
+
+ public void AddResult(string r)
+ {
+ _window.PaperBox.Text += _args + " = " + r + "\n";
+ }
+
+ public void Clear()
+ {
+ _window.PaperBox.Text = string.Empty;
+ _args = string.Empty;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.xaml b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.xaml
new file mode 100644
index 000000000..66b489294
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow.xaml
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Memory: [empty]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo3.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo3.cs
new file mode 100644
index 000000000..5429496dd
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo3.cs
@@ -0,0 +1,71 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Windows;
+using System.Windows.Interop;
+
+using Microsoft.UI;
+using Microsoft.UI.Windowing;
+
+// Demo3_Step2_AddCompact
+namespace CalculatorDemo
+{
+ public sealed partial class MainWindow : Window
+ {
+ private AppWindow _appWindow;
+
+ private void CompactView_Click(object sender, RoutedEventArgs e)
+ {
+ SetCompactView(true);
+ }
+
+ private void ExitCompactViewButton_Click(object sender, RoutedEventArgs e)
+ {
+ SetCompactView(false);
+ }
+
+ void SetCompactView(bool useCompactView)
+ {
+ // Ensure we have an AppWindow for this WPF Window.
+ if (_appWindow == null)
+ {
+ _appWindow = AppWindow.GetFromWindowId(
+ new WindowId((ulong)new WindowInteropHelper(this).Handle));
+ }
+
+ if (useCompactView)
+ {
+ // For compact view, hide the main panel and show the compact panel.
+ MyPanel.Visibility = Visibility.Collapsed;
+ CompactPanel.Visibility = Visibility.Visible;
+
+ CompactViewText.Text = DisplayBox.Text;
+
+ if (!_registeredEventHandler)
+ {
+ DisplayBox.TextChanged += DisplayBox_TextChanged;
+ _registeredEventHandler = true;
+ }
+
+ // The AppWindow's CompactOverlay mode will make it always-on-top.
+ _appWindow.SetPresenter(AppWindowPresenterKind.CompactOverlay);
+ _appWindow.ResizeClient(new Windows.Graphics.SizeInt32(400, 400));
+ }
+ else
+ {
+ MyPanel.Visibility = Visibility.Visible;
+ CompactPanel.Visibility = Visibility.Collapsed;
+
+ _appWindow.SetPresenter(AppWindowPresenterKind.Default);
+ }
+ }
+
+ private void DisplayBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
+ {
+ CompactViewText.Text = DisplayBox.Text;
+ }
+
+ bool _registeredEventHandler = false;
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo4.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo4.cs
new file mode 100644
index 000000000..3a9cc46db
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/MainWindow_Demo4.cs
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Windows;
+using CommunityToolkit.WinAppSDK.LottieIsland;
+
+// Demo4_Step1_MainWindow
+namespace CalculatorDemo
+{
+ public sealed partial class MainWindow : Window
+ {
+ private Microsoft.UI.Composition.Compositor _compositor = new();
+
+ private void CreateLottieIslandMenuItem_Click(object sender, RoutedEventArgs e)
+ {
+ var wpfIslandHost = new WpfIslandHost(_compositor);
+ var lottieContentIsland = LottieIslandScenario.CreateLottieIsland(_compositor);
+
+ DisplayAreaBorder.Child = wpfIslandHost;
+ wpfIslandHost.DesktopChildSiteBridge.Connect(lottieContentIsland.Island);
+ }
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/MyTextBox.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/MyTextBox.cs
new file mode 100644
index 000000000..f42222459
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/MyTextBox.cs
@@ -0,0 +1,17 @@
+// // Copyright (c) Microsoft. All rights reserved.
+// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace CalculatorDemo
+{
+ internal sealed class MyTextBox : TextBox
+ {
+ protected override void OnPreviewGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
+ {
+ e.Handled = true;
+ base.OnPreviewGotKeyboardFocus(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/AssemblyInfo.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..5dcea412b
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/AssemblyInfo.cs
@@ -0,0 +1,59 @@
+// // Copyright (c) Microsoft. All rights reserved.
+// // Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyTitle("CalculatorDemo")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("CalculatorDemo")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//CultureYouAreCodingWith in your .csproj file
+//inside a . For example, if you are using US english
+//in your source files, set the to en-US. Then uncomment
+//the NeutralResourceLanguage attribute below. Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+ )]
+
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.Designer.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.Designer.cs
new file mode 100644
index 000000000..66e92c0be
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace CalculatorDemo.Properties
+{
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CalculatorDemo.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.resx b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.resx
new file mode 100644
index 000000000..af7dbebba
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.Designer.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.Designer.cs
new file mode 100644
index 000000000..0610885f1
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace CalculatorDemo.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.settings b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.settings
new file mode 100644
index 000000000..c14891b94
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/Properties/Settings.settings
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/WpfIslandHost.cs b/Samples/Islands/WpfCalculator/CalculatorDemo/WpfIslandHost.cs
new file mode 100644
index 000000000..bae53d3fb
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/WpfIslandHost.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Windows.Interop;
+
+using Microsoft.UI;
+using Microsoft.UI.Composition;
+using Microsoft.UI.Content;
+
+// Demo4_Step1_IslandHost
+namespace CalculatorDemo
+{
+ internal class WpfIslandHost : HwndHost
+ {
+ public WpfIslandHost(Compositor compositor)
+ {
+ _compositor = compositor;
+ }
+
+ public DesktopChildSiteBridge DesktopChildSiteBridge { get; private set; }
+
+ protected override HandleRef BuildWindowCore(HandleRef hwndParent)
+ {
+ DesktopChildSiteBridge = Microsoft.UI.Content.DesktopChildSiteBridge.Create(
+ _compositor,
+ new Microsoft.UI.WindowId((ulong)hwndParent.Handle));
+
+ // Mark as a layered window to handle transparent HWND with WPF.
+ var hwndChild = Win32Interop.GetWindowFromWindowId(DesktopChildSiteBridge.WindowId);
+ int prevExStyleFlags = GetWindowLong(hwndChild, GWL_EXSTYLE);
+ SetWindowLongPtr(
+ hwndChild,
+ GWL_EXSTYLE,
+ new IntPtr(prevExStyleFlags | WS_EX_LAYERED));
+
+ return new HandleRef(null, (nint)DesktopChildSiteBridge.WindowId.Value);
+ }
+
+ protected override void DestroyWindowCore(HandleRef hwnd)
+ {
+ DesktopChildSiteBridge.Dispose();
+ DesktopChildSiteBridge = null;
+ }
+
+ Microsoft.UI.Composition.Compositor _compositor;
+
+#region P/Invokes
+
+ const int GWL_EXSTYLE = -20;
+ const int WS_EX_LAYERED = 0x00080000;
+
+ [DllImport("user32.dll")]
+ static extern int GetWindowLong(
+ IntPtr hwnd,
+ int index);
+
+ [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetWindowLongPtr(
+ IntPtr hWnd,
+ int nIndex,
+ IntPtr dwNewLong);
+
+#endregion
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/app.manifest b/Samples/Islands/WpfCalculator/CalculatorDemo/app.manifest
new file mode 100644
index 000000000..f78afe4b5
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemo/app.manifest
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ true
+ PerMonitorV2
+
+
+
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemo/appicon.ico b/Samples/Islands/WpfCalculator/CalculatorDemo/appicon.ico
new file mode 100644
index 000000000..2cec3ddd0
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemo/appicon.ico differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/LottieLogo1.json b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/LottieLogo1.json
new file mode 100644
index 000000000..cb637e3ea
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/LottieLogo1.json
@@ -0,0 +1,7390 @@
+{
+ "assets": [],
+ "layers": [
+ {
+ "ddd": 0,
+ "ind": 0,
+ "ty": 1,
+ "nm": "MASTER",
+ "ks": {
+ "o": { "k": 0 },
+ "r": { "k": 0 },
+ "p": { "k": [ 214.457, 347.822, 0 ] },
+ "a": { "k": [ 60, 60, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "sw": 120,
+ "sh": 120,
+ "sc": "#ffffff",
+ "ip": 12,
+ "op": 179,
+ "st": 0,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 1,
+ "ty": 4,
+ "nm": "S5-Y 4",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": -89.1 },
+ "p": { "k": [ 53.205, 131.606, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 142.038, 29.278 ],
+ [ 131.282, 21.807 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 87 ],
+ "e": [ 50.633 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 50.633 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 100 ],
+ "e": [ 75.856 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 75.856 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 76,
+ "op": 84,
+ "st": 40,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 2,
+ "ty": 4,
+ "nm": "S4-Y 4",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": -89.1 },
+ "p": { "k": [ 53.205, 131.606, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 142.183, -5.112 ],
+ [ 130.029, 5.016 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 87 ],
+ "e": [ 43.833 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 43.833 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 76,
+ "op": 84,
+ "st": 40,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 3,
+ "ty": 4,
+ "nm": "S3-Y 4",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": -89.1 },
+ "p": { "k": [ 53.205, 131.606, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 147.699, 13.025 ],
+ [ 133.195, 13.21 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 87 ],
+ "e": [ 42.133 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 42.133 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 76,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 79,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 83 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 76,
+ "op": 84,
+ "st": 40,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 4,
+ "ty": 4,
+ "nm": "S5-Y 3",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 97.9 },
+ "p": { "k": [ 58.205, -39.394, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 145.677, 22.22 ],
+ [ 134.922, 14.749 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 87 ],
+ "e": [ 50.633 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 50.633 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 100 ],
+ "e": [ 75.856 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 75.856 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 75,
+ "op": 83,
+ "st": 39,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 5,
+ "ty": 4,
+ "nm": "S4-Y 3",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 97.9 },
+ "p": { "k": [ 58.205, -39.394, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 144.429, -5.397 ],
+ [ 132.275, 4.731 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 87 ],
+ "e": [ 43.833 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 43.833 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 75,
+ "op": 83,
+ "st": 39,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 6,
+ "ty": 4,
+ "nm": "S3-Y 3",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 97.9 },
+ "p": { "k": [ 58.205, -39.394, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 149.624, 8.244 ],
+ [ 136.648, 10.156 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 87 ],
+ "e": [ 42.133 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 42.133 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 75,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 78,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 75,
+ "op": 83,
+ "st": 39,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 7,
+ "ty": 4,
+ "nm": "S13",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 128, 3.65 ],
+ [ 78.25, 3.5 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 85,
+ "s": [ 87 ],
+ "e": [ 21.233 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 90,
+ "s": [ 21.233 ],
+ "e": [ 0 ]
+ },
+ { "t": 94 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 85,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 90,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 94 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 85,
+ "op": 95,
+ "st": 49,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 8,
+ "ty": 4,
+ "nm": "S12",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 119.25, -20.05 ],
+ [ 63.5, -20.5 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 84,
+ "s": [ 87 ],
+ "e": [ 21.233 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 87,
+ "s": [ 21.233 ],
+ "e": [ 0 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 84,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 87,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 84,
+ "op": 94,
+ "st": 48,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 9,
+ "ty": 4,
+ "nm": "S11",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 119.5, -45.05 ],
+ [ 82.75, -44.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 80,
+ "s": [ 87 ],
+ "e": [ 21.233 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 83,
+ "s": [ 21.233 ],
+ "e": [ 0 ]
+ },
+ { "t": 87 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 80,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 83,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 87 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 80,
+ "op": 90,
+ "st": 44,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 10,
+ "ty": 4,
+ "nm": "S5-Y 2",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 169.5, 18.073 ],
+ [ 137.481, 11.365 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 87 ],
+ "e": [ 50.633 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 50.633 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 100 ],
+ "e": [ 75.856 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 75.856 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 97,
+ "op": 107,
+ "st": 61,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 11,
+ "ty": 4,
+ "nm": "S4-Y 2",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 156.45, -23.05 ],
+ [ 132, 2.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 87 ],
+ "e": [ 43.833 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 43.833 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 97,
+ "op": 107,
+ "st": 61,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 12,
+ "ty": 4,
+ "nm": "S3-Y 2",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 166.731, -7.927 ],
+ [ 136.731, 7.115 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 87 ],
+ "e": [ 42.133 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 42.133 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 97,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 100,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 107 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 97,
+ "op": 107,
+ "st": 61,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 13,
+ "ty": 4,
+ "nm": "S6-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -87.5, 20.95 ],
+ [ -48.75, 54.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 87 ],
+ "e": [ 43.933 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 43.933 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 100 ],
+ "e": [ 70.456 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 70.456 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 54,
+ "op": 64,
+ "st": 18,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 14,
+ "ty": 4,
+ "nm": "S5-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -94.5, 37.073 ],
+ [ -48.769, 55.365 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 87 ],
+ "e": [ 50.633 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 50.633 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 100 ],
+ "e": [ 75.856 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 75.856 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 54,
+ "op": 64,
+ "st": 18,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 15,
+ "ty": 4,
+ "nm": "S4-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 7.45, 21.95 ],
+ [ -32.75, 55.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 87 ],
+ "e": [ 43.833 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 43.833 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 54,
+ "op": 64,
+ "st": 18,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 16,
+ "ty": 4,
+ "nm": "S3-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 16.231, 39.073 ],
+ [ -32.769, 57.365 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 87 ],
+ "e": [ 42.133 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 42.133 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 57,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 64 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 2 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 54,
+ "op": 64,
+ "st": 18,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 17,
+ "ty": 4,
+ "nm": "S8",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ -0.148, 14.256 ],
+ [ 10.476, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ -8.551, -8.263 ],
+ [ -21.454, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -3, 35.95 ],
+ [ -1.352, -6.756 ],
+ [ -32.046, -20.579 ],
+ [ -42.25, 4.25 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 65,
+ "s": [ 87 ],
+ "e": [ 21.233 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 21.233 ],
+ "e": [ 0 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 65,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 65,
+ "op": 75,
+ "st": 29,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 18,
+ "ty": 4,
+ "nm": "S7",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 27, 1.45 ],
+ [ 31.046, -1.421 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ -27, -1.45 ],
+ [ -26.426, 1.21 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 34.5, -13.05 ],
+ [ -35.046, -35.579 ],
+ [ -62.25, -5.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 65,
+ "s": [ 87 ],
+ "e": [ 21.233 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 21.233 ],
+ "e": [ 0 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 65,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 65,
+ "op": 75,
+ "st": 29,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 19,
+ "ty": 4,
+ "nm": "S2-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 1.9, -10.768 ],
+ [ 1, -19 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ -3.167, 17.951 ],
+ [ -1, 19 ]
+ ],
+ "v": [
+ [ -67.25, -105.5 ],
+ [ -72.333, -84.201 ],
+ [ -76.5, -37.75 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 29,
+ "s": [ 87 ],
+ "e": [ 25.333 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 33,
+ "s": [ 25.333 ],
+ "e": [ 0 ]
+ },
+ { "t": 36 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 29,
+ "s": [ 100 ],
+ "e": [ 69.056 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 33,
+ "s": [ 69.056 ],
+ "e": [ 0 ]
+ },
+ { "t": 36 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 30,
+ "op": 37,
+ "st": -7,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 20,
+ "ty": 4,
+ "nm": "S1-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 25.043, 45.678, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 1.9, -10.768 ],
+ [ 1, -19 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ -3.167, 17.951 ],
+ [ -1, 19 ]
+ ],
+ "v": [
+ [ -67.125, -112 ],
+ [ -75.458, -89.951 ],
+ [ -80.375, -39.25 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 29,
+ "s": [ 87 ],
+ "e": [ 37.533 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 33,
+ "s": [ 37.533 ],
+ "e": [ 0 ]
+ },
+ { "t": 36 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 29,
+ "s": [ 100 ],
+ "e": [ 66.356 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 33,
+ "s": [ 66.356 ],
+ "e": [ 0 ]
+ },
+ { "t": 36 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 1.5 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1"
+ }
+ ],
+ "ip": 30,
+ "op": 37,
+ "st": -7,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 21,
+ "ty": 4,
+ "nm": "Dot1",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.823,
+ "y": 0
+ },
+ "n": "0p833_0p833_0p823_0",
+ "t": -3,
+ "s": [ 295.771, 108.994, 0 ],
+ "e": [ 35.771, 108.994, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 16 }
+ ]
+ },
+ "a": { "k": [ 196.791, 266.504, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "d": 1,
+ "ty": "el",
+ "s": { "k": [ 9.4, 9.4 ] },
+ "p": { "k": [ 0.8, -0.5 ] },
+ "nm": "Ellipse Path 1"
+ },
+ {
+ "ty": "fl",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "nm": "Fill 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 196, 267 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Ellipse 1"
+ }
+ ],
+ "ip": -5,
+ "op": 17,
+ "st": -36,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 22,
+ "ty": 4,
+ "nm": "L-B",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 25.671, -4.167 ],
+ [ 1.456, 6.902 ],
+ [ -8.481, 1.863 ],
+ [ -47.562, 13.01 ],
+ [ -0.501, 0.133 ],
+ [ -71.423, -2.315 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ -8.224, 1.335 ],
+ [ -1.456, -6.903 ],
+ [ 23.817, -5.233 ],
+ [ 0.16, -0.044 ],
+ [ 0.501, -0.133 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -8.837, -58.229 ],
+ [ -35.834, 33.662 ],
+ [ -51.688, 23.148 ],
+ [ -41.174, 7.293 ],
+ [ 51.797, 44.178 ],
+ [ 53.188, 43.741 ],
+ [ 140.394, 43.672 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 166.029, 270.643 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 8"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.703 ],
+ "y": [ 0.821 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p703_0p821_0p167_0p167" ],
+ "t": 18,
+ "s": [ 80 ],
+ "e": [ 50 ]
+ },
+ {
+ "i": {
+ "x": [ 0.263 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.037 ],
+ "y": [ 0.168 ]
+ },
+ "n": [ "0p263_1_0p037_0p168" ],
+ "t": 23,
+ "s": [ 50 ],
+ "e": [ 30 ]
+ },
+ { "t": 55 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.337 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p337_1_0p167_0p167" ],
+ "t": 18,
+ "s": [ 81 ],
+ "e": [ 73.4 ]
+ },
+ { "t": 29 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ }
+ ],
+ "ip": 18,
+ "op": 179,
+ "st": 8,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 23,
+ "ty": 4,
+ "nm": "L-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 25.671, -4.167 ],
+ [ 1.456, 6.902 ],
+ [ -8.481, 1.863 ],
+ [ -47.562, 13.01 ],
+ [ -0.501, 0.133 ],
+ [ -71.423, -2.315 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ -8.224, 1.335 ],
+ [ -1.456, -6.903 ],
+ [ 23.817, -5.233 ],
+ [ 0.16, -0.044 ],
+ [ 0.501, -0.133 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -8.837, -58.229 ],
+ [ -35.834, 33.662 ],
+ [ -51.688, 23.148 ],
+ [ -41.174, 7.293 ],
+ [ 51.797, 44.178 ],
+ [ 53.188, 43.741 ],
+ [ 140.394, 43.672 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 166.029, 270.643 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 8"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.703 ],
+ "y": [ 0.857 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p703_0p857_0p167_0p167" ],
+ "t": 16,
+ "s": [ 80 ],
+ "e": [ 50 ]
+ },
+ {
+ "i": {
+ "x": [ 0.938 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.333 ],
+ "y": [ 0.202 ]
+ },
+ "n": [ "0p938_1_0p333_0p202" ],
+ "t": 20,
+ "s": [ 50 ],
+ "e": [ 0 ]
+ },
+ { "t": 28 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.337 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p337_1_0p167_0p167" ],
+ "t": 16,
+ "s": [ 81 ],
+ "e": [ 73.4 ]
+ },
+ { "t": 27 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ }
+ ],
+ "ip": 16,
+ "op": 179,
+ "st": 8,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 24,
+ "ty": 1,
+ "nm": "N",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 0 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.26,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p26_1_0p167_0p167",
+ "t": 28,
+ "s": [ -33.667, 8.182, 0 ],
+ "e": [ -33.667, -72.818, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.74,
+ "y": 0
+ },
+ "n": "0p833_0p833_0p74_0",
+ "t": 40,
+ "s": [ -33.667, -72.818, 0 ],
+ "e": [ -33.667, 102.057, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 54 }
+ ]
+ },
+ "a": { "k": [ 60, 60, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "sw": 120,
+ "sh": 120,
+ "sc": "#ffffff",
+ "ip": 28,
+ "op": 54,
+ "st": 0,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 25,
+ "ty": 4,
+ "nm": "Dot-Y",
+ "parent": 24,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p833_0p833_0p167_0p167",
+ "t": 28,
+ "s": [ 39.875, 60, 0 ],
+ "e": [ 79.375, 60, 0 ],
+ "to": [ 6.58333349227905, 0, 0 ],
+ "ti": [ -6.58333349227905, 0, 0 ]
+ },
+ { "t": 54 }
+ ]
+ },
+ "a": { "k": [ 196.791, 266.504, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "d": 1,
+ "ty": "el",
+ "s": { "k": [ 9.4, 9.4 ] },
+ "p": { "k": [ 0.8, -0.5 ] },
+ "nm": "Ellipse Path 1"
+ },
+ {
+ "ty": "fl",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "nm": "Fill 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 196, 267 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Ellipse 1"
+ }
+ ],
+ "ip": 28,
+ "op": 54,
+ "st": 4,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 26,
+ "ty": 4,
+ "nm": "T1a-B",
+ "parent": 36,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 250, 250, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ -0.5, 9.501 ],
+ [ -0.048, 5.655 ],
+ [ 0.054, 0.06 ],
+ [ 0.946, 1.486 ],
+ [ -9.967, 8.05 ],
+ [ -40.546, 0 ]
+ ],
+ "o": [
+ [ 0.031, -0.594 ],
+ [ 0.076, -8.978 ],
+ [ -1.161, -1.3 ],
+ [ -5.939, -9.327 ],
+ [ 24.677, -19.929 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -30.72, 63.761 ],
+ [ -30.741, 45.192 ],
+ [ -37.397, 27.014 ],
+ [ -40.698, 22.661 ],
+ [ -37.873, -7.117 ],
+ [ 49.506, 11.559 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": 24.9,
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.673 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p673_1_0p167_0p167" ],
+ "t": 70,
+ "s": [ 24.9 ],
+ "e": [ 89.1 ]
+ },
+ { "t": 84 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 227.677, 234.375 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 9"
+ }
+ ],
+ "ip": 70,
+ "op": 179,
+ "st": 17,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 27,
+ "ty": 4,
+ "nm": "T2a-B",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 1.681, -29.992 ],
+ [ -1.681, 29.992 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.06 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p06_1_0p167_0p167" ],
+ "t": 75,
+ "s": [ 50 ],
+ "e": [ 0 ]
+ },
+ { "t": 85 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.06 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p06_1_0p167_0p167" ],
+ "t": 75,
+ "s": [ 50 ],
+ "e": [ 100 ]
+ },
+ { "t": 85 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 3,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 277.698, 247.258 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 7"
+ }
+ ],
+ "ip": 75,
+ "op": 179,
+ "st": 15,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 28,
+ "ty": 4,
+ "nm": "T1a-Y 2",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.667,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p667_1_0p167_0p167",
+ "t": 56,
+ "s": [ 39.043, 48.678, 0 ],
+ "e": [ 39.043, 45.678, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 64 }
+ ]
+ },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ -0.5, 9.501 ],
+ [ -0.048, 5.655 ],
+ [ 0.054, 0.06 ],
+ [ 0.946, 1.486 ],
+ [ -9.967, 8.05 ],
+ [ -40.546, 0 ]
+ ],
+ "o": [
+ [ 0.031, -0.594 ],
+ [ 0.076, -8.978 ],
+ [ -1.161, -1.3 ],
+ [ -5.939, -9.327 ],
+ [ 24.677, -19.929 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -30.72, 63.761 ],
+ [ -30.741, 45.192 ],
+ [ -37.397, 27.014 ],
+ [ -40.698, 22.661 ],
+ [ -37.873, -7.117 ],
+ [ 49.506, 11.559 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.301 ],
+ "y": [ 0 ]
+ },
+ "n": [ "0p833_1_0p301_0" ],
+ "t": 54,
+ "s": [ 0 ],
+ "e": [ 24.9 ]
+ },
+ { "t": 70 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.667 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.301 ],
+ "y": [ 0 ]
+ },
+ "n": [ "0p667_1_0p301_0" ],
+ "t": 54,
+ "s": [ 0 ],
+ "e": [ 100 ]
+ },
+ { "t": 78 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 227.677, 234.375 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 9"
+ }
+ ],
+ "ip": 59,
+ "op": 179,
+ "st": 12,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 29,
+ "ty": 4,
+ "nm": "O-B",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p833_0p833_0p167_0p167",
+ "t": 31,
+ "s": [ -62.792, 73.057, 0 ],
+ "e": [ -53.792, 7.557, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.638,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.198
+ },
+ "n": "0p638_1_0p167_0p198",
+ "t": 35.257,
+ "s": [ -53.792, 7.557, 0 ],
+ "e": [ -33.667, -72.818, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ -19.1562919616699, 1.73831975460052, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.795,
+ "y": 1
+ },
+ "o": {
+ "x": 0.523,
+ "y": 0
+ },
+ "n": "0p795_1_0p523_0",
+ "t": 44,
+ "s": [ -33.667, -72.818, 0 ],
+ "e": [ -14.167, 102.182, 0 ],
+ "to": [ 16.2075271606445, -1.47073686122894, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.348,
+ "y": 1
+ },
+ "o": {
+ "x": 0.18,
+ "y": 0
+ },
+ "n": "0p348_1_0p18_0",
+ "t": 54,
+ "s": [ -14.167, 102.182, 0 ],
+ "e": [ -14.167, 59.182, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.27,
+ "y": 1
+ },
+ "o": {
+ "x": 0.693,
+ "y": 0
+ },
+ "n": "0p27_1_0p693_0",
+ "t": 63,
+ "s": [ -14.167, 59.182, 0 ],
+ "e": [ -14.167, 62.182, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 73 }
+ ]
+ },
+ "a": { "k": [ 196.791, 266.504, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "d": 1,
+ "ty": "el",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.667, 0.667 ],
+ "y": [ 1, 1 ]
+ },
+ "o": {
+ "x": [ 0.333, 0.333 ],
+ "y": [ 0, 0 ]
+ },
+ "n": [ "0p667_1_0p333_0", "0p667_1_0p333_0" ],
+ "t": 54,
+ "s": [ 3, 3 ],
+ "e": [ 44.6, 44.6 ]
+ },
+ { "t": 61 }
+ ]
+ },
+ "p": { "k": [ 0.8, -0.5 ] },
+ "nm": "Ellipse Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 196, 267 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Ellipse 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 0 ],
+ "e": [ 30 ]
+ },
+ {
+ "i": {
+ "x": [ 0.432 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 1.124 ]
+ },
+ "n": [ "0p432_1_0p167_1p124" ],
+ "t": 63,
+ "s": [ 30 ],
+ "e": [ 39.9 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 54,
+ "s": [ 100 ],
+ "e": [ 88 ]
+ },
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 63,
+ "s": [ 88 ],
+ "e": [ 88 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ }
+ ],
+ "ip": 54,
+ "op": 179,
+ "st": 4,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 30,
+ "ty": 4,
+ "nm": "O-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p833_0p833_0p167_0p167",
+ "t": 31,
+ "s": [ -62.792, 73.057, 0 ],
+ "e": [ -53.792, 7.557, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.638,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.198
+ },
+ "n": "0p638_1_0p167_0p198",
+ "t": 35.257,
+ "s": [ -53.792, 7.557, 0 ],
+ "e": [ -33.667, -72.818, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ -19.1562919616699, 1.73831975460052, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.795,
+ "y": 1
+ },
+ "o": {
+ "x": 0.523,
+ "y": 0
+ },
+ "n": "0p795_1_0p523_0",
+ "t": 44,
+ "s": [ -33.667, -72.818, 0 ],
+ "e": [ -14.167, 102.182, 0 ],
+ "to": [ 16.2075271606445, -1.47073686122894, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.348,
+ "y": 1
+ },
+ "o": {
+ "x": 0.18,
+ "y": 0
+ },
+ "n": "0p348_1_0p18_0",
+ "t": 54,
+ "s": [ -14.167, 102.182, 0 ],
+ "e": [ -14.167, 59.182, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.27,
+ "y": 1
+ },
+ "o": {
+ "x": 0.693,
+ "y": 0
+ },
+ "n": "0p27_1_0p693_0",
+ "t": 63,
+ "s": [ -14.167, 59.182, 0 ],
+ "e": [ -14.167, 62.182, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 73 }
+ ]
+ },
+ "a": { "k": [ 196.791, 266.504, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "d": 1,
+ "ty": "el",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.667, 0.667 ],
+ "y": [ 1, 1 ]
+ },
+ "o": {
+ "x": [ 0.333, 0.333 ],
+ "y": [ 0, 0 ]
+ },
+ "n": [ "0p667_1_0p333_0", "0p667_1_0p333_0" ],
+ "t": 54,
+ "s": [ 3, 3 ],
+ "e": [ 44.6, 44.6 ]
+ },
+ { "t": 61 }
+ ]
+ },
+ "p": { "k": [ 0.8, -0.5 ] },
+ "nm": "Ellipse Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.8 },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 196, 267 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Ellipse 1"
+ }
+ ],
+ "ip": 54,
+ "op": 179,
+ "st": 4,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 31,
+ "ty": 4,
+ "nm": "T1b-B",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 1.768, -25.966 ],
+ [ -1.768, 25.966 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": 0,
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.21 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p21_1_0p167_0p167" ],
+ "t": 81,
+ "s": [ 11.7 ],
+ "e": [ 100 ]
+ },
+ { "t": 88 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 2,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 242.756, 265.581 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 10"
+ }
+ ],
+ "ip": 81,
+ "op": 179,
+ "st": 26,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 32,
+ "ty": 4,
+ "nm": "T1b-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 1.768, -25.966 ],
+ [ -1.768, 25.966 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 70,
+ "s": [ 11.7 ],
+ "e": [ 100 ]
+ },
+ { "t": 75 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 2,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 242.756, 265.581 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 10"
+ }
+ ],
+ "ip": 70,
+ "op": 161,
+ "st": 15,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 33,
+ "ty": 4,
+ "nm": "T2b-B",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 246.65, 213.814 ],
+ [ 340.956, 213.628 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 82,
+ "s": [ 29 ],
+ "e": [ 0 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 82,
+ "s": [ 41.1 ],
+ "e": [ 66.5 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 5"
+ }
+ ],
+ "ip": 82,
+ "op": 179,
+ "st": -17,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 34,
+ "ty": 4,
+ "nm": "T2a-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 1.681, -29.992 ],
+ [ -1.681, 29.992 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.06 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p06_1_0p167_0p167" ],
+ "t": 72,
+ "s": [ 50 ],
+ "e": [ 0 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.06 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p06_1_0p167_0p167" ],
+ "t": 72,
+ "s": [ 50 ],
+ "e": [ 100 ]
+ },
+ { "t": 82 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 3,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 277.698, 247.258 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 7"
+ }
+ ],
+ "ip": 72,
+ "op": 89,
+ "st": 12,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 35,
+ "ty": 4,
+ "nm": "T2b-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 39.043, 45.678, 0 ] },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 246.65, 213.814 ],
+ [ 340.956, 213.628 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 76,
+ "s": [ 29 ],
+ "e": [ 0 ]
+ },
+ { "t": 85 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 76,
+ "s": [ 41.1 ],
+ "e": [ 66.5 ]
+ },
+ { "t": 85 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 5"
+ }
+ ],
+ "ip": 76,
+ "op": 92,
+ "st": -23,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 36,
+ "ty": 4,
+ "nm": "T1a-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.667,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p667_1_0p167_0p167",
+ "t": 56,
+ "s": [ 39.043, 48.678, 0 ],
+ "e": [ 39.043, 45.678, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 64 }
+ ]
+ },
+ "a": { "k": [ 250, 250, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ -0.5, 9.501 ],
+ [ -0.048, 5.655 ],
+ [ 0.054, 0.06 ],
+ [ 0.946, 1.486 ],
+ [ -9.967, 8.05 ],
+ [ -40.546, 0 ]
+ ],
+ "o": [
+ [ 0.031, -0.594 ],
+ [ 0.076, -8.978 ],
+ [ -1.161, -1.3 ],
+ [ -5.939, -9.327 ],
+ [ 24.677, -19.929 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -30.72, 63.761 ],
+ [ -30.741, 45.192 ],
+ [ -37.397, 27.014 ],
+ [ -40.698, 22.661 ],
+ [ -37.873, -7.117 ],
+ [ 49.506, 11.559 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.301 ],
+ "y": [ 0 ]
+ },
+ "n": [ "0p833_1_0p301_0" ],
+ "t": 54,
+ "s": [ 0 ],
+ "e": [ 24.9 ]
+ },
+ { "t": 70 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.667 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.301 ],
+ "y": [ 0 ]
+ },
+ "n": [ "0p667_1_0p301_0" ],
+ "t": 54,
+ "s": [ 0 ],
+ "e": [ 100 ]
+ },
+ { "t": 74 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 227.677, 234.375 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 9"
+ }
+ ],
+ "ip": 59,
+ "op": 156,
+ "st": 12,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 37,
+ "ty": 4,
+ "nm": "E1-B",
+ "parent": 38,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 344.672, 214.842, 0 ] },
+ "a": { "k": [ 344.672, 214.842, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -13.664, -0.145 ],
+ [ 62.163, 0.29 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.562 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 344.672, 214.842 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 2"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 84,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 93 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 84,
+ "s": [ 0 ],
+ "e": [ 37.5 ]
+ },
+ { "t": 93 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ }
+ ],
+ "ip": 84,
+ "op": 179,
+ "st": 84,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 38,
+ "ty": 4,
+ "nm": "E1-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.12,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p12_1_0p167_0p167",
+ "t": 79,
+ "s": [ 113.715, 9.146, 0 ],
+ "e": [ 137.715, 9.146, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.12,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "n": "0p12_1_0p167_0",
+ "t": 88,
+ "s": [ 137.715, 9.146, 0 ],
+ "e": [ 133.715, 9.146, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 92 }
+ ]
+ },
+ "a": { "k": [ 344.672, 214.842, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -13.664, -0.145 ],
+ [ 62.163, 0.29 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 344.672, 214.842 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 2"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 79,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 88 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 79,
+ "s": [ 0 ],
+ "e": [ 37.5 ]
+ },
+ { "t": 88 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ }
+ ],
+ "ip": 79,
+ "op": 94,
+ "st": 79,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 39,
+ "ty": 4,
+ "nm": "E2-B",
+ "parent": 40,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 332.05, 237.932, 0 ] },
+ "a": { "k": [ 332.05, 237.932, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -26.67, -0.283 ],
+ [ 99.171, 0.066 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 86,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 95 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 86,
+ "s": [ 0 ],
+ "e": [ 43 ]
+ },
+ { "t": 95 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.562 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 331.664, 238.14 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 3"
+ }
+ ],
+ "ip": 86,
+ "op": 179,
+ "st": 86,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 40,
+ "ty": 4,
+ "nm": "E2-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.12,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p12_1_0p167_0p167",
+ "t": 83,
+ "s": [ 109.092, 33.61, 0 ],
+ "e": [ 121.092, 33.61, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.12,
+ "y": 0.12
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p12_0p12_0p167_0p167",
+ "t": 92,
+ "s": [ 121.092, 33.61, 0 ],
+ "e": [ 121.092, 33.61, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 96 }
+ ]
+ },
+ "a": { "k": [ 332.05, 237.932, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -26.67, -0.283 ],
+ [ 99.171, 0.066 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 83,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 92 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 83,
+ "s": [ 0 ],
+ "e": [ 43 ]
+ },
+ { "t": 92 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 331.664, 238.14 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 3"
+ }
+ ],
+ "ip": 83,
+ "op": 96,
+ "st": 83,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 41,
+ "ty": 4,
+ "nm": "I-B",
+ "parent": 42,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 303.802, 282.182, 0 ] },
+ "a": { "k": [ 303.802, 282.182, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 0.859, -21.143 ],
+ [ -4.359, 70.392 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 81,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 81,
+ "s": [ 0 ],
+ "e": [ 45.7 ]
+ },
+ { "t": 91 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.194 },
+ "lc": 3,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 304.135, 282.409 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 6"
+ }
+ ],
+ "ip": 81,
+ "op": 179,
+ "st": 18,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 42,
+ "ty": 4,
+ "nm": "I-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.12,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p12_1_0p167_0p167",
+ "t": 78,
+ "s": [ 93.594, 62.861, 0 ],
+ "e": [ 92.626, 82.829, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.12,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "n": "0p12_1_0p167_0",
+ "t": 88,
+ "s": [ 92.626, 82.829, 0 ],
+ "e": [ 92.844, 77.861, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 92 }
+ ]
+ },
+ "a": { "k": [ 303.802, 282.182, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ 0.859, -21.143 ],
+ [ -4.359, 70.392 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 0.12 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_0p12_0p167_0p167" ],
+ "t": 78,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 88 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.12 ],
+ "y": [ 1 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p12_1_0p167_0p167" ],
+ "t": 78,
+ "s": [ 0 ],
+ "e": [ 45.7 ]
+ },
+ { "t": 88 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 1"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 8.4 },
+ "lc": 3,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 304.135, 282.409 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 6"
+ }
+ ],
+ "ip": 78,
+ "op": 93,
+ "st": 15,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 43,
+ "ty": 4,
+ "nm": "E3-B",
+ "parent": 44,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 345.189, 261.801, 0 ] },
+ "a": { "k": [ 345.124, 261.801, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -13.664, -0.145 ],
+ [ 75.663, 0.29 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 92,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 97 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 92,
+ "s": [ 0 ],
+ "e": [ 31.6 ]
+ },
+ { "t": 97 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 2"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.562 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 344.674, 261.877 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 1"
+ }
+ ],
+ "ip": 92,
+ "op": 179,
+ "st": 29,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 44,
+ "ty": 4,
+ "nm": "E3-Y",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.667,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p667_1_0p167_0p167",
+ "t": 84,
+ "s": [ 119.167, 57.479, 0 ],
+ "e": [ 137.167, 57.479, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.667,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "n": "0p667_1_0p167_0",
+ "t": 92,
+ "s": [ 137.167, 57.479, 0 ],
+ "e": [ 134.167, 57.479, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 96 }
+ ]
+ },
+ "a": { "k": [ 345.124, 261.801, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ks": {
+ "k": {
+ "i": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "o": [
+ [ 0, 0 ],
+ [ 0, 0 ]
+ ],
+ "v": [
+ [ -13.664, -0.145 ],
+ [ 75.663, 0.29 ]
+ ],
+ "c": false
+ }
+ },
+ "nm": "Path 1"
+ },
+ {
+ "ty": "tm",
+ "s": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 84,
+ "s": [ 0 ],
+ "e": [ 0 ]
+ },
+ { "t": 92 }
+ ],
+ "ix": 1
+ },
+ "e": {
+ "k": [
+ {
+ "i": {
+ "x": [ 0.833 ],
+ "y": [ 0.833 ]
+ },
+ "o": {
+ "x": [ 0.167 ],
+ "y": [ 0.167 ]
+ },
+ "n": [ "0p833_0p833_0p167_0p167" ],
+ "t": 84,
+ "s": [ 0 ],
+ "e": [ 31.6 ]
+ },
+ { "t": 92 }
+ ],
+ "ix": 2
+ },
+ "o": {
+ "k": 0,
+ "ix": 3
+ },
+ "m": 1,
+ "ix": 2,
+ "nm": "Trim Paths 2"
+ },
+ {
+ "ty": "st",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.48, 0.53, 1 ] },
+ "o": { "k": 100 },
+ "w": { "k": 9.562 },
+ "lc": 2,
+ "lj": 1,
+ "ml": 10,
+ "nm": "Stroke 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 344.674, 261.877 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 1"
+ }
+ ],
+ "ip": 84,
+ "op": 102,
+ "st": 21,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 45,
+ "ty": 4,
+ "nm": "Dot-Y",
+ "parent": 46,
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0,
+ "y": 0.812
+ },
+ "o": {
+ "x": 0,
+ "y": 0
+ },
+ "n": "0_0p812_0_0",
+ "t": 96,
+ "s": [ 43.263, 59.75, 0 ],
+ "e": [ 62.513, 59.75, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.708,
+ "y": 1
+ },
+ "o": {
+ "x": 0.39,
+ "y": 0.707
+ },
+ "n": "0p708_1_0p39_0p707",
+ "t": 108,
+ "s": [ 62.513, 59.75, 0 ],
+ "e": [ 63.763, 59.75, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 115 }
+ ]
+ },
+ "a": { "k": [ 196.791, 266.504, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "d": 1,
+ "ty": "el",
+ "s": { "k": [ 9.2, 9.2 ] },
+ "p": { "k": [ 0.8, -0.5 ] },
+ "nm": "Ellipse Path 1"
+ },
+ {
+ "ty": "fl",
+ "fillEnabled": true,
+ "c": { "k": [ 1, 1, 1, 1 ] },
+ "o": { "k": 100 },
+ "nm": "Fill 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 196, 267 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Ellipse 1"
+ }
+ ],
+ "ip": 96,
+ "op": 182,
+ "st": 65,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 46,
+ "ty": 1,
+ "nm": "Bncr",
+ "parent": 0,
+ "ks": {
+ "o": { "k": 0 },
+ "r": { "k": 0 },
+ "p": {
+ "k": [
+ {
+ "i": {
+ "x": 0.18,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p18_1_0p167_0p167",
+ "t": 96,
+ "s": [ 164.782, 57.473, 0 ],
+ "e": [ 164.782, 55.473, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.82,
+ "y": 0
+ },
+ "n": "0p833_0p833_0p82_0",
+ "t": 99,
+ "s": [ 164.782, 55.473, 0 ],
+ "e": [ 164.782, 57.473, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.18,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0.167
+ },
+ "n": "0p18_1_0p167_0p167",
+ "t": 102,
+ "s": [ 164.782, 57.473, 0 ],
+ "e": [ 164.782, 56.909, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 0.833
+ },
+ "o": {
+ "x": 0.82,
+ "y": 0
+ },
+ "n": "0p833_0p833_0p82_0",
+ "t": 105,
+ "s": [ 164.782, 56.909, 0 ],
+ "e": [ 164.782, 57.473, 0 ],
+ "to": [ 0, 0, 0 ],
+ "ti": [ 0, 0, 0 ]
+ },
+ { "t": 108 }
+ ]
+ },
+ "a": { "k": [ 60, 60, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "sw": 120,
+ "sh": 120,
+ "sc": "#ffffff",
+ "ip": 96,
+ "op": 182,
+ "st": 15,
+ "bm": 0,
+ "sr": 1
+ },
+ {
+ "ddd": 0,
+ "ind": 47,
+ "ty": 4,
+ "nm": "BG",
+ "ks": {
+ "o": { "k": 100 },
+ "r": { "k": 0 },
+ "p": { "k": [ 187.5, 333.5, 0 ] },
+ "a": { "k": [ 0, 0, 0 ] },
+ "s": { "k": [ 100, 100, 100 ] }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "rc",
+ "d": 1,
+ "s": { "k": [ 375, 667 ] },
+ "p": { "k": [ 0, 0 ] },
+ "r": { "k": 0 },
+ "nm": "Rectangle Path 1"
+ },
+ {
+ "ty": "fl",
+ "fillEnabled": true,
+ "c": { "k": [ 0, 0.82, 0.76, 1 ] },
+ "o": { "k": 100 },
+ "nm": "Fill 1"
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "k": [ 0, 0 ],
+ "ix": 2
+ },
+ "a": {
+ "k": [ 0, 0 ],
+ "ix": 1
+ },
+ "s": {
+ "k": [ 100, 100 ],
+ "ix": 3
+ },
+ "r": {
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Rectangle 1"
+ }
+ ],
+ "ip": 0,
+ "op": 179,
+ "st": 0,
+ "bm": 0,
+ "sr": 1
+ }
+ ],
+ "v": "4.4.26",
+ "ddd": 0,
+ "ip": 0,
+ "op": 179,
+ "fr": 30,
+ "w": 375,
+ "h": 667
+}
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet1.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet1.bmp
new file mode 100644
index 000000000..15d64855c
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet1.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet2.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet2.bmp
new file mode 100644
index 000000000..04874cb6e
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet2.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet3.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet3.bmp
new file mode 100644
index 000000000..94ca20a2d
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet3.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet4.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet4.bmp
new file mode 100644
index 000000000..419f62840
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet4.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet5.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet5.bmp
new file mode 100644
index 000000000..2de59e897
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet5.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet6.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet6.bin
new file mode 100644
index 000000000..fda322e3e
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet6.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet7.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet7.bin
new file mode 100644
index 000000000..bb4b8e255
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet7.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet8.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet8.bin
new file mode 100644
index 000000000..165a93c07
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet8.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet9.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet9.bin
new file mode 100644
index 000000000..a4f943700
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/DamagedHelmet9.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck1.bmp b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck1.bmp
new file mode 100644
index 000000000..9fa2dd4cc
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck1.bmp differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck2.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck2.bin
new file mode 100644
index 000000000..37815892d
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck2.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck3.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck3.bin
new file mode 100644
index 000000000..6304bfad0
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck3.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck4.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck4.bin
new file mode 100644
index 000000000..74e5472dc
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck4.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck5.bin b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck5.bin
new file mode 100644
index 000000000..81dc90c73
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Assets/SceneNode/Duck5.bin differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/CalculatorDemoPackage.wapproj b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/CalculatorDemoPackage.wapproj
new file mode 100644
index 000000000..5a0786b0f
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/CalculatorDemoPackage.wapproj
@@ -0,0 +1,78 @@
+
+
+
+ 15.0
+
+
+
+ Debug
+ x86
+
+
+ Release
+ x86
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+
+ $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\
+
+
+
+ 0a343519-113b-4ef9-959c-30f559524bc4
+ 10.0.22621.0
+ 10.0.17763.0
+ en-US
+ false
+ $(NoWarn);NU1702
+ ..\CalculatorDemo\CalculatorDemo.csproj
+ true
+
+ false
+ false
+
+
+
+ $(AssetTargetFallback);net9.0-windows$(TargetPlatformVersion)
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/LockScreenLogo.scale-200.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/LockScreenLogo.scale-200.png
new file mode 100644
index 000000000..735f57adb
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/LockScreenLogo.scale-200.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/SplashScreen.scale-200.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/SplashScreen.scale-200.png
new file mode 100644
index 000000000..023e7f1fe
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/SplashScreen.scale-200.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square150x150Logo.scale-200.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square150x150Logo.scale-200.png
new file mode 100644
index 000000000..af49fec1a
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square150x150Logo.scale-200.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.scale-200.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.scale-200.png
new file mode 100644
index 000000000..ce342a2ec
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.scale-200.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png
new file mode 100644
index 000000000..f6c02ce97
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/StoreLogo.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/StoreLogo.png
new file mode 100644
index 000000000..7385b56c0
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/StoreLogo.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Wide310x150Logo.scale-200.png b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Wide310x150Logo.scale-200.png
new file mode 100644
index 000000000..288995b39
Binary files /dev/null and b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Images/Wide310x150Logo.scale-200.png differ
diff --git a/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Package.appxmanifest b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Package.appxmanifest
new file mode 100644
index 000000000..95e932b9d
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/CalculatorDemoPackage/Package.appxmanifest
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ WpfCalculatorDemo
+ jecollin
+ Images\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationCallbackHandler.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationCallbackHandler.h
new file mode 100644
index 000000000..f61638cd1
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationCallbackHandler.h
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+namespace winrt::DrawingIslandComponents
+{
+ struct __declspec(novtable) IAutomationCallbackHandler
+ {
+ virtual ~IAutomationCallbackHandler() noexcept = default;
+
+ virtual winrt::Windows::Graphics::RectInt32 GetScreenBoundsForAutomationFragment(
+ _In_::IUnknown const* const sender) const = 0;
+
+ virtual winrt::com_ptr GetFragmentFromPoint(
+ _In_ double x,
+ _In_ double y) const = 0;
+
+ virtual winrt::com_ptr GetFragmentInFocus() const = 0;
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.cpp
new file mode 100644
index 000000000..83691aa66
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.cpp
@@ -0,0 +1,464 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "AutomationFragment.h"
+
+using unique_safearray =
+ wil::unique_any;
+
+namespace winrt::DrawingIslandComponents
+{
+ void AutomationFragment::AddChildToEnd(
+ _In_ winrt::com_ptr const& child)
+ {
+ std::unique_lock lock{ m_mutex };
+
+ if (nullptr == child)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ // The child should not already have a parent.
+ winrt::check_bool(nullptr == child->GetParent());
+
+ // Set us up as the parent for the new child.
+ child->SetParent(get_weak());
+
+ // Set up the sibling relationships.
+ if (!m_children.empty())
+ {
+ auto& previousSiblingForNewChild = m_children.back();
+ previousSiblingForNewChild->SetNextSibling(child);
+ child->SetPreviousSibling(previousSiblingForNewChild);
+ }
+
+ // Finally add the child.
+ m_children.push_back(child);
+ }
+
+ void AutomationFragment::RemoveChild(
+ _In_ winrt::com_ptr const& child)
+ {
+ std::unique_lock lock{ m_mutex };
+
+ if (nullptr == child)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ auto iterator = std::find_if(
+ m_children.begin(), m_children.end(), [&child](auto const& childEntry)
+ {
+ // See if we find a matching child entry in our children.
+ return (childEntry.get() == child.get());
+ });
+
+ // We cannot remove a child that isn't ours.
+ winrt::check_bool(m_children.end() != iterator);
+
+ // Remove us from the parent relationship with the child.
+ child->SetParent(nullptr);
+
+ // Reset the sibling relationships.
+ auto previousSibling = child->GetPreviousSibling();
+ auto nextSibling = child->GetNextSibling();
+ if (nullptr != previousSibling)
+ {
+ previousSibling->SetNextSibling(nextSibling);
+ }
+ if (nullptr != nextSibling)
+ {
+ nextSibling->SetPreviousSibling(previousSibling);
+ }
+ child->SetPreviousSibling(nullptr);
+ child->SetNextSibling(nullptr);
+
+ // Finally, remove the child.
+ m_children.erase(iterator);
+ }
+
+ void AutomationFragment::RemoveAllChildren()
+ {
+ std::unique_lock lock{ m_mutex };
+
+ for (auto& child : m_children)
+ {
+ // Disconnect the relationships from all our children.
+ child->SetParent(nullptr);
+ child->SetPreviousSibling(nullptr);
+ child->SetNextSibling(nullptr);
+ }
+
+ // Remove all the children.
+ m_children.clear();
+ }
+
+ void AutomationFragment::SetCallbackHandler(
+ _In_opt_ IAutomationCallbackHandler const* const owner)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_ownerNoRef = owner;
+ }
+
+ void AutomationFragment::SetProviderOptions(
+ _In_ ProviderOptions const& providerOptions)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_providerOptions = providerOptions;
+ }
+
+ void AutomationFragment::SetName(
+ _In_ std::wstring_view const& name)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_name = name;
+ }
+
+ void AutomationFragment::SetIsContent(
+ _In_ bool const& isContent)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_isContent = isContent;
+ }
+
+ void AutomationFragment::SetIsControl(
+ _In_ bool const& isControl)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_isControl = isControl;
+ }
+
+ void AutomationFragment::SetUiaControlTypeId(
+ _In_ long const& uiaControlTypeId)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_uiaControlTypeId = uiaControlTypeId;
+ }
+
+ void AutomationFragment::SetHostProvider(
+ _In_ winrt::com_ptr const& hostProvider)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_hostProvider = hostProvider;
+ }
+
+ HRESULT __stdcall AutomationFragment::get_ProviderOptions(
+ _Out_ ProviderOptions* providerOptions)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != providerOptions)
+ {
+ *providerOptions = m_providerOptions;
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::GetPatternProvider(
+ _In_ PATTERNID patternId,
+ _COM_Outptr_opt_result_maybenull_ IUnknown** patternProvider)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != patternProvider)
+ {
+ *patternProvider = nullptr;
+ switch (patternId)
+ {
+ case UIA_InvokePatternId:
+ {
+ if (auto invokeProvider = get_strong().try_as())
+ {
+ invokeProvider.as().copy_to(patternProvider);
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::GetPropertyValue(
+ _In_ PROPERTYID propertyId,
+ _Out_ VARIANT* propertyValue)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != propertyValue)
+ {
+ ::VariantInit(propertyValue);
+ switch (propertyId)
+ {
+ case UIA_NamePropertyId:
+ {
+ propertyValue->bstrVal = wil::make_bstr(m_name.c_str()).release();
+ propertyValue->vt = VT_BSTR;
+ break;
+ }
+
+ case UIA_IsContentElementPropertyId:
+ {
+ propertyValue->boolVal = m_isContent ? VARIANT_TRUE : VARIANT_FALSE;
+ propertyValue->vt = VT_BOOL;
+ break;
+ }
+
+ case UIA_IsControlElementPropertyId:
+ {
+ propertyValue->boolVal = m_isControl ? VARIANT_TRUE : VARIANT_FALSE;
+ propertyValue->vt = VT_BOOL;
+ break;
+ }
+
+ case UIA_ControlTypePropertyId:
+ {
+ if (m_isControl)
+ {
+ propertyValue->vt = VT_I4;
+ propertyValue->lVal = m_uiaControlTypeId;
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::get_HostRawElementProvider(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderSimple** hostRawElementProviderSimple)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != hostRawElementProviderSimple)
+ {
+ m_hostProvider.copy_to(hostRawElementProviderSimple);
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::Navigate(
+ _In_ NavigateDirection direction,
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != fragment)
+ {
+ *fragment = nullptr;
+ switch (direction)
+ {
+ case NavigateDirection_Parent:
+ {
+ if (auto strongParent = m_parent.get())
+ {
+ strongParent.as().copy_to(fragment);
+ }
+ break;
+ }
+ case NavigateDirection_NextSibling:
+ {
+ if (auto strongSibling = m_nextSibling.get())
+ {
+ strongSibling.as().copy_to(fragment);
+ }
+ break;
+ }
+ case NavigateDirection_PreviousSibling:
+ {
+ if (auto strongSibling = m_previousSibling.get())
+ {
+ strongSibling.as().copy_to(fragment);
+ }
+ break;
+ }
+ case NavigateDirection_FirstChild:
+ {
+ if (!m_children.empty())
+ {
+ m_children.front().as().copy_to(fragment);
+ }
+ break;
+ }
+ case NavigateDirection_LastChild:
+ {
+ if (!m_children.empty())
+ {
+ m_children.back().as().copy_to(fragment);
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::GetRuntimeId(
+ _Outptr_opt_result_maybenull_ SAFEARRAY** runtimeId)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != runtimeId)
+ {
+ *runtimeId = nullptr;
+
+ unsigned long arraySizeAsUnsignedLong =
+ static_cast(m_runtimeId.size());
+
+ unique_safearray runtimeIdArray
+ { ::SafeArrayCreateVector(VT_I4, 0, arraySizeAsUnsignedLong) };
+ SAFEARRAY* rawPointerToSafeArray = runtimeIdArray.get();
+ winrt::check_pointer(rawPointerToSafeArray);
+
+ for (long i = 0; i < static_cast(arraySizeAsUnsignedLong); ++i)
+ {
+ winrt::check_hresult(
+ ::SafeArrayPutElement(rawPointerToSafeArray, &i, &(m_runtimeId[i])));
+ }
+
+ *runtimeId = runtimeIdArray.release();
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::get_BoundingRectangle(
+ _Out_ UiaRect* boundingRectangle)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != boundingRectangle)
+ {
+ *boundingRectangle = { 0, 0, 0, 0 };
+
+ // This provider might still be alive in a UIA callback when the DrawingIsland
+ // is being torn down. Make sure we still have a valid owner before proceeding
+ // to query the DrawingIsland for this information.
+ if (nullptr != m_ownerNoRef)
+ {
+ auto screenRectangle =
+ m_ownerNoRef->GetScreenBoundsForAutomationFragment(
+ get_strong().as<::IUnknown>().get());
+
+ boundingRectangle->left = screenRectangle.X;
+ boundingRectangle->top = screenRectangle.Y;
+ boundingRectangle->width = screenRectangle.Width;
+ boundingRectangle->height = screenRectangle.Height;
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::GetEmbeddedFragmentRoots(
+ _Outptr_opt_result_maybenull_ SAFEARRAY** embeddedFragmentRoots)
+ {
+ if (nullptr != embeddedFragmentRoots)
+ {
+ *embeddedFragmentRoots = nullptr;
+ }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::SetFocus()
+ {
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragment::get_FragmentRoot(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragmentRoot** fragmentRoot)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != fragmentRoot)
+ {
+ *fragmentRoot = nullptr;
+
+ // Walk up our fragment tree until we find our fragment root.
+ auto fragmentRootCandidate = get_strong();
+ bool currentCandidateIsThisObject = true;
+ while (nullptr != fragmentRootCandidate &&
+ nullptr == fragmentRootCandidate.try_as())
+ {
+ // Haven't found the fragment root yet, keep walking up our tree.
+ fragmentRootCandidate = currentCandidateIsThisObject ?
+ m_parent.get() : fragmentRootCandidate->GetParent();
+
+ // Once we start walking up the tree, we must ensure we're thread-safe
+ // and call through GetParent on the other objects.
+ currentCandidateIsThisObject = false;
+ }
+
+ if (nullptr != fragmentRootCandidate)
+ {
+ // Found the fragment root, return it.
+ fragmentRootCandidate.as().copy_to(
+ fragmentRoot);
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ void AutomationFragment::SetParent(
+ _In_ winrt::weak_ref const& parent)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_parent = parent;
+ }
+
+ winrt::com_ptr AutomationFragment::GetParent() const
+ {
+ std::unique_lock lock{ m_mutex };
+ return m_parent.get();
+ }
+
+ void AutomationFragment::SetPreviousSibling(
+ _In_ winrt::weak_ref const& previousSibling)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_previousSibling = previousSibling;
+ }
+
+ winrt::com_ptr AutomationFragment::GetPreviousSibling() const
+ {
+ std::unique_lock lock{ m_mutex };
+ return m_previousSibling.get();
+ }
+
+ void AutomationFragment::SetNextSibling(
+ _In_ winrt::weak_ref const& nextSibling)
+ {
+ std::unique_lock lock{ m_mutex };
+ m_nextSibling = nextSibling;
+ }
+
+ winrt::com_ptr AutomationFragment::GetNextSibling() const
+ {
+ std::unique_lock lock{ m_mutex };
+ return m_nextSibling.get();
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.h
new file mode 100644
index 000000000..c05629c0c
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragment.h
@@ -0,0 +1,129 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+#include
+#include "AutomationCallbackHandler.h"
+
+namespace winrt::DrawingIslandComponents
+{
+ struct AutomationFragment : winrt::implements
+ {
+ void AddChildToEnd(
+ _In_ winrt::com_ptr const& child);
+
+ void RemoveChild(
+ _In_ winrt::com_ptr const& child);
+
+ void RemoveAllChildren();
+
+ void SetCallbackHandler(
+ _In_opt_ IAutomationCallbackHandler const* const owner);
+
+ void SetProviderOptions(
+ _In_ ProviderOptions const& providerOptions);
+
+ void SetName(
+ _In_ std::wstring_view const& name);
+
+ void SetIsContent(
+ _In_ bool const& isContent);
+
+ void SetIsControl(
+ _In_ bool const& isControl);
+
+ void SetUiaControlTypeId(
+ _In_ long const& uiaControlTypeId);
+
+ void SetHostProvider(
+ _In_ winrt::com_ptr const& hostProvider);
+
+ // IRawElementProviderSimple overrides.
+ HRESULT __stdcall get_ProviderOptions(
+ _Out_ ProviderOptions* providerOptions
+ ) final override;
+
+ HRESULT __stdcall GetPatternProvider(
+ _In_ PATTERNID patternId,
+ _COM_Outptr_opt_result_maybenull_ IUnknown** patternProvider
+ ) final override;
+
+ HRESULT __stdcall GetPropertyValue(
+ _In_ PROPERTYID propertyId,
+ _Out_ VARIANT* propertyValue
+ ) final override;
+
+ HRESULT __stdcall get_HostRawElementProvider(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderSimple** hostRawElementProviderSimple
+ ) final override;
+
+ // IRawElementProviderFragment overrides.
+ HRESULT __stdcall Navigate(
+ _In_ NavigateDirection direction,
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment
+ ) final override;
+
+ HRESULT __stdcall GetRuntimeId(
+ _Outptr_opt_result_maybenull_ SAFEARRAY** runtimeId
+ ) final override;
+
+ HRESULT __stdcall get_BoundingRectangle(
+ _Out_ UiaRect* boundingRectangle
+ ) final override;
+
+ HRESULT __stdcall GetEmbeddedFragmentRoots(
+ _Outptr_opt_result_maybenull_ SAFEARRAY** embeddedFragmentRoots
+ ) final override;
+
+ HRESULT __stdcall SetFocus() final override;
+
+ HRESULT __stdcall get_FragmentRoot(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragmentRoot** fragmentRoot
+ ) final override;
+
+ protected:
+ mutable std::mutex m_mutex{};
+
+ // We do not hold a strong reference to the object that owns us.
+ // However we do need to be able to call back into it to get information.
+ // The owner is responsible for unsetting itself when it gets destroyed.
+ IAutomationCallbackHandler const* m_ownerNoRef{ nullptr };
+
+ private:
+ void SetParent(
+ _In_ winrt::weak_ref const& parent);
+
+ winrt::com_ptr GetParent() const;
+
+ void SetPreviousSibling(
+ _In_ winrt::weak_ref const& previousSibling);
+
+ winrt::com_ptr GetPreviousSibling() const;
+
+ void SetNextSibling(
+ _In_ winrt::weak_ref const& nextSibling);
+
+ winrt::com_ptr GetNextSibling() const;
+
+ // Automatically generate unique runtime IDs per fragment.
+ inline static unsigned __int32 s_nextAvailableInternalRuntimeId{ 0 };
+ std::array m_runtimeId
+ { UiaAppendRuntimeId, ++s_nextAvailableInternalRuntimeId };
+
+ ProviderOptions m_providerOptions
+ { ProviderOptions_ServerSideProvider | ProviderOptions_UseComThreading };
+ std::wstring m_name{ L"" };
+ bool m_isContent{ true };
+ bool m_isControl{ true };
+ long m_uiaControlTypeId{ UIA_CustomControlTypeId };
+ winrt::com_ptr m_hostProvider{ nullptr };
+
+ winrt::weak_ref m_parent{ nullptr };
+ winrt::weak_ref m_previousSibling{ nullptr };
+ winrt::weak_ref m_nextSibling{ nullptr };
+ std::vector> m_children{};
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.cpp
new file mode 100644
index 000000000..f8833f010
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.cpp
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "AutomationFragmentRoot.h"
+
+namespace winrt::DrawingIslandComponents
+{
+ HRESULT __stdcall AutomationFragmentRoot::ElementProviderFromPoint(
+ _In_ double x,
+ _In_ double y,
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != fragment)
+ {
+ *fragment = nullptr;
+
+ // This provider might still be alive in a UIA callback when the DrawingIsland
+ // is being torn down. Make sure we still have a valid owner before proceeding
+ // to query the DrawingIsland for this information.
+ if (nullptr != m_ownerNoRef)
+ {
+ m_ownerNoRef->GetFragmentFromPoint(x, y).copy_to(fragment);
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+
+ HRESULT __stdcall AutomationFragmentRoot::GetFocus(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragmentInFocus)
+ {
+ try
+ {
+ std::unique_lock lock{ m_mutex };
+ if (nullptr != fragmentInFocus)
+ {
+ *fragmentInFocus = nullptr;
+
+ // This provider might still be alive in a UIA callback when the DrawingIsland
+ // is being torn down. Make sure we still have a valid owner before proceeding
+ // to query the DrawingIsland for this information.
+ if (nullptr != m_ownerNoRef)
+ {
+ m_ownerNoRef->GetFragmentInFocus().copy_to(fragmentInFocus);
+ }
+ }
+ }
+ catch (...) { return UIA_E_ELEMENTNOTAVAILABLE; }
+ return S_OK;
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.h
new file mode 100644
index 000000000..60e629c73
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationFragmentRoot.h
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+#include "AutomationFragment.h"
+
+namespace winrt::DrawingIslandComponents
+{
+ struct AutomationFragmentRoot : winrt::implements
+ {
+ // IRawElementProviderFragmentRoot overrides.
+ HRESULT __stdcall ElementProviderFromPoint(
+ _In_ double x,
+ _In_ double y,
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragment
+ ) final override;
+
+ HRESULT __stdcall GetFocus(
+ _COM_Outptr_opt_result_maybenull_ IRawElementProviderFragment** fragmentInFocus
+ ) final override;
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationPeer.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationPeer.h
new file mode 100644
index 000000000..e47b6fce8
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/AutomationPeer.h
@@ -0,0 +1,47 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+namespace winrt::DrawingIslandComponents
+{
+ // For the DrawingIsland, each Visual corresponds to an Automation Fragment.
+ // This structure encapsulates that relationship and enables us to quickly retrieve one from
+ // the other.
+ struct AutomationPeer
+ {
+ explicit AutomationPeer(
+ winrt::Visual const& visual,
+ winrt::com_ptr const& automationProvider) :
+ _visual{ visual },
+ _automationProvider{ automationProvider }
+ {
+
+ }
+
+ winrt::Visual const& GetVisual() const
+ {
+ return _visual;
+ }
+
+ winrt::com_ptr const& GetAutomationProvider() const
+ {
+ return _automationProvider;
+ }
+
+ bool Match(winrt::Visual const& visual) const noexcept
+ {
+ return visual == _visual;
+ }
+
+ bool Match(::IUnknown const* const automationProviderAsIUnknown) const noexcept
+ {
+ return automationProviderAsIUnknown ==
+ _automationProvider.try_as<::IUnknown>().get();
+ }
+
+ private:
+ winrt::Visual _visual{ nullptr };
+ winrt::com_ptr _automationProvider{ nullptr };
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/Components.idl b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Components.idl
new file mode 100644
index 000000000..0a17ee88a
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Components.idl
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+namespace DrawingIslandComponents
+{
+ [default_interface]
+ runtimeclass DrawingIsland : Windows.Foundation.IClosable
+ {
+ // Construction
+ DrawingIsland(
+ Microsoft.UI.Composition.Compositor compositor);
+
+ // Properties
+ Boolean EnableBackgroundTransparency;
+
+ Microsoft.UI.Content.ContentIsland Island { get; };
+
+ // Methods
+ void LeftClickAndRelease(
+ Windows.Foundation.Numerics.Vector2 currentPoint);
+
+ void RightClickAndRelease(
+ Windows.Foundation.Numerics.Vector2 currentPoint);
+
+ void SetIslandOpacity(Single islandOpacity);
+
+ void SetColorIndex(UInt32 colorIndex);
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.cpp
new file mode 100644
index 000000000..3a19e2af4
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.cpp
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "DeviceLostHelper.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ void DeviceLostHelper::WatchDevice(winrt::com_ptr<::IDXGIDevice> const& dxgiDevice)
+ {
+ // If we're currently listening to a device, then stop.
+ StopWatchingCurrentDevice();
+
+ // Set the current device to the new device.
+ m_device = nullptr;
+ winrt::check_hresult(::CreateDirect3D11DeviceFromDXGIDevice(dxgiDevice.get(), reinterpret_cast<::IInspectable**>(winrt::put_abi(m_device))));
+
+ // Get the DXGI Device.
+ m_dxgiDevice = dxgiDevice;
+
+ // QI For the ID3D11Device4 interface.
+ winrt::com_ptr<::ID3D11Device4> d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() };
+
+ // Create a wait struct.
+ m_onDeviceLostHandler = nullptr;
+ m_onDeviceLostHandler = ::CreateThreadpoolWait(DeviceLostHelper::OnDeviceLost, (PVOID)this, nullptr);
+
+ // Create a handle and a cookie.
+ m_eventHandle.attach(::CreateEvent(nullptr, false, false, nullptr));
+ winrt::check_bool(bool{ m_eventHandle });
+ m_cookie = 0;
+
+ // Register for device lost.
+ ::SetThreadpoolWait(m_onDeviceLostHandler, m_eventHandle.get(), nullptr);
+ winrt::check_hresult(d3dDevice->RegisterDeviceRemovedEvent(m_eventHandle.get(), &m_cookie));
+ }
+
+ void DeviceLostHelper::StopWatchingCurrentDevice()
+ {
+ if (m_dxgiDevice)
+ {
+ // QI For the ID3D11Device4 interface.
+ auto d3dDevice{ m_dxgiDevice.as<::ID3D11Device4>() };
+
+ // Unregister from the device lost event.
+ ::CloseThreadpoolWait(m_onDeviceLostHandler);
+ d3dDevice->UnregisterDeviceRemoved(m_cookie);
+
+ // Clear member variables.
+ m_onDeviceLostHandler = nullptr;
+ m_eventHandle.close();
+ m_cookie = 0;
+ m_device = nullptr;
+ m_dxgiDevice = nullptr;
+ }
+ }
+
+ void CALLBACK DeviceLostHelper::OnDeviceLost(PTP_CALLBACK_INSTANCE /* instance */, PVOID context, PTP_WAIT /* wait */, TP_WAIT_RESULT /* waitResult */)
+ {
+ // Get the DeviceLostHelper context object.
+ auto deviceLostHelper = reinterpret_cast(context);
+
+ // Create a local reference to the old device before releasing the helper object's reference.
+ auto oldDevice = deviceLostHelper->m_device;
+
+ // Stop listening for device lost events on the old device.
+ deviceLostHelper->StopWatchingCurrentDevice();
+
+ // Invoke the event handler.
+ deviceLostHelper->RaiseDeviceLostEvent(oldDevice);
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.h
new file mode 100644
index 000000000..67f33431b
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DeviceLostHelper.h
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ struct DeviceLostEventArgs
+ {
+ DeviceLostEventArgs(IDirect3DDevice const& device) : m_device(device)
+ {
+ }
+
+ IDirect3DDevice Device() { return m_device; }
+
+ private:
+ IDirect3DDevice m_device;
+ };
+
+ struct DeviceLostHelper
+ {
+ DeviceLostHelper() = default;
+
+ ~DeviceLostHelper()
+ {
+ StopWatchingCurrentDevice();
+ }
+
+ // Not copyable or assignable.
+ DeviceLostHelper(DeviceLostHelper const&) = delete;
+ void operator=(DeviceLostHelper const&) = delete;
+
+ void WatchDevice(winrt::com_ptr<::IDXGIDevice> const& dxgiDevice);
+
+ void StopWatchingCurrentDevice();
+
+ void DeviceLost(winrt::delegate const& handler)
+ {
+ m_deviceLost = handler;
+ }
+
+ private:
+ void RaiseDeviceLostEvent(IDirect3DDevice const& oldDevice)
+ {
+ m_deviceLost(this, DeviceLostEventArgs{ oldDevice });
+ }
+
+ static void CALLBACK OnDeviceLost(PTP_CALLBACK_INSTANCE /* instance */, PVOID context, PTP_WAIT /* wait */, TP_WAIT_RESULT /* waitResult */);
+
+ private:
+ winrt::delegate m_deviceLost;
+ IDirect3DDevice m_device;
+ winrt::com_ptr<::IDXGIDevice> m_dxgiDevice;
+ PTP_WAIT m_onDeviceLostHandler{ nullptr };
+ winrt::handle m_eventHandle;
+ DWORD m_cookie{ 0 };
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.cpp
new file mode 100644
index 000000000..e45a62a35
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.cpp
@@ -0,0 +1,987 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "DrawingIsland.h"
+#include "DrawingIsland.g.cpp"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ DrawingIsland::DrawingIsland(
+ const winrt::Compositor& compositor)
+ {
+ m_output.Compositor = compositor;
+ m_output.TextRenderer = std::make_shared(m_output.Compositor);
+ m_output.DeviceLostHelper.WatchDevice(m_output.TextRenderer->GetDevice());
+ m_output.DeviceLostHelper.DeviceLost({ this, &DrawingIsland::OnDirect3DDeviceLost });
+
+ // Create the Compositor and the Content:
+ // - The Bridge's connection to the Window will keep everything alive, and perform an
+ // orderly tear-down:
+ //
+ // Window -> Bridge -> Content -> Visual -> InputSite -> InputObject
+ //
+ // - When the ContentIsland is destroyed, ContentIsland.AppData will call IClosable.Close
+ // on this instance to break cycles and clean up expensive resources.
+
+ m_output.RootVisual = m_output.Compositor.CreateContainerVisual();
+ m_output.RootVisual.RelativeSizeAdjustment({ 1.0f, 1.0f });
+
+ m_island = winrt::ContentIsland::Create(m_output.RootVisual);
+ m_island.AppData(get_strong().as());
+
+ Output_Initialize();
+ Input_Initialize();
+ Environment_Initialize();
+ Accessibility_Initialize();
+
+ m_prevState.RasterizationScale = m_island.RasterizationScale();
+
+ // Get notifications for resize, bridge changes, etc.
+ (void)m_island.StateChanged(
+ [&](auto&& ...)
+ {
+ return Island_OnStateChanged();
+ });
+
+
+ (void)m_island.Closed(
+ [&]()
+ {
+ return Island_OnClosed();
+ });
+
+ }
+
+
+ DrawingIsland::~DrawingIsland()
+ {
+ m_output.Compositor = nullptr;
+ }
+
+
+ void
+ DrawingIsland::Close()
+ {
+ m_output.RootVisual = nullptr;
+
+ m_input.KeyboardSource = nullptr;
+ m_input.PretranslateSource = nullptr;
+ m_input.PointerSource = nullptr;
+ m_input.FocusController = nullptr;
+
+ m_background.BrushDefault = nullptr;
+ m_background.BrushA = nullptr;
+ m_background.BrushB = nullptr;
+ m_background.BrushC = nullptr;
+ m_background.Visual = nullptr;
+
+ m_items.Visuals = nullptr;
+ m_items.Items.clear();
+ m_items.SelectedItem = nullptr;
+
+ if (nullptr != m_background.BackdropController)
+ {
+ // Clean up our SystemBackdropController.
+ m_background.BackdropController.RemoveAllSystemBackdropTargets();
+ m_background.BackdropController.Close();
+ m_background.BackdropController = nullptr;
+ }
+
+ if (nullptr != m_background.BackdropConfiguration)
+ {
+ m_background.BackdropConfiguration = nullptr;
+ }
+
+ // Make sure automation is destroyed.
+ for (auto& automationPeer : m_uia.AutomationPeers)
+ {
+ automationPeer.GetAutomationProvider()->SetCallbackHandler(nullptr);
+ }
+ m_uia.AutomationPeers.clear();
+
+ if (nullptr != m_uia.FragmentRoot)
+ {
+ m_uia.FragmentRoot->SetCallbackHandler(nullptr);
+ m_uia.FragmentRoot = nullptr;
+ }
+
+
+ // Destroy Content:
+ // - This handles if the ContentIsland has already started destruction and is notifying the
+ // app.
+
+ m_island.Close();
+ m_island = nullptr;
+
+ // TODO: Add the following test case in automated tests:
+ // 1. We are recursively calling ContentIsland.Close while inside the ContentIsland.Closed
+ // event.
+ // 2. We are testing the potential final Release() of ContentIsland while inside the Closed
+ // event.
+
+ m_output.Compositor = nullptr;
+ }
+
+
+ void DrawingIsland::EnableBackgroundTransparency(
+ bool value)
+ {
+ if (value != m_background.BackdropEnabled)
+ {
+ m_background.BackdropEnabled = value;
+ Output_UpdateSystemBackdrop();
+ }
+ }
+
+
+ IFACEMETHODIMP
+ DrawingIsland::OnDirectMessage(
+ IInputPreTranslateKeyboardSourceInterop* /*source*/,
+ const MSG* msg,
+ UINT keyboardModifiers,
+ _Inout_ bool* handled)
+ {
+ *handled = false;
+
+ // Alt+A Debug print to see the order of the PreTranslate callbacks
+ if ((keyboardModifiers & FALT) &&
+ (msg->message == WM_SYSKEYDOWN) &&
+ (static_cast(msg->wParam) == winrt::VirtualKey::A))
+ {
+
+ }
+
+ if (keyboardModifiers & FALT)
+ {
+ *handled = Input_AcceleratorKeyActivated(
+ static_cast(msg->wParam));
+ }
+
+ return S_OK;
+ }
+
+
+ IFACEMETHODIMP
+ DrawingIsland::OnTreeMessage(
+ IInputPreTranslateKeyboardSourceInterop* /*source*/,
+ const MSG* msg,
+ UINT keyboardModifiers,
+ _Inout_ bool* handled)
+ {
+ // Alt+A Debug print to see the order of the PreTranslate callbacks
+ if ((keyboardModifiers & FALT) &&
+ (msg->message == WM_SYSKEYDOWN) &&
+ (static_cast(msg->wParam) == winrt::VirtualKey::A))
+ {
+
+ }
+
+ *handled = false;
+ return S_OK;
+ }
+
+
+ winrt::Windows::Graphics::RectInt32
+ DrawingIsland::GetScreenBoundsForAutomationFragment(
+ _In_::IUnknown const* const sender) const
+ {
+ // Check if the automation provider that has sent this callback is the fragment root.
+ if (m_uia.FragmentRoot.as<::IUnknown>().get() == sender)
+ {
+ winrt::Rect logicalRect;
+ logicalRect.X = 0;
+ logicalRect.Y = 0;
+ logicalRect.Width = m_island.ActualSize().x;
+ logicalRect.Height = m_island.ActualSize().y;
+
+ // This will convert from the logical coordinate space of the ContentIsland to
+ // Win32 screen coordinates that are needed by Accessibility.
+ return m_island.CoordinateConverter().ConvertLocalToScreen(logicalRect);
+ }
+
+ // Else find the matching automation peer entry for the sending fragment.
+ auto iterator = std::find_if(
+ m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(),
+ [&sender](auto const& automationPeer)
+ {
+ return automationPeer.Match(sender);
+ });
+
+ if (m_uia.AutomationPeers.end() == iterator)
+ {
+ // Did not find any match for this automation provider.
+ return { 0, 0, 0, 0 };
+ }
+
+ auto const& visualPeer = iterator->GetVisual();
+ winrt::Rect logicalRect;
+ logicalRect.X = visualPeer.Offset().x;
+ logicalRect.Y = visualPeer.Offset().y;
+ logicalRect.Width = visualPeer.Size().x;
+ logicalRect.Height = visualPeer.Size().y;
+
+ // This will convert from the logical coordinate space of the ContentIsland to
+ // Win32 screen coordinates that are needed by Accessibility.
+ return m_island.CoordinateConverter().ConvertLocalToScreen(logicalRect);
+ }
+
+
+ winrt::com_ptr
+ DrawingIsland::GetFragmentFromPoint(
+ _In_ double x,
+ _In_ double y) const
+ {
+ // UIA provides hit test points in screen space.
+ // Convert the point into a dummy empty rectangle to use with the coordinate converter.
+ winrt::Windows::Graphics::RectInt32 screenRect
+ { static_cast(x + 0.5), static_cast(y + 0.5), 0, 0 };
+
+ auto logicalRect = m_island.CoordinateConverter().ConvertScreenToLocal(screenRect);
+ float2 localPoint{ logicalRect.X, logicalRect.Y };
+ auto hitTestElement = HitTestItem(localPoint);
+
+ // Find the automation peer for the hit test visual if any.
+ if (nullptr != hitTestElement)
+ {
+ auto& hitTestVisual = hitTestElement->GetVisual();
+
+ auto iterator = std::find_if(
+ m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(),
+ [&hitTestVisual](auto const& automationPeer)
+ {
+ return automationPeer.Match(hitTestVisual);
+ });
+
+ if (m_uia.AutomationPeers.end() != iterator)
+ {
+ // Return the automation provider if we found an automation peer
+ // for the hit test visual.
+ return iterator->GetAutomationProvider().as();
+ }
+ }
+
+ return nullptr;
+ }
+
+
+ winrt::com_ptr
+ DrawingIsland::GetFragmentInFocus() const
+ {
+ if (m_items.SelectedItem != nullptr)
+ {
+ auto& visual = m_items.SelectedItem->GetVisual();
+
+ // Find the currently selected visual's automation peer.
+ auto iterator = std::find_if(
+ m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(),
+ [visual](auto const& automationPeer)
+ {
+ return automationPeer.Match(visual);
+ });
+
+ if (m_uia.AutomationPeers.end() != iterator)
+ {
+ // Return the automation provider if we found an automation peer
+ // for the selected visual.
+ return iterator->GetAutomationProvider().as();
+ }
+ }
+
+ return nullptr;
+ }
+
+
+ Item* DrawingIsland::HitTestItem(float2 const& point) const
+ {
+ // Iterate from the end of the vector, i.e., from front to back.
+ for (size_t i = m_items.Items.size(); i != 0; i--)
+ {
+ Item* item = m_items.Items[i - 1].get();
+ auto& visual = item->GetVisual();
+
+ winrt::float3 const offset = visual.Offset();
+ float2 const size = visual.Size();
+
+ if (point.x >= offset.x &&
+ point.x < offset.x + size.x &&
+ point.y >= offset.y &&
+ point.y < offset.y + size.y)
+ {
+ return item;
+ }
+ }
+ return nullptr;
+ }
+
+
+ void
+ DrawingIsland::Accessibility_Initialize()
+ {
+ // Create an UI automation fragment root for our island's content.
+ m_uia.FragmentRoot = winrt::make_self();
+ m_uia.FragmentRoot->SetName(L"Drawing Squares");
+ m_uia.FragmentRoot->SetProviderOptions(
+ ProviderOptions_ServerSideProvider |
+ ProviderOptions_UseComThreading |
+ ProviderOptions_RefuseNonClientSupport);
+ m_uia.FragmentRoot->SetUiaControlTypeId(UIA_WindowControlTypeId);
+ m_uia.FragmentRoot->SetCallbackHandler(this);
+
+ (void)m_island.AutomationProviderRequested(
+ { this, &DrawingIsland::Accessibility_OnAutomationProviderRequested });
+ }
+
+
+ void
+ DrawingIsland::Accessibility_CreateItemFragment(
+ const winrt::Visual& itemVisual)
+ {
+ // Create a new automation fragment.
+ auto fragment = winrt::make_self();
+ fragment->SetName(s_colorNames[m_output.CurrentColorIndex].c_str());
+ fragment->SetCallbackHandler(this);
+
+ // Add an entry to our automation peers (a mapping between the Visual and the Fragment):
+ // - This is keeping the UIA objects alive.
+ // - The lookup is used to get back to the item Fragment for
+ // specific operations, such as hit-testing or tree walking.
+ // This avoids adding to more expensive data storage,
+ // such as the Visual.CustomProperties map.
+ m_uia.AutomationPeers.push_back(AutomationPeer{ itemVisual, fragment });
+
+ // Connect the automation fragment to our fragment root.
+ m_uia.FragmentRoot->AddChildToEnd(fragment);
+ }
+
+
+ void
+ DrawingIsland::Accessibility_OnAutomationProviderRequested(
+ const winrt::ContentIsland& island,
+ const winrt::ContentIslandAutomationProviderRequestedEventArgs& args)
+ {
+ // Make sure the host provider is up to date.
+ m_uia.FragmentRoot->SetHostProvider(
+ island.GetAutomationHostProvider().as());
+
+ // Return the fragment root as an IInspectable.
+ args.AutomationProvider(m_uia.FragmentRoot.as());
+
+ args.Handled(true);
+ }
+
+
+ void
+ DrawingIsland::Input_Initialize()
+ {
+ m_input.PointerSource = winrt::InputPointerSource::GetForIsland(m_island);
+
+ m_input.PointerSource.PointerPressed(
+ [this](winrt::InputPointerSource const&,
+ winrt::PointerEventArgs const& args)
+ {
+ auto currentPoint = args.CurrentPoint();
+ auto properties = currentPoint.Properties();
+
+ if (properties.IsLeftButtonPressed())
+ {
+ Input_OnLeftButtonPressed(args);
+ }
+ else if (properties.IsRightButtonPressed())
+ {
+ Input_OnRightButtonPressed(args);
+ }
+ });
+
+ m_input.PointerSource.PointerMoved(
+ [this](winrt::InputPointerSource const&,
+ winrt::PointerEventArgs const& args)
+ {
+ Input_OnPointerMoved(args);
+ });
+
+ m_input.PointerSource.PointerReleased(
+ [&](auto&& ...)
+ {
+ Input_OnPointerReleased();
+ });
+
+ // Set up the keyboard source.
+ m_input.KeyboardSource = winrt::InputKeyboardSource::GetForIsland(m_island);
+
+ m_input.KeyboardSource.KeyDown(
+ [this](winrt::InputKeyboardSource const&,
+ winrt::KeyEventArgs const& args)
+ {
+ bool handled = Input_OnKeyDown(args.VirtualKey());
+
+ // Mark the event as handled
+ if (handled)
+ {
+ args.Handled(true);
+ }
+ });
+
+ m_input.PretranslateSource =
+ winrt::InputPreTranslateKeyboardSource::GetForIsland(m_island);
+
+ m_input.PretranslateSource.as<
+ Microsoft::UI::Input::IInputPreTranslateKeyboardSourceInterop>()->
+ SetPreTranslateHandler(this);
+
+ auto activationListener = winrt::InputActivationListener::GetForIsland(m_island);
+ (void)activationListener.InputActivationChanged(
+ [this, activationListener](
+ winrt::InputActivationListener const&,
+ winrt::InputActivationListenerActivationChangedEventArgs const&)
+ {
+ switch (activationListener.State())
+ {
+ case winrt::InputActivationState::Activated:
+ m_output.RootVisual.Opacity(1.0f);
+ if (nullptr != m_background.BackdropConfiguration)
+ {
+ m_background.BackdropConfiguration.IsInputActive(true);
+ }
+ break;
+
+ default:
+ m_output.RootVisual.Opacity(m_output.Opacity);
+ if (nullptr != m_background.BackdropConfiguration)
+ {
+ m_background.BackdropConfiguration.IsInputActive(false);
+ }
+ break;
+ }
+ });
+
+ m_input.FocusController = winrt::InputFocusController::GetForIsland(m_island);
+ m_input.FocusController.NavigateFocusRequested(
+ [this](winrt::InputFocusController const&,
+ winrt::FocusNavigationRequestEventArgs const& args)
+ {
+ bool setFocus = m_input.FocusController.TrySetFocus();
+ // Mark the event as handled
+ if (setFocus)
+ {
+ args.Result(winrt::FocusNavigationResult::Moved);
+ }
+ });
+ }
+
+
+ bool
+ DrawingIsland::Input_OnKeyDown(
+ winrt::Windows::System::VirtualKey virtualKey)
+ {
+ bool handled = false;
+
+ switch (virtualKey)
+ {
+ case winrt::VirtualKey::A:
+ {
+ m_background.Visual.Brush(m_background.BrushA);
+ handled = true;
+ break;
+ }
+
+ case winrt::VirtualKey::B:
+ {
+ m_background.Visual.Brush(m_background.BrushB);
+ handled = true;
+ break;
+ }
+
+ case winrt::VirtualKey::C:
+ {
+ m_background.Visual.Brush(m_background.BrushC);
+ handled = true;
+ break;
+ }
+
+ case winrt::VirtualKey::Space:
+ {
+ m_background.Visual.Brush(m_background.BrushDefault);
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Number1:
+ {
+ m_output.CurrentColorIndex = 0;
+ handled = true;
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Number2:
+ {
+ m_output.CurrentColorIndex = 1;
+ handled = true;
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Number3:
+ {
+ m_output.CurrentColorIndex = 2;
+ handled = true;
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Number4:
+ {
+ m_output.CurrentColorIndex = 3;
+ handled = true;
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Delete:
+ case winrt::Windows::System::VirtualKey::Escape:
+ {
+ m_items.Visuals.RemoveAll();
+ m_items.Items.clear();
+
+ // Update accessibility.
+ m_uia.FragmentRoot->RemoveAllChildren();
+ m_uia.AutomationPeers.clear();
+
+ handled = true;
+ break;
+ }
+
+ case winrt::Windows::System::VirtualKey::Tab:
+ {
+ auto request = winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
+ winrt::Microsoft::UI::Input::FocusNavigationReason::First);
+ m_input.FocusController.DepartFocus(request);
+ }
+ }
+
+ Output_UpdateCurrentColorVisual();
+
+ return handled;
+ }
+
+ bool
+ DrawingIsland::Input_AcceleratorKeyActivated(
+ winrt::Windows::System::VirtualKey virtualKey)
+ {
+ bool handled = false;
+
+ switch (virtualKey)
+ {
+ case winrt::VirtualKey::X:
+ {
+ m_background.Visual.Brush(m_background.BrushA);
+ handled = true;
+ break;
+ }
+
+ case winrt::VirtualKey::Y:
+ {
+ m_background.Visual.Brush(m_background.BrushB);
+ handled = true;
+ break;
+ }
+
+ case winrt::VirtualKey::Z:
+ {
+ m_background.Visual.Brush(m_background.BrushC);
+ handled = true;
+ break;
+ }
+ }
+
+ return handled;
+ }
+
+
+ void
+ DrawingIsland::Input_OnLeftButtonPressed(
+ const winrt::PointerEventArgs& args)
+ {
+ // Left button manipulates the custom-drawn content
+ float2 const point = args.CurrentPoint().Position();
+
+ bool controlPressed = WI_IsFlagSet(
+ args.KeyModifiers(),
+ winrt::Windows::System::VirtualKeyModifiers::Control);
+
+ OnLeftClick(point, controlPressed);
+ }
+
+
+ void
+ DrawingIsland::Input_OnPointerReleased()
+ {
+ m_items.SelectedItem = nullptr;
+ }
+
+
+ void
+ DrawingIsland::LeftClickAndRelease(
+ const float2 currentPoint)
+ {
+ OnLeftClick(currentPoint, false);
+ Input_OnPointerReleased();
+ }
+
+
+ void
+ DrawingIsland::RightClickAndRelease(
+ const float2 currentPoint)
+ {
+ OnRightClick(currentPoint);
+ Input_OnPointerReleased();
+ }
+
+
+ void
+ DrawingIsland::OnLeftClick(
+ const float2 point,
+ bool controlPressed)
+ {
+ m_items.SelectedItem = HitTestItem(point);
+
+ if (m_items.SelectedItem != nullptr)
+ {
+ Item* item = m_items.SelectedItem;
+ auto& visual = m_items.SelectedItem->GetVisual();
+ winrt::float3 const offset = visual.Offset();
+
+ m_items.Offset.x = offset.x - point.x;
+ m_items.Offset.y = offset.y - point.y;
+
+ // Move the visual to the top.
+ m_items.Visuals.Remove(visual);
+ m_items.Visuals.InsertAtTop(visual);
+
+ // Move the VisualElement to the end of the vector if it isn't already.
+ if (!m_items.Items.empty() && m_items.Items.back().get() != item)
+ {
+ auto i = std::find_if(
+ m_items.Items.begin(),
+ m_items.Items.end(),
+ [item](auto& elem) { return elem.get() == item; }
+ );
+ if (i != m_items.Items.end())
+ {
+ std::rotate(i, i + 1, m_items.Items.end());
+ }
+ }
+
+ // Update automation.
+ // First find the existing automation peer.
+ auto iterator = std::find_if(
+ m_uia.AutomationPeers.begin(), m_uia.AutomationPeers.end(),
+ [visual](auto const& automationPeer)
+ {
+ return automationPeer.Match(visual);
+ });
+ if (m_uia.AutomationPeers.end() != iterator)
+ {
+ // Mirror the change to the visuals above.
+ m_uia.FragmentRoot->RemoveChild(iterator->GetAutomationProvider());
+ m_uia.FragmentRoot->AddChildToEnd(iterator->GetAutomationProvider());
+ }
+ }
+ else
+ {
+ Output_AddVisual(point, controlPressed);
+ }
+ }
+
+
+ void
+ DrawingIsland::Input_OnRightButtonPressed(
+ const winrt::PointerEventArgs& args)
+ {
+ OnRightClick(args.CurrentPoint().Position());
+ }
+
+ void
+ DrawingIsland::OnRightClick(const float2 point)
+ {
+ // TODO - what is the purpose of this?
+ UNREFERENCED_PARAMETER(point);
+ // auto selectedVisual = HitTestVisual(point);
+ }
+
+ void
+ DrawingIsland::Input_OnPointerMoved(
+ const winrt::PointerEventArgs& args)
+ {
+ if (m_items.SelectedItem)
+ {
+ auto& visual = m_items.SelectedItem->GetVisual();
+ float2 const point = args.CurrentPoint().Position();
+
+ visual.Offset(
+ { point.x + m_items.Offset.x,
+ point.y + m_items.Offset.y,
+ 0.0f });
+ }
+ }
+
+
+ void
+ DrawingIsland::Island_OnClosed()
+ {
+
+ }
+
+
+ void
+ DrawingIsland::Island_OnStateChanged()
+ {
+ if (m_prevState.RasterizationScale != m_island.RasterizationScale())
+ {
+ float newScale = m_island.RasterizationScale();
+
+ m_prevState.RasterizationScale = newScale;
+
+ m_output.TextRenderer->SetDpiScale(newScale);
+
+ for (auto& item : m_items.Items)
+ {
+ item->OnDpiScaleChanged();
+ }
+ }
+
+ if (m_prevState.LayoutDirection != m_island.LayoutDirection())
+ {
+ Environment_SetLayoutDirection();
+ }
+
+ Output_UpdateCurrentColorVisual();
+ }
+
+
+ void
+ DrawingIsland::Environment_SetLayoutDirection()
+ {
+ if (m_island.LayoutDirection() == ContentLayoutDirection::RightToLeft)
+ {
+ // The following will mirror the visuals. If any text is inside the visuals the text is
+ // also mirrored. The text will need another RelativeOffsetAdjustment and Scale to
+ // return to the normal space.
+
+ m_output.RootVisual.RelativeOffsetAdjustment(winrt::float3(1, 0, 0));
+ m_output.RootVisual.Scale(winrt::float3(-1, 1, 1));
+ }
+ else
+ {
+ m_output.RootVisual.RelativeOffsetAdjustment(winrt::float3(0, 0, 0));
+ m_output.RootVisual.Scale(winrt::float3(1, 1, 1));
+ }
+ m_prevState.LayoutDirection = m_island.LayoutDirection();
+ }
+
+
+ void
+ DrawingIsland::OnDirect3DDeviceLost(
+ DeviceLostHelper const* /* sender */,
+ DeviceLostEventArgs const& /* args */)
+ {
+ // This call comes in on a Threadpool worker thread, so use the DispatcherQueue
+ // to marshal the call to the UI thread.
+ m_island.DispatcherQueue().TryEnqueue(
+ [this] {
+ // Recreate the text renderer's D3D and D2D devices.
+ m_output.TextRenderer->RecreateDirect2DDevice();
+
+ // Give each item an opportunity to recreate its device-dependent resources.
+ for (auto& item : m_items.Items)
+ {
+ item->OnDeviceLost();
+ }
+
+ // Listen for device lost on the new device.
+ m_output.DeviceLostHelper.WatchDevice(m_output.TextRenderer->GetDevice());
+ });
+ }
+
+
+ void
+ DrawingIsland::Output_Initialize()
+ {
+ // Create the background visual.
+ m_background.Visual = m_output.Compositor.CreateSpriteVisual();
+ m_background.Visual.RelativeSizeAdjustment({ 1.0f, 1.0f });
+
+ m_background.BrushDefault = m_output.Compositor.CreateColorBrush(
+ winrt::Color{ 0xFF, 0x20, 0x20, 0x20 });
+
+ m_background.BrushA = m_output.Compositor.CreateColorBrush(
+ winrt::Color{ 0xFF, 0x99, 0x20, 0x20 });
+
+ m_background.BrushB = m_output.Compositor.CreateColorBrush(
+ winrt::Color{ 0xFF, 0x20, 0x99, 0x20 });
+
+ m_background.BrushC = m_output.Compositor.CreateColorBrush(
+ winrt::Color{ 0xFF, 0x20, 0x20, 0x99 });
+
+ m_background.Visual.Brush(m_background.BrushDefault);
+ m_output.RootVisual.Children().InsertAtTop(m_background.Visual);
+
+ for (int i = 0; i < _countof(m_output.ColorBrushes); i++)
+ {
+ m_output.ColorBrushes[i] = m_output.Compositor.CreateColorBrush(s_colors[i]);
+
+ winrt::Color halfTransparent = s_colors[i];
+ halfTransparent.A = 0x80;
+ m_output.HalfTransparentColorBrushes[i] =
+ m_output.Compositor.CreateColorBrush(halfTransparent);
+ }
+
+ winrt::ContainerVisual drawingVisualsRoot = m_output.Compositor.CreateContainerVisual();
+ m_items.Visuals = drawingVisualsRoot.Children();
+ m_output.RootVisual.Children().InsertAtTop(drawingVisualsRoot);
+
+ m_items.CurrentColorVisual = m_output.Compositor.CreateSpriteVisual();
+ m_items.CurrentColorVisual.Offset({0.0f, 0.0f, 0.0f});
+ m_output.RootVisual.Children().InsertAtTop(m_items.CurrentColorVisual);
+
+ Output_UpdateSystemBackdrop();
+
+ Output_UpdateCurrentColorVisual();
+ }
+
+
+ void
+ DrawingIsland::Output_AddVisual(
+ float2 const point,
+ bool halfTransparent)
+ {
+ // Determine the visual background and text colors.
+ Color backgroundColor = s_colors[m_output.CurrentColorIndex];
+ Color textColor = { 0xFF, 0, 0, 0 };
+ if (halfTransparent)
+ {
+ backgroundColor.A /= 2;
+ textColor.A /= 2;
+ }
+
+ // Create a TextElement object.
+ auto textItem = std::make_unique(
+ m_output.TextRenderer,
+ backgroundColor,
+ textColor,
+ s_colorNames[m_output.CurrentColorIndex]
+ );
+
+ // Get the visual and its size in DIPs.
+ auto& visual = textItem->GetVisual();
+ float2 size = visual.Size();
+
+ // Set the visual's offset.
+ visual.Offset({ point.x - size.x / 2.0f, point.y - size.y / 2.0f, 0.0f });
+
+ // Add the new text element to the vector.
+ m_items.Items.push_back(std::move(textItem));
+
+ // Add the visual as a child of the container visual.
+ m_items.Visuals.InsertAtTop(visual);
+
+ m_items.SelectedItem = m_items.Items.back().get();
+ m_items.Offset.x = -size.x / 2.0f;
+ m_items.Offset.y = -size.y / 2.0f;
+
+ Accessibility_CreateItemFragment(visual);
+ }
+
+
+ void
+ DrawingIsland::Output_UpdateCurrentColorVisual()
+ {
+ m_items.CurrentColorVisual.Brush(m_output.ColorBrushes[m_output.CurrentColorIndex]);
+ m_items.CurrentColorVisual.Offset({0.0f, m_island.ActualSize().y - 25.0f, 0.0f});
+ m_items.CurrentColorVisual.Size({m_island.ActualSize().x, 25.0f});
+ }
+
+
+ void
+ DrawingIsland::Output_UpdateSystemBackdrop()
+ {
+ if (m_background.BackdropEnabled && nullptr == m_background.BackdropController)
+ {
+ // Reduce the opacity of the background color visual so that we can see
+ // the Mica/DesktopAcrylic behind it.
+ m_background.Visual.Opacity(0.1f);
+
+ // Create a new SystemBackdropConfiguration if we do not already have one.
+ if (nullptr == m_background.BackdropConfiguration)
+ {
+ m_background.BackdropConfiguration = winrt::SystemBackdropConfiguration();
+ }
+
+ // Decide between Mica and DesktopAcrylic.
+ if (winrt::MicaController::IsSupported())
+ {
+ m_background.BackdropController = winrt::MicaController();
+
+ }
+ else
+ {
+ m_background.BackdropController = winrt::DesktopAcrylicController();
+ }
+
+ // Link the SystemBackdropConfiguration to our SystemBackdropController.
+ m_background.BackdropController.SetSystemBackdropConfiguration(
+ m_background.BackdropConfiguration);
+
+ // Add our island as the target.
+ m_background.BackdropController.AddSystemBackdropTarget(m_island);
+ }
+ else
+ {
+ // Reset the background opacity to 1.0
+ m_background.Visual.Opacity(1.0f);
+
+ if (nullptr != m_background.BackdropController)
+ {
+ // Clean up our SystemBackdropController.
+ m_background.BackdropController.RemoveAllSystemBackdropTargets();
+ m_background.BackdropController.Close();
+ m_background.BackdropController = nullptr;
+ }
+ }
+ }
+
+ void
+ DrawingIsland::Environment_Initialize()
+ {
+ auto window = m_island.Environment();
+
+ (void)window.SettingChanged(
+ [this](winrt::ContentIslandEnvironment const&,
+ winrt::ContentEnvironmentSettingChangedEventArgs const& args)
+ {
+ return Environment_OnSettingChanged(args);
+ });
+
+ (void)window.StateChanged(
+ [this](winrt::ContentIslandEnvironment const& sender, winrt::IInspectable const&)
+ {
+ return Environment_OnStateChanged(sender);
+ });
+ }
+
+
+ void
+ DrawingIsland::Environment_OnSettingChanged(
+ const winrt::ContentEnvironmentSettingChangedEventArgs& args)
+ {
+ auto settingChanged = args.SettingName();
+
+ if (settingChanged == L"intl")
+ {
+ m_background.Visual.Brush(m_background.BrushA);
+ }
+ }
+
+
+ void
+ DrawingIsland::Environment_OnStateChanged(winrt::ContentIslandEnvironment const& /*sender*/)
+ {
+
+ }
+} // namespace winrt::OneTest::ContentIslandHelpers::implementation
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.h
new file mode 100644
index 000000000..a1924001f
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIsland.h
@@ -0,0 +1,300 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include "DrawingIsland.g.h"
+#include "AutomationFragmentRoot.h"
+#include "AutomationPeer.h"
+#include "TextRenderer.h"
+#include "DeviceLostHelper.h"
+#include "TextItem.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ struct DrawingIsland :
+ public DrawingIslandT<
+ DrawingIsland,
+ Microsoft::UI::Input::IInputPreTranslateKeyboardSourceHandler>,
+ IAutomationCallbackHandler
+ {
+ public:
+ // Construction
+
+ DrawingIsland(
+ const winrt::Compositor& compositor);
+
+ ~DrawingIsland();
+
+ // IClosable methods
+ void Close();
+
+ // Properties
+
+ bool EnableBackgroundTransparency()
+ {
+ return m_background.BackdropEnabled;
+ }
+
+ void EnableBackgroundTransparency(
+ bool value);
+
+ winrt::ContentIsland Island() const
+ {
+ return m_island;
+ }
+
+ // Methods
+
+ void LeftClickAndRelease(
+ const float2 currentPoint);
+
+ void RightClickAndRelease(
+ const float2 currentPoint);
+
+ void SetIslandOpacity(float islandOpacity)
+ {
+ m_output.Opacity = islandOpacity;
+ }
+
+ void SetColorIndex(std::uint32_t colorIndex)
+ {
+ m_output.CurrentColorIndex = std::clamp(
+ colorIndex, 0, _countof(s_colors) - 1);
+
+ if (m_output.CurrentColorIndex >= 4)
+ {
+ m_background.BrushDefault =
+ m_output.Compositor.CreateColorBrush(s_colors[m_output.CurrentColorIndex]);
+
+ m_background.Visual.Brush(m_background.BrushDefault);
+ }
+ Output_UpdateCurrentColorVisual();
+ }
+
+ // IInputKeyboardSourcePreTranslateHandler methods
+ IFACEMETHOD(OnDirectMessage)(
+ IInputPreTranslateKeyboardSourceInterop* source,
+ const MSG* msg,
+ UINT keyboardModifiers,
+ _Inout_ bool* handled);
+
+ IFACEMETHOD(OnTreeMessage)(
+ IInputPreTranslateKeyboardSourceInterop* source,
+ const MSG* msg,
+ UINT keyboardModifiers,
+ _Inout_ bool* handled);
+
+ // IAutomationCallbackHandler overrides.
+ winrt::Windows::Graphics::RectInt32 GetScreenBoundsForAutomationFragment(
+ _In_::IUnknown const* const sender) const override;
+
+ winrt::com_ptr GetFragmentFromPoint(
+ _In_ double x,
+ _In_ double y) const override;
+
+ winrt::com_ptr GetFragmentInFocus() const override;
+
+ private:
+ Item* HitTestItem(float2 const& point) const;
+
+ void Accessibility_Initialize();
+
+ void Accessibility_CreateItemFragment(
+ const winrt::Visual& itemVisual);
+
+ void Accessibility_OnAutomationProviderRequested(
+ const winrt::ContentIsland& island,
+ const winrt::ContentIslandAutomationProviderRequestedEventArgs& args);
+
+ void Input_Initialize();
+
+ bool Input_OnKeyDown(
+ winrt::Windows::System::VirtualKey virtualKey);
+
+ bool Input_AcceleratorKeyActivated(
+ winrt::Windows::System::VirtualKey virtualKey);
+
+ void Input_OnLeftButtonPressed(
+ const winrt::PointerEventArgs& args);
+
+ void Input_OnRightButtonPressed(
+ const winrt::PointerEventArgs& args);
+
+ void Input_OnPointerMoved(
+ const winrt::PointerEventArgs& args);
+
+ void Input_OnPointerReleased();
+
+ void OnLeftClick(
+ const float2 point,
+ bool controlPressed);
+
+ void OnRightClick(
+ const float2 currentPoint);
+
+ void Island_OnClosed();
+
+ void Island_OnStateChanged();
+
+ void OnDirect3DDeviceLost(
+ DeviceLostHelper const* /* sender */,
+ DeviceLostEventArgs const& /* args */);
+
+ void Output_Initialize();
+
+ void Output_AddVisual(
+ const float2 point,
+ bool halfTransparent);
+
+ void Output_UpdateCurrentColorVisual();
+
+ void Output_UpdateSystemBackdrop();
+
+ void Environment_Initialize();
+
+ void Environment_OnSettingChanged(
+ const winrt::ContentEnvironmentSettingChangedEventArgs& args);
+
+ void Environment_OnStateChanged(winrt::ContentIslandEnvironment const& sender);
+
+ void Environment_SetLayoutDirection();
+
+ private:
+ static inline winrt::Color s_colors[] =
+ {
+ { 0xFF, 0x5B, 0x9B, 0xD5 },
+ { 0xFF, 0xED, 0x7D, 0x31 },
+ { 0xFF, 0x70, 0xAD, 0x47 },
+ { 0xFF, 0xFF, 0xC0, 0x00 },
+ { 0xFF, 0xFA, 0xEB, 0xD7 },
+ { 0xFF, 0xFF, 0xFF, 0xFF },
+ { 0xFF, 0xFF, 0xFA, 0xFA },
+ { 0xFF, 0xFF, 0xC0, 0xCB },
+ { 0xFF, 0xB0, 0xE0, 0xE6 },
+ { 0xFF, 0x98, 0xFB, 0x98 },
+ { 0xFF, 0x87, 0xCE, 0xFA },
+ };
+
+ static inline std::wstring s_colorNames[] =
+ {
+ L"Blue",
+ L"Orange",
+ L"Green",
+ L"Yellow",
+ L"AntiqueWhite",
+ L"White",
+ L"Snow",
+ L"Pink",
+ L"PowderBlue",
+ L"PaleGreen",
+ L"LightSkyBlue",
+ };
+
+ // The underlying Island holding everything together.
+ winrt::ContentIsland m_island{ nullptr };
+
+ // Output
+ struct
+ {
+ winrt::Compositor Compositor{ nullptr };
+
+ winrt::ContainerVisual RootVisual{ nullptr };
+
+ std::shared_ptr TextRenderer;
+ DeviceLostHelper DeviceLostHelper;
+
+ float Opacity{ 0.5f };
+
+ // Current color used for new items
+ unsigned int CurrentColorIndex = 0;
+
+ // Cached brushes for items
+ winrt::CompositionColorBrush ColorBrushes[_countof(s_colors)]
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr };
+
+ winrt::CompositionColorBrush HalfTransparentColorBrushes[_countof(s_colors)]
+ { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr, nullptr, nullptr, nullptr };
+ } m_output;
+
+ // Input handling
+ struct
+ {
+ // Keyboard input handling
+ winrt::InputKeyboardSource KeyboardSource{ nullptr };
+
+ // Message loop integration
+ winrt::InputPreTranslateKeyboardSource PretranslateSource{ nullptr };
+
+ // Spatial input handling (mouse, pen, touch, etc.)
+ winrt::InputPointerSource PointerSource{ nullptr };
+
+ // Focus navigation handling
+ winrt::InputFocusController FocusController{ nullptr };
+ } m_input;
+
+ // Background behind the items
+ struct Background
+ {
+ winrt::CompositionColorBrush BrushDefault{ nullptr };
+ winrt::CompositionColorBrush BrushA{ nullptr };
+ winrt::CompositionColorBrush BrushB{ nullptr };
+ winrt::CompositionColorBrush BrushC{ nullptr };
+ winrt::SpriteVisual Visual{ nullptr };
+ winrt::RectangleClip Clip{ nullptr };
+
+ // System backdrops (Mica on Win11+, DesktopAcrylic on Win10)
+ bool BackdropEnabled{ true };
+ winrt::SystemBackdropConfiguration BackdropConfiguration{ nullptr };
+ winrt::ISystemBackdropControllerWithTargets BackdropController{ nullptr };
+ } m_background;
+
+ // Drawing items being manipulated.
+ struct
+ {
+ // The container visual's Children collection. Each Item's visual must be
+ // added to this collection to be rendered.
+ winrt::VisualCollection Visuals{ nullptr };
+
+ // Vector of Item objects representing items that can be manipulated, in
+ // back-to-front order. Each item has an associated Visual.
+ std::vector> Items;
+
+ // Pointer to the currently-selected item, if any.
+ Item* SelectedItem{ nullptr };
+
+ // Offset from the top-left corner of the selected item to the pointer.
+ float2 Offset{};
+
+ // Visual that shows the current color.
+ winrt::SpriteVisual CurrentColorVisual{ nullptr };
+ } m_items;
+
+ struct
+ {
+ float RasterizationScale = 0;
+
+ winrt::ContentLayoutDirection LayoutDirection =
+ winrt::ContentLayoutDirection::LeftToRight;
+ } m_prevState;
+
+ struct
+ {
+ // The UIA parent Root for this Island that contains the fragment children.
+ winrt::com_ptr FragmentRoot{ nullptr };
+
+ // Map a given square (Visual) to its UIA fragment object.
+ std::vector AutomationPeers{};
+ } m_uia;
+ };
+}
+
+namespace winrt::DrawingIslandComponents::factory_implementation
+{
+ struct DrawingIsland :
+ DrawingIslandT
+ {
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.def b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.def
new file mode 100644
index 000000000..24e7c1235
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.def
@@ -0,0 +1,3 @@
+EXPORTS
+DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE
+DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj
new file mode 100644
index 000000000..c817eed95
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj
@@ -0,0 +1,190 @@
+
+
+
+
+
+
+ true
+ true
+ true
+ true
+ {709c54e1-0f2f-4a59-80b2-4cfd08b720e5}
+ DrawingIslandComponents
+ DrawingIslandComponents
+ en-US
+ 14.0
+ 10.0.22621.0
+ 10.0.17134.0
+ true
+ C++/WinRT
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ DynamicLibrary
+ v143
+ v142
+ v141
+ v140
+ Unicode
+ false
+
+
+ true
+ true
+
+
+ false
+ true
+ false
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Use
+ pch.h
+ $(IntDir)pch.pch
+ Level4
+ %(AdditionalOptions) /bigobj
+ _WINRT_DLL;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)
+ $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories)
+
+
+ Console
+ false
+ DrawingIslandComponents.def
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+ Components.idl
+
+
+
+
+
+
+
+
+
+
+ Create
+
+
+ Components.idl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters
new file mode 100644
index 000000000..8d5d319bd
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/DrawingIslandComponents.vcxproj.filters
@@ -0,0 +1,83 @@
+
+
+
+
+ accd3aa8-1ba0-4223-9bbe-0c431709210b
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms
+
+
+ {926ab91d-31b4-48c3-b9a4-e681349f27f0}
+
+
+ {d824b7c5-294e-46a7-ae4e-2d146beef954}
+
+
+ {23c94a0e-e18d-4439-9afc-234fafb5cfcb}
+
+
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.cpp
new file mode 100644
index 000000000..4e28b475e
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "Item.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ Item::Item(winrt::Compositor const& compositor) :
+ m_visual(compositor.CreateSpriteVisual())
+ {
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.h
new file mode 100644
index 000000000..14d8a7569
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/Item.h
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ // Abstract base class for an item that owns a SpriteVisual and can
+ // re-rasterize the sprite if the DPI changes.
+ class Item
+ {
+ public:
+ Item(winrt::Compositor const& compositor);
+
+ virtual ~Item()
+ {
+ }
+
+ virtual void OnDpiScaleChanged()
+ {
+ }
+
+ virtual void OnDeviceLost()
+ {
+ }
+
+ winrt::SpriteVisual const& GetVisual() const noexcept
+ {
+ return m_visual;
+ }
+
+ private:
+ winrt::SpriteVisual m_visual;
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/PropertySheet.props b/Samples/Islands/WpfCalculator/DrawingIslandComponents/PropertySheet.props
new file mode 100644
index 000000000..e34141b01
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/PropertySheet.props
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.cpp
new file mode 100644
index 000000000..823c4469c
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.cpp
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "TextItem.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ TextItem::TextItem(
+ std::shared_ptr const& textRenderer,
+ Windows::UI::Color backgroundColor,
+ Windows::UI::Color textColor,
+ std::wstring const& text) :
+ Item(textRenderer->GetCompositor()),
+ m_textRenderer(textRenderer),
+ m_backgroundColor(backgroundColor),
+ m_textColor(textColor),
+ m_text(text)
+ {
+ InitializeVisual();
+ }
+
+ void TextItem::InitializeVisual()
+ {
+ // Render the text to the sprite visual.
+ m_textRenderer->Render(m_text.c_str(), m_backgroundColor, m_textColor, GetVisual());
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.h
new file mode 100644
index 000000000..e0754bf4a
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextItem.h
@@ -0,0 +1,40 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include "TextRenderer.h"
+#include "Item.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ class TextItem final : public Item
+ {
+ public:
+ TextItem(
+ std::shared_ptr const& textRenderer,
+ Windows::UI::Color backgroundColor,
+ Windows::UI::Color textColor,
+ std::wstring const& text);
+
+ void OnDpiScaleChanged() override
+ {
+ // Re-render the text using the current DPI scale.
+ InitializeVisual();
+ }
+
+ void OnDeviceLost() override
+ {
+ // Re-render the text using the current device.
+ InitializeVisual();
+ }
+
+ private:
+ void InitializeVisual();
+
+ std::shared_ptr m_textRenderer;
+ Windows::UI::Color m_backgroundColor;
+ Windows::UI::Color m_textColor;
+ std::wstring m_text;
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.cpp
new file mode 100644
index 000000000..c071f768f
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.cpp
@@ -0,0 +1,201 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "TextRenderer.h"
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ TextRenderer::TextRenderer(winrt::Compositor compositor) : m_compositor(compositor)
+ {
+ // Create the DWrite factory object.
+ winrt::check_hresult(DWriteCreateFactory(
+ DWRITE_FACTORY_TYPE_SHARED,
+ __uuidof(decltype(*m_dwriteFactory)),
+ reinterpret_cast<::IUnknown**>(m_dwriteFactory.put())));
+
+ // Create an object that encapsulates text formatting properties.
+ constexpr float defaultFontSize = 16;
+ winrt::check_hresult(m_dwriteFactory->CreateTextFormat(
+ L"Segoe UI",
+ nullptr,
+ DWRITE_FONT_WEIGHT_NORMAL,
+ DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL,
+ defaultFontSize,
+ L"en-US",
+ m_textFormat.put()));
+ winrt::check_hresult(m_textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP));
+
+ // Create the D2D factory.
+ winrt::check_hresult(D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, m_d2dFactory.put()));
+
+ // Create the Direct3D and Direct2D device objects.
+ CreateDirect2DDevice();
+
+ // Create the composition graphics device.
+ auto compositorInterop = m_compositor.as();
+ ICompositionGraphicsDevice compositionGraphicsDevice;
+ winrt::check_hresult(compositorInterop->CreateGraphicsDevice(m_d2dDevice.get(), &compositionGraphicsDevice));
+ m_compositionGraphicsDevice = compositionGraphicsDevice.as();
+ }
+
+ void TextRenderer::RecreateDirect2DDevice()
+ {
+ // Release the old Direct2D and Direct2D device objects.
+ m_dxgiDevice = nullptr;
+ m_d2dDevice = nullptr;
+
+ // Create new Direct3D and Direct2D device objects.
+ CreateDirect2DDevice();
+
+ // Restore the composition graphics device to health by pointing to the new Direct2D device.
+ auto compositionGraphicsDeviceInterop = m_compositionGraphicsDevice.as();
+ winrt::check_hresult(compositionGraphicsDeviceInterop->SetRenderingDevice(m_d2dDevice.get()));
+ }
+
+ void TextRenderer::CreateDirect2DDevice()
+ {
+ uint32_t createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+
+ // Array with DirectX hardware feature levels in order of preference.
+ static const D3D_FEATURE_LEVEL featureLevels[] =
+ {
+ D3D_FEATURE_LEVEL_11_1,
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ D3D_FEATURE_LEVEL_9_3,
+ D3D_FEATURE_LEVEL_9_2,
+ D3D_FEATURE_LEVEL_9_1
+ };
+
+ // Create the Direct3D 11 API device object and a corresponding context.
+ winrt::com_ptr<::ID3D11Device> d3dDevice;
+ winrt::com_ptr<::ID3D11DeviceContext> d3dImmediateContext;
+ D3D_FEATURE_LEVEL d3dFeatureLevel{ D3D_FEATURE_LEVEL_9_1 };
+
+ winrt::check_hresult(D3D11CreateDevice(
+ nullptr, // Default adapter.
+ D3D_DRIVER_TYPE_HARDWARE,
+ 0, // Not asking for a software driver, so not passing a module to one.
+ createDeviceFlags, // Set debug and Direct2D compatibility flags.
+ featureLevels,
+ ARRAYSIZE(featureLevels),
+ D3D11_SDK_VERSION,
+ d3dDevice.put(),
+ &d3dFeatureLevel,
+ d3dImmediateContext.put()));
+
+ // Initialize Direct2D resources.
+ D2D1_FACTORY_OPTIONS d2d1FactoryOptions{ D2D1_DEBUG_LEVEL_NONE };
+
+ // Create the Direct2D device object.
+ // Obtain the underlying DXGI device of the Direct3D device.
+ auto dxgiDevice = d3dDevice.as<::IDXGIDevice>();
+
+ winrt::com_ptr d2dDevice;
+ winrt::check_hresult(m_d2dFactory->CreateDevice(dxgiDevice.get(), d2dDevice.put()));
+
+ // Save the newly-created objects.
+ m_dxgiDevice = std::move(dxgiDevice);
+ m_d2dDevice = std::move(d2dDevice);
+ }
+
+ void TextRenderer::Render(
+ _In_z_ WCHAR const* text,
+ Windows::UI::Color backgroundColor,
+ Windows::UI::Color textColor,
+ SpriteVisual const& visual)
+ {
+ // Margins between the layout bounds of the text and the edges of the visual.
+ // These are in device-independent pixels (DIPs).
+ constexpr float marginLeft = 5;
+ constexpr float marginRight = 5;
+ constexpr float marginTop = 5;
+ constexpr float marginBottom = 5;
+
+ // Create the IDWriteTextlayout object. This will be used to render the text
+ // and can also be used to get properties, such as the size.
+ winrt::com_ptr textLayout;
+ winrt::check_hresult(m_dwriteFactory->CreateTextLayout(
+ text,
+ static_cast(wcslen(text)),
+ m_textFormat.get(),
+ /*maxWidth*/ 0,
+ /*maxHeight*/ 0,
+ /*out*/ textLayout.put()));
+
+ // Get the metrics from the text layout, and add the margins to compute the
+ // width and height of the visual.
+ DWRITE_TEXT_METRICS textMetrics;
+ winrt::check_hresult(textLayout->GetMetrics(/*out*/ &textMetrics));
+ const float width = textMetrics.width + (marginLeft + marginRight);
+ const float height = textMetrics.height + (marginTop + marginBottom);
+
+ visual.Size(float2(width, height));
+
+ try
+ {
+ // Create a composition surface to draw to.
+ CompositionDrawingSurface drawingSurface = m_compositionGraphicsDevice.CreateDrawingSurface(
+ winrt::Windows::Foundation::Size(width * m_dpiScale, height * m_dpiScale),
+ winrt::Microsoft::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
+ winrt::Microsoft::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
+ auto drawingSurfaceInterop = drawingSurface.as();
+
+ // Begin drawing to get a Direct2D device context.
+ winrt::com_ptr deviceContext;
+ POINT pixelOffset;
+ winrt::check_hresult(drawingSurfaceInterop->BeginDraw(
+ nullptr,
+ __uuidof(ID2D1DeviceContext),
+ deviceContext.put_void(),
+ &pixelOffset));
+
+ // Set the DPI of the device context, where 96 DPI corresponds to a 1.0 scale factor.
+ deviceContext->SetDpi(m_dpiScale * 96, m_dpiScale * 96);
+
+ // Compute the origin (top-left corner) of the text layout in DIPs by converting
+ // the drawing surface offset from pixels to DIPs and adding the margin.
+ D2D_POINT_2F origin{
+ pixelOffset.x / m_dpiScale + marginLeft,
+ pixelOffset.y / m_dpiScale + marginTop };
+
+ // Clear the background and draw the text.
+ deviceContext->Clear(ToColorF(backgroundColor));
+
+ // Use ClearType antialiasing if rendering onto an opaque background.
+ // Otherwise use grayscale.
+ deviceContext->SetTextAntialiasMode(
+ backgroundColor.A == 255 ?
+ D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE :
+ D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
+
+ // Create the brush used to fill the text.
+ winrt::com_ptr textBrush;
+ winrt::check_hresult(deviceContext->CreateSolidColorBrush(ToColorF(textColor), textBrush.put()));
+
+ // Draw the text layout object.
+ deviceContext->DrawTextLayout(origin, textLayout.get(), textBrush.get());
+
+ // End drawing.
+ winrt::check_hresult(drawingSurfaceInterop->EndDraw());
+
+ // Create the surface brush and set it as the visual's brush.
+ auto surfaceBrush = m_compositor.CreateSurfaceBrush();
+ surfaceBrush.Surface(drawingSurface);
+ visual.Brush(surfaceBrush);
+ }
+ catch (winrt::hresult_error& e)
+ {
+ // Silently ignore device-removed error.
+ // We'll draw again after the device is recreated.
+ if (e.code() == DXGI_ERROR_DEVICE_REMOVED)
+ return;
+
+ // Rethrow all other exceptions.
+ throw;
+ }
+ }
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.h
new file mode 100644
index 000000000..d05072d5a
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/TextRenderer.h
@@ -0,0 +1,58 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+namespace winrt::DrawingIslandComponents::implementation
+{
+ class TextRenderer final
+ {
+ public:
+ TextRenderer(winrt::Compositor compositor);
+
+ void SetDpiScale(float scale)
+ {
+ m_dpiScale = scale;
+ }
+
+ void Render(
+ _In_z_ WCHAR const* text,
+ Windows::UI::Color backgroundColor,
+ Windows::UI::Color textColor,
+ SpriteVisual const& visual);
+
+ winrt::Compositor const& GetCompositor() const noexcept
+ {
+ return m_compositor;
+ }
+
+ winrt::com_ptr<::IDXGIDevice> const& GetDevice() const noexcept
+ {
+ return m_dxgiDevice;
+ }
+
+ void RecreateDirect2DDevice();
+
+ private:
+ static inline D2D_COLOR_F ToColorF(Windows::UI::Color color)
+ {
+ return D2D_COLOR_F{ color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f };
+ }
+
+ void CreateDirect2DDevice();
+
+ winrt::Compositor m_compositor;
+
+ // Device-independent resources.
+ winrt::com_ptr<::IDWriteFactory7> m_dwriteFactory;
+ winrt::com_ptr<::IDWriteTextFormat> m_textFormat;
+ winrt::com_ptr<::ID2D1Factory7> m_d2dFactory;
+
+ // Device-dependent resources.
+ winrt::com_ptr<::IDXGIDevice> m_dxgiDevice;
+ winrt::com_ptr<::ID2D1Device6> m_d2dDevice;
+ CompositionGraphicsDevice m_compositionGraphicsDevice{ nullptr };
+
+ float m_dpiScale = 1.0f;
+ };
+}
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/packages.config b/Samples/Islands/WpfCalculator/DrawingIslandComponents/packages.config
new file mode 100644
index 000000000..8401faf51
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.cpp b/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.cpp
new file mode 100644
index 000000000..40e691ba7
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.cpp
@@ -0,0 +1,4 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.h b/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.h
new file mode 100644
index 000000000..f15602e4b
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/pch.h
@@ -0,0 +1,67 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+// Windows Platform Win32
+#include
+#include
+#include
+#include
+
+// DWriteWrite and Direct2D for rendering text
+#include
+#include
+#include
+#include
+
+// WIL
+#include
+#include
+#include
+
+// Windows Platform WinRT
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Windows App SDK
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//#include
+#include
+#include
+
+#include
+
+namespace winrt
+{
+ using namespace winrt::Windows::Foundation;
+ using namespace winrt::Windows::Foundation::Collections;
+ using namespace winrt::Windows::Foundation::Numerics;
+ using namespace winrt::Windows::Graphics::DirectX;
+ using namespace winrt::Windows::Graphics::DirectX::Direct3D11;
+ using namespace winrt::Windows::System;
+ using namespace winrt::Windows::UI;
+
+ using namespace winrt::Microsoft::UI;
+ using namespace winrt::Microsoft::UI::Composition;
+ using namespace winrt::Microsoft::UI::Composition::SystemBackdrops;
+ using namespace winrt::Microsoft::UI::Content;
+ using namespace winrt::Microsoft::UI::Dispatching;
+ using namespace winrt::Microsoft::UI::Input;
+ using namespace winrt::Microsoft::UI::Windowing;
+}
+
+using namespace Windows::Foundation::Numerics;
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandComponents/readme.txt b/Samples/Islands/WpfCalculator/DrawingIslandComponents/readme.txt
new file mode 100644
index 000000000..f269f729f
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandComponents/readme.txt
@@ -0,0 +1,23 @@
+========================================================================
+ C++/WinRT DrawingIslandComponent Project Overview
+========================================================================
+
+This project demonstrates how to get started authoring Windows Runtime
+classes directly with standard C++, using the C++/WinRT SDK component
+to generate implementation headers from interface (IDL) files. The
+generated Windows Runtime component binary and WinMD files should then
+be bundled with the Universal Windows Platform (UWP) app consuming them.
+
+Steps:
+1. Create an interface (IDL) file to define your Windows Runtime class,
+ its default interface, and any other interfaces it implements.
+2. Build the project once to generate module.g.cpp, module.h.cpp, and
+ implementation templates under the "Generated Files" folder, as
+ well as skeleton class definitions under "Generated Files\sources".
+3. Use the skeleton class definitions for reference to implement your
+ Windows Runtime classes.
+
+========================================================================
+Learn more about C++/WinRT here:
+http://aka.ms/cppwinrt/
+========================================================================
diff --git a/Samples/Islands/WpfCalculator/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj b/Samples/Islands/WpfCalculator/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj
new file mode 100644
index 000000000..cba03600e
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/DrawingIslandCsProjection/DrawingIslandCsProjection.csproj
@@ -0,0 +1,37 @@
+
+
+
+
+ net9.0-windows10.0.22621.0
+ enable
+ enable
+ x64;x86;ARM64
+
+
+ win-x86;win-x64;win-arm64
+
+ true
+
+
+
+
+
+
+ DrawingIslandComponents
+
+
+ $(OutDir)
+ 10.0.17763.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Samples/Islands/WpfCalculator/WpfCalculator.sln b/Samples/Islands/WpfCalculator/WpfCalculator.sln
new file mode 100644
index 000000000..759d4e907
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/WpfCalculator.sln
@@ -0,0 +1,94 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34728.123
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DrawingIslandComponents", "DrawingIslandComponents\DrawingIslandComponents.vcxproj", "{709C54E1-0F2F-4A59-80B2-4CFD08B720E5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CalculatorDemo", "CalculatorDemo\CalculatorDemo.csproj", "{5731865D-6685-47A7-8877-5DBAF39B54CD}"
+EndProject
+Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "CalculatorDemoPackage", "CalculatorDemoPackage\CalculatorDemoPackage.wapproj", "{0A343519-113B-4EF9-959C-30F559524BC4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo3_Step1", "Demo3_Step1", "{D326EA21-1EE1-4D67-A0CE-898D9EC84300}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo4_Step2", "Demo4_Step2", "{1C23C858-0772-4881-A947-32E8870C35AE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawingIslandCsProjection", "DrawingIslandCsProjection\DrawingIslandCsProjection.csproj", "{4A5A8328-28E9-4B32-9284-6BCB33553E10}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|ARM64.Build.0 = Debug|ARM64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x64.ActiveCfg = Debug|x64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x64.Build.0 = Debug|x64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x86.ActiveCfg = Debug|Win32
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Debug|x86.Build.0 = Debug|Win32
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|ARM64.ActiveCfg = Release|ARM64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|ARM64.Build.0 = Release|ARM64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x64.ActiveCfg = Release|x64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x64.Build.0 = Release|x64
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x86.ActiveCfg = Release|Win32
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5}.Release|x86.Build.0 = Release|Win32
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|ARM64.Build.0 = Debug|ARM64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|x64.ActiveCfg = Debug|x64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|x64.Build.0 = Debug|x64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|x86.ActiveCfg = Debug|x86
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Debug|x86.Build.0 = Debug|x86
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|ARM64.ActiveCfg = Release|ARM64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|ARM64.Build.0 = Release|ARM64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|x64.ActiveCfg = Release|x64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|x64.Build.0 = Release|x64
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|x86.ActiveCfg = Release|x86
+ {5731865D-6685-47A7-8877-5DBAF39B54CD}.Release|x86.Build.0 = Release|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|ARM64.Build.0 = Debug|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x64.ActiveCfg = Debug|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x64.Build.0 = Debug|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x64.Deploy.0 = Debug|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x86.ActiveCfg = Debug|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x86.Build.0 = Debug|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Debug|x86.Deploy.0 = Debug|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|ARM64.ActiveCfg = Release|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|ARM64.Build.0 = Release|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|ARM64.Deploy.0 = Release|ARM64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x64.ActiveCfg = Release|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x64.Build.0 = Release|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x64.Deploy.0 = Release|x64
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x86.ActiveCfg = Release|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x86.Build.0 = Release|x86
+ {0A343519-113B-4EF9-959C-30F559524BC4}.Release|x86.Deploy.0 = Release|x86
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|ARM64.Build.0 = Debug|ARM64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|x64.ActiveCfg = Debug|x64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|x64.Build.0 = Debug|x64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|x86.ActiveCfg = Debug|x86
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Debug|x86.Build.0 = Debug|x86
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|ARM64.ActiveCfg = Release|ARM64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|ARM64.Build.0 = Release|ARM64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|x64.ActiveCfg = Release|x64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|x64.Build.0 = Release|x64
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|x86.ActiveCfg = Release|x86
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {709C54E1-0F2F-4A59-80B2-4CFD08B720E5} = {1C23C858-0772-4881-A947-32E8870C35AE}
+ {0A343519-113B-4EF9-959C-30F559524BC4} = {D326EA21-1EE1-4D67-A0CE-898D9EC84300}
+ {4A5A8328-28E9-4B32-9284-6BCB33553E10} = {1C23C858-0772-4881-A947-32E8870C35AE}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {85542A88-746B-4646-9027-3AA360D075C2}
+ EndGlobalSection
+EndGlobal
diff --git a/Samples/Islands/WpfCalculator/directory.build.props b/Samples/Islands/WpfCalculator/directory.build.props
new file mode 100644
index 000000000..96ca6b023
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/directory.build.props
@@ -0,0 +1,14 @@
+
+
+
+
+
+ True
+
+
+ $([MSBuild]::NormalizeDirectory('$(SolutionDir)', '_build', '$(Platform)', '$(Configuration)'))
+ $([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'bin'))
+ $([MSBuild]::NormalizeDirectory('$(BuildOutDir)', '$(MSBuildProjectName)', 'obj'))
+
+
+
diff --git a/Samples/Islands/WpfCalculator/img/image-1.png b/Samples/Islands/WpfCalculator/img/image-1.png
new file mode 100644
index 000000000..2242c7637
Binary files /dev/null and b/Samples/Islands/WpfCalculator/img/image-1.png differ
diff --git a/Samples/Islands/WpfCalculator/img/image.png b/Samples/Islands/WpfCalculator/img/image.png
new file mode 100644
index 000000000..821a8eb90
Binary files /dev/null and b/Samples/Islands/WpfCalculator/img/image.png differ
diff --git a/Samples/Islands/WpfCalculator/readme.md b/Samples/Islands/WpfCalculator/readme.md
new file mode 100644
index 000000000..31b7255c1
--- /dev/null
+++ b/Samples/Islands/WpfCalculator/readme.md
@@ -0,0 +1,38 @@
+
+Here's the basic process:
+
+
+
+**Demo2_Step2_RunCalcWithThemes**
+* Open WpfCalculator.sln.
+* Ensure settings are:
+
+
+
+* ctrl+f5
+
+**Demo2_Step3_AddPackaging**
+* Change Startup project to:
+
+
+
+* ctrl+f5
+* App runs, and looks the same. Note how the Start Menu now contains "CalculatorDemoPackage".
+
+**Demo3_Step1_AddWasdk**
+* Remove comments for "Demo3_Step1_AddWasdk"
+* Demo will look the same.
+
+
+**Demo3_Step2_AddCompact**
+* Remove comments for "Demo3_Step2_AddCompact"
+* ctrl+f5
+* App now has "compact" mode
+
+**Demo4_Step2_AddIsland**
+* Remove comments for "Demo4_Step2_AddIsland"
+* ctrl+f5
+* App now has an option File | Add DrawingIsland.
+
+
+