├── .gitignore
├── LICENSE.md
├── app
├── common
│ ├── timer.ts
│ └── timespan.ts
├── contact-manager.html
├── contact-manager.ts
├── status-board
│ ├── status-board-floating.html
│ ├── status-board-floating.ts
│ ├── status-board.html
│ └── status-board.ts
├── tsconfig.json
└── twitter
│ └── twitter.ts
├── custom-types
└── ng2.custom.d.ts
├── gulpfile.js
├── package.json
├── readme.md
├── tsd.json
└── wwwroot
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 | .settings
13 | node_modules
14 | typings
15 | wwwroot/app
16 |
17 | # Build results
18 | [Dd]ebug/
19 | [Dd]ebugPublic/
20 | [Rr]elease/
21 | [Rr]eleases/
22 | x64/
23 | x86/
24 | build/
25 | bld/
26 | [Bb]in/
27 | [Oo]bj/
28 |
29 | # Visual Studo 2015 cache/options directory
30 | .vs/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | *_i.c
46 | *_p.c
47 | *_i.h
48 | *.ilk
49 | *.meta
50 | *.obj
51 | *.pch
52 | *.pdb
53 | *.pgc
54 | *.pgd
55 | *.rsp
56 | *.sbr
57 | *.tlb
58 | *.tli
59 | *.tlh
60 | *.tmp
61 | *.tmp_proj
62 | *.log
63 | *.vspscc
64 | *.vssscc
65 | .builds
66 | *.pidb
67 | *.svclog
68 | *.scc
69 |
70 | # Chutzpah Test files
71 | _Chutzpah*
72 |
73 | # Visual C++ cache files
74 | ipch/
75 | *.aps
76 | *.ncb
77 | *.opensdf
78 | *.sdf
79 | *.cachefile
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 | *.vspx
85 |
86 | # TFS 2012 Local Workspace
87 | $tf/
88 |
89 | # Guidance Automation Toolkit
90 | *.gpState
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding addin-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | # TODO: Comment the next line if you want to checkin your web deploy settings
137 | # but database connection strings (with potential passwords) will be unencrypted
138 | *.pubxml
139 | *.publishproj
140 |
141 | # NuGet Packages
142 | *.nupkg
143 | # The packages folder can be ignored because of Package Restore
144 | **/packages/*
145 | # except build/, which is used as an MSBuild target.
146 | !**/packages/build/
147 | # Uncomment if necessary however generally it will be regenerated when needed
148 | #!**/packages/repositories.config
149 |
150 | # Windows Azure Build Output
151 | csx/
152 | *.build.csdef
153 |
154 | # Windows Store app package directory
155 | AppPackages/
156 |
157 | # Others
158 | *.[Cc]ache
159 | ClientBin/
160 | [Ss]tyle[Cc]op.*
161 | ~$*
162 | *~
163 | *.dbmdl
164 | *.dbproj.schemaview
165 | *.pfx
166 | *.publishsettings
167 | node_modules/
168 | bower_components/
169 |
170 | # RIA/Silverlight projects
171 | Generated_Code/
172 |
173 | # Backup & report files from converting an old project file
174 | # to a newer Visual Studio version. Backup files are not needed,
175 | # because we have git ;-)
176 | _UpgradeReport_Files/
177 | Backup*/
178 | UpgradeLog*.XML
179 | UpgradeLog*.htm
180 |
181 | # SQL Server files
182 | *.mdf
183 | *.ldf
184 |
185 | # Business Intelligence projects
186 | *.rdl.data
187 | *.bim.layout
188 | *.bim_*.settings
189 |
190 | # Microsoft Fakes
191 | FakesAssemblies/
192 |
193 | # Node.js Tools for Visual Studio
194 | .ntvs_analysis.dat
195 |
196 | # Visual Studio 6 build log
197 | *.plg
198 |
199 | # Visual Studio 6 workspace options file
200 | *.opt
201 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Josh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/common/timer.ts:
--------------------------------------------------------------------------------
1 | import {TimeSpan} from './timespan';
2 |
3 | export class Timer {
4 | private _startTime: Date;
5 | private _endTime: Date;
6 |
7 | start() {
8 | this._startTime = new Date();
9 | }
10 |
11 | stop() {
12 | this._endTime = new Date();
13 | }
14 |
15 | reset() {
16 | this._startTime = new Date();
17 | this._endTime = null;
18 | }
19 |
20 | elapsed() {
21 | if (!this._startTime) {
22 | return new TimeSpan();
23 | }
24 |
25 | var endTime = this._endTime || new Date();
26 |
27 | return TimeSpan.fromDateTime(this._startTime, endTime);
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/app/common/timespan.ts:
--------------------------------------------------------------------------------
1 | export class TimeSpan {
2 | private _totalMilliseconds: number = 0;
3 |
4 | constructor(milliseconds: number = 0) {
5 | this._totalMilliseconds = milliseconds;
6 | }
7 |
8 | totalSeconds() {
9 | return this._totalMilliseconds / 1000;
10 | }
11 |
12 | totalMilliseconds() {
13 | return this._totalMilliseconds;
14 | }
15 |
16 | static fromDateTime(dateBegin: Date, dateEnd: Date) {
17 | if (!(dateBegin instanceof Date) && !(dateEnd instanceof Date)) {
18 | throw new Error("A begin and end date must be supplied and both must be of type Date");
19 | }
20 |
21 | return new TimeSpan(dateEnd.getTime() - dateBegin.getTime());
22 | }
23 | }
--------------------------------------------------------------------------------
/app/contact-manager.html:
--------------------------------------------------------------------------------
1 |
{{title}} by
2 |
3 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/contact-manager.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import {Component, View, bootstrap} from 'angular2/angular2';
4 | import {routerDirectives, routerInjectables, RouteConfig, Router} from 'angular2/router';
5 | import {StatusBoard} from './status-board/status-board';
6 | import {StatusBoardFloating} from './status-board/status-board-floating';
7 | import {TwitterLink} from './twitter/twitter';
8 |
9 | @Component({
10 | selector:'contact-manager'
11 | })
12 | @View({
13 | templateUrl:'app/contact-manager.html',
14 | directives:[routerDirectives, TwitterLink]
15 | })
16 | @RouteConfig([
17 | {path: '/status-board', as:'status-board', component:StatusBoard},
18 | {path: '/status-board-floating', as:'status-board-floating', component:StatusBoardFloating}
19 | ])
20 | class ContactManager{
21 | title: string;
22 |
23 | constructor(private router:Router){
24 | this.title = "Angular2 Databinding Examples";
25 | }
26 | }
27 |
28 | bootstrap(
29 | ContactManager,
30 | [
31 | routerInjectables
32 | ]
33 | );
--------------------------------------------------------------------------------
/app/status-board/status-board-floating.html:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 | |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/status-board/status-board-floating.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import {Component, View, NgFor, NgIf} from 'angular2/angular2';
4 |
5 | var dimensions = {
6 | rows: 30,
7 | cols: 10
8 | };
9 |
10 | interface IMinMax {
11 | min: number;
12 | max: number;
13 | }
14 |
15 | interface IBounds {
16 | x: IMinMax;
17 | y: IMinMax;
18 | }
19 |
20 | interface IPositionConfig {
21 | velocity: IBounds;
22 | bounds: IBounds;
23 | }
24 |
25 | var requestAnimationFrame = window.requestAnimationFrame || window['mozRequestAnimationFrame'] ||
26 | window['webkitRequestAnimationFrame'] || window.msRequestAnimationFrame;
27 |
28 | @Component({
29 | selector: 'status-board'
30 | })
31 | @View({
32 | templateUrl: 'app/status-board/status-board-floating.html',
33 | directives: [NgFor, NgIf]
34 | })
35 | export class StatusBoardFloating {
36 | statusBoard: Position[][] = [];
37 |
38 | private _lastStep: number = 0;
39 |
40 | private _config: IPositionConfig = {
41 | velocity: {
42 | x: { min: 0, max: 100 },
43 | y: { min: 0, max: 100 }
44 | },
45 | bounds: {
46 | x: { min: 100, max: 900 },
47 | y: { min: 100, max: 700 }
48 | }
49 | };
50 |
51 | constructor() {
52 | this.initStatusBoard();
53 |
54 | requestAnimationFrame(this.updateBoard.bind(this));
55 | }
56 |
57 | initStatusBoard() {
58 | for (var row = 0; row < dimensions.rows; row++) {
59 | for (var col = 0; col < dimensions.cols; col++) {
60 | if (!this.statusBoard[row]) {
61 | this.statusBoard[row] = [];
62 | }
63 |
64 | this.statusBoard[row][col] = Position.create(this._config);
65 | }
66 | }
67 | }
68 |
69 | updateBoard(elapsedMilliseconds) {
70 | var elapsedSeconds = new TimeSpan(elapsedMilliseconds - this._lastStep).totalSeconds;
71 | this._lastStep = elapsedMilliseconds;
72 |
73 | for (var row = 0; row < dimensions.rows; row++) {
74 | for (var col = 0; col < dimensions.cols; col++) {
75 | this.statusBoard[row][col].move(elapsedSeconds, this._config.bounds);
76 | }
77 | }
78 |
79 | requestAnimationFrame(this.updateBoard.bind(this));
80 | }
81 | }
82 |
83 | class Position {
84 | top:string;
85 | left:string;
86 |
87 | constructor(
88 | public x: number,
89 | public y: number,
90 | private velocityX: number,
91 | private velocityY: number) { }
92 |
93 | move(timeDelta: number, bounds?:IBounds) {
94 | this.x += (this.velocityX * timeDelta);
95 | this.y += (this.velocityY * timeDelta);
96 |
97 | this.top = `${this.y}px`;
98 | this.left = `${this.x}px`;
99 |
100 | if(!bounds) return;
101 |
102 | if(this.x > bounds.x.max || this.x < bounds.x.min){
103 | this.x = this.x > bounds.x.max ? bounds.x.max : bounds.x.min;
104 | this.velocityX *= -1;
105 | }
106 | if(this.y > bounds.y.max || this.y < bounds.y.min){
107 | this.y = this.y > bounds.y.max ? bounds.y.max : bounds.y.min;
108 | this.velocityY *= -1;
109 | }
110 | }
111 |
112 | static create(config:IPositionConfig){
113 | return new Position(
114 | getRandomInt(config.bounds.x.min, config.bounds.x.max),
115 | getRandomInt(config.bounds.y.min, config.bounds.y.max),
116 | getRandomInt(config.velocity.x.min, config.velocity.x.max),
117 | getRandomInt(config.velocity.y.min, config.velocity.y.max)
118 | );
119 | }
120 | }
121 |
122 | function getRandomInt(min: number, max: number): number {
123 | return Math.floor(Math.random() * (max - min)) + min;
124 | }
125 |
126 | class TimeSpan {
127 | constructor(private _totalMilliseconds: number = 0) { }
128 |
129 | get totalSeconds() {
130 | return this._totalMilliseconds / 1000;
131 | }
132 |
133 | get totalMilliseconds() {
134 | return this._totalMilliseconds;
135 | }
136 | }
--------------------------------------------------------------------------------
/app/status-board/status-board.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
Status Updates: {{statusUpdates}}
9 |
10 |
11 |
Init Time: {{timings.init.totalMilliseconds()}}
12 |
13 |
14 |
15 |
16 |
17 | {{col.val}} |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/status-board/status-board.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import {Component, View, NgFor, NgIf} from 'angular2/angular2';
4 | import * as _ from 'lodash';
5 | import {Timer} from '../common/timer';
6 | import {TimeSpan} from '../common/timespan';
7 |
8 | interface IStatus {
9 | val: number,
10 | class: string
11 | }
12 |
13 | interface ITimings{
14 | [index: string]:TimeSpan
15 | }
16 |
17 | var dimensions = {
18 | rows: 25,
19 | cols: 60
20 | };
21 |
22 | var timeouts = {
23 | min:50,
24 | max:500
25 | }
26 |
27 | var statuses = [
28 | 'active',
29 | 'success',
30 | 'warning',
31 | 'danger',
32 | 'info'
33 | ];
34 |
35 | var requestAnimationFrame = window.requestAnimationFrame || window['mozRequestAnimationFrame'] ||
36 | window['webkitRequestAnimationFrame'] || window.msRequestAnimationFrame;
37 |
38 | @Component({
39 | selector: 'status-board'
40 | })
41 | @View({
42 | templateUrl: 'app/status-board/status-board.html',
43 | directives: [NgFor, NgIf]
44 | })
45 | export class StatusBoard {
46 | statusBoard: IStatus[][] = [];
47 | updateBoardCallback: () => void;
48 | statusUpdates: number = 0;
49 | timings:ITimings = {};
50 |
51 | private _maxStatusUpdates: number = dimensions.cols * dimensions.rows;
52 |
53 | constructor() {
54 | this.initStatusBoard();
55 | this.updateBoardCallback = this.updateBoard.bind(this);
56 |
57 | //requestAnimationFrame(this.updateBoardCallback);
58 | }
59 |
60 | initStatusBoard() {
61 | var timer = new Timer();
62 | timer.start();
63 |
64 | for (var row = 0; row < dimensions.rows; row++) {
65 | for (var col = 0; col < dimensions.cols; col++) {
66 | if (!this.statusBoard[row]) {
67 | this.statusBoard[row] = [];
68 | }
69 |
70 | this.statusBoard[row][col] = Status.defaultStatus;
71 | this.updateCellAsync(row, col);
72 | }
73 | }
74 |
75 | timer.stop();
76 | this.timings['init'] = timer.elapsed();
77 | }
78 |
79 | updateCellAsync(row: number, col: number) {
80 | var timeout = getRandomInt(timeouts.min, timeouts.max);
81 |
82 | setTimeout(() => {
83 | this.statusBoard[row][col] = Status.createStatus();
84 | this.statusUpdates += 1;
85 | }, timeout);
86 | }
87 |
88 | updateBoard() {
89 | var row = getRandomInt(0, dimensions.rows);
90 | var col = getRandomInt(0, dimensions.cols);
91 |
92 | this.statusBoard[row][col] = Status.createStatus();
93 |
94 | this.statusUpdates += 1;
95 |
96 | if (this.statusUpdates < this._maxStatusUpdates) {
97 | requestAnimationFrame(this.updateBoardCallback);
98 | }
99 | }
100 | }
101 |
102 | function getRandomInt(min: number, max: number): number {
103 | return Math.floor(Math.random() * (max - min)) + min;
104 | }
105 |
106 | class Status {
107 | static defaultStatus = { val: 0, class: '' };
108 |
109 | static createStatus(): IStatus {
110 | var status: any = {
111 | val: getRandomInt(0, statuses.length)
112 | };
113 |
114 | status.class = statuses[status.val];
115 |
116 | return status;
117 | }
118 | }
--------------------------------------------------------------------------------
/app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES5",
4 | "module": "commonjs",
5 | "sourceMap": true,
6 | "emitDecoratorMetadata": true,
7 | "watch": false,
8 | "removeComments": true
9 | }
10 | }
--------------------------------------------------------------------------------
/app/twitter/twitter.ts:
--------------------------------------------------------------------------------
1 | import {Component, View} from 'angular2/angular2';
2 |
3 | @Component({
4 | selector:'twitter-link',
5 | properties:["name"]
6 | })
7 | @View({
8 | template:'{{name}}'
9 | })
10 | export class TwitterLink{
11 | name: string;
12 |
13 | get url(){
14 | return `https://twitter.com/${this.name}`;
15 | }
16 | }
--------------------------------------------------------------------------------
/custom-types/ng2.custom.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module "angular2/router" {
4 | class Instruction {}
5 | class Router {
6 | navigate(url: string): Promise;
7 | config(config: any): Promise;
8 | deactivate(): Promise;
9 | activate(instruction: Instruction): Promise;
10 | recognize(url: string): Instruction;
11 | recognize(url: string): Instruction;
12 | renavigate(): Promise;
13 | generate(name:string, params:any): string;
14 | subscribe(onNext: Function): void;
15 | parent:Router;
16 | }
17 | class RouteParams {
18 | params: StringMap;
19 | constructor(params: StringMap);
20 | get(param: string): string;
21 | }
22 | class BrowserLocation {
23 | path():string;
24 | }
25 |
26 | var RouterOutlet: any;
27 | var RouterLink: any;
28 | var routerInjectables: any;
29 | var routerDirectives: any;
30 | var RouteConfigAnnotation: any;
31 | var RouteConfig: any;
32 | }
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | This file is the main entry point for defining Gulp tasks and using Gulp plugins
3 | To learn more visit: https://github.com/gulpjs/gulp/blob/master/docs/README.md
4 | */
5 | 'use strict';
6 |
7 | var gulp = require('gulp');
8 | var ts = require('gulp-typescript');
9 | var _ = require('lodash');
10 | var packages = require('./package.json');
11 | var app = './app';
12 | var releaseDir = './wwwroot/app';
13 |
14 | // The default task (called when you run `gulp` from CLI)
15 | gulp.task('default', ['copy-deps', 'copy-templates', 'scripts']);
16 |
17 | gulp.task('copy-deps', function() {
18 | _.forEach(packages.dependencies, function(val, key){
19 | gulp.src('./node_modules/' + key + '/**/*')
20 | .pipe(gulp.dest(releaseDir + '/lib/' + key));
21 | });
22 | });
23 |
24 | gulp.task('copy-templates', function() {
25 | gulp.src(app + '/**/*.html')
26 | .pipe(gulp.dest(releaseDir));
27 | });
28 |
29 | gulp.task("scripts", function(){
30 | var tsProj = ts.createProject(app + '/tsconfig.json', {
31 | typescript: require('typescript')
32 | });
33 |
34 | var tsResult = gulp.src(app + '/**/*.ts')
35 | .pipe(ts(tsProj));
36 |
37 | return tsResult.js.pipe(gulp.dest(releaseDir));
38 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "diving-into-angular",
3 | "version": "0.0.1",
4 | "description": "Simple Angular2 Application",
5 | "main": "gulpfile.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "jwcarroll",
10 | "license": "MIT",
11 | "dependencies": {
12 | "angular2": "^2.0.0-alpha.26",
13 | "bootstrap": "^3.3.5",
14 | "lodash": "^3.9.3"
15 | },
16 | "devDependencies": {
17 | "http-server":"^0.8.0",
18 | "tsd":"^0.6.3",
19 | "gulp": "^3.9.0",
20 | "gulp-tsc": "^0.10.1",
21 | "gulp-typescript": "^2.7.6",
22 | "typescript": "^1.5.0-beta"
23 | },
24 | "scripts": {
25 | "postinstall":"tsd install",
26 | "prestart":"gulp default",
27 | "start":"http-server .\\wwwroot -c-1 -o"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Some Crazy Databinding Examples in Angular2
2 |
3 | To get started:
4 |
5 | ```
6 | npm install
7 | npm start
8 | ```
9 |
10 | Now just play around with the examples :)
--------------------------------------------------------------------------------
/tsd.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "v4",
3 | "repo": "borisyankov/DefinitelyTyped",
4 | "ref": "master",
5 | "path": "typings",
6 | "bundle": "typings/tsd.d.ts",
7 | "installed": {
8 | "es6-promise/es6-promise.d.ts": {
9 | "commit": "ac3a1f059f655059484d6aa5ba1f0f85908ae06c"
10 | },
11 | "angular2/angular2.d.ts": {
12 | "commit": "ac3a1f059f655059484d6aa5ba1f0f85908ae06c"
13 | },
14 | "rx/rx.d.ts": {
15 | "commit": "ac3a1f059f655059484d6aa5ba1f0f85908ae06c"
16 | },
17 | "rx/rx-lite.d.ts": {
18 | "commit": "ac3a1f059f655059484d6aa5ba1f0f85908ae06c"
19 | },
20 | "lodash/lodash.d.ts": {
21 | "commit": "ac3a1f059f655059484d6aa5ba1f0f85908ae06c"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/wwwroot/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Angular 2 Quickstart
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
31 |
32 |
33 |
--------------------------------------------------------------------------------