diff --git a/templates/Angular2Spa/.babelrc b/templates/Angular2Spa/.babelrc
new file mode 100644
index 0000000..c13c5f6
--- /dev/null
+++ b/templates/Angular2Spa/.babelrc
@@ -0,0 +1,3 @@
+{
+ "presets": ["es2015"]
+}
diff --git a/templates/Angular2Spa/.gitignore b/templates/Angular2Spa/.gitignore
new file mode 100644
index 0000000..342cf93
--- /dev/null
+++ b/templates/Angular2Spa/.gitignore
@@ -0,0 +1,233 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+/wwwroot/dist/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Microsoft Azure ApplicationInsights config file
+ApplicationInsights.config
+
+# Windows Store app package directory
+AppPackages/
+BundleArtifacts/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+
+# FAKE - F# Make
+.fake/
diff --git a/templates/Angular2Spa/ClientApp/boot.ts b/templates/Angular2Spa/ClientApp/boot.ts
new file mode 100644
index 0000000..c5bb264
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/boot.ts
@@ -0,0 +1,9 @@
+import 'bootstrap/dist/css/bootstrap.css';
+
+import { bootstrap } from 'angular2/platform/browser';
+import { FormBuilder } from 'angular2/common';
+import * as router from 'angular2/router';
+import { Http, HTTP_PROVIDERS } from 'angular2/http';
+import { App } from './components/app/app';
+
+bootstrap(App, [router.ROUTER_BINDINGS, HTTP_PROVIDERS, FormBuilder]);
diff --git a/templates/Angular2Spa/ClientApp/components/about/about.html b/templates/Angular2Spa/ClientApp/components/about/about.html
new file mode 100644
index 0000000..bbdd3b1
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/about/about.html
@@ -0,0 +1,3 @@
+
About
+
+Use this area to provide additional information.
diff --git a/templates/Angular2Spa/ClientApp/components/about/about.ts b/templates/Angular2Spa/ClientApp/components/about/about.ts
new file mode 100644
index 0000000..0f9bbf7
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/about/about.ts
@@ -0,0 +1,10 @@
+import * as ng from 'angular2/core';
+
+@ng.Component({
+ selector: 'about'
+})
+@ng.View({
+ template: require('./about.html')
+})
+export class About {
+}
diff --git a/templates/Angular2Spa/ClientApp/components/app/app.css b/templates/Angular2Spa/ClientApp/components/app/app.css
new file mode 100644
index 0000000..cea1842
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/app/app.css
@@ -0,0 +1,21 @@
+/* Wrapping element */
+/* Set some basic padding to keep content from hitting the edges */
+.body-content {
+ padding-top: 50px;
+ padding-bottom: 20px;
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+/* Set widths on the form inputs since otherwise they're 100% wide */
+input,
+select,
+textarea {
+ max-width: 280px;
+}
+
+/* Carousel */
+.carousel-caption p {
+ font-size: 20px;
+ line-height: 1.4;
+}
diff --git a/templates/Angular2Spa/ClientApp/components/app/app.html b/templates/Angular2Spa/ClientApp/components/app/app.html
new file mode 100644
index 0000000..018305b
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/app/app.html
@@ -0,0 +1,28 @@
+
+
+
diff --git a/templates/Angular2Spa/ClientApp/components/app/app.ts b/templates/Angular2Spa/ClientApp/components/app/app.ts
new file mode 100644
index 0000000..b1632fe
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/app/app.ts
@@ -0,0 +1,22 @@
+import * as ng from 'angular2/core';
+import * as router from 'angular2/router';
+import { Http, HTTP_BINDINGS } from 'angular2/http';
+import { Home } from '../home/home.ts';
+import { About } from '../about/about';
+import { Counter } from '../counter/counter';
+
+@ng.Component({
+ selector: 'app'
+})
+@router.RouteConfig([
+ { path: '/', component: Home, name: 'Home' },
+ { path: '/about', component: About, name: 'About' },
+ { path: '/counter', component: Counter, name: 'Counter' }
+])
+@ng.View({
+ template: require('./app.html'),
+ styles: [require('./app.css')],
+ directives: [router.ROUTER_DIRECTIVES]
+})
+export class App {
+}
diff --git a/templates/Angular2Spa/ClientApp/components/counter/counter.html b/templates/Angular2Spa/ClientApp/components/counter/counter.html
new file mode 100644
index 0000000..4d1dfd9
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/counter/counter.html
@@ -0,0 +1,7 @@
+Counter
+
+This is a simple example of an Angular 2 component.
+
+Current count: {{ currentCount }}
+
+
diff --git a/templates/Angular2Spa/ClientApp/components/counter/counter.ts b/templates/Angular2Spa/ClientApp/components/counter/counter.ts
new file mode 100644
index 0000000..33f72e7
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/counter/counter.ts
@@ -0,0 +1,15 @@
+import * as ng from 'angular2/core';
+
+@ng.Component({
+ selector: 'counter'
+})
+@ng.View({
+ template: require('./counter.html')
+})
+export class Counter {
+ public currentCount = 0;
+
+ public incrementCounter() {
+ this.currentCount++;
+ }
+}
diff --git a/templates/Angular2Spa/ClientApp/components/home/home.html b/templates/Angular2Spa/ClientApp/components/home/home.html
new file mode 100644
index 0000000..e4343e8
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/home/home.html
@@ -0,0 +1,36 @@
+
+
+
+
+
diff --git a/templates/Angular2Spa/ClientApp/components/home/home.ts b/templates/Angular2Spa/ClientApp/components/home/home.ts
new file mode 100644
index 0000000..b5042c0
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/components/home/home.ts
@@ -0,0 +1,14 @@
+import * as ng from 'angular2/core';
+import { carouselItems } from '../../data/CarouselItems';
+import { linkLists } from '../../data/HomepageLinkLists';
+
+@ng.Component({
+ selector: 'home'
+})
+@ng.View({
+ template: require('./home.html')
+})
+export class Home {
+ public carouselItems = carouselItems;
+ public linkLists = linkLists;
+}
diff --git a/templates/Angular2Spa/ClientApp/data/CarouselItems.ts b/templates/Angular2Spa/ClientApp/data/CarouselItems.ts
new file mode 100644
index 0000000..bc96797
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/data/CarouselItems.ts
@@ -0,0 +1,28 @@
+export interface CarouselItem {
+ imageUrl: string;
+ imageAlt: string;
+ text: string;
+ learnMoreUrl: string;
+}
+
+export const carouselItems: CarouselItem[] = [{
+ imageUrl: "/images/ASP-NET-Banners-01.png",
+ imageAlt: "ASP.NET",
+ text: "Learn how to build ASP.NET apps that can run anywhere.",
+ learnMoreUrl: "http://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409"
+}, {
+ imageUrl: "/images/Banner-02-VS.png",
+ imageAlt: "Visual Studio",
+ text: "There are powerful new features in Visual Studio for building modern web apps.",
+ learnMoreUrl: "http://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409"
+}, {
+ imageUrl: "/images/ASP-NET-Banners-02.png",
+ imageAlt: "Package Management",
+ text: "Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.",
+ learnMoreUrl: "http://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409"
+}, {
+ imageUrl: "/images/Banner-01-Azure.png",
+ imageAlt: "Microsoft Azure",
+ text: "Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.",
+ learnMoreUrl: "http://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409"
+}];
diff --git a/templates/Angular2Spa/ClientApp/data/HomepageLinkLists.ts b/templates/Angular2Spa/ClientApp/data/HomepageLinkLists.ts
new file mode 100644
index 0000000..162df19
--- /dev/null
+++ b/templates/Angular2Spa/ClientApp/data/HomepageLinkLists.ts
@@ -0,0 +1,43 @@
+export interface LinkList {
+ title: string;
+ entries: string[];
+}
+
+export const linkLists: LinkList[] = [{
+ title: "Application uses",
+ entries: [
+ "Sample pages using ASP.NET MVC 6",
+ "Gulp and Bower for managing client-side libraries",
+ "Theming using Bootstrap"
+ ]
+}, {
+ title: "How to",
+ entries: [
+ "Add a Controller and View",
+ "Add an appsetting in config and access it in app.",
+ "Manage User Secrets using Secret Manager.",
+ "Use logging to log a message.",
+ "Add packages using NuGet.",
+ "Add client packages using Bower.",
+ "Target development, staging or production environment."
+ ]
+}, {
+ title: "Overview",
+ entries: [
+ "Conceptual overview of what is ASP.NET 5",
+ "Fundamentals of ASP.NET 5 such as Startup and middleware.",
+ "Working with Data",
+ "Security",
+ "Client side development",
+ "Develop on different platforms",
+ "Read more on the documentation site"
+ ]
+}, {
+ title: "Run & Deploy",
+ entries: [
+ "Run your app",
+ "Run your app on .NET Core",
+ "Run commands in your project.json",
+ "Publish to Microsoft Azure Web Apps"
+ ]
+}];
diff --git a/templates/Angular2Spa/Controllers/HomeController.cs b/templates/Angular2Spa/Controllers/HomeController.cs
new file mode 100755
index 0000000..7c59f1e
--- /dev/null
+++ b/templates/Angular2Spa/Controllers/HomeController.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Mvc;
+
+namespace WebApplicationBasic.Controllers
+{
+ public class HomeController : Controller
+ {
+ public IActionResult Index()
+ {
+ return View();
+ }
+
+ public IActionResult Error()
+ {
+ return View();
+ }
+ }
+}
diff --git a/templates/Angular2Spa/Dockerfile b/templates/Angular2Spa/Dockerfile
new file mode 100644
index 0000000..63d7c45
--- /dev/null
+++ b/templates/Angular2Spa/Dockerfile
@@ -0,0 +1,11 @@
+FROM microsoft/aspnet:1.0.0-rc1-update1
+
+RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list
+RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/*
+
+COPY . /app
+WORKDIR /app
+RUN ["dnu", "restore"]
+
+EXPOSE 5000/tcp
+ENTRYPOINT ["dnx", "-p", "project.json", "web"]
diff --git a/templates/Angular2Spa/README.md b/templates/Angular2Spa/README.md
new file mode 100644
index 0000000..4e494c9
--- /dev/null
+++ b/templates/Angular2Spa/README.md
@@ -0,0 +1,40 @@
+# Welcome to ASP.NET 5
+
+We've made some big updates in this release, so it’s **important** that you spend a few minutes to learn what’s new.
+
+You've created a new ASP.NET 5 project. [Learn what's new](http://go.microsoft.com/fwlink/?LinkId=518016)
+
+## This application consists of:
+
+* Sample pages using ASP.NET MVC 6
+* [Gulp](http://go.microsoft.com/fwlink/?LinkId=518007) and [Bower](http://go.microsoft.com/fwlink/?LinkId=518004) for managing client-side libraries
+* Theming using [Bootstrap](http://go.microsoft.com/fwlink/?LinkID=398939)
+
+## How to
+
+* [Add a Controller and View](http://go.microsoft.com/fwlink/?LinkID=398600)
+* [Add an appsetting in config and access it in app.](http://go.microsoft.com/fwlink/?LinkID=699562)
+* [Manage User Secrets using Secret Manager.](http://go.microsoft.com/fwlink/?LinkId=699315)
+* [Use logging to log a message.](http://go.microsoft.com/fwlink/?LinkId=699316)
+* [Add packages using NuGet.](http://go.microsoft.com/fwlink/?LinkId=699317)
+* [Add client packages using Bower.](http://go.microsoft.com/fwlink/?LinkId=699318)
+* [Target development, staging or production environment.](http://go.microsoft.com/fwlink/?LinkId=699319)
+
+## Overview
+
+* [Conceptual overview of what is ASP.NET 5](http://go.microsoft.com/fwlink/?LinkId=518008)
+* [Fundamentals of ASP.NET 5 such as Startup and middleware.](http://go.microsoft.com/fwlink/?LinkId=699320)
+* [Working with Data](http://go.microsoft.com/fwlink/?LinkId=398602)
+* [Security](http://go.microsoft.com/fwlink/?LinkId=398603)
+* [Client side development](http://go.microsoft.com/fwlink/?LinkID=699321)
+* [Develop on different platforms](http://go.microsoft.com/fwlink/?LinkID=699322)
+* [Read more on the documentation site](http://go.microsoft.com/fwlink/?LinkID=699323)
+
+## Run & Deploy
+
+* [Run your app](http://go.microsoft.com/fwlink/?LinkID=517851)
+* [Run your app on .NET Core](http://go.microsoft.com/fwlink/?LinkID=517852)
+* [Run commands in your project.json](http://go.microsoft.com/fwlink/?LinkID=517853)
+* [Publish to Microsoft Azure Web Apps](http://go.microsoft.com/fwlink/?LinkID=398609)
+
+We would love to hear your [feedback](http://go.microsoft.com/fwlink/?LinkId=518015)
diff --git a/templates/Angular2Spa/Startup.cs b/templates/Angular2Spa/Startup.cs
new file mode 100755
index 0000000..429f9d7
--- /dev/null
+++ b/templates/Angular2Spa/Startup.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNet.Builder;
+using Microsoft.AspNet.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace WebApplicationBasic
+{
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ // Set up configuration sources.
+ var builder = new ConfigurationBuilder()
+ .AddJsonFile("appsettings.json")
+ .AddEnvironmentVariables();
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; set; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ // Add framework services.
+ services.AddMvc();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ loggerFactory.AddConsole(Configuration.GetSection("Logging"));
+ loggerFactory.AddDebug();
+
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+ else
+ {
+ app.UseExceptionHandler("/Home/Error");
+ }
+
+ app.UseIISPlatformHandler();
+
+ app.UseStaticFiles();
+
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute(
+ name: "default",
+ template: "{controller=Home}/{action=Index}/{id?}");
+
+ routes.MapSpaFallbackRoute(
+ name: "spa-fallback",
+ defaults: new { controller = "Home", action = "Index" });
+ });
+ }
+
+ // Entry point for the application.
+ public static void Main(string[] args) => Microsoft.AspNet.Hosting.WebApplication.Run(args);
+ }
+}
diff --git a/templates/Angular2Spa/Views/Home/Index.cshtml b/templates/Angular2Spa/Views/Home/Index.cshtml
new file mode 100644
index 0000000..693b74f
--- /dev/null
+++ b/templates/Angular2Spa/Views/Home/Index.cshtml
@@ -0,0 +1,9 @@
+@{
+ ViewData["Title"] = "Home Page";
+}
+
+Loading...
+
+@section scripts {
+
+}
diff --git a/templates/Angular2Spa/Views/Shared/Error.cshtml b/templates/Angular2Spa/Views/Shared/Error.cshtml
new file mode 100755
index 0000000..a288cb0
--- /dev/null
+++ b/templates/Angular2Spa/Views/Shared/Error.cshtml
@@ -0,0 +1,6 @@
+@{
+ ViewData["Title"] = "Error";
+}
+
+Error.
+An error occurred while processing your request.
diff --git a/templates/Angular2Spa/Views/Shared/_Layout.cshtml b/templates/Angular2Spa/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000..a94428f
--- /dev/null
+++ b/templates/Angular2Spa/Views/Shared/_Layout.cshtml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ @ViewData["Title"] - WebApplicationBasic
+
+
+
+
+
+
+
+ @RenderBody()
+
+
+ @RenderSection("scripts", required: false)
+
+
diff --git a/templates/Angular2Spa/Views/_ViewImports.cshtml b/templates/Angular2Spa/Views/_ViewImports.cshtml
new file mode 100755
index 0000000..7252adc
--- /dev/null
+++ b/templates/Angular2Spa/Views/_ViewImports.cshtml
@@ -0,0 +1,2 @@
+@using WebApplicationBasic
+@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
diff --git a/templates/Angular2Spa/Views/_ViewStart.cshtml b/templates/Angular2Spa/Views/_ViewStart.cshtml
new file mode 100755
index 0000000..66b5da2
--- /dev/null
+++ b/templates/Angular2Spa/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "_Layout";
+}
diff --git a/templates/Angular2Spa/appsettings.json b/templates/Angular2Spa/appsettings.json
new file mode 100755
index 0000000..e5472e5
--- /dev/null
+++ b/templates/Angular2Spa/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "IncludeScopes": false,
+ "LogLevel": {
+ "Default": "Verbose",
+ "System": "Information",
+ "Microsoft": "Information"
+ }
+ }
+}
diff --git a/templates/Angular2Spa/package.json b/templates/Angular2Spa/package.json
new file mode 100644
index 0000000..2847eb3
--- /dev/null
+++ b/templates/Angular2Spa/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "WebApplicationBasic",
+ "version": "0.0.0",
+ "devDependencies": {
+ "babel-loader": "^6.2.3",
+ "babel-preset-es2015": "^6.5.0",
+ "babel-preset-react": "^6.5.0",
+ "bootstrap": "^3.3.6",
+ "css-loader": "^0.23.1",
+ "expose-loader": "^0.7.1",
+ "extendify": "^1.0.0",
+ "extract-text-webpack-plugin": "^1.0.1",
+ "file-loader": "^0.8.5",
+ "jquery": "^2.2.1",
+ "raw-loader": "^0.5.1",
+ "style-loader": "^0.13.0",
+ "ts-loader": "^0.8.1",
+ "typescript": "^1.8.2",
+ "url-loader": "^0.5.7",
+ "webpack": "^1.12.14"
+ },
+ "dependencies": {
+ "angular2": "^2.0.0-beta.7",
+ "babel-core": "^6.5.2",
+ "es6-shim": "^0.33.13",
+ "es7-reflect-metadata": "^1.5.5",
+ "reflect-metadata": "^0.1.2",
+ "rxjs": "^5.0.0-beta.2",
+ "zone.js": "^0.5.15"
+ }
+}
diff --git a/templates/Angular2Spa/project.json b/templates/Angular2Spa/project.json
new file mode 100755
index 0000000..033f196
--- /dev/null
+++ b/templates/Angular2Spa/project.json
@@ -0,0 +1,51 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true
+ },
+ "tooling": {
+ "defaultNamespace": "WebApplicationBasic"
+ },
+
+ "dependencies": {
+ "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final",
+ "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
+ "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
+ "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
+ "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
+ "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
+ "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
+ "Microsoft.Extensions.Configuration.FileProviderExtensions" : "1.0.0-rc1-final",
+ "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final",
+ "Microsoft.Extensions.Logging": "1.0.0-rc1-final",
+ "Microsoft.Extensions.Logging.Console": "1.0.0-rc1-final",
+ "Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
+ "Microsoft.AspNet.AngularServices": "1.0.0-alpha7"
+ },
+
+ "commands": {
+ "web": "Microsoft.AspNet.Server.Kestrel"
+ },
+
+ "frameworks": {
+ "dnx451": {},
+ "dnxcore50": {}
+ },
+
+ "exclude": [
+ "wwwroot",
+ "node_modules",
+ ],
+ "publishExclude": [
+ "node_modules",
+ "**.xproj",
+ "**.user",
+ "**.vspscc"
+ ],
+ "scripts": {
+ "prepublish": [
+ "npm install",
+ "webpack"
+ ]
+ }
+}
diff --git a/templates/Angular2Spa/tsconfig.json b/templates/Angular2Spa/tsconfig.json
new file mode 100644
index 0000000..361d496
--- /dev/null
+++ b/templates/Angular2Spa/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "moduleResolution": "node",
+ "target": "es6",
+ "sourceMap": true,
+ "experimentalDecorators": true
+ },
+ "exclude": [
+ "node_modules"
+ ]
+}
diff --git a/templates/Angular2Spa/tsd.json b/templates/Angular2Spa/tsd.json
new file mode 100644
index 0000000..79fb09e
--- /dev/null
+++ b/templates/Angular2Spa/tsd.json
@@ -0,0 +1,12 @@
+{
+ "version": "v4",
+ "repo": "borisyankov/DefinitelyTyped",
+ "ref": "master",
+ "path": "typings",
+ "bundle": "typings/tsd.d.ts",
+ "installed": {
+ "requirejs/require.d.ts": {
+ "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7"
+ }
+ }
+}
diff --git a/templates/Angular2Spa/typings/requirejs/require.d.ts b/templates/Angular2Spa/typings/requirejs/require.d.ts
new file mode 100644
index 0000000..e9cdb3e
--- /dev/null
+++ b/templates/Angular2Spa/typings/requirejs/require.d.ts
@@ -0,0 +1,397 @@
+// Type definitions for RequireJS 2.1.20
+// Project: http://requirejs.org/
+// Definitions by: Josh Baldwin
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+/*
+require-2.1.8.d.ts may be freely distributed under the MIT license.
+
+Copyright (c) 2013 Josh Baldwin https://github.com/jbaldwin/require.d.ts
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+declare module 'module' {
+ var mod: {
+ config: () => any;
+ id: string;
+ uri: string;
+ }
+ export = mod;
+}
+
+interface RequireError extends Error {
+
+ /**
+ * The error ID that maps to an ID on a web page.
+ **/
+ requireType: string;
+
+ /**
+ * Required modules.
+ **/
+ requireModules: string[];
+
+ /**
+ * The original error, if there is one (might be null).
+ **/
+ originalError: Error;
+}
+
+interface RequireShim {
+
+ /**
+ * List of dependencies.
+ **/
+ deps?: string[];
+
+ /**
+ * Name the module will be exported as.
+ **/
+ exports?: string;
+
+ /**
+ * Initialize function with all dependcies passed in,
+ * if the function returns a value then that value is used
+ * as the module export value instead of the object
+ * found via the 'exports' string.
+ * @param dependencies
+ * @return
+ **/
+ init?: (...dependencies: any[]) => any;
+}
+
+interface RequireConfig {
+
+ // The root path to use for all module lookups.
+ baseUrl?: string;
+
+ // Path mappings for module names not found directly under
+ // baseUrl.
+ paths?: { [key: string]: any; };
+
+
+ // Dictionary of Shim's.
+ // does not cover case of key->string[]
+ shim?: { [key: string]: RequireShim; };
+
+ /**
+ * For the given module prefix, instead of loading the
+ * module with the given ID, substitude a different
+ * module ID.
+ *
+ * @example
+ * requirejs.config({
+ * map: {
+ * 'some/newmodule': {
+ * 'foo': 'foo1.2'
+ * },
+ * 'some/oldmodule': {
+ * 'foo': 'foo1.0'
+ * }
+ * }
+ * });
+ **/
+ map?: {
+ [id: string]: {
+ [id: string]: string;
+ };
+ };
+
+ /**
+ * Allows pointing multiple module IDs to a module ID that contains a bundle of modules.
+ *
+ * @example
+ * requirejs.config({
+ * bundles: {
+ * 'primary': ['main', 'util', 'text', 'text!template.html'],
+ * 'secondary': ['text!secondary.html']
+ * }
+ * });
+ **/
+ bundles?: { [key: string]: string[]; };
+
+ /**
+ * AMD configurations, use module.config() to access in
+ * define() functions
+ **/
+ config?: { [id: string]: {}; };
+
+ /**
+ * Configures loading modules from CommonJS packages.
+ **/
+ packages?: {};
+
+ /**
+ * The number of seconds to wait before giving up on loading
+ * a script. The default is 7 seconds.
+ **/
+ waitSeconds?: number;
+
+ /**
+ * A name to give to a loading context. This allows require.js
+ * to load multiple versions of modules in a page, as long as
+ * each top-level require call specifies a unique context string.
+ **/
+ context?: string;
+
+ /**
+ * An array of dependencies to load.
+ **/
+ deps?: string[];
+
+ /**
+ * A function to pass to require that should be require after
+ * deps have been loaded.
+ * @param modules
+ **/
+ callback?: (...modules: any[]) => void;
+
+ /**
+ * If set to true, an error will be thrown if a script loads
+ * that does not call define() or have shim exports string
+ * value that can be checked.
+ **/
+ enforceDefine?: boolean;
+
+ /**
+ * If set to true, document.createElementNS() will be used
+ * to create script elements.
+ **/
+ xhtml?: boolean;
+
+ /**
+ * Extra query string arguments appended to URLs that RequireJS
+ * uses to fetch resources. Most useful to cache bust when
+ * the browser or server is not configured correctly.
+ *
+ * @example
+ * urlArgs: "bust= + (new Date()).getTime()
+ **/
+ urlArgs?: string;
+
+ /**
+ * Specify the value for the type="" attribute used for script
+ * tags inserted into the document by RequireJS. Default is
+ * "text/javascript". To use Firefox's JavasScript 1.8
+ * features, use "text/javascript;version=1.8".
+ **/
+ scriptType?: string;
+
+ /**
+ * If set to true, skips the data-main attribute scanning done
+ * to start module loading. Useful if RequireJS is embedded in
+ * a utility library that may interact with other RequireJS
+ * library on the page, and the embedded version should not do
+ * data-main loading.
+ **/
+ skipDataMain?: boolean;
+
+ /**
+ * Allow extending requirejs to support Subresource Integrity
+ * (SRI).
+ **/
+ onNodeCreated?: (node: HTMLScriptElement, config: RequireConfig, moduleName: string, url: string) => void;
+}
+
+// todo: not sure what to do with this guy
+interface RequireModule {
+
+ /**
+ *
+ **/
+ config(): {};
+
+}
+
+/**
+*
+**/
+interface RequireMap {
+
+ /**
+ *
+ **/
+ prefix: string;
+
+ /**
+ *
+ **/
+ name: string;
+
+ /**
+ *
+ **/
+ parentMap: RequireMap;
+
+ /**
+ *
+ **/
+ url: string;
+
+ /**
+ *
+ **/
+ originalName: string;
+
+ /**
+ *
+ **/
+ fullName: string;
+}
+
+interface Require {
+
+ /**
+ * Configure require.js
+ **/
+ config(config: RequireConfig): Require;
+
+ /**
+ * CommonJS require call
+ * @param module Module to load
+ * @return The loaded module
+ */
+ (module: string): any;
+
+ /**
+ * Start the main app logic.
+ * Callback is optional.
+ * Can alternatively use deps and callback.
+ * @param modules Required modules to load.
+ **/
+ (modules: string[]): void;
+
+ /**
+ * @see Require()
+ * @param ready Called when required modules are ready.
+ **/
+ (modules: string[], ready: Function): void;
+
+ /**
+ * @see http://requirejs.org/docs/api.html#errbacks
+ * @param ready Called when required modules are ready.
+ **/
+ (modules: string[], ready: Function, errback: Function): void;
+
+ /**
+ * Generate URLs from require module
+ * @param module Module to URL
+ * @return URL string
+ **/
+ toUrl(module: string): string;
+
+ /**
+ * Returns true if the module has already been loaded and defined.
+ * @param module Module to check
+ **/
+ defined(module: string): boolean;
+
+ /**
+ * Returns true if the module has already been requested or is in the process of loading and should be available at some point.
+ * @param module Module to check
+ **/
+ specified(module: string): boolean;
+
+ /**
+ * On Error override
+ * @param err
+ **/
+ onError(err: RequireError, errback?: (err: RequireError) => void): void;
+
+ /**
+ * Undefine a module
+ * @param module Module to undefine.
+ **/
+ undef(module: string): void;
+
+ /**
+ * Semi-private function, overload in special instance of undef()
+ **/
+ onResourceLoad(context: Object, map: RequireMap, depArray: RequireMap[]): void;
+}
+
+interface RequireDefine {
+
+ /**
+ * Define Simple Name/Value Pairs
+ * @param config Dictionary of Named/Value pairs for the config.
+ **/
+ (config: { [key: string]: any; }): void;
+
+ /**
+ * Define function.
+ * @param func: The function module.
+ **/
+ (func: () => any): void;
+
+ /**
+ * Define function with dependencies.
+ * @param deps List of dependencies module IDs.
+ * @param ready Callback function when the dependencies are loaded.
+ * callback param deps module dependencies
+ * callback return module definition
+ **/
+ (deps: string[], ready: Function): void;
+
+ /**
+ * Define module with simplified CommonJS wrapper.
+ * @param ready
+ * callback require requirejs instance
+ * callback exports exports object
+ * callback module module
+ * callback return module definition
+ **/
+ (ready: (require: Require, exports: { [key: string]: any; }, module: RequireModule) => any): void;
+
+ /**
+ * Define a module with a name and dependencies.
+ * @param name The name of the module.
+ * @param deps List of dependencies module IDs.
+ * @param ready Callback function when the dependencies are loaded.
+ * callback deps module dependencies
+ * callback return module definition
+ **/
+ (name: string, deps: string[], ready: Function): void;
+
+ /**
+ * Define a module with a name.
+ * @param name The name of the module.
+ * @param ready Callback function when the dependencies are loaded.
+ * callback return module definition
+ **/
+ (name: string, ready: Function): void;
+
+ /**
+ * Used to allow a clear indicator that a global define function (as needed for script src browser loading) conforms
+ * to the AMD API, any global define function SHOULD have a property called "amd" whose value is an object.
+ * This helps avoid conflict with any other existing JavaScript code that could have defined a define() function
+ * that does not conform to the AMD API.
+ * define.amd.jQuery is specific to jQuery and indicates that the loader is able to account for multiple version
+ * of jQuery being loaded simultaneously.
+ */
+ amd: Object;
+}
+
+// Ambient declarations for 'require' and 'define'
+declare var requirejs: Require;
+declare var require: Require;
+declare var define: RequireDefine;
diff --git a/templates/Angular2Spa/typings/tsd.d.ts b/templates/Angular2Spa/typings/tsd.d.ts
new file mode 100644
index 0000000..e7d781f
--- /dev/null
+++ b/templates/Angular2Spa/typings/tsd.d.ts
@@ -0,0 +1,2 @@
+
+///
diff --git a/templates/Angular2Spa/webpack.config.dev.js b/templates/Angular2Spa/webpack.config.dev.js
new file mode 100644
index 0000000..91b645f
--- /dev/null
+++ b/templates/Angular2Spa/webpack.config.dev.js
@@ -0,0 +1,8 @@
+module.exports = {
+ devtool: 'inline-source-map',
+ module: {
+ loaders: [
+ { test: /\.css/, exclude: /ClientApp/, loader: 'style!css' }
+ ]
+ }
+};
diff --git a/templates/Angular2Spa/webpack.config.js b/templates/Angular2Spa/webpack.config.js
new file mode 100644
index 0000000..44d5d5f
--- /dev/null
+++ b/templates/Angular2Spa/webpack.config.js
@@ -0,0 +1,35 @@
+var path = require('path');
+var webpack = require('webpack');
+var merge = require('extendify')({ isDeep: true, arrays: 'concat' });
+var devConfig = require('./webpack.config.dev');
+var prodConfig = require('./webpack.config.prod');
+var isDevelopment = process.env.ASPNET_ENV === 'Development';
+
+module.exports = merge({
+ resolve: {
+ extensions: [ '', '.js', '.ts' ]
+ },
+ module: {
+ loaders: [
+ { test: /\.ts(x?)$/, include: /ClientApp/, loader: 'babel-loader' },
+ { test: /\.ts(x?)$/, include: /ClientApp/, loader: 'ts-loader' },
+ { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' },
+ { test: /\.css$/, include: /ClientApp/, loader: 'raw-loader' },
+ { test: /\.html$/, loader: 'raw-loader' }
+ ]
+ },
+ entry: {
+ main: ['./ClientApp/boot.ts'],
+ vendor: ['angular2/bundles/angular2-polyfills.js', 'bootstrap', 'bootstrap/dist/css/bootstrap.css', 'style-loader', 'jquery', 'angular2/core', 'angular2/common', 'angular2/http', 'angular2/router', 'angular2/platform/browser']
+ },
+ output: {
+ path: path.join(__dirname, 'wwwroot', 'dist'),
+ filename: '[name].js',
+ publicPath: '/dist/'
+ },
+ plugins: [
+ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
+ new webpack.optimize.OccurenceOrderPlugin(),
+ new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js') // Moves vendor content out of other bundles
+ ]
+}, isDevelopment ? devConfig : prodConfig);
diff --git a/templates/Angular2Spa/webpack.config.prod.js b/templates/Angular2Spa/webpack.config.prod.js
new file mode 100644
index 0000000..17c70f3
--- /dev/null
+++ b/templates/Angular2Spa/webpack.config.prod.js
@@ -0,0 +1,18 @@
+var webpack = require('webpack');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+var extractCSS = new ExtractTextPlugin('site.css');
+
+module.exports = {
+ module: {
+ loaders: [
+ { test: /\.css/, exclude: /ClientApp/, loader: extractCSS.extract(['css']) },
+ ]
+ },
+ plugins: [
+ extractCSS,
+ new webpack.optimize.UglifyJsPlugin({
+ minimize: true,
+ mangle: false // Due to https://github.com/angular/angular/issues/6678
+ })
+ ]
+};
diff --git a/templates/Angular2Spa/wwwroot/favicon.ico b/templates/Angular2Spa/wwwroot/favicon.ico
new file mode 100755
index 0000000..a3a7999
Binary files /dev/null and b/templates/Angular2Spa/wwwroot/favicon.ico differ
diff --git a/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-01.png b/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-01.png
new file mode 100755
index 0000000..ad3c267
Binary files /dev/null and b/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-01.png differ
diff --git a/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-02.png b/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-02.png
new file mode 100755
index 0000000..16c37fc
Binary files /dev/null and b/templates/Angular2Spa/wwwroot/images/ASP-NET-Banners-02.png differ
diff --git a/templates/Angular2Spa/wwwroot/images/Banner-01-Azure.png b/templates/Angular2Spa/wwwroot/images/Banner-01-Azure.png
new file mode 100755
index 0000000..59fb923
Binary files /dev/null and b/templates/Angular2Spa/wwwroot/images/Banner-01-Azure.png differ
diff --git a/templates/Angular2Spa/wwwroot/images/Banner-02-VS.png b/templates/Angular2Spa/wwwroot/images/Banner-02-VS.png
new file mode 100755
index 0000000..c9f4611
Binary files /dev/null and b/templates/Angular2Spa/wwwroot/images/Banner-02-VS.png differ
diff --git a/templates/Angular2Spa/wwwroot/web.config b/templates/Angular2Spa/wwwroot/web.config
new file mode 100644
index 0000000..db6e6f4
--- /dev/null
+++ b/templates/Angular2Spa/wwwroot/web.config
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+