diff --git a/.tool-versions b/.tool-versions
index 63c2ed8..91cdd73 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1 +1 @@
-dotnet-core 8.0.414
+dotnet-core 8.0.413
diff --git a/ecosystem/database/1_core_language/setup.sh b/ecosystem/database/1_core_language/setup.sh
index 0e0a392..62cbe6d 100755
--- a/ecosystem/database/1_core_language/setup.sh
+++ b/ecosystem/database/1_core_language/setup.sh
@@ -1,3 +1,11 @@
echo "Installing EF Global Tool"
dotnet tool install -g dotnet-ef
echo "Done Installing EF Global Tool"
+
+# Useful Commands
+# 1. Create Migrations
+ # pattern: dotnet ef migrations add {Migration Name}
+dotnet ef migrations add InitialCreate
+
+# 2. Run Migrations
+dotnet ef database update
\ No newline at end of file
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/.devcontainer/devcontainer.json b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..8e63ad6
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/.devcontainer/devcontainer.json
@@ -0,0 +1,16 @@
+{
+ "name": "pizza_shop",
+ "build": {
+ "dockerfile": "../DockerFile.dev"
+ },
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "ms-dotnettools.csdevkit"
+ ],
+ "settings": {}
+ }
+ },
+ "workspaceMount": "source=${localWorkspaceFolder},target=/pizza_shop,type=bind,consistency=delegated",
+ "workspaceFolder": "/pizza_shop"
+}
\ No newline at end of file
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/Dockerfile.dev b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/Dockerfile.dev
new file mode 100644
index 0000000..dbf2d47
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/Dockerfile.dev
@@ -0,0 +1,5 @@
+FROM mcr.microsoft.com/devcontainers/dotnet:8.0
+
+RUN dotnet tool install --global dotnet-ef --version 8.0.0
+
+ENV PATH="$PATH:/root/.dotnet/tools"
\ No newline at end of file
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop.sln b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop.sln
new file mode 100644
index 0000000..a4f3cf7
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop.sln
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pizza_shop", "pizza_shop\pizza_shop.csproj", "{70096DE8-8824-3D33-70A2-FE4E18953E5B}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {70096DE8-8824-3D33-70A2-FE4E18953E5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {70096DE8-8824-3D33-70A2-FE4E18953E5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {70096DE8-8824-3D33-70A2-FE4E18953E5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {70096DE8-8824-3D33-70A2-FE4E18953E5B}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F5990F53-54B8-4D8D-A393-68F71D4BF4A0}
+ EndGlobalSection
+EndGlobal
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.Designer.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.Designer.cs
new file mode 100644
index 0000000..3c0eb0b
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.Designer.cs
@@ -0,0 +1,167 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using PizzaShop.Data;
+
+#nullable disable
+
+namespace pizza_shop.Migrations
+{
+ [DbContext(typeof(PizzaShopContext))]
+ [Migration("20251003024533_InitialCreate")]
+ partial class InitialCreate
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.20")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("PizzaShop.Models.Customer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Address")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Phone")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Customers");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CustomerId")
+ .HasColumnType("int");
+
+ b.Property("OrderFulfilled")
+ .HasColumnType("datetime2");
+
+ b.Property("OrderPlaced")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CustomerId");
+
+ b.ToTable("Orders");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.OrderDetail", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("OrderId")
+ .HasColumnType("int");
+
+ b.Property("ProductId")
+ .HasColumnType("int");
+
+ b.Property("Quantity")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderId");
+
+ b.HasIndex("ProductId");
+
+ b.ToTable("OrderDetails");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Product", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Price")
+ .HasColumnType("decimal(6,2)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Products");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.HasOne("PizzaShop.Models.Customer", "Customer")
+ .WithMany("Orders")
+ .HasForeignKey("CustomerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Customer");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.OrderDetail", b =>
+ {
+ b.HasOne("PizzaShop.Models.Order", "Order")
+ .WithMany("OrderDetails")
+ .HasForeignKey("OrderId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("PizzaShop.Models.Product", "Product")
+ .WithMany()
+ .HasForeignKey("ProductId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Order");
+
+ b.Navigation("Product");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Customer", b =>
+ {
+ b.Navigation("Orders");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.Navigation("OrderDetails");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.cs
new file mode 100644
index 0000000..d633d96
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/20251003024533_InitialCreate.cs
@@ -0,0 +1,124 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace pizza_shop.Migrations
+{
+ ///
+ public partial class InitialCreate : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Customers",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ FirstName = table.Column(type: "nvarchar(max)", nullable: false),
+ LastName = table.Column(type: "nvarchar(max)", nullable: false),
+ Address = table.Column(type: "nvarchar(max)", nullable: true),
+ Phone = table.Column(type: "nvarchar(max)", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Customers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Products",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(max)", nullable: false),
+ Price = table.Column(type: "decimal(6,2)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Products", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Orders",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ OrderPlaced = table.Column(type: "datetime2", nullable: false),
+ OrderFulfilled = table.Column(type: "datetime2", nullable: true),
+ CustomerId = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Orders", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Orders_Customers_CustomerId",
+ column: x => x.CustomerId,
+ principalTable: "Customers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "OrderDetails",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Quantity = table.Column(type: "int", nullable: false),
+ ProductId = table.Column(type: "int", nullable: false),
+ OrderId = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_OrderDetails", x => x.Id);
+ table.ForeignKey(
+ name: "FK_OrderDetails_Orders_OrderId",
+ column: x => x.OrderId,
+ principalTable: "Orders",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_OrderDetails_Products_ProductId",
+ column: x => x.ProductId,
+ principalTable: "Products",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_OrderDetails_OrderId",
+ table: "OrderDetails",
+ column: "OrderId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_OrderDetails_ProductId",
+ table: "OrderDetails",
+ column: "ProductId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Orders_CustomerId",
+ table: "Orders",
+ column: "CustomerId");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "OrderDetails");
+
+ migrationBuilder.DropTable(
+ name: "Orders");
+
+ migrationBuilder.DropTable(
+ name: "Products");
+
+ migrationBuilder.DropTable(
+ name: "Customers");
+ }
+ }
+}
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/PizzaShopContextModelSnapshot.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/PizzaShopContextModelSnapshot.cs
new file mode 100644
index 0000000..e35f57b
--- /dev/null
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Migrations/PizzaShopContextModelSnapshot.cs
@@ -0,0 +1,164 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using PizzaShop.Data;
+
+#nullable disable
+
+namespace pizza_shop.Migrations
+{
+ [DbContext(typeof(PizzaShopContext))]
+ partial class PizzaShopContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.20")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("PizzaShop.Models.Customer", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Address")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Phone")
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Customers");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("CustomerId")
+ .HasColumnType("int");
+
+ b.Property("OrderFulfilled")
+ .HasColumnType("datetime2");
+
+ b.Property("OrderPlaced")
+ .HasColumnType("datetime2");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CustomerId");
+
+ b.ToTable("Orders");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.OrderDetail", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("OrderId")
+ .HasColumnType("int");
+
+ b.Property("ProductId")
+ .HasColumnType("int");
+
+ b.Property("Quantity")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrderId");
+
+ b.HasIndex("ProductId");
+
+ b.ToTable("OrderDetails");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Product", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Price")
+ .HasColumnType("decimal(6,2)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Products");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.HasOne("PizzaShop.Models.Customer", "Customer")
+ .WithMany("Orders")
+ .HasForeignKey("CustomerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Customer");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.OrderDetail", b =>
+ {
+ b.HasOne("PizzaShop.Models.Order", "Order")
+ .WithMany("OrderDetails")
+ .HasForeignKey("OrderId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("PizzaShop.Models.Product", "Product")
+ .WithMany()
+ .HasForeignKey("ProductId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Order");
+
+ b.Navigation("Product");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Customer", b =>
+ {
+ b.Navigation("Orders");
+ });
+
+ modelBuilder.Entity("PizzaShop.Models.Order", b =>
+ {
+ b.Navigation("OrderDetails");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Program.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Program.cs
index 694fa2b..4670448 100644
--- a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Program.cs
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/Program.cs
@@ -1,2 +1,2 @@
// See https://aka.ms/new-console-template for more information
-Console.WriteLine("Graet Pizza Coming Soon");
+Console.WriteLine("Great Pizza Coming Soon");
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/pizza_shop.csproj b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/pizza_shop.csproj
index 96d3725..53140b6 100644
--- a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/pizza_shop.csproj
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/pizza_shop.csproj
@@ -9,6 +9,14 @@
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
\ No newline at end of file
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Data/PizzaShopContext.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Data/PizzaShopContext.cs
index 5991623..e92ef2e 100644
--- a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Data/PizzaShopContext.cs
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Data/PizzaShopContext.cs
@@ -3,6 +3,10 @@
namespace PizzaShop.Data;
+/*
+ This is the critical piece that Entity Framework uses to determine
+ the migrations to create.
+*/
public class PizzaShopContext : DbContext
{
public DbSet Customers { get; set; } = null!;
@@ -15,7 +19,7 @@ public class PizzaShopContext : DbContext
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
- optionsBuilder.UseSqlServer();
+ // Never hard code in PROD of-course
+ optionsBuilder.UseSqlServer("Server=localhost,1433; Database=PizzaShop; User Id=sa; Password=example_123; Encrypt=false; TrustServerCertificate=true; MultipleActiveResultSets=true;");
}
-
}
\ No newline at end of file
diff --git a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Models/OrderDetail.cs b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Models/OrderDetail.cs
index 691b0e6..961e529 100644
--- a/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Models/OrderDetail.cs
+++ b/ecosystem/database/4_experiments/4_applications/entity_framework_core/pizza_shop/pizza_shop/src/Models/OrderDetail.cs
@@ -26,7 +26,7 @@ It will be created as a shadow property.
This is a navigation property.
It will generate a One-to-Many ER Model.
*/
- public OrderDetail Order { get; set; } = null!;
+ public Order Order { get; set; } = null!;
/*
This is a navigation property.
diff --git a/setup.sh b/setup.sh
index be5b5bb..bf08536 100755
--- a/setup.sh
+++ b/setup.sh
@@ -1,17 +1,17 @@
VERSION=8.0.413
-echo "adding asdf dotnet-core plugin"
+echo "adding asdf .NET Core plugin"
asdf plugin add dotnet-core
echo "done"
-echo "installing dotnet-core "
+echo "Installing .NET Core SDK"
asdf install dotnet-core $VERSION
echo "done"
-echo "set version"
- asdf set dotnet-core $VERSION
+echo "Installing nuget"
+ brew install nuget
echo "done"
-echo "install nuget"
- brew install nuget
+echo "Installing .NET runtime"
+ brew install dotnet-runtime
echo "done"
\ No newline at end of file