From f9b157566af34b8dc28ba10b34d025ac04f3168b Mon Sep 17 00:00:00 2001
From: 沈斌 <bluelazysb@hotmail.com>
Date: Fri, 15 Dec 2017 09:29:58 +0800
Subject: [PATCH] updates

---
 src/app/routes/forms/standard/standard.component.spec.ts                 |   16 
 src/app/routes/elements/typography/typography.component.ts               |   15 
 src/app/routes/pages/lock/lock.component.spec.ts                         |   16 
 src/app/routes/pages/register/register.component.html                    |   69 
 .angular-cli.json                                                        |  169 
 src/app/routes/pro/user/register-result/register-result.component.html   |   10 
 src/app/routes/elements/modal/modal.component.html                       |   35 
 src/app/routes/extras/settings/settings.component.spec.ts                |   16 
 src/app/routes/pro/form/step-form/step-form.component.html               |   17 
 src/assets/demo.xlsx                                                     |    0 
 src/app/routes/elements/modal/custom.component.ts                        |   56 
 src/app/routes/extras/settings/settings.component.ts                     |   56 
 src/app/routes/pro/user/register-result/register-result.component.less   |    0 
 src/app/routes/elements/dropdown/dropdown.component.html                 |   53 
 src/assets/demo.pptx                                                     |    0 
 tslint.json                                                              |   32 
 src/app/routes/pro/list/basic-list/basic-list.component.html             |   88 
 src/app/routes/maps/baidu/baidu.component.html                           |   25 
 src/app/routes/dashboard/monitor/monitor.component.ts                    |  594 ++
 src/app/routes/tables/standard/standard.component.ts                     |  137 
 src/app/routes/pro/form/advanced-form/advanced-form.component.html       |  246 
 src/app/routes/routes.ts                                                 |   71 
 src/app/routes/pro/list/basic-list/basic-list.component.ts               |   30 
 src/assets/img/5.png                                                     |    0 
 src/app/routes/forms/cropper/cropper.component.html                      |   35 
 src/app/routes/pro/list/basic-list/basic-list.component.less             |   21 
 src/assets/img/bg5.jpg                                                   |    0 
 src/app/routes/dashboard/analysis/analysis.component.html                |  288 +
 src/app/routes/elements/grid/grid.component.ts                           |   52 
 src/app/routes/pro/user/login/login.component.html                       |   92 
 src/app/routes/maps/baidu/baidu.component.ts                             |   70 
 src/assets/img/1.png                                                     |    0 
 src/assets/img/logo-full.svg                                             |   47 
 package-lock.json                                                        |    4 
 src/environments/environment.hmr.ts                                      |    6 
 src/app/routes/logics/guard/can-auth.provide.ts                          |   28 
 src/app/routes/dashboard/v1/v1.component.html                            |  150 
 src/app/routes/elements/sortable/sortable.component.spec.ts              |   18 
 src/assets/img/bg2.jpg                                                   |    0 
 src/app/routes/extras/extras.module.ts                                   |   31 
 src/app/routes/pro/user/login/login.component.less                       |   75 
 src/app/routes/elements/colors/colors.component.html                     |   72 
 src/app/routes/elements/tree-antd/basic.component.ts                     |   24 
 src/app/routes/extras/poi/poi.component.ts                               |   54 
 src/app/routes/extras/poi/edit/edit.component.html                       |   90 
 src/app/routes/callback/callback.component.ts                            |   32 
 src/app/routes/elements/notification/notification.component.ts           |   89 
 src/app/routes/pro/form/step-form/step-form.component.less               |   29 
 src/app/routes/elements/gridmasonry/gridmasonry.component.html           |  235 
 src/app/routes/pro/profile/basic/basic.component.ts                      |   26 
 src/app/routes/pro/form/step-form/step1.component.ts                     |  107 
 src/app/routes/pro/form/step-form/transfer.service.ts                    |   54 
 src/app/routes/forms/standard/standard.component.html                    |  497 +
 src/app/routes/pages/register/register.component.spec.ts                 |   16 
 src/assets/demo.docx                                                     |    0 
 src/app/routes/extras/helpcenter/helpcenter.component.spec.ts            |   16 
 src/app/routes/elements/dropdown/dropdown.component.spec.ts              |   16 
 src/main.ts                                                              |   30 
 src/app/routes/logics/guard/leave.component.ts                           |   12 
 src/app/routes/charts/charts.module.ts                                   |   27 
 src/app/routes/forms/upload/upload.component.html                        |   91 
 src/app/routes/extras/settings/settings.component.html                   |  230 
 src/app/routes/elements/sweetalert/sweetalert.component.html             |   25 
 src/assets/iconsfont.json                                                | 2310 ++++++++
 src/app/routes/logics/guard/admin.component.ts                           |    9 
 src/assets/img/avatar.jpg                                                |    0 
 src/assets/img/bg9.jpg                                                   |    0 
 src/app/routes/elements/sweetalert/sweetalert.component.ts               |   50 
 src/app/routes/elements/notification/notification.component.spec.ts      |   16 
 src/app/routes/pro/user/register/register.component.html                 |   94 
 src/app/routes/elements/tree-antd/tree-antd.component.html               |   13 
 src/assets/img/6.png                                                     |    0 
 src/app/routes/pro/result/success/success.component.html                 |   30 
 src/app/routes/widgets/widgets.module.ts                                 |   23 
 src/app/routes/pro/list/search/search.component.html                     |  100 
 src/app/routes/dashboard/v1/v1.component.spec.ts                         |   16 
 src/app/routes/elements/tree-antd/searchable.component.ts                |   41 
 src/app/routes/pro/exception/403.component.ts                            |    7 
 src/app/routes/elements/sortable/sortable.component.html                 |   55 
 src/app/routes/pro/list/search/search.component.less                     |    4 
 src/app/routes/elements/tree-antd/tree-antd.component.ts                 |    8 
 src/app/routes/pages/login/login.component.html                          |   62 
 src/app/routes/pages/404/404.component.spec.ts                           |   16 
 src/assets/img/bg6.jpg                                                   |    0 
 src/app/routes/forms/extended/extended.component.spec.ts                 |   18 
 src/app/routes/pro/profile/advanced/advanced.component.html              |  192 
 tsconfig.json                                                            |    8 
 src/app/routes/maps/qq/qq.component.html                                 |   25 
 src/app/routes/pages/forget/forget.component.ts                          |   30 
 src/app/routes/widgets/widgets/widgets.component.spec.ts                 |   16 
 src/app/routes/elements/typography/typography.component.html             |  111 
 src/app/routes/charts/g2/g2.component.ts                                 |    9 
 src/app/routes/elements/buttons/buttons.component.ts                     |   19 
 src/app/routes/logics/downfile/downfile.component.html                   |    7 
 src/assets/img/2.png                                                     |    0 
 src/app/routes/pro/list/table-list/table-list.component.html             |  162 
 src/app/routes/elements/buttons/buttons.component.html                   |  208 
 src/app/routes/maps/qq/qq.component.ts                                   |   72 
 src/app/routes/logics/acl/acl.component.html                             |   30 
 src/app/routes/dashboard/analysis/analysis.component.ts                  |   79 
 src/app/routes/pages/maintenance/maintenance.component.ts                |    8 
 src/app/routes/pro/list/search/search.component.ts                       |   85 
 src/app/routes/tables/full/full.component.ts                             |   73 
 src/app/routes/elements/tree-antd/generate-data.ts                       |   21 
 src/app/routes/tables/tables.module.ts                                   |   32 
 src/assets/img/bg1.jpg                                                   |    0 
 src/app/routes/elements/elements.module.ts                               |   83 
 src/app/routes/pages/maintenance/maintenance.component.spec.ts           |   16 
 src/app/routes/dashboard/workplace/workplace.component.less              |  241 
 src/app/routes/dashboard/workplace/workplace.component.html              |  105 
 package.json                                                             |   28 
 src/app/routes/elements/modal/modal.component.spec.ts                    |   16 
 src/app/routes/forms/validation/validation.component.html                |  168 
 src/app/routes/elements/spin/spin.component.spec.ts                      |   16 
 src/assets/img/zorro.svg                                                 |   34 
 src/app/routes/data-v/relation/relation.component.html                   |    0 
 src/app/routes/widgets/widgets/widgets.component.less                    |    5 
 src/environments/environment.chore.ts                                    |    6 
 src/app/routes/elements/tree-antd/draggable.component.ts                 |   28 
 src/app/routes/elements/spin/spin.component.html                         |   53 
 src/app/routes/pages/lock/lock.component.ts                              |   30 
 src/app/routes/maps/qq/qq.component.spec.ts                              |   22 
 src/assets/img/bg10.jpg                                                  |    0 
 src/app/routes/forms/extended/extended.component.html                    |   39 
 src/app/routes/elements/modal/modal.component.ts                         |   58 
 src/assets/environments/environment.ts                                   |   11 
 src/assets/img/bg7.jpg                                                   |    0 
 src/app/routes/data-v/data-v.module.ts                                   |   23 
 src/app/routes/elements/grid/grid.component.spec.ts                      |   16 
 src/assets/environments/environment.chore.ts                             |    6 
 src/app/routes/pro/list/filter-card-list/filter-card-list.component.ts   |   80 
 src/environments/environment.ts                                          |    6 
 src/app/routes/pages/register/register.component.ts                      |   34 
 src/app/routes/elements/iconsfont/iconsfont.component.ts                 |   40 
 src/app/routes/forms/cropper/cropper.component.spec.ts                   |   18 
 src/app/routes/pages/500/500.component.html                              |   28 
 src/app/routes/pages/500/500.component.ts                                |   12 
 src/app/routes/pro/form/advanced-form/advanced-form.component.ts         |  127 
 src/app/routes/forms/standard/standard.component.ts                      |   99 
 src/app/routes/elements/tree-antd/line.component.ts                      |   24 
 src/app/routes/dashboard/monitor/monitor.component.html                  |   98 
 src/app/routes/widgets/widgets/widgets.component.html                    |  770 ++
 src/app/routes/pro/user/register-result/register-result.component.ts     |   11 
 src/assets/img/half-float-bg-1.jpg                                       |    0 
 src/app/routes/elements/iconsfont/iconsfont.component.spec.ts            |   16 
 src/assets/img/logo.svg                                                  |   25 
 src/app/routes/forms/upload/upload.component.ts                          |   35 
 src/app/routes/logics/guard/can-admin.provide.ts                         |   28 
 src/app/routes/pro/user/index.md                                         |    1 
 src/app/routes/pro/list/card-list/card-list.component.ts                 |   29 
 src/app/routes/elements/typography/typography.component.spec.ts          |   16 
 src/app/routes/logics/logics.module.ts                                   |   48 
 src/app/routes/pro/profile/basic/basic.component.html                    |   75 
 src/app/routes/pages/lock/lock.component.html                            |   36 
 src/app/routes/elements/tree-antd/tree-antd.component.spec.ts            |   16 
 src/assets/img/bg4.jpg                                                   |    0 
 src/app/routes/pages/forget/forget.component.spec.ts                     |   16 
 src/app/routes/elements/iconsfont/iconsfont.component.less               |   20 
 src/app/routes/pages/500/500.component.spec.ts                           |   16 
 src/app/routes/logics/acl/acl.component.ts                               |   46 
 src/app/routes/extras/helpcenter/helpcenter.component.html               |   94 
 src/app/routes/elements/colors/colors.component.spec.ts                  |   17 
 src/app/routes/elements/gridmasonry/gridmasonry.component.ts             |    8 
 src/assets/environments/environment.prod.ts                              |    6 
 src/app/routes/charts/g2/g2.component.html                               |   11 
 src/app/routes/pro/exception/404.component.ts                            |    7 
 src/app/routes/pages/404/404.component.ts                                |   12 
 src/app/routes/elements/iconsfont/iconsfont.component.html               |   19 
 src/assets/img/3.png                                                     |    0 
 src/app/routes/pro/form/step-form/step3.component.ts                     |   42 
 src/app/routes/elements/buttons/buttons.component.spec.ts                |   16 
 src/app/routes/dashboard/monitor/monitor.component.less                  |   60 
 src/app/routes/logics/acl/acl.component.spec.ts                          |   16 
 src/app/routes/logics/guard/guard.component.html                         |   29 
 src/app/routes/forms/upload/upload.component.spec.ts                     |   18 
 src/app/routes/charts/g2/g2.component.spec.ts                            |   16 
 src/app/routes/pro/user/register/register.component.ts                   |  102 
 src/app/routes/dashboard/workplace/workplace.component.ts                |   98 
 src/app/routes/pro/list/cover-card-list/cover-card-list.component.html   |   76 
 src/app/routes/pro/result/fail/fail.component.html                       |   21 
 src/app/routes/pro/user/register/register.component.less                 |   54 
 src/app/routes/forms/forms.module.ts                                     |   45 
 src/app/routes/logics/guard/auth.component.ts                            |    9 
 src/app/routes/pro/user/login/login.component.ts                         |  141 
 src/app/routes/tables/standard/standard.component.spec.ts                |   18 
 src/app/routes/extras/helpcenter/helpcenter.component.ts                 |   22 
 src/app/routes/elements/spin/spin.component.ts                           |   25 
 src/app/routes/logics/guard/can-leave.provide.ts                         |   33 
 src/app/routes/forms/validation/validation.component.ts                  |  115 
 src/app/routes/pro/profile/advanced/advanced.component.ts                |   21 
 src/assets/pois.json                                                     |   59 
 src/app/routes/pages/forget/forget.component.html                        |   32 
 src/app/routes/elements/dropdown/dropdown.component.ts                   |   63 
 src/assets/img/bg8.jpg                                                   |    0 
 src/app/routes/tables/standard/standard.component.html                   |  257 
 karma.conf.js                                                            |    3 
 src/assets/demo.pdf                                                      |    0 
 src/environments/environment.prod.ts                                     |    6 
 src/app/routes/pages/login/login.component.ts                            |   32 
 src/assets/environments/environment.hmr.ts                               |    6 
 src/app/routes/pro/form/step-form/step2.component.ts                     |   81 
 src/app/routes/pro/list/table-list/table-list.component.ts               |  127 
 src/app/routes/pages/login/login.component.spec.ts                       |   16 
 src/app/routes/tables/full/full.component.spec.ts                        |   18 
 src/app/routes/data-v/relation/relation.component.ts                     |  144 
 src/app/routes/elements/sweetalert/sweetalert.component.spec.ts          |   16 
 src/app/routes/forms/validation/validation.component.spec.ts             |   16 
 src/app/routes/routes.module.ts                                          |   43 
 src/app/routes/maps/maps.module.ts                                       |   38 
 src/app/routes/pro/result/fail/fail.component.ts                         |    9 
 src/assets/img/4.png                                                     |    0 
 src/app/routes/pro/list/card-list/card-list.component.html               |   44 
 src/app/routes/callback/callback.component.html                          |    0 
 src/app/routes/dashboard/analysis/analysis.component.less                |  149 
 src/app/routes/logics/guard/user.service.ts                              |   44 
 src/assets/img/logo-color.svg                                            |   25 
 src/app/routes/extras/poi/poi.component.html                             |   67 
 src/app/routes/maps/baidu/baidu.component.spec.ts                        |   22 
 src/app/routes/tables/full/full.component.html                           |  153 
 src/app/routes/pro/list/cover-card-list/cover-card-list.component.ts     |   81 
 src/app/routes/elements/colors/colors.component.ts                       |   14 
 src/assets/img/bg3.jpg                                                   |    0 
 src/app/routes/pages/maintenance/maintenance.component.html              |   13 
 src/app/routes/forms/extended/extended.component.ts                      |   10 
 src/app/routes/elements/tree-antd/async.component.ts                     |   48 
 src/app/routes/pro/pro.module.ts                                         |   97 
 src/app/routes/widgets/widgets/widgets.component.ts                      |   31 
 src/app/routes/elements/notification/notification.component.html         |  212 
 src/app/routes/pro/list/filter-card-list/filter-card-list.component.html |   92 
 src/app/routes/logics/guard/guard.component.ts                           |   32 
 src/app/routes/pro/form/step-form/step-form.component.ts                 |   17 
 src/app/routes/logics/downfile/downfile.component.ts                     |   16 
 src/app/routes/tables/randomUser.service.ts                              |   27 
 src/app/routes/dashboard/v1/v1.component.ts                              |   29 
 src/app/routes/logics/downfile/downfile.component.spec.ts                |   16 
 src/app/routes/pages/404/404.component.html                              |   28 
 src/app/routes/elements/grid/grid.component.html                         |  388 +
 src/app/routes/elements/gridmasonry/gridmasonry.component.spec.ts        |   16 
 src/app/routes/pro/list/filter-card-list/filter-card-list.component.less |   35 
 src/app/routes/extras/poi/edit/edit.component.ts                         |   38 
 src/app/routes/elements/sortable/sortable.component.ts                   |   12 
 src/assets/app-data.json                                                 |  408 +
 src/app/routes/pro/exception/500.component.ts                            |    7 
 src/app/routes/elements/grid/grid.component.less                         |  134 
 src/app/routes/pro/result/success/success.component.ts                   |   10 
 src/app/routes/data-v/relation/relation.component.less                   |    0 
 src/app/routes/forms/cropper/cropper.component.ts                        |   57 
 src/hmr.ts                                                               |   20 
 src/app/routes/pages/pages.module.ts                                     |   28 
 src/app/routes/logics/guard/guard.component.spec.ts                      |   18 
 250 files changed, 15,702 insertions(+), 126 deletions(-)

diff --git a/.angular-cli.json b/.angular-cli.json
index 1e8b64b..71940fd 100644
--- a/.angular-cli.json
+++ b/.angular-cli.json
@@ -1,86 +1,89 @@
 {
-  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
-  "project": {
-    "name": "screen-frontend"
-  },
-  "apps": [
-    {
-      "root": "src",
-      "outDir": "dist",
-      "assets": [
-        "assets",
-        "favicon.ico"
-      ],
-      "index": "index.html",
-      "main": "main.ts",
-      "polyfills": "polyfills.ts",
-      "test": "test.ts",
-      "tsconfig": "tsconfig.app.json",
-      "testTsconfig": "tsconfig.spec.json",
-      "prefix": "app",
-      "styles": [
-        "styles.less"
-      ],
-      "scripts": [],
-      "environmentSource": "environments/environment.ts",
-      "environments": {
-        "dev": "environments/environment.ts",
-        "prod": "environments/environment.prod.ts"
-      }
+    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+    "project": {
+        "name": "ng-alain"
+    },
+    "apps": [{
+        "root": "src",
+        "outDir": "dist",
+        "assets": [
+            "assets",
+            "favicon.ico"
+        ],
+        "index": "index.html",
+        "main": "main.ts",
+        "polyfills": "polyfills.ts",
+        "test": "test.ts",
+        "tsconfig": "tsconfig.app.json",
+        "testTsconfig": "tsconfig.spec.json",
+        "prefix": "app",
+        "styles": [
+            "styles.less"
+        ],
+        "scripts": [
+            "../node_modules/@antv/g2/dist/g2.min.js",
+            "../node_modules/@antv/data-set/dist/data-set.min.js",
+            "../node_modules/@antv/g2-plugin-slider/dist/g-2.0.0.min.js"
+        ],
+        "environmentSource": "environments/environment.ts",
+        "environments": {
+            "dev": "environments/environment.ts",
+            "prod": "environments/environment.prod.ts",
+            "hmr": "environments/environment.hmr.ts",
+            "chore": "environments/environment.chore.ts"
+        }
+    }],
+    "e2e": {
+        "protractor": {
+            "config": "./protractor.conf.js"
+        }
+    },
+    "lint": [{
+            "project": "src/tsconfig.app.json",
+            "exclude": "**/node_modules/**"
+        },
+        {
+            "project": "src/tsconfig.spec.json",
+            "exclude": "**/node_modules/**"
+        },
+        {
+            "project": "e2e/tsconfig.e2e.json",
+            "exclude": "**/node_modules/**"
+        }
+    ],
+    "test": {
+        "karma": {
+            "config": "./karma.conf.js"
+        }
+    },
+    "defaults": {
+        "styleExt": "less",
+        "class": {
+            "spec": false
+        },
+        "component": {
+            "flat": false,
+            "spec": false,
+            "inlineStyle": true,
+            "inlineTemplate": false
+        },
+        "directive": {
+            "spec": false
+        },
+        "guard": {
+            "spec": false
+        },
+        "interface": {
+            "prefix": "I"
+        },
+        "module": {
+            "spec": false
+        },
+        "pipe": {
+            "spec": true
+        },
+        "service": {
+            "spec": false
+        }
     }
-  ],
-  "e2e": {
-    "protractor": {
-      "config": "./protractor.conf.js"
-    }
-  },
-  "lint": [
-    {
-      "project": "src/tsconfig.app.json",
-      "exclude": "**/node_modules/**"
-    },
-    {
-      "project": "src/tsconfig.spec.json",
-      "exclude": "**/node_modules/**"
-    },
-    {
-      "project": "e2e/tsconfig.e2e.json",
-      "exclude": "**/node_modules/**"
-    }
-  ],
-  "test": {
-    "karma": {
-      "config": "./karma.conf.js"
-    }
-  },
-  "defaults": {
-    "styleExt": "css",
-    "class": {
-      "spec": false
-    },
-    "component": {
-      "flat": false,
-      "spec": false,
-      "inlineStyle": true,
-      "inlineTemplate": false
-    },
-    "directive": {
-      "spec": false
-    },
-    "guard": {
-      "spec": false
-    },
-    "interface": {
-      "prefix": "I"
-    },
-    "module": {
-      "spec": false
-    },
-    "pipe": {
-      "spec": true
-    },
-    "service": {
-      "spec": false
-    }
-  }
 }
diff --git a/karma.conf.js b/karma.conf.js
index af139fa..795f946 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -28,6 +28,7 @@
     logLevel: config.LOG_INFO,
     autoWatch: true,
     browsers: ['Chrome'],
-    singleRun: false
+    singleRun: false,
+    browserNoActivityTimeout: 60000 
   });
 };
diff --git a/package-lock.json b/package-lock.json
index 0a9a570..e69daf1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
-  "name": "screen-frontend",
-  "version": "0.0.0",
+  "name": "ng-alain",
+  "version": "0.3.0-rc.1",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index a3f832f..cdfaf25 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,32 @@
 {
   "name": "screen-frontend",
   "version": "1.0.0",
+  "description": "ng-zorro-antd admin panel front-end framework",
+  "author": "cipchk",
+  "homepage": "https://cipchk.github.io/ng-alain/",
+  "bugs": {
+    "url": "https://github.com/cipchk/ng-alain/issues"
+  },
+  "engines": {
+    "node": ">= 4.2.1",
+    "npm": ">= 3"
+  },
   "license": "MIT",
   "scripts": {
+    "precommit": "npm run lint-staged",
     "ng": "ng",
-    "start": "ng serve",
-    "build": "ng build",
-    "test": "ng test",
-    "lint": "ng lint",
-    "e2e": "ng e2e"
+    "start": "ng serve -o",
+    "serve:hmr": "ng serve -o --hmr -e=hmr",
+    "build": "ng build --prod --build-optimizer",
+    "analyze": "ng build --prod --build-optimizer --stats-json",
+    "lint": "run-s lint:ts lint:style",
+    "lint:ts": "ng lint",
+    "lint:style": "stylelint \"{src}/**/*.less\" --syntax less",
+    "lint-staged": "lint-staged",
+    "e2e": "ng e2e",
+    "test": "ng test -sr",
+    "test-coverage": "ng test -sr -cc"
   },
-  "private": true,
   "dependencies": {
     "@angular/animations": "^5.0.0",
     "@angular/common": "^5.0.0",
diff --git a/src/app/routes/callback/callback.component.html b/src/app/routes/callback/callback.component.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/app/routes/callback/callback.component.html
diff --git a/src/app/routes/callback/callback.component.ts b/src/app/routes/callback/callback.component.ts
new file mode 100644
index 0000000..e24d8da
--- /dev/null
+++ b/src/app/routes/callback/callback.component.ts
@@ -0,0 +1,32 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { SocialService } from '@delon/auth';
+
+@Component({
+    selector: 'app-callback',
+    templateUrl: './callback.component.html',
+    providers: [ SocialService ]
+})
+export class CallbackComponent implements OnInit {
+
+    type: string;
+
+    constructor(private socialService: SocialService, private route: ActivatedRoute, private router: Router) {}
+
+    ngOnInit(): void {
+        this.route.params.subscribe(params => {
+            this.type = params['type'];
+            this.mockModel();
+        });
+    }
+
+    private mockModel() {
+        this.socialService.callback({
+            token: '123456789',
+            name: 'cipchk',
+            email: `${this.type}@${this.type}.com`,
+            id: 10000,
+            time: +new Date
+        });
+    }
+}
diff --git a/src/app/routes/charts/charts.module.ts b/src/app/routes/charts/charts.module.ts
new file mode 100644
index 0000000..0087613
--- /dev/null
+++ b/src/app/routes/charts/charts.module.ts
@@ -0,0 +1,27 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SharedModule } from '@shared/shared.module';
+
+import { G2Component } from './g2/g2.component';
+
+const routes: Routes = [
+    { path: 'g2', component: G2Component }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    declarations: [
+        G2Component
+    ],
+    exports: [
+        RouterModule
+    ],
+    entryComponents: [
+
+    ]
+})
+export class ChartsModule { }
diff --git a/src/app/routes/charts/g2/g2.component.html b/src/app/routes/charts/g2/g2.component.html
new file mode 100644
index 0000000..e727a1a
--- /dev/null
+++ b/src/app/routes/charts/g2/g2.component.html
@@ -0,0 +1,11 @@
+<div class="content__title">
+    <h1>
+        G2
+        <small>use <a href="//github.com/cipchk/g2-angular" target="_blank">g2-angular</a> library.</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        ������DEMO��������� https://antv.alipay.com/g2/demo
+    </div>
+</div>
diff --git a/src/app/routes/charts/g2/g2.component.spec.ts b/src/app/routes/charts/g2/g2.component.spec.ts
new file mode 100644
index 0000000..aa6c023
--- /dev/null
+++ b/src/app/routes/charts/g2/g2.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { G2Component } from './g2.component';
+
+describe('Component: Chart.js', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ G2Component ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(G2Component);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/charts/g2/g2.component.ts b/src/app/routes/charts/g2/g2.component.ts
new file mode 100644
index 0000000..ee73a83
--- /dev/null
+++ b/src/app/routes/charts/g2/g2.component.ts
@@ -0,0 +1,9 @@
+// tslint:disable:member-ordering
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-g2',
+    templateUrl: './g2.component.html'
+})
+export class G2Component {
+}
diff --git a/src/app/routes/dashboard/analysis/analysis.component.html b/src/app/routes/dashboard/analysis/analysis.component.html
new file mode 100644
index 0000000..69cf79f
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.html
@@ -0,0 +1,288 @@
+<div nz-row [nzGutter]="24" class="pt-lg">
+    <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+        <chart-card
+            [title]="'������������'"
+            total="�� 126,560"
+            contentHeight="46px"
+            [action]="action1"
+            [footer]="footer1">
+            <ng-template #action1>
+                <nz-tooltip [nzTitle]="'������������'">
+                    <nz-icon nz-tooltip nzType="info-circle-o"></nz-icon>
+                </nz-tooltip>
+            </ng-template>
+            <trend flag="up" style="display:block; margin-top:2px;">���������<span class="pl-sm">12%</span></trend>
+            <trend flag="down">���������<span class="pl-sm">11%</span></trend>
+            <ng-template #footer1>
+                <p class="text-truncate">���������������<span class="ml-sm">���12,423</span></p>
+            </ng-template>
+        </chart-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+        <chart-card [title]="'���������'"
+            total="8,848"
+            contentHeight="46px"
+            [action]="action2"
+            [footer]="footer2">
+            <ng-template #action2>
+                <nz-tooltip [nzTitle]="'������������'">
+                    <nz-icon nz-tooltip nzType="info-circle-o"></nz-icon>
+                </nz-tooltip>
+            </ng-template>
+            <mini-area
+                color="#975FE4"
+                height="46"
+                [data]="data.visitData"></mini-area>
+            <ng-template #footer2>
+                <p class="text-truncate">������������<span class="ml-sm">1,234</span></p>
+            </ng-template>
+        </chart-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+        <chart-card [title]="'������������'"
+            total="6,560"
+            contentHeight="46px"
+            [action]="action3"
+            [footer]="footer3">
+            <ng-template #action3>
+                <nz-tooltip [nzTitle]="'������������'">
+                    <nz-icon nz-tooltip nzType="info-circle-o"></nz-icon>
+                </nz-tooltip>
+            </ng-template>
+            <mini-bar
+                height="46"
+                [data]="data.visitData"></mini-bar>
+            <ng-template #footer3>
+                <p class="text-truncate">���������<span class="ml-sm">60%</span></p>
+            </ng-template>
+        </chart-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+        <chart-card [title]="'������������������'"
+            total="78%"
+            contentHeight="46px"
+            [action]="action4"
+            [footer]="footer4">
+            <ng-template #action4>
+                <nz-tooltip [nzTitle]="'������������'">
+                    <nz-icon nz-tooltip nzType="info-circle-o"></nz-icon>
+                </nz-tooltip>
+            </ng-template>
+            <mini-progress
+                height="46"
+                percent="78"
+                strokeWidth="8"
+                target="80"
+                color="#13C2C2"></mini-progress>
+            <ng-template #footer4>
+                <div class="d-flex justify-content-between">
+                    <trend flag="up">���������<span class="pl-sm">12%</span></trend>
+                    <trend flag="down">���������<span class="pl-sm">11%</span></trend>
+                </div>
+            </ng-template>
+        </chart-card>
+    </div>
+</div>
+<nz-card [nzLoading]="loading" [nzBordered]="false" nzNoPadding class="sales-card">
+    <ng-template #body>
+        <nz-tabset>
+            <nz-tab>
+                <ng-template #nzTabHeading>���������</ng-template>
+                <div nz-row>
+                    <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="16">
+                        <div class="bar">
+                            <bar
+                                height="295"
+                                [title]="'���������������'"
+                                [data]="data.salesData"></bar>
+                        </div>
+                    </div>
+                    <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="8">
+                        <div class="rank-list">
+                            <h4 class="rank-title">���������������������</h4>
+                            <ul>
+                                <li *ngFor="let i of rankingListData; let idx = index">
+                                    <div>
+                                        <span class="icon" [ngClass]="{'active': idx < 3}">{{idx+1}}</span>
+                                        {{i.title}}
+                                    </div>
+                                    <span>{{i.total | number: '3.0'}}</span>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </nz-tab>
+            <nz-tab>
+                <ng-template #nzTabHeading>���������</ng-template>
+                <div nz-row>
+                    <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="16">
+                        <div class="bar">
+                            <bar
+                                height="295"
+                                [title]="'���������������'"
+                                [data]="data.salesData"></bar>
+                        </div>
+                    </div>
+                    <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="8">
+                        <div class="rank-list">
+                            <h4 class="rank-title">���������������������</h4>
+                            <ul>
+                                <li *ngFor="let i of rankingListData; let idx = index">
+                                    <div>
+                                        <span class="icon" [ngClass]="{'active': idx < 3}">{{idx+1}}</span>
+                                        {{i.title}}
+                                    </div>
+                                    <span>{{i.total | number: '3.0'}}</span>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                </div>
+            </nz-tab>
+            <ng-template #nzTabBarExtraContent>
+                <div class="sales-extra-wrap">
+                    <div class="sales-extra">
+                        <a (click)="setDate('today')">������</a>
+                        <a (click)="setDate('week')">������</a>
+                        <a (click)="setDate('month')">������</a>
+                        <a (click)="setDate('year')">������</a>
+                    </div>
+                    <nz-datepicker style="width:120px" class="mr-md" [(ngModel)]="q.start" [nzFormat]="'YYYY-MM-DD'" [nzPlaceHolder]="'������������'"></nz-datepicker>
+                    <nz-datepicker style="width:120px" [(ngModel)]="q.end" [nzFormat]="'YYYY-MM-DD'" [nzPlaceHolder]="'������������'"></nz-datepicker>
+                </div>
+            </ng-template>
+        </nz-tabset>
+    </ng-template>
+</nz-card>
+<div nz-row [nzGutter]="24">
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
+        <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="������������������">
+            <ng-template #extra>
+                <nz-dropdown>
+                    <nz-icon class="icon-group" nz-dropdown nzType="ellipsis"></nz-icon>
+                    <ul nz-menu>
+                        <li nz-menu-item>���������</li>
+                        <li nz-menu-item>���������</li>
+                    </ul>
+                </nz-dropdown>
+            </ng-template>
+            <ng-template #body>
+                <div nz-row [nzGutter]="64">
+                    <div nz-col nzXs="24" nzSm="12" class="mb-md">
+                        <number-info total="12,321" subTotal="17.1" status="up" [subTitle]="subTitle">
+                            <ng-template #subTitle>
+                                ���������������
+                                <nz-tooltip [nzTitle]="'������������'">
+                                    <nz-icon nz-tooltip nzType="info-circle-o" class="ml-sm"></nz-icon>
+                                </nz-tooltip>
+                            </ng-template>
+                        </number-info>
+                        <mini-area [line]="true" height="45" [data]="data.visitData2"></mini-area>
+                    </div>
+                    <div nz-col nzXs="24" nzSm="12" class="mb-md">
+                        <number-info subTitle="������������������" total="2.7" subTotal="26.2" status="down"></number-info>
+                        <mini-area [line]="true" height="45" [data]="data.visitData2"></mini-area>
+                    </div>
+                </div>
+                <nz-table #keyTable [nzDataSource]="data.searchData" [nzPageSize]="5" nzSize="small">
+                    <thead nz-thead>
+                        <tr>
+                            <th nz-th><span>������</span></th>
+                            <th nz-th><span>���������������</span></th>
+                            <th nz-th class="text-right">
+                                <span>���������</span>
+                                <nz-table-sort (nzValueChange)="sort('count',$event)"></nz-table-sort>
+                            </th>
+                            <th nz-th class="text-right">
+                                <span>���������</span>
+                                <nz-table-sort (nzValueChange)="sort('range',$event)"></nz-table-sort>
+                            </th>
+                        </tr>
+                    </thead>
+                    <tbody nz-tbody>
+                        <tr nz-tbody-tr *ngFor="let i of keyTable.data">
+                            <td nz-td>{{i.index}}</td>
+                            <td nz-td><a (click)="msg.success(i.keyword)">{{i.keyword}}</a></td>
+                            <td nz-td class="text-right">{{i.count}}</td>
+                            <td nz-td class="text-right">
+                                <trend [flag]="i.status === 1 ? 'down' : 'up'">
+                                    <span>{{i.range}}%</span>
+                                </trend>
+                            </td>
+                        </tr>
+                    </tbody>
+                </nz-table>
+            </ng-template>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="12">
+        <nz-card [nzLoading]="loading" [nzBordered]="false" nzTitle="���������������������" [nzBodyStyle]="{'padding.px': 24}" class="sales-card" style="min-height: 482px;">
+            <ng-template #extra>
+                <div class="sales-card-extra">
+                    <nz-dropdown>
+                        <nz-icon class="icon-group" nz-dropdown nzType="ellipsis"></nz-icon>
+                        <ul nz-menu>
+                            <li nz-menu-item>���������</li>
+                            <li nz-menu-item>���������</li>
+                        </ul>
+                    </nz-dropdown>
+                    <div class="sales-type-radio">
+                        <nz-radio-group [(ngModel)]="salesType" (ngModelChange)="changeSaleType()" [nzSize]="'large'">
+                            <label nz-radio-button [nzValue]="'all'"><span>������������</span></label>
+                            <label nz-radio-button [nzValue]="'online'"><span>������</span></label>
+                            <label nz-radio-button [nzValue]="'offline'"><span>������</span></label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+            </ng-template>
+            <ng-template #body>
+                <h4 class="margin:8px 0 32px 0;">���������</h4>
+                <pie
+                    [hasLegend]="true"
+                    subTitle="���������"
+                    [height]="248"
+                    [lineWidth]="4"
+                    [total]="salesTotal"
+                    [data]="salesPieData"
+                    [valueFormat]="handlePieValueFormat">
+                </pie>
+            </ng-template>
+        </nz-card>
+    </div>
+</div>
+<nz-card [nzLoading]="loading" [nzBordered]="false" [nzBodyStyle]="{'padding': '0 0 32px'}" class="offline-card mt-lg">
+    <ng-template #body>
+        <nz-tabset [(nzSelectedIndex)]="_activeTab" (nzSelectChange)="_tabChange($event)">
+            <nz-tab *ngFor="let tab of data.offlineData; let i = index;">
+                <ng-template #nzTabHeading>
+                    <div nz-row [nzGutter]="8" style="width: 138px; margin: 8px 0">
+                        <div nz-col [nzSpan]="12">
+                            <number-info
+                                [title]="tab.name"
+                                subTitle="���������"
+                                gap="2"
+                                [total]="(tab.cvr * 100) + '%'"
+                                [theme]="i !== _activeTab && 'light'"></number-info>
+                        </div>
+                        <div nz-col [nzSpan]="12" style="padding-top: 36px">
+                            <pie
+                                [animate]="false"
+                                [color]="i !== _activeTab && '#BDE4FF'"
+                                [inner]="0.55"
+                                [tooltip]="false"
+                                [padding]="[0, 0, 0, 0]"
+                                [percent]="tab.cvr * 100"
+                                [height]="64">
+                            </pie>
+                        </div>
+                    </div>
+                </ng-template>
+                <div class="px-lg">
+                    <timeline [data]="tab.chart"
+                              [titleMap]="{ y1: '���������', y2: '������������' }"></timeline>
+                </div>
+            </nz-tab>
+        </nz-tabset>
+    </ng-template>
+</nz-card>
diff --git a/src/app/routes/dashboard/analysis/analysis.component.less b/src/app/routes/dashboard/analysis/analysis.component.less
new file mode 100644
index 0000000..1cf0646
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.less
@@ -0,0 +1,149 @@
+@import '~@delon/theme/styles/antd/themes/default.less';
+
+:host ::ng-deep {
+	.icon-group {
+		transition: color 0.32s;
+		color: @text-color-secondary;
+		cursor: pointer;
+		margin-left: 16px;
+		&:hover {
+			color: @text-color;
+		}
+	}
+
+	.rank-list {
+		padding: 0px 32px 32px 72px;
+		ul {
+			margin-top: 25px;
+		}
+		li {
+			zoom: 1;
+			margin-top: 16px;
+			display: flex;
+			justify-content: space-between;
+			.icon {
+				background-color: #f5f5f5;
+				border-radius: 20px;
+				display: inline-block;
+				font-size: 12px;
+				font-weight: 600;
+				margin-right: 24px;
+				height: 20px;
+				line-height: 20px;
+				width: 20px;
+				text-align: center;
+			}
+			.active {
+				background-color: #314659;
+				color: #fff;
+			}
+		}
+	}
+
+	.sales-extra {
+		display: inline-block;
+		margin-right: 24px;
+		a {
+			margin-left: 24px;
+        }
+	}
+
+	.sales-card {
+        .bar {
+            padding: 0px 0px 32px 32px;
+        }
+        .rank {
+            padding: 0 32px 32px 72px;
+        }
+		.ant-tabs-tab {
+			padding-top: 16px;
+            padding-bottom: 14px;
+            line-height: 24px;
+        }
+
+        .ant-tabs-extra-content {
+            padding-right: 24px;
+            line-height: 55px;
+        }
+
+		.ant-card-head {
+			position: relative;
+		}
+    }
+
+    .sales-card-extra {
+        height: 68px;
+    }
+
+    .sales-type-radio {
+        position: absolute;
+        left: 24px;
+        bottom: 15px;
+    }
+
+    .offline-card {
+        .ant-tabs-ink-bar {
+            bottom: auto;
+        }
+        .ant-tabs-bar {
+            border-bottom: none;
+        }
+        .ant-tabs-nav-container-scrolling {
+            padding-left: 40px;
+            padding-right: 40px;
+        }
+        .ant-tabs-tab-prev-icon:before {
+            position: relative;
+            left: 6px;
+        }
+        .ant-tabs-tab-next-icon:before {
+            position: relative;
+            right: 6px;
+        }
+    }
+
+    .trend-text {
+        margin-left: 8px;
+        color: @heading-color;
+    }
+
+    @media screen and (max-width: @screen-lg) {
+        .sales-extra {
+            display: none;
+        }
+
+        .rank-list {
+            li {
+                span:first-child {
+                    margin-right: 8px;
+                }
+            }
+        }
+    }
+
+    @media screen and (max-width: @screen-md) {
+        .rank-title {
+            margin-top: 16px;
+        }
+
+        .sales-card .bar {
+            padding: 16px;
+        }
+    }
+
+    @media screen and (max-width: @screen-sm) {
+        .sales-extra-wrap {
+            display: none;
+        }
+
+        .sales-card {
+            .ant-tabs-content {
+              padding-top: 30px;
+            }
+        }
+    }
+
+	.ant-table-pagination {
+		margin-bottom: 0;
+	}
+}
diff --git a/src/app/routes/dashboard/analysis/analysis.component.ts b/src/app/routes/dashboard/analysis/analysis.component.ts
new file mode 100644
index 0000000..cf7b128
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.ts
@@ -0,0 +1,79 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getTimeDistance, yuan } from '@delon/abc';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-dashboard-analysis',
+    templateUrl: './analysis.component.html',
+    styleUrls: ['./analysis.component.less']
+})
+export class DashboardAnalysisComponent implements OnInit {
+    data: any = {
+        salesData: [],
+        offlineData: []
+    };
+    loading = true;
+    q: any = {
+        start: null,
+        end: null
+    };
+    rankingListData: any[] = Array(7).fill({}).map((item, i) => {
+        return {
+            title: `��������� ${i} ������`,
+            total: 323234
+        };
+    });
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        setTimeout(() => {
+            this.data = Object.assign({}, getFakeChartData);
+            this.data.offlineData.forEach((item: any) => {
+                item.chart = Object.assign([], getFakeChartData.offlineChartData);
+            });
+            this.loading = false;
+            this.changeSaleType();
+        }, 500);
+    }
+
+    setDate(type: any) {
+        const rank = getTimeDistance(type);
+        this.q.start = rank[0];
+        this.q.end = rank[1];
+    }
+
+    sort(sortName, sortValue) {
+        this.data.searchData = [
+            ...(<any[]>this.data.searchData).sort((a, b) => {
+                if (a[ sortName ] > b[ sortName ]) {
+                    return (sortValue === 'ascend') ? 1 : -1;
+                } else if (a[ sortName ] < b[ sortName ]) {
+                    return (sortValue === 'ascend') ? -1 : 1;
+                } else {
+                    return 0;
+                }
+            })
+        ];
+    }
+
+    salesType = 'all';
+    salesPieData: any;
+    salesTotal = 0;
+    changeSaleType() {
+        this.salesPieData = this.salesType === 'all' ? this.data.salesTypeData : (
+            this.salesType === 'online' ? this.data.salesTypeDataOnline : this.data.salesTypeDataOffline
+        );
+        if (this.salesPieData) this.salesTotal = this.salesPieData.reduce((pre, now) => now.y + pre, 0);
+    }
+
+    handlePieValueFormat(value: any) {
+        return yuan(value);
+    }
+
+    _activeTab = 0;
+    _tabChange(value: any) {
+        console.log('tab', this._activeTab, value);
+    }
+}
diff --git a/src/app/routes/dashboard/monitor/monitor.component.html b/src/app/routes/dashboard/monitor/monitor.component.html
new file mode 100644
index 0000000..9b8223c
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.html
@@ -0,0 +1,98 @@
+<div nz-row [nzGutter]="24" class="pt-lg">
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="18">
+        <nz-card nzTitle="������������������������" [nzBordered]="false" class="mb-lg">
+            <div nz-row>
+                <div nz-col nzXs="24" nzSm="12" nzMd="6">
+                    <number-info subTitle="������������������" [total]="'124,543,233'" suffix="���"></number-info>
+                </div>
+                <div nz-col nzXs="24" nzSm="12" nzMd="6">
+                    <number-info subTitle="���������������������" [total]="'92%'"></number-info>
+                </div>
+                <div nz-col nzXs="24" nzSm="12" nzMd="6">
+                    <number-info subTitle="������������������" [total]="lastTotalTime">
+                        <ng-template #lastTotalTime><count-down [target]="30"></count-down></ng-template>
+                    </number-info>
+                </div>
+                <div nz-col nzXs="24" nzSm="12" nzMd="6">
+                    <number-info subTitle="������������������" [total]="234" suffix="���"></number-info>
+                </div>
+            </div>
+            <div class="map-chart">
+                <nz-tooltip [nzTitle]="'������������������'">
+                    <img nz-tooltip src="https://gw.alipayobjects.com/zos/rmsportal/HBWnDEUXCnGnGrRfrpKa.png" alt="map" />
+                </nz-tooltip>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzMd="24" nzLg="6">
+        <nz-card nzTitle="������������������" [nzBordered]="false" class="mb-lg">
+            <div class="active-chart">
+                <number-info subTitle="������������" total="������������������"></number-info>
+                <mini-area [animate]="false"
+                        [line]="true"
+                        [borderWidth]="2"
+                        [height]="84"
+                        [yAxis]="activeYAxis"
+                        [data]="activeData"></mini-area>
+                <ng-container *ngIf="activeData?.length > 0">
+                    <div class="active-grid">
+                        <p>{{activeStat.max}} ������</p>
+                        <p>{{activeStat.min}} ������</p>
+                    </div>
+                    <div class="active-legend">
+                        <span>00:00</span>
+                        <span>{{activeStat.t1}}</span>
+                        <span>{{activeStat.t2}}</span>
+                    </div>
+                </ng-container>
+            </div>
+        </nz-card>
+        <nz-card nzTitle="������������" [nzBordered]="false" [nzBodyStyle]="{'text-align': 'center'}" class="mb-lg">
+            <gauge [title]="'���������'" [height]="180" [percent]="87" [format]="couponFormat"></gauge>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="24">
+    <div nz-col nzXs="24" nzSm="24" nzLg="12" class="mb-lg">
+        <nz-card nzTitle="���������������" [nzBordered]="false" class="pie-card">
+            <div nz-row [nzGutter]="4" style="padding:16px 0">
+                <div nz-col [nzSpan]="8">
+                    <pie [animate]="false"
+                         [percent]="28"
+                         subTitle="������������"
+                         total="28%"
+                         [height]="128"
+                         [lineWidth]="2"></pie>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <pie [animate]="false"
+                         color="#5DDECF"
+                         [percent]="22"
+                         subTitle="������"
+                         total="22%"
+                         [height]="128"
+                         [lineWidth]="2"></pie>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <pie [animate]="false"
+                         color="#2FC25B"
+                         [percent]="32"
+                         subTitle="������"
+                         total="32%"
+                         [height]="128"
+                         [lineWidth]="2"></pie>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzLg="6" class="mb-lg">
+        <nz-card nzTitle="������������" [nzBordered]="false" [nzBodyStyle]="{'overflow': 'hidden'}">
+            <tag-cloud [data]="tags" [height]="165"></tag-cloud>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzLg="6" class="mb-lg">
+        <nz-card nzTitle="������������" [nzBordered]="false" [nzBodyStyle]="{'overflow': 'hidden'}">
+            <water-wave [title]="'������������������'" [percent]="34" [height]="165"></water-wave>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/dashboard/monitor/monitor.component.less b/src/app/routes/dashboard/monitor/monitor.component.less
new file mode 100644
index 0000000..0486ca6
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.less
@@ -0,0 +1,60 @@
+@import '~@delon/theme/styles/antd/themes/default.less';
+
+:host ::ng-deep {
+    .map-chart {
+        padding-top: 24px;
+        height: 457px;
+        text-align: center;
+        img {
+            display: inline-block;
+            max-width: 100%;
+            max-height: 437px;
+        }
+    }
+    .pie-card {
+        .pie-stat {
+            font-size: 24px !important;
+        }
+    }
+
+    .active-chart {
+        position: relative;
+        mini-area {
+            margin-top: 32px;
+        }
+        .active-grid {
+            p {
+                position: absolute;
+                top: 80px;
+            }
+            p:last-child {
+                top: 115px;
+            }
+        }
+        .active-legend {
+            position: relative;
+            font-size: 0;
+            margin-top: 8px;
+            height: 20px;
+            line-height: 20px;
+            span {
+                display: inline-block;
+                font-size: 12px;
+                text-align: center;
+                width: 33.33%;
+            }
+            span:first-child {
+                text-align: left;
+            }
+            span:last-child {
+                text-align: right;
+            }
+        }
+    }
+
+    @media screen and (max-width: @screen-lg) {
+        .map-chart {
+            height: auto;
+        }
+    }
+}
diff --git a/src/app/routes/dashboard/monitor/monitor.component.ts b/src/app/routes/dashboard/monitor/monitor.component.ts
new file mode 100644
index 0000000..81ed1c2
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.ts
@@ -0,0 +1,594 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getTimeDistance, yuan, fixedZero } from '@delon/abc';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-dashboard-monitor',
+    templateUrl: './monitor.component.html',
+    styleUrls: ['./monitor.component.less']
+})
+export class DashboardMonitorComponent implements OnInit, OnDestroy {
+    data: any = {
+    };
+    loading = true;
+    q: any = {
+        start: null,
+        end: null
+    };
+
+    // from [http://jsfiddle.net/uTSqT/12/]
+    tags = [
+        {
+            'name': '������������',
+            'value': 99,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 17,
+            'type': 0
+        },
+        {
+            'name': '������������',
+            'value': 92,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 83,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 79,
+            'type': 1
+        },
+        {
+            'name': '���������������������',
+            'value': 92,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 78,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 86,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 18,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 13,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 17,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 52,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 82,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 3,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 62,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 38,
+            'type': 1
+        },
+        {
+            'name': '���������������',
+            'value': 35,
+            'type': 2
+        },
+        {
+            'name': '������������',
+            'value': 62,
+            'type': 2
+        },
+        {
+            'name': '���������������������',
+            'value': 51,
+            'type': 1
+        },
+        {
+            'name': '���������������������',
+            'value': 50,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 94,
+            'type': 1
+        },
+        {
+            'name': '������',
+            'value': 95,
+            'type': 0
+        },
+        {
+            'name': '���������������������',
+            'value': 37,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 44,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 49,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 95,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 1050,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 19,
+            'type': 2
+        },
+        {
+            'name': '���������������������������������',
+            'value': 86,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 97,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 42,
+            'type': 2
+        },
+        {
+            'name': '������������',
+            'value': 11,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 19,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 17,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 16,
+            'type': 1
+        },
+        {
+            'name': '������',
+            'value': 96,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 94,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 49,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 72,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 97,
+            'type': 2
+        },
+        {
+            'name': '���������������',
+            'value': 39,
+            'type': 0
+        },
+        {
+            'name': '������������',
+            'value': 92,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 66,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 11,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 43,
+            'type': 0
+        },
+        {
+            'name': '���������������',
+            'value': 53,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 9,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 50,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 17,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 2,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 93,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 3,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 21,
+            'type': 1
+        },
+        {
+            'name': '���������������',
+            'value': 66,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 45,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 36,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 95,
+            'type': 2
+        },
+        {
+            'name': '���������������������������',
+            'value': 50,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 39,
+            'type': 2
+        },
+        {
+            'name': '������������',
+            'value': 36,
+            'type': 1
+        },
+        {
+            'name': '���������������������',
+            'value': 18,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 86,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 33,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 66,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 41,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 8,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 38,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 96,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 52,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 68,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 20,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 50,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 41,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 26,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 58,
+            'type': 1
+        },
+        {
+            'name': '���������������',
+            'value': 80,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 70,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 18,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 64,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 99,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 95,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 55,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 63,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 32,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 23,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 30,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 43,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 86,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 86,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 13,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 40,
+            'type': 1
+        },
+        {
+            'name': '���������',
+            'value': 72,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 9,
+            'type': 2
+        },
+        {
+            'name': '���������',
+            'value': 22,
+            'type': 2
+        },
+        {
+            'name': '������������',
+            'value': 81,
+            'type': 1
+        },
+        {
+            'name': '���������������',
+            'value': 3,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 50,
+            'type': 0
+        },
+        {
+            'name': '���������',
+            'value': 74,
+            'type': 2
+        },
+        {
+            'name': '������',
+            'value': 50,
+            'type': 1
+        },
+        {
+            'name': '������������',
+            'value': 56,
+            'type': 1
+        }
+    ];
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        setTimeout(() => {
+            this.data = getFakeChartData;
+            this.loading = false;
+        }, 500);
+
+        // active chart
+        this.genActiveData();
+        this.activeTime$ = setInterval(() => this.genActiveData(), 1000);
+    }
+
+    // region: active chart
+
+    activeTime$: any;
+
+    activeYAxis = {
+        tickCount: 3,
+        tickLine: false,
+        labels: false,
+        title: false,
+        line: false
+    };
+
+    activeData: any[] = [];
+
+    activeStat = {
+        max: 0,
+        min: 0,
+        t1: '',
+        t2: ''
+    };
+
+    genActiveData() {
+        const activeData = [];
+        for (let i = 0; i < 24; i += 1) {
+            activeData.push({
+                x: `${fixedZero(i)}:00`,
+                y: (i * 50) + (Math.floor(Math.random() * 200)),
+            });
+        }
+        this.activeData = activeData;
+        // stat
+        this.activeStat.max = [...activeData].sort()[activeData.length - 1].y + 200;
+        this.activeStat.min = [...activeData].sort()[Math.floor(activeData.length / 2)].y;
+        this.activeStat.t1 = activeData[Math.floor(activeData.length / 2)].x;
+        this.activeStat.t2 = activeData[activeData.length - 1].x;
+    }
+
+    // endregion
+
+    couponFormat(val: any) {
+        switch (parseInt(val, 10)) {
+            case 20:
+              return '���';
+            case 40:
+              return '���';
+            case 60:
+              return '���';
+            case 80:
+              return '���';
+            default:
+              return '';
+        }
+    }
+
+    ngOnDestroy(): void {
+        if (this.activeTime$) clearInterval(this.activeTime$);
+    }
+}
diff --git a/src/app/routes/dashboard/v1/v1.component.html b/src/app/routes/dashboard/v1/v1.component.html
new file mode 100644
index 0000000..21cb2f0
--- /dev/null
+++ b/src/app/routes/dashboard/v1/v1.component.html
@@ -0,0 +1,150 @@
+<div class="content__title">
+    <h1>
+        Dashboard
+        <small class="text-sm hidden-xs">Welcome !</small>
+    </h1>
+</div>
+<div class="quick-menu" [class.show]="quickMenu" (click)="quickMenu=!quickMenu">
+    <div class="quick-menu-inner">
+        <div class="settings-ctrl">
+            <i class="anticon anticon-question-circle-o"></i>
+        </div>
+        <div class="list-group list-group-flush">
+            <a (click)="msg.info('item 1')" class="list-group-item">How do i create account?</a>
+            <a (click)="msg.info('item 2')" class="list-group-item">How do i create account?</a>
+            <a (click)="msg.info('item 3')" class="list-group-item">How do i create account?</a>
+            <a (click)="msg.info('item 4')" class="list-group-item">How do i create account?</a>
+            <a (click)="msg.info('item 5')" class="list-group-item">How do i create account?</a>
+        </div>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-primary rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">123,456</div>
+                <p class="text-nowrap">Website Traffics</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-success rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">234,567K</div>
+                <p class="text-nowrap">Website Impressions</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-orange rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">$458,778</div>
+                <p class="text-nowrap">Total Sales</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-pink rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">456</div>
+                <p class="text-nowrap">Support Tickets</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card [nzBordered]="false">
+            <ng-template #title>
+                Sales Statistics
+                <small class="text-sm font-weight-normal">Business Expectations & Retail Sales Statistics</small>
+            </ng-template>
+            <bar
+                height="275"
+                [data]="salesData"></bar>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card [nzTitle]="nzTitle" [nzBordered]="false">
+            <ng-template #nzTitle>
+                Growth Rate
+                <small class="text-sm font-weight-normal">Business Expectations & Retail Sales Statistics</small>
+            </ng-template>
+            <timeline [data]="offlineChartData" [height]="239" [padding]="[0, 0, 0, 0]"
+                      [titleMap]="{ y1: '���������', y2: '������������' }"></timeline>
+        </nz-card>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card [nzBordered]="false" class="ant-card__img">
+            <img class="img" src="//os.alipayobjects.com/rmsportal/GhjqstwSgxBXrZS.png">
+            <div class="p-md">
+                <h3>ANT DESIGN</h3>
+                <p class="text-grey">A UI Design Language</p>
+                <ol class="list-styled text-lg pt-md">
+                    <li>Designed by experienced team, and showcase dozens of inspiring projects.</li>
+                    <li>Provide solutions for usual problems that may be encountered while developing enterprise-like complex UIs.</li>
+                    <li>Dozens of flexible and practical reusable components that increase your productivity.</li>
+                </ol>
+                <p class="pt-md">
+                    <a class="text-grey" href="//ng.ant.design" target="_blank">View Site...</a>
+                </p>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card [nzTitle]="nzTitle" [nzBordered]="false" nzNoPadding>
+            <ng-template #nzTitle>
+                Recent Posts
+                <small class="text-sm font-weight-normal">Venenatis portauam Inceptos ameteiam</small>
+            </ng-template>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point"
+                *ngFor="let item of todoData">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <nz-avatar [nzSrc]="'./assets/img/' + item.avatar + '.png'" [nzSize]="'large'"></nz-avatar>
+                </div>
+                <div nz-col [nzSpan]="20">
+                    <strong>{{item.name}}</strong>
+                    <p>{{item.content}}</p>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card nzTitle="Todo lists" [nzBordered]="false" nzNoPadding>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point"
+                *ngFor="let item of todoData">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <nz-avatar [nzSrc]="'./assets/img/' + item.avatar + '.png'" [nzSize]="'large'"></nz-avatar>
+                </div>
+                <div nz-col [nzSpan]="18">
+                    <strong>{{item.name}}</strong>
+                    <p [class.text-deleted]="item.completed">{{item.content}}</p>
+                </div>
+                <div nz-col [nzSpan]="2" class="text-right pr-md">
+                    <nz-dropdown [nzPlacement]="'topRight'">
+                        <i nz-dropdown class="icon-options-vertical"></i>
+                        <ul nz-menu>
+                            <li nz-menu-item *ngIf="item.completed" (click)="item.completed=false">Active</li>
+                            <li nz-menu-item *ngIf="!item.completed" (click)="item.completed=true">Completed</li>
+                            <li nz-menu-item (click)="todoData.splice(todoData.indexOf(item), 1)">Delted</li>
+                        </ul>
+                    </nz-dropdown>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/dashboard/v1/v1.component.spec.ts b/src/app/routes/dashboard/v1/v1.component.spec.ts
new file mode 100644
index 0000000..906dd4e
--- /dev/null
+++ b/src/app/routes/dashboard/v1/v1.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { DashboardV1Component } from './v1.component';
+
+describe('Comoponent: DashboardV1', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ DashboardV1Component ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(DashboardV1Component);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/dashboard/v1/v1.component.ts b/src/app/routes/dashboard/v1/v1.component.ts
new file mode 100644
index 0000000..4906f4b
--- /dev/null
+++ b/src/app/routes/dashboard/v1/v1.component.ts
@@ -0,0 +1,29 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component } from '@angular/core';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-dashboard-v1',
+    templateUrl: './v1.component.html'
+})
+export class DashboardV1Component {
+
+    constructor(public msg: NzMessageService) {
+        console.log(this.offlineChartData);
+    }
+
+    todoData: any[] = [
+        { completed: true, avatar: '1', name: '���������', content: `������������������������������������������` },
+        { completed: false, avatar: '2', name: '������������', content: `���������������������������������������` },
+        { completed: false, avatar: '3', name: 'cipchk', content: `this world was never meant for one as beautiful as you.` },
+        { completed: false, avatar: '4', name: 'Kent', content: `my heart is beating with hers` },
+        { completed: false, avatar: '5', name: 'Are you', content: `They always said that I love beautiful girl than my friends` },
+        { completed: false, avatar: '6', name: 'Forever', content: `Walking through green fields ���sunshine in my eyes.` }
+    ];
+
+    quickMenu = false;
+
+    webSite = [ ...getFakeChartData.visitData.slice(0, 10) ];
+    salesData =  [...getFakeChartData.salesData];
+    offlineChartData = Object.assign([], getFakeChartData.offlineChartData);
+}
diff --git a/src/app/routes/dashboard/workplace/workplace.component.html b/src/app/routes/dashboard/workplace/workplace.component.html
new file mode 100644
index 0000000..1e15215
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.html
@@ -0,0 +1,105 @@
+<pro-header>
+    <ng-template #breadcrumb>
+        <nz-breadcrumb>
+            <nz-breadcrumb-item><a [routerLink]="['/']">������</a></nz-breadcrumb-item>
+            <nz-breadcrumb-item><a [routerLink]="['/']">Dashboard</a></nz-breadcrumb-item>
+            <nz-breadcrumb-item>���������</nz-breadcrumb-item>
+        </nz-breadcrumb>
+    </ng-template>
+    <ng-template #content>
+        <div class="page-header">
+            <div class="avatar"><nz-avatar nzSize="large" nzSrc="https://gw.alipayobjects.com/zos/rmsportal/lctvVCLfRpYCkYxAsiVQ.png"></nz-avatar></div>
+            <div class="desc">
+                <div class="desc-title">���������������������������������</div>
+                <p>��������� | ���������������������������������������������������������������</p>
+            </div>
+        </div>
+    </ng-template>
+    <ng-template #extra>
+        <div class="page-extra">
+            <div>
+                <p>���������</p>
+                <p>56</p>
+            </div>
+            <div>
+                <p>���������������</p>
+                <p>8<span> / 24</span></p>
+            </div>
+            <div>
+                <p>������������</p>
+                <p>2,223</p>
+            </div>
+        </div>
+    </ng-template>
+</pro-header>
+<div nz-row [nzGutter]="24">
+    <div nz-col nzXs="24" nzSm="24" nzMd="16">
+        <nz-card nzTitle="������������������" [nzBordered]="false" [nzLoading]="loading" nzNoPadding class="mb-lg project-list">
+            <ng-template #extra>
+                <a (click)="msg.success('to')">������������</a>
+            </ng-template>
+            <div *ngFor="let item of notice" nz-card-grid class="project-grid">
+                <nz-card nzNoPadding [nzBordered]="false" class="mb0">
+                    <nz-card-meta [nzTitle]="noticeTitle" [nzDescription]="item.description">
+                        <ng-template #noticeTitle>
+                            <div class="card-title">
+                                <nz-avatar [nzSrc]="item.logo" [nzSize]="'small'"></nz-avatar>
+                                <a (click)="msg.info('to' + item.href)">{{item.title}}</a>
+                            </div>
+                        </ng-template>
+                    </nz-card-meta>
+                    <div class="project-item">
+                        <a (click)="msg.info('show user: ' + item.member)">{{item.member}}</a>
+                        <span *ngIf="item.updatedAt" class="datetime" title="{{item.updatedAt}}">
+                            {{item.updatedAt | _date: 'fn' }}
+                        </span>
+                    </div>
+                </nz-card>
+            </div>
+        </nz-card>
+        <nz-card nzTitle="������" [nzBordered]="false" [nzLoading]="loading" nzNoPadding class="mb-lg active-card">
+            <nz-list nzSize="large">
+                <nz-list-item *ngFor="let item of activities" class="activities">
+                    <nz-list-item-meta
+                        [nzAvatar]="item.user.avatar"
+                        [nzTitle]="activeTitle"
+                        [nzDescription]="activeDescription">
+                        <ng-template #activeTitle>
+                            <a (click)="msg.success(item.user.name)" class="username">{{item.user.name}}</a>
+                            &nbsp;
+                            <span class="event" [innerHTML]="item.template"></span>
+                        </ng-template>
+                        <ng-template #activeDescription>
+                            <span class="datetime" title="{{item.updatedAt}}">{{item.updatedAt | _date: 'fn'}}</span>
+                        </ng-template>
+                    </nz-list-item-meta>
+                </nz-list-item>
+            </nz-list>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="24" nzMd="8">
+        <nz-card nzTitle="������������ / ������������" [nzBordered]="false" nzNoPadding class="mb-lg">
+            <div class="links">
+                <a *ngFor="let item of links" (click)="msg.success(item.title)">{{item.title}}</a>
+                <button nz-button (click)="links.push({title: 'new titel', href: 'href'})" [nzType]="'dashed'" [nzSize]="'small'">
+                    <i class="anticon anticon-plus"></i><span>������</span>
+                </button>
+            </div>
+        </nz-card>
+        <nz-card nzTitle="XX ������" [nzBordered]="false" [nzLoading]="loading" class="mb-lg">
+            <ng-template #body><radar [data]="radarData" [height]="343" [hasLegend]="true"></radar></ng-template>
+        </nz-card>
+        <nz-card nzTitle="������" [nzBordered]="false" [nzBodyStyle]="{'padding-top.px': 12, 'padding-bottom.px': 12 }" class="mb-lg">
+            <div class="members">
+                <div nz-row [nzGutter]="48">
+                    <div nz-col [nzSpan]="12" *ngFor="let i of members">
+                        <a (click)="msg.success(i.title)">
+                            <nz-avatar [nzSrc]="i.logo" [nzSize]="'small'"></nz-avatar>
+                            <span class="member">{{i.title}}</span>
+                        </a>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/dashboard/workplace/workplace.component.less b/src/app/routes/dashboard/workplace/workplace.component.less
new file mode 100644
index 0000000..f9b26ae
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.less
@@ -0,0 +1,241 @@
+@import '~@delon/theme/styles/antd/themes/default.less';
+@import '~@delon/abc/components/utils/utils.less';
+
+:host ::ng-deep {
+	.page-header {
+		display: flex;
+		.avatar {
+			flex: 0 1 72px;
+			margin-bottom: 8px;
+			.ant-avatar {
+				border-radius: 72px;
+				display: block;
+				width: 72px;
+				height: 72px;
+			}
+		}
+		.desc {
+			position: relative;
+			top: 4px;
+			margin-left: 24px;
+			flex: 1 1 auto;
+			color: @text-color-secondary;
+			line-height: 22px;
+			.desc-title {
+				font-size: 20px;
+				line-height: 28px;
+				font-weight: 500;
+				color: @heading-color;
+				margin-bottom: 12px;
+			}
+		}
+	}
+
+	.page-extra {
+        .clearfix();
+		float: right;
+		& > div {
+			padding: 0 32px;
+			position: relative;
+			float: left;
+			& > p:first-child {
+				color: @text-color-secondary;
+				font-size: @font-size-base;
+				line-height: 22px;
+				margin-bottom: 4px;
+			}
+			& > p {
+				color: @heading-color;
+				font-size: 30px;
+				line-height: 38px;
+				margin: 0;
+				& > span {
+					color: @text-color-secondary;
+					font-size: 20px;
+				}
+			}
+			&:after {
+				background-color: @border-color-split;
+				position: absolute;
+				top: 8px;
+				right: 0;
+				width: 1px;
+				height: 40px;
+				content: "";
+			}
+		}
+		& > div:last-child {
+			padding-right: 0;
+			&:after {
+				display: none;
+			}
+		}
+    }
+
+    .project-list {
+        .ant-card-meta-description {
+            color: @text-color-secondary;
+            height: 44px;
+            line-height: 22px;
+            overflow: hidden;
+        }
+        .card-title {
+            font-size: 0;
+            a {
+                color: @heading-color;
+                margin-left: 12px;
+                line-height: 24px;
+                height: 24px;
+                display: inline-block;
+                vertical-align: top;
+                font-size: @font-size-base;
+                &:hover {
+                    color: @primary-color;
+                }
+            }
+        }
+
+        .project-grid {
+            width: 33.33%;
+        }
+
+        .project-item {
+            display: flex;
+            margin-top: 8px;
+            overflow: hidden;
+            font-size: 12px;
+            height: 20px;
+            line-height: 20px;
+            .textOverflow();
+            a {
+                color: @text-color-secondary;
+                display: inline-block;
+                flex: 1 1 0;
+                .textOverflow();
+                &:hover {
+                    color: @primary-color;
+                }
+            }
+            .datetime {
+                color: @disabled-color;
+                flex: 0 0 auto;
+                float: right;
+            }
+        }
+    }
+
+    .activities {
+        padding: 0 24px 8px;
+        .username {
+            color: @text-color;
+        }
+        .event {
+            font-weight: normal;
+        }
+    }
+
+    .members {
+        a {
+          display: block;
+          margin: 12px 0;
+          line-height: 24px;
+          height: 24px;
+          .textOverflow();
+          .member {
+            font-size: @font-size-base;
+            color: @text-color;
+            line-height: 24px;
+            max-width: 100px;
+            vertical-align: top;
+            margin-left: 12px;
+            transition: all .3s;
+            display: inline-block;
+            .textOverflow();
+          }
+          &:hover {
+            span {
+              color: @primary-color;
+            }
+          }
+        }
+    }
+
+    .datetime {
+        color: @disabled-color;
+    }
+
+    .links {
+        padding: 20px 0 8px 24px;
+        font-size: 0;
+        > a {
+            color: rgba(0, 0, 0, 0.65);
+            display: inline-block;
+            font-size: 14px;
+            margin-bottom: 13px;
+            width: 25%;
+        }
+    }
+
+	@media screen and (max-width: @screen-xl) and (min-width: @screen-lg) {
+        .active-card {
+            margin-bottom: 24px;
+        }
+        .members {
+            margin-bottom: 0;
+        }
+		.page-extra {
+			margin-left: -44px;
+			& > div {
+				padding: 0 16px;
+			}
+		}
+	}
+
+	@media screen and (max-width: @screen-lg) {
+        .active-card {
+            margin-bottom: 24px;
+        }
+        .members {
+            margin-bottom: 0;
+        }
+		.page-extra {
+			float: none;
+			margin-right: 0;
+			& > div {
+				padding: 0 16px;
+				text-align: left;
+				&:after {
+					display: none;
+				}
+			}
+		}
+	}
+
+	@media screen and (max-width: @screen-md) {
+		.page-extra {
+			margin-left: -16px;
+		}
+	}
+
+	@media screen and (max-width: @screen-sm) {
+		.page-header {
+			display: block;
+			.desc {
+				margin-left: 0;
+			}
+		}
+		.page-extra {
+			& > div {
+				float: none;
+			}
+		}
+	}
+
+	@media screen and (max-width: @screen-xs) {
+        .project-list {
+            .project-grid {
+                width: 100%;
+            }
+        }
+	}
+}
diff --git a/src/app/routes/dashboard/workplace/workplace.component.ts b/src/app/routes/dashboard/workplace/workplace.component.ts
new file mode 100644
index 0000000..bb72437
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.ts
@@ -0,0 +1,98 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getTimeDistance, yuan, fixedZero } from '@delon/abc';
+import { getNotice, getActivities } from '../../../../../_mock/api.service';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-dashboard-workplace',
+    templateUrl: './workplace.component.html',
+    styleUrls: ['./workplace.component.less']
+})
+export class DashboardWorkplaceComponent implements OnInit, OnDestroy {
+    notice: any[] = [];
+    activities: any[] = [];
+    radarData: any[] = [];
+    loading = true;
+
+    // region: mock data
+    links = [
+        {
+          title: '���������',
+          href: '',
+        },
+        {
+          title: '���������',
+          href: '',
+        },
+        {
+          title: '���������',
+          href: '',
+        },
+        {
+          title: '���������',
+          href: '',
+        },
+        {
+          title: '���������',
+          href: '',
+        },
+        {
+          title: '���������',
+          href: '',
+        },
+    ];
+    members = [
+        {
+          id: 'members-1',
+          title: '���������������',
+          logo: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
+          link: '',
+        },
+        {
+          id: 'members-2',
+          title: '���������������',
+          logo: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png',
+          link: '',
+        },
+        {
+          id: 'members-3',
+          title: '������������',
+          logo: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png',
+          link: '',
+        },
+        {
+          id: 'members-4',
+          title: '���������������',
+          logo: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png',
+          link: '',
+        },
+        {
+          id: 'members-5',
+          title: '������������������',
+          logo: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png',
+          link: '',
+        },
+      ];
+    // endregion
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        setTimeout(() => {
+            this.notice = getNotice();
+            this.activities = getActivities().map((item: any) => {
+                item.template = item.template.split(/@\{([^{}]*)\}/gi).map((key: string) => {
+                    if (item[key]) return `<a>${item[key].name}</a>`;
+                    return key;
+                });
+                return item;
+            });
+            this.radarData = getFakeChartData.radarData;
+            this.loading = false;
+        }, 500);
+    }
+
+    ngOnDestroy(): void {
+    }
+}
diff --git a/src/app/routes/data-v/data-v.module.ts b/src/app/routes/data-v/data-v.module.ts
new file mode 100644
index 0000000..f0e4cea
--- /dev/null
+++ b/src/app/routes/data-v/data-v.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { RelationComponent } from './relation/relation.component';
+
+const routes: Routes = [
+    { path: 'relation', component: RelationComponent }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    declarations: [
+        RelationComponent
+    ],
+    exports: [
+        RouterModule
+    ]
+})
+export class DataVModule { }
diff --git a/src/app/routes/data-v/relation/relation.component.html b/src/app/routes/data-v/relation/relation.component.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/app/routes/data-v/relation/relation.component.html
diff --git a/src/app/routes/data-v/relation/relation.component.less b/src/app/routes/data-v/relation/relation.component.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/app/routes/data-v/relation/relation.component.less
diff --git a/src/app/routes/data-v/relation/relation.component.ts b/src/app/routes/data-v/relation/relation.component.ts
new file mode 100644
index 0000000..e77ee0d
--- /dev/null
+++ b/src/app/routes/data-v/relation/relation.component.ts
@@ -0,0 +1,144 @@
+import { Component, OnDestroy, ViewEncapsulation, OnInit } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+    selector: 'app-data-v-relation',
+    templateUrl: './relation.component.html',
+    styleUrls: [ './relation.component.less' ]
+})
+export class RelationComponent implements OnInit, OnDestroy {
+
+    ecIntance: any;
+
+    options: any = {
+        title: {
+            text: 'User Releaction'
+        },
+        tooltip: {},
+        animationDurationUpdate: 1500,
+        animationEasingUpdate: 'quinticInOut',
+        series: [{
+            type: 'graph',
+            layout: 'force',
+            symbolSize: 60,
+            focusNodeAdjacency: true,
+            roam: true,
+            categories: [{
+                name: 'User'
+            }],
+            label: {
+                normal: {
+                    show: true,
+                    textStyle: {
+                        fontSize: 12
+                    },
+                }
+            },
+            force: {
+                repulsion: 2000,
+                gravity: .3
+            },
+            edgeSymbol: ['circle', 'arrow'],
+            edgeSymbolSize: [4, 10],
+            draggable: true,
+            tooltip: {
+                triggerOn: 'click',
+                formatter: (item) => {
+                    if (item.dataType === 'node')
+                        return `${item.data.name}���${item.data.arg}`;
+                    return item.name;
+                }
+            },
+            data: Array(20).fill({}).map((v, i) => {
+                return {
+                    name: 'User' + i,
+                    arg: i + 10,
+                    category: 0
+                };
+            }),
+            links: [{
+                source: 'User0',
+                target: 'User1'
+            }, {
+                source: 'User0',
+                target: 'User2'
+            }, {
+                source: 'User0',
+                target: 'User3'
+            }, {
+                source: 'User1',
+                target: 'User4'
+            }, {
+                source: 'User2',
+                target: 'User5'
+            }, {
+                source: 'User3',
+                target: 'User6'
+            }, {
+                source: 'User4',
+                target: 'User7'
+            }, {
+                source: 'User5',
+                target: 'User8'
+            }, {
+                source: 'User6',
+                target: 'User9'
+            }, {
+                source: 'User1',
+                target: 'User10'
+            }, {
+                source: 'User1',
+                target: 'User11'
+            }, {
+                source: 'User11',
+                target: 'User12'
+            }, {
+                source: 'User11',
+                target: 'User13'
+            }, {
+                source: 'User11',
+                target: 'User14'
+            }, {
+                source: 'User11',
+                target: 'User15'
+            }, {
+                source: 'User11',
+                target: 'User16'
+            }, {
+                source: 'User11',
+                target: 'User17'
+            }, {
+                source: 'User11',
+                target: 'User18'
+            }, {
+                source: 'User11',
+                target: 'User19'
+            }],
+            lineStyle: {
+                normal: {
+                    opacity: 0.7,
+                    width: 1,
+                    curveness: 0.1
+                }
+            }
+        }]
+    };
+
+    constructor(private http: _HttpClient) { }
+
+    chartInit(ec) {
+        this.ecIntance = ec;
+    }
+
+    ngOnInit() {
+        window.addEventListener('resize', () => this.resize);
+    }
+
+    private resize() {
+        if (this.ecIntance) this.ecIntance.resize();
+    }
+
+    ngOnDestroy(): void {
+        window.removeEventListener('resize', () => this.resize);
+    }
+}
diff --git a/src/app/routes/elements/buttons/buttons.component.html b/src/app/routes/elements/buttons/buttons.component.html
new file mode 100644
index 0000000..34e7805
--- /dev/null
+++ b/src/app/routes/elements/buttons/buttons.component.html
@@ -0,0 +1,208 @@
+<div class="content__title">
+    <h1>Button</h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Type">
+            <button nz-button [nzType]="'primary'" [disabled]="disabled" class="mr-sm">
+                <span>Primary</span>
+            </button>
+            <button nz-button [nzType]="'default'" [disabled]="disabled" class="mr-sm">
+                <span>Default</span>
+            </button>
+            <button nz-button [nzType]="'dashed'" [disabled]="disabled" class="mr-sm">
+                <span>Dashed</span>
+            </button>
+            <button nz-button [nzType]="'danger'" [disabled]="disabled" class="mr-sm">
+                <span>Danger</span>
+            </button>
+            <button nz-button [nzType]="'dashed'" (click)="toggleDisabled()" class="mr-sm">
+                <span>Toggle disabled</span>
+            </button>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Icon">
+            <button nz-button [nzType]="'primary'" [nzShape]="'circle'" [disabled]="disabled" class="mr-sm">
+                <i class="anticon anticon-search"></i>
+            </button>
+            <button nz-button [nzType]="'primary'" [disabled]="disabled" class="mr-sm">
+                <i class="anticon anticon-search"></i><span>Search</span>
+            </button>
+            <button nz-button [nzType]="'dashed'" [nzShape]="'circle'" [disabled]="disabled" class="mr-sm">
+                <i class="anticon anticon-search"></i>
+            </button>
+            <button nz-button [nzType]="'default'" [disabled]="disabled" class="mr-sm">
+                <i class="anticon anticon-search"></i><span>Search</span>
+            </button>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Size">
+            <nz-radio-group [(ngModel)]="size" class="mb-md">
+                <label nz-radio-button [nzValue]="'large'"><span>Large</span></label>
+                <label nz-radio-button [nzValue]="'default'"><span>Default</span></label>
+                <label nz-radio-button [nzValue]="'small'"><span>Small</span></label>
+            </nz-radio-group>
+            <div class="mb-md">
+                <button nz-button [nzType]="'primary'" [nzSize]="size" [nzShape]="'circle'" class="mr-sm">
+                    <i class="anticon anticon-download"></i>
+                </button>
+                <button nz-button [nzType]="'primary'" [nzSize]="size" class="mr-sm">
+                    <i class="anticon anticon-download"></i><span>Download</span>
+                </button>
+                <button nz-button [nzType]="'primary'" [nzSize]="size">
+                    <span>Normal</span>
+                </button>
+            </div>
+            <nz-button-group [nzSize]="size">
+                <button nz-button [nzType]="'primary'" class="mr-sm">
+                    <i class="anticon anticon-left"></i><span>Backward</span>
+                </button>
+                <button nz-button [nzType]="'primary'">
+                    <span>Forward</span><i class="anticon anticon-right"></i>
+                </button>
+            </nz-button-group>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Loading">
+            <div class="mb-md">
+                <button nz-button [nzType]="'primary'" [nzLoading]="loading" class="mr-sm">
+                    <span><i class="anticon anticon-poweroff"></i> Loading</span>
+                </button>
+                <button nz-button [nzType]="'primary'" [nzSize]="'small'" [nzLoading]="loading" class="mr-sm">
+                    <span>Loading</span>
+                </button>
+                <button nz-button [nzType]="'dashed'" (click)="toggleLoading()">
+                    <span>Toggle Loading</span>
+                </button>
+            </div>
+            <div class="mb-md">
+                <button nz-button [nzType]="'primary'" [nzLoading]="loading" class="mr-sm">
+                    <span>Click me!</span>
+                </button>
+                <button nz-button [nzType]="'primary'" [nzLoading]="loading">
+                    <i class="anticon anticon-poweroff"></i>
+                    <span>Click me!</span>
+                </button>
+            </div>
+            <button nz-button [nzLoading]="true" [nzShape]="'circle'" class="mr-sm"></button>
+            <button nz-button [nzLoading]="true" [nzShape]="'circle'" [nzType]="'primary'"></button>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Multiple Buttons">
+            <button nz-button [nzType]="'primary'" class="mr-sm">
+                <span>primary</span>
+            </button>
+            <button nz-button [nzType]="'default'" class="mr-sm">
+                <span>secondary</span>
+            </button>
+            <nz-dropdown class="mr-sm">
+                <button nz-button nz-dropdown><span>more</span> <i class="anticon anticon-down"></i></button>
+                <ul nz-menu>
+                    <li nz-menu-item>
+                        <a>1st item</a>
+                    </li>
+                    <li nz-menu-item>
+                        <a>2nd item</a>
+                    </li>
+                    <li nz-menu-item>
+                        <a>3rd item</a>
+                    </li>
+                </ul>
+            </nz-dropdown>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Ghost Button">
+            <div class="bg-grey p-lg">
+                <button nz-button [nzType]="'primary'" [nzGhost]="true" class="mr-sm">
+                    <span>Primary</span>
+                </button>
+                <button nz-button [nzType]="'default'" [nzGhost]="true" class="mr-sm">
+                    <span>Default</span>
+                </button>
+                <button nz-button [nzType]="'dashed'" [nzGhost]="true" class="mr-sm">
+                    <span>Dashed</span>
+                </button>
+                <button nz-button [nzType]="'danger'" [nzGhost]="true">
+                    <span>Danger</span>
+                </button>
+            </div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Button Group">
+            <h4 class="pb-sm">Basic</h4>
+            <nz-button-group>
+                <button nz-button>Cancel</button>
+                <button nz-button [nzType]="'primary'">OK</button>
+            </nz-button-group>
+            <nz-button-group>
+                <button nz-button [nzType]="'default'" disabled>
+                    <span>L</span>
+                </button>
+                <button nz-button [nzType]="'default'" disabled>
+                    <span>M</span>
+                </button>
+                <button nz-button [nzType]="'default'" disabled>
+                    <span>R</span>
+                </button>
+            </nz-button-group>
+            <nz-button-group>
+                <button nz-button [nzType]="'primary'" disabled>
+                    <span>L</span>
+                </button>
+                <button nz-button [nzType]="'default'" disabled>
+                    <span>M</span>
+                </button>
+                <button nz-button [nzType]="'default'">
+                    <span>M</span>
+                </button>
+                <button nz-button [nzType]="'dashed'" disabled>
+                    <span>R</span>
+                </button>
+            </nz-button-group>
+            <h4 class="py-sm">With Icon</h4>
+            <nz-button-group>
+                <button nz-button [nzType]="'primary'">
+                    <i class=" anticon anticon-left"></i>
+                    <span>Go back</span>
+                </button>
+                <button nz-button [nzType]="'primary'">
+                    <span>Go forward</span>
+                    <i class=" anticon anticon-right"></i>
+                </button>
+            </nz-button-group>
+            <nz-button-group>
+                <button nz-button [nzType]="'primary'">
+                    <i class=" anticon anticon-cloud"></i>
+                </button>
+                <button nz-button [nzType]="'primary'">
+                    <i class=" anticon anticon-cloud-download"></i>
+                </button>
+            </nz-button-group>
+            <h4 class="py-sm">Size</h4>
+            <nz-button-group [nzSize]="'large'">
+                <button nz-button>Large</button>
+                <button nz-button>Large</button>
+            </nz-button-group>
+            <nz-button-group>
+                <button nz-button>Default</button>
+                <button nz-button>Default</button>
+            </nz-button-group>
+            <nz-button-group [nzSize]="'small'">
+                <button nz-button>Small</button>
+                <button nz-button>Small</button>
+            </nz-button-group>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/buttons/buttons.component.spec.ts b/src/app/routes/elements/buttons/buttons.component.spec.ts
new file mode 100644
index 0000000..a947f1f
--- /dev/null
+++ b/src/app/routes/elements/buttons/buttons.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ButtonsComponent } from './buttons.component';
+
+describe('Component: Buttons', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ButtonsComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ButtonsComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/buttons/buttons.component.ts b/src/app/routes/elements/buttons/buttons.component.ts
new file mode 100644
index 0000000..3df3590
--- /dev/null
+++ b/src/app/routes/elements/buttons/buttons.component.ts
@@ -0,0 +1,19 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+    selector: 'app-buttons',
+    templateUrl: './buttons.component.html'
+})
+export class ButtonsComponent {
+    disabled = false;
+    loading = false;
+    size = 'default';
+
+    toggleDisabled() {
+        this.disabled = !this.disabled;
+    }
+
+    toggleLoading() {
+        this.loading = !this.loading;
+    }
+}
diff --git a/src/app/routes/elements/colors/colors.component.html b/src/app/routes/elements/colors/colors.component.html
new file mode 100644
index 0000000..10d3ce1
--- /dev/null
+++ b/src/app/routes/elements/colors/colors.component.html
@@ -0,0 +1,72 @@
+<div class="content__title">
+    <h1>
+        Colors
+        <small>Color Palettes</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Classic colors">
+            <div nz-row *ngFor="let c of colorSrv.brands">
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}}-light p-lg">.bg-{{c}}-light<br>.text-{{c}}-light</div>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}} p-lg">.bg-{{c}}<br>.text-{{c}}</div>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}}-dark p-lg">.bg-{{c}}-dark<br>.text-{{c}}-dark</div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Name colors">
+            <div nz-row *ngFor="let c of colors">
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}}-light p-lg">.bg-{{c}}-light<br>.text-{{c}}-light</div>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}} p-lg">.bg-{{c}}<br>.text-{{c}}</div>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <div class="bg-{{c}}-dark p-lg">.bg-{{c}}-dark<br>.text-{{c}}-dark</div>
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="5">
+                    <div class="bg-grey-darker p-lg">.bg-grey-darker<br>.color-grey-darker</div>
+                </div>
+                <div nz-col [nzSpan]="5">
+                    <div class="bg-grey-dark p-lg">.bg-grey-dark<br>.color-grey-dark</div>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <div class="bg-grey p-lg">.bg-grey<br>.color-grey</div>
+                </div>
+                <div nz-col [nzSpan]="5">
+                    <div class="bg-grey-light p-lg">.bg-grey-light<br>.color-grey-light</div>
+                </div>
+                <div nz-col [nzSpan]="5">
+                    <div class="bg-grey-lighter p-lg">.bg-grey-lighter<br>.color-grey-lighter</div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Full Colors">
+            <div nz-row>
+                <div nz-col [nzSpan]="4" *ngFor="let c of colorSrv.names">
+                    <div *ngFor="let i of nums" class="bg-{{c}}-{{i}} p-lg">
+                        .bg-{{c}}-{{i}}<br>
+                        .bg-{{c}}-{{i}}-h<br>
+                        .text-{{c}}-{{i}}<br>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/colors/colors.component.spec.ts b/src/app/routes/elements/colors/colors.component.spec.ts
new file mode 100644
index 0000000..89e1c8a
--- /dev/null
+++ b/src/app/routes/elements/colors/colors.component.spec.ts
@@ -0,0 +1,17 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ColorsComponent } from './colors.component';
+
+describe('Component: Colors', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ColorsComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ColorsComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/colors/colors.component.ts b/src/app/routes/elements/colors/colors.component.ts
new file mode 100644
index 0000000..3f1cc26
--- /dev/null
+++ b/src/app/routes/elements/colors/colors.component.ts
@@ -0,0 +1,14 @@
+import { Component } from '@angular/core';
+import { ColorsService } from '@delon/theme';
+
+@Component({
+    selector: 'app-colors',
+    templateUrl: './colors.component.html'
+})
+export class ColorsComponent {
+    nums = Array(10).fill(1).map((v, i) => v + i);
+    colors = [];
+    constructor(public colorSrv: ColorsService) {
+        this.colors = colorSrv.names.slice(0, colorSrv.names.length - 1);
+    }
+}
diff --git a/src/app/routes/elements/dropdown/dropdown.component.html b/src/app/routes/elements/dropdown/dropdown.component.html
new file mode 100644
index 0000000..d8e6dd1
--- /dev/null
+++ b/src/app/routes/elements/dropdown/dropdown.component.html
@@ -0,0 +1,53 @@
+<div class="content__title">
+    <h1>
+        Dropdown Animations
+        <small>Extends the dropdown effects when open just adding an animation class</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Basic">
+            <nz-dropdown class="mr-sm">
+                <a class="ant-dropdown-link" nz-dropdown>
+                    Hover me <i class="anticon anticon-down"></i>
+                </a>
+                <ul nz-menu>
+                    <li nz-menu-item>1st menu item</li>
+                    <li nz-menu-item>2st menu item</li>
+                    <li nz-menu-divider></li>
+                    <li nz-menu-item [nzDisable]="true">3st menu item</li>
+                    <li nz-menu-divider></li>
+                    <li nz-submenu>
+                        <span title>sub menu</span>
+                        <ul>
+                            <li nz-menu-item>1rd menu item</li>
+                            <li nz-menu-item>2th menu item</li>
+                        </ul>
+                    </li>
+                </ul>
+            </nz-dropdown>
+            <nz-dropdown-button>
+                DropDown Button
+                <ul nz-menu>
+                    <li nz-menu-item>1st menu item</li>
+                    <li nz-menu-item>2st menu item</li>
+                </ul>
+            </nz-dropdown-button>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="6" *ngFor="let name of ants">
+        <div class="ant-box">
+            <nz-dropdown [nzTrigger]="'click'">
+                <a class="ant-dropdown-link" nz-dropdown>
+                    {{name}} <i class="anticon anticon-down"></i>
+                </a>
+                <ul nz-menu class="animated {{name}}">
+                    <li nz-menu-item>1st menu item</li>
+                    <li nz-menu-item>2st menu item</li>
+                </ul>
+            </nz-dropdown>
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/elements/dropdown/dropdown.component.spec.ts b/src/app/routes/elements/dropdown/dropdown.component.spec.ts
new file mode 100644
index 0000000..9788ee3
--- /dev/null
+++ b/src/app/routes/elements/dropdown/dropdown.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { DropdownComponent } from './dropdown.component';
+
+describe('Component: Dropdown', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ DropdownComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(DropdownComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/dropdown/dropdown.component.ts b/src/app/routes/elements/dropdown/dropdown.component.ts
new file mode 100644
index 0000000..22563fb
--- /dev/null
+++ b/src/app/routes/elements/dropdown/dropdown.component.ts
@@ -0,0 +1,63 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-dropdown',
+    templateUrl: './dropdown.component.html',
+    styles: [`
+        .ant-box {
+            margin-bottom: 16px;
+            padding: 24px;
+            border: 1px dashed #ddd;
+            background: #fafafa;
+            color: #444;
+        }
+    `]
+})
+export class DropdownComponent {
+    ants = [
+        'bounce',
+        'flash',
+        'pulse',
+        'rubberBand',
+        'shake',
+        'swing',
+        'tada',
+        'wobble',
+        'jello',
+        'bounceIn',
+        'bounceInDown',
+        'bounceInLeft',
+        'bounceInRight',
+        'bounceInUp',
+        'fadeIn',
+        'fadeInDown',
+        'fadeInDownBig',
+        'fadeInLeft',
+        'fadeInLeftBig',
+        'fadeInRight',
+        'fadeInRightBig',
+        'fadeInUp',
+        'fadeInUpBig',
+        'flip',
+        'flipInX',
+        'flipInY',
+        'lightSpeedIn',
+        'rotateIn',
+        'rotateInDownLeft',
+        'rotateInDownRight',
+        'rotateInUpLeft',
+        'rotateInUpRight',
+        'slideInUp',
+        'slideInDown',
+        'slideInLeft',
+        'slideInRight',
+        'zoomIn',
+        'zoomInDown',
+        'zoomInLeft',
+        'zoomInRight',
+        'zoomInUp',
+        'hinge',
+        'jackInTheBox',
+        'rollIn'
+    ];
+}
diff --git a/src/app/routes/elements/elements.module.ts b/src/app/routes/elements/elements.module.ts
new file mode 100644
index 0000000..27392f9
--- /dev/null
+++ b/src/app/routes/elements/elements.module.ts
@@ -0,0 +1,83 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+import { NzTreeModule } from 'ng-tree-antd';
+import { DndModule } from 'ng2-dnd';
+
+import { ButtonsComponent } from './buttons/buttons.component';
+import { NotificationComponent } from './notification/notification.component';
+import { ModalComponent } from './modal/modal.component';
+import { ModelCustomComponent } from './modal/custom.component';
+import { SpinComponent } from './spin/spin.component';
+import { DropdownComponent } from './dropdown/dropdown.component';
+import { GridComponent } from './grid/grid.component';
+import { GridMasonryComponent } from './gridmasonry/gridmasonry.component';
+import { TypographyComponent } from './typography/typography.component';
+import { IconsFontComponent } from './iconsfont/iconsfont.component';
+import { ColorsComponent } from './colors/colors.component';
+import { TreeAntdComponent } from './tree-antd/tree-antd.component';
+import { DemoSortableComponent } from './sortable/sortable.component';
+import { SweetAlertComponent } from './sweetalert/sweetalert.component';
+
+const routes: Routes = [
+    { path: 'buttons', component: ButtonsComponent },
+    { path: 'notification', component: NotificationComponent },
+    { path: 'modal', component: ModalComponent },
+    { path: 'sweetalert', component: SweetAlertComponent },
+    { path: 'spin', component: SpinComponent },
+    { path: 'dropdown', component: DropdownComponent },
+    { path: 'tree-antd', component: TreeAntdComponent },
+    { path: 'sortable', component: DemoSortableComponent },
+    { path: 'grid', component: GridComponent },
+    { path: 'gridmasonry', component: GridMasonryComponent },
+    { path: 'typography', component: TypographyComponent },
+    { path: 'iconsfont', component: IconsFontComponent },
+    { path: 'colors', component: ColorsComponent }
+];
+
+import { TreeAntdBasicComponent } from './tree-antd/basic.component';
+import { TreeAntdAsyncComponent } from './tree-antd/async.component';
+import { TreeAntdDraggableComponent } from './tree-antd/draggable.component';
+import { TreeAntdSearchableComponent } from './tree-antd/searchable.component';
+import { TreeAntdLineComponent } from './tree-antd/line.component';
+
+const TreeAntdDemoComponentes = [
+    TreeAntdBasicComponent,
+    TreeAntdAsyncComponent,
+    TreeAntdDraggableComponent,
+    TreeAntdSearchableComponent,
+    TreeAntdLineComponent
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        NzTreeModule,
+        DndModule.forRoot(),
+        RouterModule.forChild(routes)
+    ],
+    declarations: [
+        ButtonsComponent,
+        NotificationComponent,
+        ModalComponent,
+        ModelCustomComponent,
+        SpinComponent,
+        DropdownComponent,
+        GridComponent,
+        GridMasonryComponent,
+        TypographyComponent,
+        IconsFontComponent,
+        ColorsComponent,
+        TreeAntdComponent,
+        ...TreeAntdDemoComponentes,
+        DemoSortableComponent,
+        SweetAlertComponent
+    ],
+    exports: [
+        RouterModule
+    ],
+    entryComponents: [
+        ModelCustomComponent
+    ]
+})
+export class ElementsModule { }
diff --git a/src/app/routes/elements/grid/grid.component.html b/src/app/routes/elements/grid/grid.component.html
new file mode 100644
index 0000000..3ec3642
--- /dev/null
+++ b/src/app/routes/elements/grid/grid.component.html
@@ -0,0 +1,388 @@
+<div class="content__title">
+    <h1>
+        Grid
+        <small>24 Grids System</small>
+    </h1>
+</div>
+<div class="text-md bg-white p-lg">
+    <h2 class="mb-md">Design concept</h2>
+    <div class="grid-demo">
+        <div class="ant-row demo-row">
+            <div class="ant-col-24 demo-col demo-col-1">
+                100%
+            </div>
+        </div>
+        <div class="ant-row demo-row">
+            <div class="ant-col-6 demo-col demo-col-2">
+                25%
+            </div>
+            <div class="ant-col-6 demo-col demo-col-3">
+                25%
+            </div>
+            <div class="ant-col-6 demo-col demo-col-2">
+                25%
+            </div>
+            <div class="ant-col-6 demo-col demo-col-3">
+                25%
+            </div>
+        </div>
+        <div class="ant-row demo-row">
+            <div class="ant-col-8 demo-col demo-col-4">
+                33.33%
+            </div>
+            <div class="ant-col-8 demo-col demo-col-5">
+                33.33%
+            </div>
+            <div class="ant-col-8 demo-col demo-col-4">
+                33.33%
+            </div>
+        </div>
+        <div class="ant-row demo-row">
+            <div class="ant-col-12 demo-col demo-col-1">
+                50%
+            </div>
+            <div class="ant-col-12 demo-col demo-col-3">
+                50%
+            </div>
+        </div>
+        <div class="ant-row demo-row">
+            <div class="ant-col-16 demo-col demo-col-4">
+                66.66%
+            </div>
+            <div class="ant-col-8 demo-col demo-col-5">
+                33.33%
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">In most business situations,Ant Design need solve a lot of information storage problems within the design area,so based
+        on 12 Grids System,we divided the design area into 24 aliquots.</p>
+    <p class="mt-md">We name the divided area as 'box'.We suggest that four boxes horizontal arrangement at most, one at least.Box on the
+        proportion of the entire screen as above picture.To ensure that the level of visual comfort,we custom typography
+        inside of the box based on the box unit.</p>
+    <h2 class="mt-md">Outline</h2>
+    <p class="mt-md">In the grid system, we define the frame outside the information area based on row and column, to ensure that every area
+        can steady arrangement.</p>
+    <p class="mt-md">Following is a brief look at how it works:</p>
+    <ul class="list-styled mt-md">
+        <li>
+            To establish a set of <code>column</code> in the horizontal direction by <code>row</code> (abbreviated col)
+        </li>
+        <li>
+            Direct your content elements should be placed in the <code>col</code>, and only <code>col</code> as the <code>row</code>
+        </li>
+        <li>
+            The column grid system is a value of 1-24 to represent its range spans.For example, three columns of equal width can be created
+            by <code>.col-8</code>.
+        </li>
+        <li>
+            If a <code>row</code> sum of <code>col</code> more than 24, then the extra <code>col</code> as a whole will start
+            a new line arrangement.
+        </li>
+    </ul>
+    <h2 class="mt-md">Flex layout</h2>
+    <p class="mt-md">Our grid systems support Flex layout to allow the child elements within the parent horizontal alignment - Left, center,
+        right of abode, and other wide arrangement, decentralized arrangement. Between sub-elements and sub-elements, support
+        the top of the aligned vertically centered, bottom-aligned manner. At the same time, you can define the order of
+        elements by using 'order'.</p>
+    <p class="mt-md">Flex layout is based on a grid 24 to define each "box" in width, but not rigidly adhere to the grid layout.</p>
+    <h2 class="mt-md">Examples</h2>
+    <h3 class="mt-md">Base Grid</h3>
+    <div class="mt-md" id="components-grid-demo-basic">
+        <div class="code-box-demo">
+            <div nz-row>
+                <div nz-col [nzSpan]="12">
+                    col-12
+                </div>
+                <div nz-col [nzSpan]="12">
+                    col-12
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="8">
+                    col-8
+                </div>
+                <div nz-col [nzSpan]="8">
+                    col-8
+                </div>
+                <div nz-col [nzSpan]="8">
+                    col-8
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="6">
+                    col-6
+                </div>
+                <div nz-col [nzSpan]="6">
+                    col-6
+                </div>
+                <div nz-col [nzSpan]="6">
+                    col-6
+                </div>
+                <div nz-col [nzSpan]="6">
+                    col-6
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">From the stack to the horizontal arrangement.</p>
+    <p class="mt-md">
+        You can create a basic grid system by using a single set of <code>Row</code> and <code>Col</code> grid assembly,
+        all of the columns (Col) must be placed in <code>Row</code>.
+    </p>
+    <h3 class="mt-md">Grid Gutter</h3>
+    <div class="mt-md" id="components-grid-demo-gutter">
+        <div class="code-box-demo">
+            <div nz-row [nzGutter]="8">
+                <div nz-col class="gutter-row" [nzSpan]="6">
+                    <div class="gutter-box">col-6</div>
+                </div>
+                <div nz-col class="gutter-row" [nzSpan]="6">
+                    <div class="gutter-box">col-6</div>
+                </div>
+                <div nz-col class="gutter-row" [nzSpan]="6">
+                    <div class="gutter-box">col-6</div>
+                </div>
+                <div nz-col class="gutter-row" [nzSpan]="6">
+                    <div class="gutter-box">col-6</div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">
+        You can use the <code>gutter</code> property of <code>Row</code> as grid spacing, we recommend set it to <code>(16 + 8n) px</code>.
+        (
+        <code>n</code> stands for natural number.)</p>
+    <h3 class="mt-md">Column offset</h3>
+    <div class="mt-md" id="components-grid-demo-offset">
+        <div class="code-box-demo">
+            <div nz-row>
+                <div nz-col [nzSpan]="8">
+                    col-8
+                </div>
+                <div nz-col [nzSpan]="8" [nzOffset]="8">
+                    col-8
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="6" [nzOffset]="6">
+                    col-6 col-offset-6
+                </div>
+                <div nz-col [nzSpan]="6" [nzOffset]="6">
+                    col-6 col-offset-6
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="12" [nzOffset]="6">
+                    col-12 col-offset-6
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md"><code>Offset</code> can set the column to the right side. For example, using <code>[nzOffset]="'4'"</code> can set the
+        element shifted to the right four columns width.</p>
+    <h3 class="mt-md">Grid sort</h3>
+    <div class="mt-md" id="components-grid-demo-offset">
+        <div class="code-box-demo">
+            <div nz-row>
+                <div nz-col [nzSpan]="18" [nzPush]="6">
+                    col-18 col-push-6
+                </div>
+                <div nz-col [nzSpan]="6" [nzPull]="18">
+                    col-6 col-pull-18
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">
+        By using <code>push</code> and <code>pull</code> class you can easily change column order.
+    </p>
+    <h3 class="mt-md">Flex Layout</h3>
+    <div class="mt-md" id="components-grid-demo-flex">
+        <div class="code-box-demo">
+            <p>sub-element align left</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'start'">
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+            </div>
+            <p>sub-element align center</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'">
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+            </div>
+            <p>sub-element align right</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'end'">
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+            </div>
+            <p>sub-element monospaced arrangement</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'space-between'">
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+            </div>
+            <p>sub-element align full</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'space-around'">
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+                <div nz-col [nzSpan]="4">
+                    col-4
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">
+        Use <code>row-flex</code> define <code>flex</code> layout, its child elements depending on the value of the <code>start</code>,<code>center</code>,<code>end</code>,<code>space-between</code>,<code>space-around</code>,
+        which are defined in its parent node layout mode.
+    </p>
+    <h3 class="mt-md">Flex Alignment</h3>
+    <div class="mt-md" id="components-grid-demo-flex-align">
+        <div class="code-box-demo">
+            <p>Align Top</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'top'">
+                <div nz-col [nzSpan]="4">
+                    <p class="height-100">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-50">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-120">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-80">col-4</p>
+                </div>
+            </div>
+            <p>Align Center</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'space-around'" [nzAlign]="'middle'">
+                <div nz-col [nzSpan]="4">
+                    <p class="height-100">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-50">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-120">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-80">col-4</p>
+                </div>
+            </div>
+            <p>Align Bottom</p>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'space-between'" [nzAlign]="'bottom'">
+                <div nz-col [nzSpan]="4">
+                    <p class="height-100">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-50">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-120">col-4</p>
+                </div>
+                <div nz-col [nzSpan]="4">
+                    <p class="height-80">col-4</p>
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">Flex child elements vertically aligned.</p>
+    <h3 class="mt-md">Flex Order</h3>
+    <div class="mt-md" id="components-grid-demo-flex-order">
+        <div class="code-box-demo">
+            <div nz-row [nzType]="'flex'">
+                <div nz-col [nzSpan]="6" [nzOrder]="order" *ngFor="let order of orderList;index as i">
+                    {{i + 1}} col-order-{{order}}
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">To change the element sort by Flex layout order.</p>
+    <h3 class="mt-md">Responsive</h3>
+    <div class="mt-md" id="components-grid-demo-responsive">
+        <div class="code-box-demo">
+            <div nz-row>
+                <div nz-col [nzXs]="2" [nzSm]="4" [nzMd]="6" [nzLg]="8" [nzXl]="10">
+                    Col
+                </div>
+                <div nz-col [nzXs]="20" [nzSm]="16" [nzMd]="12" [nzLg]="8" [nzXl]="4">
+                    Col
+                </div>
+                <div nz-col [nzXs]="2" [nzSm]="4" [nzMd]="6" [nzLg]="8" [nzXl]="10">
+                    Col
+                </div>
+            </div>
+        </div>
+    </div>
+    <p class="mt-md">
+        Referring to the Bootstrap <a href="//getbootstrap.com/css/#grid-media-queries" target="_blank">responsive design</a>,
+        here preset five dimensions: <code>xs</code> <code>sm</code> <code>md</code> <code>lg</code> <code>xl</code>.
+    </p>
+    <h3 class="mt-md">Playground</h3>
+    <div class="mt-md" id="components-grid-demo-responsive">
+        <div class="code-box-demo">
+            <div style="margin-bottom:16px;">
+                <span style="margin-right: 6px;">Gutter (px): </span>
+                <div style="width: 50%">
+                    <nz-slider [nzMarks]="marksGutter" [nzStep]="null" [nzDefaultValue]="16" [nzMax]="48" [(ngModel)]="gutter" (nzOnAfterChange)="generateCode()"></nz-slider>
+                </div>
+                <span style="margin-right: 6px;">Column Count:</span>
+                <div style="width: 50%">
+                    <nz-slider [nzMarks]="marksCount" [nzStep]="null" [nzDefaultValue]="4" [nzMax]="12" [(ngModel)]="count" (nzOnAfterChange)="generateCode()"></nz-slider>
+                </div>
+            </div>
+            <div class="gutter-example">
+                <div nz-row [nzGutter]="gutter">
+                    <div nz-col class="gutter-row" [nzSpan]="24/count" *ngFor="let i of generateArray(count)">
+                        <div class="grid-config">Column</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <pre class="mt-md"><code>{{code}}</code></pre>
+</div>
diff --git a/src/app/routes/elements/grid/grid.component.less b/src/app/routes/elements/grid/grid.component.less
new file mode 100644
index 0000000..67bcaff
--- /dev/null
+++ b/src/app/routes/elements/grid/grid.component.less
@@ -0,0 +1,134 @@
+.grid-demo .demo-row,
+[id^="components-grid-demo-"] .demo-row,
+.grid-demo .code-box-demo .demo-row,
+[id^="components-grid-demo-"] .code-box-demo .demo-row {
+    background-image: -webkit-linear-gradient(left, #F5F5F5 4.16666667%, transparent 4.16666667%, transparent 8.33333333%, #F5F5F5 8.33333333%, #F5F5F5 12.5%, transparent 12.5%, transparent 16.66666667%, #F5F5F5 16.66666667%, #F5F5F5 20.83333333%, transparent 20.83333333%, transparent 25%, #F5F5F5 25%, #F5F5F5 29.16666667%, transparent 29.16666667%, transparent 33.33333333%, #F5F5F5 33.33333333%, #F5F5F5 37.5%, transparent 37.5%, transparent 41.66666667%, #F5F5F5 41.66666667%, #F5F5F5 45.83333333%, transparent 45.83333333%, transparent 50%, #F5F5F5 50%, #F5F5F5 54.16666667%, transparent 54.16666667%, transparent 58.33333333%, #F5F5F5 58.33333333%, #F5F5F5 62.5%, transparent 62.5%, transparent 66.66666667%, #F5F5F5 66.66666667%, #F5F5F5 70.83333333%, transparent 70.83333333%, transparent 75%, #F5F5F5 75%, #F5F5F5 79.16666667%, transparent 79.16666667%, transparent 83.33333333%, #F5F5F5 83.33333333%, #F5F5F5 87.5%, transparent 87.5%, transparent 91.66666667%, #F5F5F5 91.66666667%, #F5F5F5 95.83333333%, transparent 95.83333333%);
+    background-image: linear-gradient(90deg, #F5F5F5 4.16666667%, transparent 4.16666667%, transparent 8.33333333%, #F5F5F5 8.33333333%, #F5F5F5 12.5%, transparent 12.5%, transparent 16.66666667%, #F5F5F5 16.66666667%, #F5F5F5 20.83333333%, transparent 20.83333333%, transparent 25%, #F5F5F5 25%, #F5F5F5 29.16666667%, transparent 29.16666667%, transparent 33.33333333%, #F5F5F5 33.33333333%, #F5F5F5 37.5%, transparent 37.5%, transparent 41.66666667%, #F5F5F5 41.66666667%, #F5F5F5 45.83333333%, transparent 45.83333333%, transparent 50%, #F5F5F5 50%, #F5F5F5 54.16666667%, transparent 54.16666667%, transparent 58.33333333%, #F5F5F5 58.33333333%, #F5F5F5 62.5%, transparent 62.5%, transparent 66.66666667%, #F5F5F5 66.66666667%, #F5F5F5 70.83333333%, transparent 70.83333333%, transparent 75%, #F5F5F5 75%, #F5F5F5 79.16666667%, transparent 79.16666667%, transparent 83.33333333%, #F5F5F5 83.33333333%, #F5F5F5 87.5%, transparent 87.5%, transparent 91.66666667%, #F5F5F5 91.66666667%, #F5F5F5 95.83333333%, transparent 95.83333333%);
+    overflow: hidden;
+    margin-bottom: 8px;
+}
+
+.grid-demo .ant-row-flex,
+[id^="components-grid-demo-"] .ant-row-flex,
+.grid-demo .code-box-demo .ant-row-flex,
+[id^="components-grid-demo-"] .code-box-demo .ant-row-flex {
+    background: #F5F5F5;
+}
+
+.grid-demo .ant-row>div,
+[id^="components-grid-demo-"] .ant-row>div,
+.grid-demo .code-box-demo .ant-row>div,
+[id^="components-grid-demo-"] .code-box-demo .ant-row>div,
+.grid-demo .ant-row-flex>div,
+[id^="components-grid-demo-"] .ant-row-flex>div,
+.grid-demo .code-box-demo .ant-row-flex>div,
+[id^="components-grid-demo-"] .code-box-demo .ant-row-flex>div {
+    padding: 5px 0;
+    text-align: center;
+    border-radius: 0;
+    min-height: 30px;
+    margin-top: 8px;
+    margin-bottom: 8px;
+    color: #fff;
+}
+
+.grid-demo .code-box-demo .ant-row>div:not(.gutter-row),
+[id^="components-grid-demo-"] .code-box-demo .ant-row>div:not(.gutter-row),
+.grid-demo .code-box-demo .ant-row-flex>div:not(.gutter-row),
+[id^="components-grid-demo-"] .code-box-demo .ant-row-flex>div:not(.gutter-row) {
+    background: #00A0E9;
+    padding: 16px 0;
+}
+
+.grid-demo .code-box-demo .ant-row>div:not(.gutter-row):nth-child(2n+1),
+[id^="components-grid-demo-"] .code-box-demo .ant-row>div:not(.gutter-row):nth-child(2n+1),
+.grid-demo .code-box-demo .ant-row-flex>div:not(.gutter-row):nth-child(2n+1),
+[id^="components-grid-demo-"] .code-box-demo .ant-row-flex>div:not(.gutter-row):nth-child(2n+1) {
+    background: rgba(0, 160, 233, 0.7);
+}
+
+.grid-demo .ant-row .demo-col,
+[id^="components-grid-demo-"] .ant-row .demo-col,
+.grid-demo .code-box-demo .ant-row .demo-col,
+[id^="components-grid-demo-"] .code-box-demo .ant-row .demo-col {
+    text-align: center;
+    padding: 30px 0;
+    color: #fff;
+    font-size: 18px;
+    border: none;
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+.grid-demo .ant-row .demo-col-1,
+[id^="components-grid-demo-"] .ant-row .demo-col-1,
+.grid-demo .ant-row .demo-col-1,
+[id^="components-grid-demo-"] .ant-row .demo-col-1 {
+    background: rgba(0, 160, 233, 0.7);
+}
+
+.grid-demo .ant-row .demo-col-2,
+[id^="components-grid-demo-"] .ant-row .demo-col-2,
+.grid-demo .code-box-demo .ant-row .demo-col-2,
+[id^="components-grid-demo-"] .code-box-demo .ant-row .demo-col-2 {
+    background: rgba(0, 160, 233, 0.5);
+}
+
+.grid-demo .ant-row .demo-col-3,
+[id^="components-grid-demo-"] .ant-row .demo-col-3,
+.grid-demo .code-box-demo .ant-row .demo-col-3,
+[id^="components-grid-demo-"] .code-box-demo .ant-row .demo-col-3 {
+    background: rgba(255, 255, 255, 0.2);
+    color: #999;
+}
+
+.grid-demo .ant-row .demo-col-4,
+[id^="components-grid-demo-"] .ant-row .demo-col-4,
+.grid-demo .code-box-demo .ant-row .demo-col-4,
+[id^="components-grid-demo-"] .code-box-demo .ant-row .demo-col-4 {
+    background: rgba(0, 160, 233, 0.6);
+}
+
+.grid-demo .ant-row .demo-col-5,
+[id^="components-grid-demo-"] .ant-row .demo-col-5,
+.grid-demo .code-box-demo .ant-row .demo-col-5,
+[id^="components-grid-demo-"] .code-box-demo .ant-row .demo-col-5 {
+    background: rgba(255, 255, 255, 0.5);
+    color: #999;
+}
+
+.grid-demo .code-box-demo .height-100,
+[id^="components-grid-demo-"] .code-box-demo .height-100 {
+    height: 100px;
+    line-height: 100px;
+}
+
+.grid-demo .code-box-demo .height-50,
+[id^="components-grid-demo-"] .code-box-demo .height-50 {
+    height: 50px;
+    line-height: 50px;
+}
+
+.grid-demo .code-box-demo .height-120,
+[id^="components-grid-demo-"] .code-box-demo .height-120 {
+    height: 120px;
+    line-height: 120px;
+}
+
+.grid-demo .code-box-demo .height-80,
+[id^="components-grid-demo-"] .code-box-demo .height-80 {
+    height: 80px;
+    line-height: 80px;
+}
+
+.gutter-box {
+    background: #00A0E9;
+    padding: 5px 0;
+}
+
+.grid-config {
+    background: #00A0E9;
+    height: 120px;
+    line-height: 120px;
+    font-size: 13px;
+}
\ No newline at end of file
diff --git a/src/app/routes/elements/grid/grid.component.spec.ts b/src/app/routes/elements/grid/grid.component.spec.ts
new file mode 100644
index 0000000..894b4ae
--- /dev/null
+++ b/src/app/routes/elements/grid/grid.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { GridComponent } from './grid.component';
+
+describe('Component: Grid', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ GridComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(GridComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/grid/grid.component.ts b/src/app/routes/elements/grid/grid.component.ts
new file mode 100644
index 0000000..7fbf7d2
--- /dev/null
+++ b/src/app/routes/elements/grid/grid.component.ts
@@ -0,0 +1,52 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+    selector: 'app-grid',
+    templateUrl: './grid.component.html',
+    styleUrls: ['./grid.component.less']
+})
+export class GridComponent implements OnInit {
+    gutter = 16;
+    count = 4;
+    marksGutter = {
+        8: 8,
+        16: 16,
+        24: 24,
+        32: 32,
+        40: 40,
+        48: 48
+    };
+    marksCount = {
+        2: 2,
+        3: 3,
+        4: 4,
+        6: 6,
+        8: 8,
+        12: 12
+    };
+    code = '';
+    orderList = [1, 2, 3, 4];
+
+    generateArray(value) {
+        return new Array(value);
+    }
+
+    generateCode() {
+        const html = [];
+        html.push(`<div nz-row [nzGutter]="${this.gutter}">\r\n`);
+        for (const i of this.generateArray(this.count)) {
+            html.push(`    <div nz-col [nzSpan]="${24 / this.count}"></div>\r\n`);
+        }
+        html.push(`</div>`);
+        this.code = html.join('');
+    }
+
+    ngOnInit() {
+
+        this.generateCode();
+
+        setTimeout(_ => {
+            this.orderList = [...this.orderList.reverse()];
+        }, 10000);
+    }
+}
diff --git a/src/app/routes/elements/gridmasonry/gridmasonry.component.html b/src/app/routes/elements/gridmasonry/gridmasonry.component.html
new file mode 100644
index 0000000..99cc551
--- /dev/null
+++ b/src/app/routes/elements/gridmasonry/gridmasonry.component.html
@@ -0,0 +1,235 @@
+<div class="content__title">
+    <h1>
+        Grid Masonry
+        <small>Pure CSS and mobile first with a fallback to inline grid, Supported from IE10, <a href="//caniuse.com/#feat=multicolumn" target="_blank">browser compatibility</a></small>
+    </h1>
+</div>
+<div class="row-masonry row-masonry-xl-8 row-masonry-lg-5 row-masonry-md-4 row-masonry-sm-3 row-masonry-xs-2">
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Ipsum do ullamco laboris excepteur. Do incididunt commodo adipisicing officia sunt tempor. Deserunt exercitation
+                proident enim veniam laboris fugiat ipsum veniam dolore duis sit duis. In deserunt ut nulla ad eu.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Veniam non sunt quis ex consequat ea esse duis esse. Ut incididunt eiusmod occaecat esse aute adipisicing culpa.
+                Voluptate ullamco labore laboris et do in.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Esse elit et aute do aliqua ipsum cillum consectetur deserunt deserunt cupidatat aute aliqua aute. Aliquip ad
+                incididunt dolor cupidatat quis officia cillum sit ex. Irure ut sit Lorem sunt nulla excepteur ipsum ipsum
+                dolore cillum cupidatat ipsum. Do amet aliquip sunt consectetur nulla. Cupidatat ad consectetur veniam aliqua
+                non ullamco laboris eiusmod. In voluptate officia aliquip dolore sit qui consectetur fugiat aliqua duis occaecat.
+                Non mollit elit nisi ea mollit anim excepteur ut qui exercitation.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Ullamco incididunt do deserunt cillum veniam cillum amet ad. Deserunt laborum cupidatat mollit proident adipisicing
+                in culpa consequat adipisicing et non. Aliqua ea elit voluptate esse aliqua dolor ipsum. Ut officia officia
+                fugiat sint esse qui incididunt Lorem occaecat.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Ea non irure qui fugiat aliquip esse adipisicing. Cillum aliquip dolor non fugiat ad aliqua. In voluptate et
+                non irure elit. Tempor qui sunt incididunt amet tempor sint et voluptate sunt qui sit culpa proident ipsum.
+                Sunt duis pariatur officia ut magna pariatur fugiat dolor cillum laboris eu. Qui incididunt minim nostrud
+                exercitation aliquip.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Fugiat commodo ad consectetur reprehenderit. Officia fugiat ea proident exercitation occaecat mollit laboris
+                fugiat consequat deserunt anim ipsum magna ex. Esse do amet cillum aute ut ea.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Magna id fugiat laborum elit ullamco deserunt do laboris non qui. Duis et exercitation nulla labore cupidatat
+                nostrud pariatur reprehenderit in nostrud. Consequat consequat consectetur mollit adipisicing. Laborum amet
+                sit sint aliquip fugiat adipisicing enim reprehenderit. Voluptate nisi reprehenderit voluptate sit enim aute
+                deserunt cupidatat et dolore labore voluptate id dolore.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Reprehenderit non ullamco quis non excepteur irure excepteur anim ullamco labore. Sit occaecat consectetur laborum
+                consequat elit sint sit sunt. Duis aliquip magna ipsum consequat eiusmod officia.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Magna nostrud ex cupidatat id in non labore ad voluptate est irure tempor. Nostrud aliqua magna laborum incididunt
+                deserunt veniam nulla nulla labore cillum. Id laboris Lorem dolore minim reprehenderit eu proident aliqua
+                magna id aute aute. Aliqua est et nulla eu duis id laborum magna.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Sint pariatur eiusmod id sit est exercitation laboris mollit pariatur minim. Ex aliquip commodo nulla reprehenderit
+                et laboris consequat pariatur culpa culpa proident ullamco laboris. Ex aliquip deserunt labore aliquip ea
+                est sit quis amet tempor sunt amet. Id reprehenderit do elit sit consectetur. Aute amet sint tempor ipsum
+                sint laboris est do culpa tempor. Pariatur fugiat aute officia et laboris voluptate sit nisi in anim excepteur
+                amet eu.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Incididunt ut eu fugiat do deserunt voluptate id et est aliqua eu sint. Ad dolore excepteur ipsum nulla proident
+                dolore aute sunt. Aute enim do dolor laborum id eiusmod sit.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Amet elit et ad amet nulla minim deserunt mollit adipisicing. Laboris non ipsum ad laborum non magna velit tempor
+                cillum cillum. Proident dolore eiusmod ex elit cillum. Cupidatat duis pariatur ut id deserunt laboris. Culpa
+                excepteur est deserunt eiusmod do do ut est labore eiusmod. Eu eu veniam excepteur mollit anim est velit
+                nisi. Velit quis tempor laboris culpa.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Nostrud nulla nisi laboris officia anim nostrud nulla cupidatat veniam ea duis. Pariatur ea ullamco irure laborum.
+                Consectetur labore in occaecat ullamco est fugiat nisi sunt deserunt. Non sunt dolor elit culpa dolore adipisicing.
+                Fugiat mollit ex voluptate nulla deserunt dolore ea sunt commodo et qui laborum.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Quis pariatur ea nisi excepteur mollit nulla reprehenderit labore. Exercitation pariatur eu pariatur tempor deserunt
+                ad occaecat ad in pariatur id et dolore. Enim veniam aute magna fugiat eiusmod velit quis. Laborum sit consequat
+                dolore qui minim culpa aliqua pariatur cillum velit. Nostrud enim aliqua ut nisi consectetur pariatur fugiat
+                do esse fugiat enim et tempor ad. Eiusmod ut incididunt proident labore sint sit culpa excepteur id. Fugiat
+                mollit qui eu eu fugiat proident.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Tempor do officia magna do sunt. Nulla cillum anim excepteur adipisicing commodo culpa. Adipisicing pariatur
+                qui voluptate consectetur mollit quis sunt enim veniam ullamco. Duis nostrud anim aliqua adipisicing fugiat
+                aute excepteur deserunt enim occaecat pariatur ad. Qui aliquip aute labore minim ipsum in aute et. Aliqua
+                laboris magna aute incididunt esse ex. Eu ipsum occaecat aliquip enim aute.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Labore cillum id non anim eiusmod officia. Nostrud laboris sint aliquip cillum magna. Minim sit labore proident
+                culpa non nisi cillum non officia est. Proident elit sit adipisicing est cupidatat ex cupidatat labore aliqua
+                ad.
+            </p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Officia tempor ea adipisicing ad sit qui dolore consequat irure veniam. Est sit magna deserunt sint aute commodo
+                fugiat fugiat irure sint dolore commodo amet. Duis cillum dolor quis consectetur dolor et et culpa id elit.
+                Amet ut nulla sunt non in non duis sit fugiat consequat. Velit incididunt ullamco sunt deserunt nulla ad
+                adipisicing. In fugiat ullamco deserunt amet. Ex voluptate amet magna minim ut incididunt veniam.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Occaecat anim do cillum est dolore sint. Do ut proident exercitation est incididunt irure duis ea laborum minim
+                cillum est. Mollit irure non qui veniam labore eu elit veniam ea amet nisi esse labore. Elit ut nulla exercitation
+                fugiat cupidatat non cupidatat sint id minim.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Voluptate incididunt tempor nulla voluptate esse dolor Lorem veniam voluptate adipisicing laborum in aliqua.
+                Proident voluptate exercitation mollit consectetur qui commodo minim. Ea esse veniam velit minim reprehenderit
+                incididunt reprehenderit do laborum aliqua. In quis et excepteur cupidatat qui duis. Pariatur Lorem laborum
+                ut consectetur deserunt consectetur officia tempor commodo aliqua aliqua ipsum.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Ullamco officia esse ex reprehenderit reprehenderit cupidatat. Sunt excepteur sint consectetur ex aliqua excepteur.
+                Laborum id cupidatat ea reprehenderit sit eiusmod ad exercitation ullamco nostrud. Nulla tempor voluptate
+                magna amet culpa exercitation ad laborum in. Aliqua voluptate deserunt pariatur excepteur. Ullamco voluptate
+                est dolore velit aliquip tempor nostrud deserunt. Minim excepteur dolor nulla commodo incididunt ex ullamco
+                excepteur cillum veniam quis reprehenderit.</p>
+        </div>
+    </div>
+</div>
+<h3 class="my-md">Masonry with any kind of element</h3>
+<div class="row-masonry row-masonry-xl-8 row-masonry-lg-5 row-masonry-md-4 row-masonry-sm-3 row-masonry-xs-2">
+    <div class="col-masonry">
+        <img src="assets/img/bg1.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Proident est cillum magna qui pariatur. Deserunt ut voluptate sint aliquip anim nisi consequat. Elit laboris anim anim dolor incididunt. Nostrud qui labore qui cillum excepteur mollit excepteur consequat esse anim enim ad enim. Esse qui mollit et minim mollit laboris reprehenderit laborum fugiat do id. Mollit labore proident cupidatat aliqua dolore exercitation consectetur commodo sint mollit nostrud esse sunt. Nostrud fugiat duis sit excepteur excepteur mollit.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg2.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg3.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg4.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg5.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg6.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Dolore consequat elit est qui dolore dolore tempor amet magna adipisicing non in commodo. Veniam sint et proident duis eu nulla commodo sunt duis aliquip eiusmod. Occaecat incididunt deserunt consectetur non aliquip velit ullamco eu sit labore proident exercitation. Cillum deserunt voluptate eu eiusmod sint in esse. Velit anim non Lorem proident eu sit nisi Lorem aute do sit ea. Esse nostrud amet excepteur occaecat incididunt amet laborum aliqua qui mollit ullamco. Labore incididunt ullamco non ipsum Lorem duis commodo adipisicing in.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Amet est dolor id esse veniam duis eu ex velit. Id qui deserunt voluptate veniam. Voluptate ea ipsum in eiusmod enim do velit commodo nulla sint. Fugiat ipsum esse pariatur voluptate exercitation magna ut proident consectetur et. Sint qui elit exercitation anim duis nulla commodo aliqua excepteur pariatur.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg7.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg8.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <div class="box-placeholder">
+            <h2 class="text-grey text-md mb-sm">Masonry Item</h2>
+            <p>Culpa amet adipisicing consequat nisi dolore sunt amet labore officia aliquip elit tempor officia aliqua. Deserunt laborum enim ut laboris duis. Cillum non proident dolor ullamco cillum nostrud in sint aliqua cillum. Proident magna incididunt occaecat eiusmod cillum dolor tempor Lorem adipisicing nisi adipisicing mollit ex exercitation. Magna nostrud est sunt incididunt culpa. Duis nulla elit ut ea adipisicing duis esse ullamco.</p>
+        </div>
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg9.jpg" alt="" />
+    </div>
+    <div class="col-masonry">
+        <img src="assets/img/bg10.jpg" alt="" />
+    </div>
+</div>
diff --git a/src/app/routes/elements/gridmasonry/gridmasonry.component.spec.ts b/src/app/routes/elements/gridmasonry/gridmasonry.component.spec.ts
new file mode 100644
index 0000000..516c657
--- /dev/null
+++ b/src/app/routes/elements/gridmasonry/gridmasonry.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { GridMasonryComponent } from './gridmasonry.component';
+
+describe('Component: GridMasonry', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ GridMasonryComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(GridMasonryComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/gridmasonry/gridmasonry.component.ts b/src/app/routes/elements/gridmasonry/gridmasonry.component.ts
new file mode 100644
index 0000000..460208f
--- /dev/null
+++ b/src/app/routes/elements/gridmasonry/gridmasonry.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-gridmasonry',
+    templateUrl: './gridmasonry.component.html'
+})
+export class GridMasonryComponent {
+}
diff --git a/src/app/routes/elements/iconsfont/iconsfont.component.html b/src/app/routes/elements/iconsfont/iconsfont.component.html
new file mode 100644
index 0000000..b713b71
--- /dev/null
+++ b/src/app/routes/elements/iconsfont/iconsfont.component.html
@@ -0,0 +1,19 @@
+<div class="content__title">
+    <h1>
+        Font Icons
+        <small>Semantic vector graphics, includes antd icons & Simple Line & Font Awesome that can instantly be customized.</small>
+    </h1>
+</div>
+<div class="mb-sm" *ngFor="let group of data">
+    <h4 class="border-bottom-1 pb-sm mb-sm">{{group.title}}</h4>
+    <nz-alert *ngIf="group.tip" [nzType]="'warning'" [nzShowIcon]="'true'" class="mb-sm">
+        <span alert-body [innerHTML]="group.tip"></span>
+    </nz-alert>
+    <div class="icons" nz-row [nzGutter]="16">
+        <div class="item" nz-col [nzXs]="8" [nzMd]="4"
+            *ngFor="let item of group.list" (click)="copy(group, item)">
+            <em class="{{group.prefix}}{{item.k}}"></em> {{item.k}}
+            <em *ngIf="item.a" class="text-grey">(alias)</em>
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/elements/iconsfont/iconsfont.component.less b/src/app/routes/elements/iconsfont/iconsfont.component.less
new file mode 100644
index 0000000..171f505
--- /dev/null
+++ b/src/app/routes/elements/iconsfont/iconsfont.component.less
@@ -0,0 +1,20 @@
+.icons {
+    .item {
+        cursor: pointer;
+        &:hover {
+            em {
+                transform: scale(3);
+            }
+        }
+    }
+    em {
+        font-size: 14px;
+        width: 40px;
+        vertical-align: middle;
+        margin: 0;
+        display: inline-block;
+        text-align: center;
+        transition: all .2s;
+        line-height: 30px;
+    }
+}
diff --git a/src/app/routes/elements/iconsfont/iconsfont.component.spec.ts b/src/app/routes/elements/iconsfont/iconsfont.component.spec.ts
new file mode 100644
index 0000000..77fdd60
--- /dev/null
+++ b/src/app/routes/elements/iconsfont/iconsfont.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { IconsFontComponent } from './iconsfont.component';
+
+describe('Component: IconsFont', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [IconsFontComponent]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(IconsFontComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/iconsfont/iconsfont.component.ts b/src/app/routes/elements/iconsfont/iconsfont.component.ts
new file mode 100644
index 0000000..a0e19aa
--- /dev/null
+++ b/src/app/routes/elements/iconsfont/iconsfont.component.ts
@@ -0,0 +1,40 @@
+import { Component, ElementRef, Inject, OnInit } from '@angular/core';
+import { DOCUMENT } from '@angular/common';
+import { NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+    selector: 'app-iconsfont',
+    templateUrl: './iconsfont.component.html'
+})
+export class IconsFontComponent implements OnInit {
+    data = [];
+
+    constructor(
+        private msg: NzMessageService,
+        private http: _HttpClient,
+        @Inject(DOCUMENT) private dom: Document, private _el: ElementRef) { }
+
+    ngOnInit(): void {
+        this.http.get('./assets/iconsfont.json').subscribe(res => this.data = res);
+    }
+
+    copy(group: any, item: any) {
+        let copyTextArea = null as HTMLTextAreaElement;
+        try {
+            copyTextArea = this.dom.createElement('textarea');
+            copyTextArea.style.height = '0px';
+            copyTextArea.style.opacity = '0';
+            copyTextArea.style.width = '0px';
+            this.dom.body.appendChild(copyTextArea);
+            copyTextArea.value = group.tpl.replace(`{0}`, item.k);
+            copyTextArea.select();
+            this.dom.execCommand('copy');
+            this.msg.success(`Copied Success!`);
+        } finally {
+            if (copyTextArea && copyTextArea.parentNode) {
+                copyTextArea.parentNode.removeChild(copyTextArea);
+            }
+        }
+    }
+}
diff --git a/src/app/routes/elements/modal/custom.component.ts b/src/app/routes/elements/modal/custom.component.ts
new file mode 100644
index 0000000..6382afa
--- /dev/null
+++ b/src/app/routes/elements/modal/custom.component.ts
@@ -0,0 +1,56 @@
+import { Component, Input } from '@angular/core';
+import { NzModalSubject, NzModalService, NzMessageService } from 'ng-zorro-antd';
+import { ModalHelper } from '@delon/theme';
+
+@Component({
+    selector: 'app-model-custom',
+    template: `
+    <div class="modal-header">
+        <div class="modal-title">Custom component</div>
+    </div>
+    <h3>From Custom Componetn!</h3>
+    <p>Input Data: {{name}}</p>
+    <p>submodal: <a (click)="show()">show</a></p>
+    <p>
+        Popconfirm ������������������
+        <nz-popconfirm [nzTitle]="'���������������������������������'">
+            <a nz-popconfirm>������</a>
+        </nz-popconfirm>
+    </p>
+    <div class="modal-footer">
+        <button nz-button [nzType]="'default'" [nzSize]="'large'" (click)="cancel()">
+            Cancel
+        </button>
+        <button nz-button [nzType]="'primary'" [nzSize]="'large'" (click)="ok()">
+            OK
+        </button>
+    </div>
+    `
+})
+export class ModelCustomComponent {
+
+    @Input() name: string;
+
+    constructor(
+        private modalHelper: ModalHelper,
+        private model: NzModalService,
+        private msg: NzMessageService,
+        private subject: NzModalSubject) {}
+
+    show() {
+        this.modalHelper
+            .open(ModelCustomComponent, { name: 'From Submodal Data' }, 'sm', {
+                zIndex: 1001 // https://github.com/NG-ZORRO/ng-zorro-antd/issues/317
+            })
+            .subscribe(result => this.msg.info(`subscribe sub status: ${JSON.stringify(result)}`));
+    }
+
+    ok() {
+        this.subject.next(`new time: ${+new Date}`);
+        this.cancel();
+    }
+
+    cancel() {
+        this.subject.destroy();
+    }
+}
diff --git a/src/app/routes/elements/modal/modal.component.html b/src/app/routes/elements/modal/modal.component.html
new file mode 100644
index 0000000..8907030
--- /dev/null
+++ b/src/app/routes/elements/modal/modal.component.html
@@ -0,0 +1,35 @@
+<div class="content__title">
+    <h1>
+        Modal
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <ng-template #modelContent>
+            <p>Some contents...</p>
+            <p>Some contents...</p>
+            <p>Some contents...</p>
+            <p>Some contents...</p>
+        </ng-template>
+        <nz-card nzTitle="Basic">
+            <div class="pb-md">
+                <button nz-button (click)="basicModel(modelContent)" class="mr-sm">Open</button>
+                <button nz-button (click)="confirmModel(modelContent)">Confirm</button>
+            </div>
+            <button nz-button (click)="showModel('info')" class="mr-sm">Info</button>
+            <button nz-button (click)="showModel('success')" class="mr-sm">Success</button>
+            <button nz-button (click)="showModel('error')" class="mr-sm">Error</button>
+            <button nz-button (click)="showModel('warning')">Warning</button>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Custom Component">
+            <button nz-button (click)="customCompModel()" class="mr-sm">Default</button>
+            <button nz-button (click)="customCompModel('sm')" class="mr-sm">Small</button>
+            <button nz-button (click)="customCompModel('lg')">Large</button>
+            <div class="mt-sm">
+                <pre [innerHTML]="options | json"></pre>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/modal/modal.component.spec.ts b/src/app/routes/elements/modal/modal.component.spec.ts
new file mode 100644
index 0000000..ba7817c
--- /dev/null
+++ b/src/app/routes/elements/modal/modal.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ModalComponent } from './modal.component';
+
+describe('Component: Modal', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ModalComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ModalComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/modal/modal.component.ts b/src/app/routes/elements/modal/modal.component.ts
new file mode 100644
index 0000000..bf18b98
--- /dev/null
+++ b/src/app/routes/elements/modal/modal.component.ts
@@ -0,0 +1,58 @@
+import { Component } from '@angular/core';
+import { NzModalService, NzMessageService } from 'ng-zorro-antd';
+import { ModelCustomComponent } from './custom.component';
+
+@Component({
+    selector: 'app-modal',
+    templateUrl: './modal.component.html'
+})
+export class ModalComponent {
+    options = {};
+
+    constructor(
+        private modal: NzModalService,
+        private msg: NzMessageService) { }
+
+    basicModel(contentTpl) {
+        this.modal.open({
+            title: 'Basic Modal',
+            content: contentTpl
+        });
+    }
+
+    confirmModel(contentTpl) {
+        this.modal.open({
+            title: 'Confirm Modal',
+            content: contentTpl,
+            okText: 'OK',
+            cancelText: 'Return',
+            onOk: () => {
+                this.msg.success('Click OK!');
+            },
+            onCancel: () => {
+                this.msg.error('Click Return!');
+            }
+        });
+    }
+
+    customCompModel(size: '' | 'lg' | 'sm' = '') {
+        this.options = {
+            wrapClassName: size ? 'modal-' + size : '',
+            content: ModelCustomComponent,
+            footer: false,
+            componentParams: {
+                name: 'From Parent Data'
+            }
+        };
+        this.modal.open(this.options).subscribe(result => {
+            this.msg.info(`subscribe status: ${JSON.stringify(result)}`);
+        });
+    }
+
+    showModel(type: string) {
+        this.modal[type]({
+            title: `This is a ${type} message`,
+            content: `some messages...some messages...`
+        });
+    }
+}
diff --git a/src/app/routes/elements/notification/notification.component.html b/src/app/routes/elements/notification/notification.component.html
new file mode 100644
index 0000000..fbcce51
--- /dev/null
+++ b/src/app/routes/elements/notification/notification.component.html
@@ -0,0 +1,212 @@
+<div class="content__title">
+    <h1>
+        Notifications
+        <small>A complete set of notification posibilities</small>
+    </h1>
+    <nz-breadcrumb>
+        <nz-breadcrumb-item>
+            <a [routerLink]="['/dashboard']">Dashboard</a>
+        </nz-breadcrumb-item>
+        <nz-breadcrumb-item>
+            <a [routerLink]="['/elements/buttons']">Buttons</a>
+        </nz-breadcrumb-item>
+        <nz-breadcrumb-item>
+            Notifications
+        </nz-breadcrumb-item>
+    </nz-breadcrumb>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Message">
+            <div nz-form>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label nz-form-item-required>Type</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-radio-group [(ngModel)]="message.type">
+                            <label nz-radio-button [nzValue]="'info'">
+                                <span>Normal</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'success'">
+                                <span>Success</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'error'">
+                                <span>Error</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'warning'">
+                                <span>Warning</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'loading'">
+                                <span>Loading</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label for="messageContent" nz-form-item-required>Content</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-input [nzSize]="'large'" [(ngModel)]="message.content" [nzId]="'messageContent'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label for="messageDuration" nz-form-item-required>Duration</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-slider [(ngModel)]="message.duration" [nzMin]="0" [nzMax]="10" [nzMarks]="marks"></nz-slider>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-control nz-col [nzSpan]="18" [nzOffset]="6">
+                        <button nz-button (click)="createMessage()" [nzType]="'primary'">Show</button>
+                        <button nz-button (click)="clearMessage()">Clear</button>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Notification">
+            <div nz-form>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label nz-form-item-required>Type</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-radio-group [(ngModel)]="notify.type">
+                            <label nz-radio-button [nzValue]="'info'">
+                                <span>Normal</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'success'">
+                                <span>Success</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'error'">
+                                <span>Error</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'warning'">
+                                <span>Warning</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'blank'">
+                                <span>Blank</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label for="notifyTitle" nz-form-item-required>Title</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-input [nzSize]="'large'" [(ngModel)]="notify.title" [nzId]="'notifyTitle'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label for="notifyContent" nz-form-item-required>Content</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-input [nzSize]="'large'" [(ngModel)]="notify.content" [nzId]="'notifyContent'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6">
+                        <label for="notifyDuration" nz-form-item-required>Duration</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="18">
+                        <nz-slider [(ngModel)]="notify.duration" [nzMin]="0" [nzMax]="10" [nzMarks]="marks"></nz-slider>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-control nz-col [nzSpan]="18" [nzOffset]="6">
+                        <button nz-button (click)="createNotify()" [nzType]="'primary'">Show</button>
+                        <button nz-button (click)="clearNotify()">Clear</button>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Alert Styles">
+            <nz-alert [nzType]="'success'" [nzShowIcon]="'true'" class="mb-md">
+                <span alert-body>
+                    <pre>Success Text</pre>
+                </span>
+            </nz-alert>
+            <nz-alert [nzType]="'info'" [nzCloseable]="'true'" class="mb-md">
+                <span alert-body>
+                    <pre>Info Text</pre>
+                </span>
+            </nz-alert>
+            <nz-alert [nzType]="'warning'" [nzCloseText]="'Close Now'" class="mb-md">
+                <span alert-body>
+                    <pre>Warning Text</pre>
+                </span>
+            </nz-alert>
+            <nz-alert [nzType]="'error'" [nzMessage]="'Error'" [nzCloseable]="'true'"
+            [nzDescription]="'This is an error message about copywriting.'" [nzShowIcon]="'true'"></nz-alert>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Progress Bar">
+            <h4 class="pb-sm">Basic</h4>
+            <nz-progress [ngModel]="30"></nz-progress>
+            <nz-progress [ngModel]="50" [nzStatus]="'active'"></nz-progress>
+            <nz-progress [ngModel]="percent" [nzStatus]="'exception'"></nz-progress>
+            <div class="width-sm">
+                <nz-progress [ngModel]="percent"></nz-progress>
+                <nz-progress [ngModel]="50" [nzShowInfo]="false"></nz-progress>
+            </div>
+            <h4 class="py-sm">Circular</h4>
+            <nz-progress [ngModel]="75" [nzType]="'circle'" [nzWidth]="80"></nz-progress>
+            <nz-progress [ngModel]="percent" [nzType]="'circle'" [nzWidth]="60" [nzStrokeWidth]="4" [nzStatus]="'exception'" class="mx-sm"></nz-progress>
+            <nz-progress [ngModel]="percent" [nzType]="'circle'" [nzWidth]="40" [nzStrokeWidth]="2"></nz-progress>
+            <nz-button-group class="ml-lg">
+                <button nz-button (click)="decline()" [nzType]="'ghost'"><i class="anticon anticon-minus"></i></button>
+                <button nz-button [nzType]="'ghost'" (click)="increase()"><i class="anticon anticon-plus"></i></button>
+            </nz-button-group>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Popconfirm">
+            <nz-popconfirm [nzTitle]="'Are you sure?'"
+                [nzOkText]="'Yes'" [nzCancelText]="'No'"
+                (nzOnConfirm)="popConfirm()" (nzOnCancel)="popCancel()">
+                <a nz-popconfirm>Delete</a>
+            </nz-popconfirm>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Tooltip">
+            <nz-tooltip [nzTitle]="'prompt text'">
+                <span nz-tooltip class="mr-sm">Tooltip will show when mouse enter.</span>
+            </nz-tooltip>
+            <nz-tooltip>
+                <button nz-button nz-tooltip>This Tooltip Have Icon</button>
+                <ng-template #nzTemplate>
+                    <i class="anticon anticon-file"></i> <span>������������Tooltip</span>
+                </ng-template>
+            </nz-tooltip>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Popover">
+            <nz-popover [nzTitle]="'Title'" [nzPlacement]="'left'">
+                <button nz-button nz-popover>Hover me</button>
+                <ng-template #nzTemplate>
+                    <p>Content</p>
+                    <p>Content</p>
+                </ng-template>
+            </nz-popover>
+            <nz-popover [nzTitle]="'Title'" [nzTrigger]="'click'">
+                <button nz-button nz-popover class="ml-sm">Click me</button>
+                <ng-template #nzTemplate>
+                    <p>Content</p>
+                    <p>Content</p>
+                </ng-template>
+            </nz-popover>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/notification/notification.component.spec.ts b/src/app/routes/elements/notification/notification.component.spec.ts
new file mode 100644
index 0000000..58be5d1
--- /dev/null
+++ b/src/app/routes/elements/notification/notification.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { NotificationComponent } from './notification.component';
+
+describe('Component: Notification', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ NotificationComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(NotificationComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/notification/notification.component.ts b/src/app/routes/elements/notification/notification.component.ts
new file mode 100644
index 0000000..7143057
--- /dev/null
+++ b/src/app/routes/elements/notification/notification.component.ts
@@ -0,0 +1,89 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService, NzNotificationService, NzModalService } from 'ng-zorro-antd';
+
+@Component({
+    selector: 'app-notification',
+    templateUrl: './notification.component.html'
+})
+export class NotificationComponent {
+    constructor(
+        private msg: NzMessageService,
+        private ntf: NzNotificationService
+    ) { }
+
+    marks = {
+        0: 'naver'
+    };
+
+    notify = {
+        type: 'info',
+        title: 'Notification Title',
+        content: `This is the content of the notification.
+        This is the content of the notification. This is the content of the notification.`,
+        duration: 5
+    };
+
+    percent = 0;
+
+    // =====Message=====
+
+    message = {
+        type: 'info',
+        content: 'This is a message!',
+        duration: 2
+    };
+
+    createMessage() {
+        this.msg.create(
+            this.message.type,
+            this.message.content,
+            {
+                nzDuration: this.message.duration * 1000
+            }
+        );
+    }
+
+    clearMessage() {
+        this.msg.remove();
+    }
+
+
+    createNotify() {
+        this.ntf.create(
+            this.notify.type,
+            this.notify.title,
+            this.notify.content,
+            {
+                nzDuration: this.notify.duration * 1000
+            }
+        );
+    }
+
+    clearNotify() {
+        this.ntf.remove();
+    }
+
+    // Popconfirm
+    popConfirm() {
+        this.msg.success('Next step.');
+    }
+
+    popCancel() {
+        this.msg.error('Click on No');
+    }
+
+    // Progress Bar
+    decline() {
+        this.percent = this.percent - 10;
+        if (this.percent < 0) {
+          this.percent = 0;
+        }
+    }
+
+    increase() {
+        this.percent = this.percent + 10;
+        if (this.percent > 100) {
+          this.percent = 100;
+        }
+    }
+}
diff --git a/src/app/routes/elements/sortable/sortable.component.html b/src/app/routes/elements/sortable/sortable.component.html
new file mode 100644
index 0000000..f9a31d0
--- /dev/null
+++ b/src/app/routes/elements/sortable/sortable.component.html
@@ -0,0 +1,55 @@
+<div class="content__title">
+    <h1>
+        Sortable ������
+        <small>use <a href="//github.com/akserg/ng2-dnd" target="_blank">ng2-dnd</a> library.</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="���������������������">
+            <ul class="list-group" dnd-sortable-container [sortableData]="hiBaby">
+                <li *ngFor="let item of hiBaby; let i = index"
+                    class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
+            </ul>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="���������">
+            <ol>
+                <li *ngFor="let item of hiBaby; let i = index">{{i + 1}}: {{item}}</li>
+            </ol>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="������" [nzBordered]="false" nzNoPadding class="ant-card__pink">
+            <div class="p-md" dnd-sortable-container [dropZones]="['zone']" [sortableData]="hiBabyLove">
+                <ul class="list-group">
+                    <li *ngFor="let item of hiBabyLove; let i = index"
+                        class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
+                </ul>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="���������" [nzBordered]="false" nzNoPadding class="ant-card__green">
+            <div class="p-md" dnd-sortable-container [dropZones]="['zone']" [sortableData]="frontMidnight">
+                <ul class="list-group">
+                    <li *ngFor="let item of frontMidnight; let i = index"
+                        class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
+                </ul>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="���������" [nzBordered]="false" nzNoPadding class="ant-card__warning">
+            <div class="p-md" dnd-sortable-container [dropZones]="['zone']" [sortableData]="afterMidnight">
+                <ul class="list-group">
+                    <li *ngFor="let item of afterMidnight; let i = index"
+                        class="list-group-item" dnd-sortable [sortableIndex]="i">{{item}}</li>
+                </ul>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/sortable/sortable.component.spec.ts b/src/app/routes/elements/sortable/sortable.component.spec.ts
new file mode 100644
index 0000000..6f5b3cb
--- /dev/null
+++ b/src/app/routes/elements/sortable/sortable.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { DemoSortableComponent } from './sortable.component';
+import { DndModule } from 'ng2-dnd';
+
+describe('Component: Sortable', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ DemoSortableComponent ],
+        imports: [DndModule.forRoot()]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(DemoSortableComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/sortable/sortable.component.ts b/src/app/routes/elements/sortable/sortable.component.ts
new file mode 100644
index 0000000..dfe2ec9
--- /dev/null
+++ b/src/app/routes/elements/sortable/sortable.component.ts
@@ -0,0 +1,12 @@
+import { Component, ViewEncapsulation } from '@angular/core';
+@Component({
+    selector: 'app-sortable',
+    templateUrl: './sortable.component.html'
+})
+export class DemoSortableComponent {
+    hiBaby: string[] = ['���������', '������', '������', '������������', '������', '������', '������'];
+    hiBabyLove: string[] = ['������', '������', '������'];
+
+    frontMidnight: string[] = ['���������', '������'];
+    afterMidnight: string[] = ['������������', '������'];
+}
diff --git a/src/app/routes/elements/spin/spin.component.html b/src/app/routes/elements/spin/spin.component.html
new file mode 100644
index 0000000..3f0e709
--- /dev/null
+++ b/src/app/routes/elements/spin/spin.component.html
@@ -0,0 +1,53 @@
+<div class="content__title">
+    <h1>
+        Loading Spin
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Basic">
+            <div class="mb-sm">
+                <nz-spin [nzSize]="'small'" class="d-inline-block mr-sm"></nz-spin>
+                <nz-spin class="d-inline-block mr-sm"></nz-spin>
+                <nz-spin [nzSize]="'large'" class="d-inline-block mr-sm"></nz-spin>
+            </div>
+            <div class="mb-sm">
+                <nz-spin [nzTip]="'Loading...'" [nzSpinning]="loading">
+                    <nz-alert [nzType]="'info'" [nzMessage]="'Alert message title'" [nzDescription]="'Further details about the context of this alert.'">
+                    </nz-alert>
+                </nz-spin>
+            </div>
+            Loading state:
+            <nz-switch [(ngModel)]="loading"></nz-switch>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Table">
+            <ng-template #extra>
+                <button nz-button (click)="load()" [nzType]="'dashed'">
+                    <span>Load data</span>
+                </button>
+            </ng-template>
+            <nz-spin [nzTip]="'Loading...'" [nzSpinning]="dataLoading">
+                <nz-table #nzTable [nzDataSource]="data" [nzPageSize]="5">
+                    <thead nz-thead>
+                        <tr>
+                            <th nz-th><span>Name</span></th>
+                            <th nz-th><span>Age</span></th>
+                            <th nz-th><span>Address</span></th>
+                        </tr>
+                    </thead>
+                    <tbody nz-tbody>
+                        <tr nz-tbody-tr *ngFor="let data of nzTable.data">
+                            <td nz-td>
+                                <a>{{data.name}}</a>
+                            </td>
+                            <td nz-td>{{data.age}}</td>
+                            <td nz-td>{{data.address}}</td>
+                        </tr>
+                    </tbody>
+                </nz-table>
+            </nz-spin>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/spin/spin.component.spec.ts b/src/app/routes/elements/spin/spin.component.spec.ts
new file mode 100644
index 0000000..b4930f1
--- /dev/null
+++ b/src/app/routes/elements/spin/spin.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { SpinComponent } from './spin.component';
+
+describe('Component: Spin', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ SpinComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(SpinComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/spin/spin.component.ts b/src/app/routes/elements/spin/spin.component.ts
new file mode 100644
index 0000000..f038c22
--- /dev/null
+++ b/src/app/routes/elements/spin/spin.component.ts
@@ -0,0 +1,25 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-spin',
+    templateUrl: './spin.component.html'
+})
+export class SpinComponent {
+    loading = true;
+
+    data = [];
+    dataLoading = false;
+
+    load() {
+        this.dataLoading = true;
+        setTimeout(() => {
+            this.dataLoading = false;
+            this.data = Array(100).fill({}).map((item, index) => <any>{
+                key: index + 1,
+                age: Math.floor(Math.random() * (50 - 20 + 1) + 20),
+                name: `name ${index + 1}`,
+                address: `London No. ${index + 1} Lake Park`
+            });
+        }, 1000 * 2);
+    }
+}
diff --git a/src/app/routes/elements/sweetalert/sweetalert.component.html b/src/app/routes/elements/sweetalert/sweetalert.component.html
new file mode 100644
index 0000000..9be79a7
--- /dev/null
+++ b/src/app/routes/elements/sweetalert/sweetalert.component.html
@@ -0,0 +1,25 @@
+<div class="content__title">
+    <h1>
+        SweetAlert
+        <small>A beautiful replacement for JavaScript's "alert"</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="MODAL TYPES">
+            <button nz-button (click)="alertType(t)" *ngFor="let t of types" class="mr-sm">
+                <span>{{t}}</span>
+            </button>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="INPUT TYPES">
+            <button nz-button (click)="alertText()" class="mr-sm">
+                <span>text</span>
+            </button>
+            <button nz-button (click)="alertHtml()">
+                <span>html</span>
+            </button>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/sweetalert/sweetalert.component.spec.ts b/src/app/routes/elements/sweetalert/sweetalert.component.spec.ts
new file mode 100644
index 0000000..57bd3dd
--- /dev/null
+++ b/src/app/routes/elements/sweetalert/sweetalert.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { SweetAlertComponent } from './sweetalert.component';
+
+describe('Component: SweetAlert', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ SweetAlertComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(SweetAlertComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/sweetalert/sweetalert.component.ts b/src/app/routes/elements/sweetalert/sweetalert.component.ts
new file mode 100644
index 0000000..3b169de
--- /dev/null
+++ b/src/app/routes/elements/sweetalert/sweetalert.component.ts
@@ -0,0 +1,50 @@
+import { Component } from '@angular/core';
+import swal, { SweetAlertType } from 'sweetalert2';
+
+@Component({
+    selector: 'app-sweetalert',
+    templateUrl: './sweetalert.component.html'
+})
+export class SweetAlertComponent {
+    types = [ 'success', 'error', 'warning', 'info', 'question' ];
+
+    alertType(type: SweetAlertType) {
+        swal(`Try me! Example: ${type} modal`, '', type);
+    }
+
+    async alertText() {
+        const { value: name } = await swal({
+            title: 'What is your name?',
+            input: 'text',
+            inputPlaceholder: 'Enter your name or nickname',
+            showCancelButton: true,
+            inputValidator: function (value) {
+                return !value && 'You need to write something!';
+            }
+        });
+
+        if (name) {
+            swal({type: 'success', title: 'Hi, ' + name});
+        }
+    }
+
+    async alertHtml() {
+        const {value: formValues} = await swal({
+            title: 'Multiple inputs',
+            html:
+              '<input id="swal-input1" class="swal2-input">' +
+              '<input id="swal-input2" class="swal2-input">',
+            focusConfirm: false,
+            preConfirm: function () {
+              return [
+                (document.querySelector('#swal-input1') as HTMLInputElement).value,
+                (document.querySelector('#swal-input2') as HTMLInputElement).value
+              ];
+            }
+        });
+
+        if (formValues) {
+            swal(JSON.stringify(formValues));
+        }
+    }
+}
diff --git a/src/app/routes/elements/tree-antd/async.component.ts b/src/app/routes/elements/tree-antd/async.component.ts
new file mode 100644
index 0000000..fd98cd7
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/async.component.ts
@@ -0,0 +1,48 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-tree-antd-demo-async',
+  template: `
+    <nz-card nzTitle="Async">
+        <nz-tree [nzNodes]="nodes"
+                [nzCheckable]="true"
+                [nzOptions]="options"
+                (nzEvent)="onEvent($event)"></nz-tree>
+    </nz-card>
+  `
+})
+export class TreeAntdAsyncComponent {
+  nodes = [
+    {
+      name: 'root1',
+      hasChildren: true
+    },
+    {
+      name: 'root2',
+      hasChildren: true
+    },
+    {
+      name: 'root3',
+      hasChildren: true
+    },
+    {
+      name: 'root4',
+      hasChildren: true
+    }
+  ];
+
+  options = {
+    getChildren: (node: any) => {
+      return new Promise((resolve, reject) => {
+        setTimeout(() => resolve([
+          { name: 'async data1' },
+          { name: 'async data2', hasChildren: true }
+        ]), 1000);
+      });
+    }
+  };
+
+  onEvent(ev: any) {
+    console.log('async', 'onEvent', ev);
+  }
+}
diff --git a/src/app/routes/elements/tree-antd/basic.component.ts b/src/app/routes/elements/tree-antd/basic.component.ts
new file mode 100644
index 0000000..2ab8c07
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/basic.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit } from '@angular/core';
+import { generateData } from './generate-data';
+
+@Component({
+  selector: 'app-tree-antd-demo-basic',
+  template: `
+    <nz-card nzTitle="Basic">
+        <nz-tree [nzNodes]="nodes"
+                [nzCheckable]="true"
+                (nzEvent)="onEvent($event)"></nz-tree>
+    </nz-card>
+  `
+})
+export class TreeAntdBasicComponent implements OnInit {
+  nodes = [];
+
+  ngOnInit() {
+    generateData(this.nodes, 3, 2, 1);
+  }
+
+  onEvent(ev: any) {
+    console.log('basic', 'onEvent', ev);
+  }
+}
diff --git a/src/app/routes/elements/tree-antd/draggable.component.ts b/src/app/routes/elements/tree-antd/draggable.component.ts
new file mode 100644
index 0000000..db23454
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/draggable.component.ts
@@ -0,0 +1,28 @@
+import { Component, OnInit } from '@angular/core';
+import { generateData } from './generate-data';
+
+@Component({
+  selector: 'app-tree-antd-demo-draggable',
+  template: `
+    <nz-card nzTitle="Draggable">
+        <nz-tree [nzNodes]="nodes"
+                [nzOptions]="options"
+                (nzEvent)="onEvent($event)"></nz-tree>
+    </nz-card>
+  `
+})
+export class TreeAntdDraggableComponent implements OnInit {
+  nodes = [];
+
+  options = {
+    allowDrag: true
+  };
+
+  ngOnInit() {
+    generateData(this.nodes, 3, 2, 1);
+  }
+
+  onEvent(ev: any) {
+    console.log('basic', 'onEvent', ev);
+  }
+}
diff --git a/src/app/routes/elements/tree-antd/generate-data.ts b/src/app/routes/elements/tree-antd/generate-data.ts
new file mode 100644
index 0000000..802271b
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/generate-data.ts
@@ -0,0 +1,21 @@
+export function generateData(nodes, _x, _y, _z, _preKey?: any, _tns?: any) {
+    const preKey = _preKey || '0';
+    const tns = _tns || nodes;
+
+    const children = [];
+    for (let i = 0; i < _x; i++) {
+      const key = `${preKey}-${i}`;
+      tns.push({ name: key, id: key, disableCheckbox: i === 1 });
+      if (i < _y) {
+        children.push(key);
+      }
+    }
+    if (_z < 0) {
+      return tns;
+    }
+    const level = _z - 1;
+    children.forEach((key, index) => {
+      tns[index].children = [];
+      return generateData(nodes, _x, _y, level, key, tns[index].children);
+    });
+  }
diff --git a/src/app/routes/elements/tree-antd/line.component.ts b/src/app/routes/elements/tree-antd/line.component.ts
new file mode 100644
index 0000000..2419a88
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/line.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit } from '@angular/core';
+import { generateData } from './generate-data';
+
+@Component({
+  selector: 'app-tree-antd-demo-line',
+  template: `
+    <nz-card nzTitle="Line">
+        <nz-tree [nzNodes]="nodes"
+                [nzShowLine]="true"
+                (nzEvent)="onEvent($event)"></nz-tree>
+    </nz-card>
+  `
+})
+export class TreeAntdLineComponent implements OnInit {
+  nodes = [];
+
+  ngOnInit() {
+    generateData(this.nodes, 3, 2, 1);
+  }
+
+  onEvent(ev: any) {
+    console.log('line', 'onEvent', ev);
+  }
+}
diff --git a/src/app/routes/elements/tree-antd/searchable.component.ts b/src/app/routes/elements/tree-antd/searchable.component.ts
new file mode 100644
index 0000000..c607244
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/searchable.component.ts
@@ -0,0 +1,41 @@
+import { Component, ViewChild, OnInit } from '@angular/core';
+import { generateData } from './generate-data';
+import { NzTreeComponent } from 'ng-tree-antd';
+
+@Component({
+  selector: 'app-tree-antd-demo-searchable',
+  template: `
+    <nz-card nzTitle="Searchable">
+        <nz-input [nzType]="'search'" [nzPlaceHolder]="'input search text'" [(ngModel)]="q" (ngModelChange)="filterNodes()"></nz-input>
+        <nz-tree #tree [nzNodes]="nodes"
+                [nzOptions]="options"
+                [nzCheckable]="true"
+                (nzEvent)="onEvent($event)"></nz-tree>
+    </nz-card>
+  `
+})
+export class TreeAntdSearchableComponent implements OnInit {
+  q = '';
+
+  nodes = [];
+
+  options = {
+    allowDrag: false
+  };
+
+  @ViewChild(NzTreeComponent) tree: NzTreeComponent;
+  filterNodes() {
+    this.tree.treeModel.filterNodes(this.q);
+    if (!this.q) {
+      this.tree.treeModel.collapseAll();
+    }
+  }
+
+  ngOnInit() {
+    generateData(this.nodes, 3, 2, 1);
+  }
+
+  onEvent(ev: any) {
+    console.log('basic', 'onEvent', ev);
+  }
+}
diff --git a/src/app/routes/elements/tree-antd/tree-antd.component.html b/src/app/routes/elements/tree-antd/tree-antd.component.html
new file mode 100644
index 0000000..b8aa886
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/tree-antd.component.html
@@ -0,0 +1,13 @@
+<div class="content__title">
+    <h1>
+        Tree ������������
+        <small>use <a href="//github.com/cipchk/ng-tree-antd" target="_blank">ng-tree-antd</a> library.</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12"><app-tree-antd-demo-basic></app-tree-antd-demo-basic></div>
+    <div nz-col [nzMd]="12"><app-tree-antd-demo-async></app-tree-antd-demo-async></div>
+    <div nz-col [nzMd]="12"><app-tree-antd-demo-draggable></app-tree-antd-demo-draggable></div>
+    <div nz-col [nzMd]="12"><app-tree-antd-demo-searchable></app-tree-antd-demo-searchable></div>
+    <div nz-col [nzMd]="12"><app-tree-antd-demo-line></app-tree-antd-demo-line></div>
+</div>
diff --git a/src/app/routes/elements/tree-antd/tree-antd.component.spec.ts b/src/app/routes/elements/tree-antd/tree-antd.component.spec.ts
new file mode 100644
index 0000000..d8258ed
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/tree-antd.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { TreeAntdComponent } from './tree-antd.component';
+
+describe('Component: Tree Antd', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ TreeAntdComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(TreeAntdComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/tree-antd/tree-antd.component.ts b/src/app/routes/elements/tree-antd/tree-antd.component.ts
new file mode 100644
index 0000000..af12776
--- /dev/null
+++ b/src/app/routes/elements/tree-antd/tree-antd.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+@Component({
+    selector: 'app-tree-antd',
+    templateUrl: './tree-antd.component.html'
+})
+export class TreeAntdComponent {
+
+}
diff --git a/src/app/routes/elements/typography/typography.component.html b/src/app/routes/elements/typography/typography.component.html
new file mode 100644
index 0000000..b98b776
--- /dev/null
+++ b/src/app/routes/elements/typography/typography.component.html
@@ -0,0 +1,111 @@
+<div class="content__title">
+    <h1>
+        Typography
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Headings">
+            <h1 class="h1">
+                Heading 1
+                <small>Sub-heading</small>
+            </h1>
+            <h2 class="h2">
+                Heading 2
+                <small>Sub-heading</small>
+            </h2>
+            <h3 class="h3">
+                Heading 3
+                <small>Sub-heading</small>
+            </h3>
+            <h4 class="h4">
+                Heading 4
+                <small>Sub-heading</small>
+            </h4>
+            <h5 class="h5">
+                Heading 5
+                <small>Sub-heading</small>
+            </h5>
+            <h6 class="h6">
+                Heading 6
+                <small>Sub-heading</small>
+            </h6>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Paragraphs">
+            <p>
+                <small>This is an example of small, fine print text.</small>
+            </p>
+            <p class="mt-sm">
+                <strong>This is an example of strong, bold text.</strong>
+            </p>
+            <p class="mt-sm">
+                <em>This is an example of emphasized, italic text.</em>
+            </p>
+            <h4 class="mt-sm">Alignment & Sizing Helpers</h4>
+            <p class="mt-sm text-left text-sm">Left aligned text.</p>
+            <p class="mt-sm text-center text-md">Center aligned text.</p>
+            <p class="text-right text-lg">Right aligned text.</p>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Text Colors">
+            <p *ngFor="let color of colors" class="pt-sm text-{{color}}">This is an example of {{color}} text.</p>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Formatting">
+            <h4>text-nowrap</h4>
+            <p class="pt-sm text-nowrap">Ad eiusmod eu velit veniam laborum voluptate duis aliqua esse eiusmod ut labore deserunt. Minim cillum ullamco sit do dolor non adipisicing nulla dolore id minim sint. Commodo occaecat eu laboris ut do irure amet nulla dolor ex do anim quis dolor. Pariatur est deserunt esse anim commodo fugiat esse sit. Aliquip ipsum velit Lorem elit excepteur laboris in aute dolor.</p>
+            <h4 class="pt-sm">text-truncate</h4>
+            <p class="pt-sm text-truncate">Officia nulla velit minim mollit laborum et irure ullamco nisi dolore qui. Sint aute aliqua tempor commodo officia sunt non do id laborum mollit ex ea cupidatat. Amet ad non fugiat magna. Ut cupidatat labore pariatur esse reprehenderit esse sint in proident elit minim sunt enim sit. Enim sint deserunt exercitation duis. Aliquip cillum irure do incididunt do eu eiusmod excepteur culpa ex consectetur nulla duis sit. Ex officia excepteur officia ea ea cupidatat veniam officia officia est.</p>
+            <h4 class="pt-sm">Transformation</h4>
+            <p class="pt-sm text-lowercase">text-lowercase</p>
+            <p class="pt-sm text-uppercase">text-uppercase</p>
+            <p class="pt-sm text-capitalize">text-capitalize</p>
+            <p class="pt-sm text-deleted">text-deleted</p>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Border">
+            <div class="p-sm m-sm text-center width-sm d-inline-block border border-primary">border-primary</div>
+            <div class="p-sm m-sm text-center width-sm d-inline-block border-top-1 border-success rounded-circle">border-success</div>
+            <div class="p-sm m-sm text-center width-sm d-inline-block border-bottom-1 border-error">border-error</div>
+            <div class="p-sm m-sm text-center width-md d-inline-block border-right-1 border-warning">border-warning</div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Lists">
+            <h4>list styled</h4>
+            <ol class="mt-sm list-styled">
+                <li>List Item</li>
+                <li>List Item</li>
+                <li>List Item</li>
+            </ol>
+            <h4 class="mt-sm">Unstyled List</h4>
+            <ul class="mt-sm list-unstyled">
+                <li>List Item</li>
+                <li>List Item</li>
+                <li>List Item</li>
+            </ul>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Display">
+            <p class="display-1">.display-1</p>
+            <p class="display-2">.display-2</p>
+            <p class="display-3">.display-3</p>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="8">
+        <nz-card nzTitle="Code">
+            <p>This is an example of an inline code element within body copy. Wrap inline code within a<code>...</code>tag.</p>
+            <pre class="mt-sm"><code>This is an example of preformatted text.</code></pre>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/elements/typography/typography.component.spec.ts b/src/app/routes/elements/typography/typography.component.spec.ts
new file mode 100644
index 0000000..29323bf
--- /dev/null
+++ b/src/app/routes/elements/typography/typography.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { TypographyComponent } from './typography.component';
+
+describe('Component: Typography', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ TypographyComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(TypographyComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/elements/typography/typography.component.ts b/src/app/routes/elements/typography/typography.component.ts
new file mode 100644
index 0000000..7b7b770
--- /dev/null
+++ b/src/app/routes/elements/typography/typography.component.ts
@@ -0,0 +1,15 @@
+import { Component } from '@angular/core';
+import { ColorsService } from '@delon/theme';
+
+@Component({
+    selector: 'app-typography',
+    templateUrl: './typography.component.html'
+})
+export class TypographyComponent {
+
+    colors: string[] = [];
+
+    constructor(srv: ColorsService) {
+        this.colors = srv.brands;
+    }
+}
diff --git a/src/app/routes/extras/extras.module.ts b/src/app/routes/extras/extras.module.ts
new file mode 100644
index 0000000..0503806
--- /dev/null
+++ b/src/app/routes/extras/extras.module.ts
@@ -0,0 +1,31 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { HelpCenterComponent } from './helpcenter/helpcenter.component';
+import { ExtrasSettingsComponent } from './settings/settings.component';
+import { ExtrasPoiComponent } from './poi/poi.component';
+import { ExtrasPoiEditComponent } from './poi/edit/edit.component';
+
+const routes: Routes = [
+    { path: 'helpcenter', component: HelpCenterComponent },
+    { path: 'settings', component: ExtrasSettingsComponent },
+    { path: 'poi', component: ExtrasPoiComponent }
+];
+
+const COMPONENTS_NOROUNT = [ ExtrasPoiEditComponent ];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    declarations: [
+        HelpCenterComponent,
+        ExtrasSettingsComponent,
+        ExtrasPoiComponent,
+        ...COMPONENTS_NOROUNT
+    ],
+    entryComponents: COMPONENTS_NOROUNT
+})
+export class ExtrasModule { }
diff --git a/src/app/routes/extras/helpcenter/helpcenter.component.html b/src/app/routes/extras/helpcenter/helpcenter.component.html
new file mode 100644
index 0000000..d75f5c3
--- /dev/null
+++ b/src/app/routes/extras/helpcenter/helpcenter.component.html
@@ -0,0 +1,94 @@
+<div class="text-center pb-lg">
+    <h1 class="py-md mt-sm">������������</h1>
+    <p>������������������������������������</p>
+</div>
+<div class="text-center">
+    <nz-input-group [nzCompact]="true">
+        <input [(ngModel)]="q" placeholder="���������������������������������������������������������������" style="width: 50%;" nz-input [nzSize]="'large'">
+        <nz-select [(ngModel)]="type" [nzSize]="'large'" style="width:20%;">
+            <nz-option [nzLabel]="'������'" [nzValue]="''"></nz-option>
+            <nz-option [nzLabel]="'������������'" [nzValue]="'������������'"></nz-option>
+            <nz-option [nzLabel]="'���������CDN'" [nzValue]="'���������CDN'"></nz-option>
+            <nz-option [nzLabel]="'������������'" [nzValue]="'������������'"></nz-option>
+            <nz-option [nzLabel]="'���������'" [nzValue]="'���������'"></nz-option>
+        </nz-select>
+        <button nz-button [nzType]="'primary'" [nzSize]="'large'" (click)="search()">
+            <span>������</span>
+        </button>
+    </nz-input-group>
+    <p class="py-sm text-grey-dark">
+        ���������������
+        <a (click)="quick('���������������������')">���������������������</a>
+        <a (click)="quick('���������������')">���������������</a>
+        <a (click)="quick('������������')">������������</a>
+        <a (click)="quick('������������������')">������������������</a>
+        <a (click)="quick('������������������')">������������������</a>
+        <a (click)="quick('������������')">������������</a>
+    </p>
+</div>
+<div nz-row [nzGutter]="16" class="py-lg">
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('������������')" class="d-block text-center text-primary">
+                <i class="fa fa-5x fa-television mb-lg"></i>
+                <h2>������������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('���������CDN')" class="d-block text-center text-red">
+                <i class="fa fa-5x fa-coffee mb-lg"></i>
+                <h2>���������CDN</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('������������')" class="d-block text-center text-orange">
+                <i class="anticon anticon-user fa-5x mb-lg"></i>
+                <h2>������������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('���������')" class="d-block text-center text-purple">
+                <i class="fa fa-5x fa-database mb-lg"></i>
+                <h2>���������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('���������������')" class="d-block text-center text-cyan">
+                <i class="fa fa-5x fa-sitemap mb-lg"></i>
+                <h2>���������������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('������')" class="d-block text-center text-teal">
+                <i class="fa fa-5x fa-eraser mb-lg"></i>
+                <h2>������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('������������')" class="d-block text-center text-pink">
+                <i class="anticon fa-5x anticon-appstore-o mb-lg"></i>
+                <h2>������������</h2>
+            </a>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="12" [nzMd]="8">
+        <nz-card>
+            <a (click)="msg.info('���������������')" class="d-block text-center text-success">
+                <i class="anticon fa-5x anticon-tool mb-lg"></i>
+                <h2>���������������</h2>
+            </a>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/extras/helpcenter/helpcenter.component.spec.ts b/src/app/routes/extras/helpcenter/helpcenter.component.spec.ts
new file mode 100644
index 0000000..7996c28
--- /dev/null
+++ b/src/app/routes/extras/helpcenter/helpcenter.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { HelpCenterComponent } from './helpcenter.component';
+
+describe('Comoponent: HelpCenter', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ HelpCenterComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(HelpCenterComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/extras/helpcenter/helpcenter.component.ts b/src/app/routes/extras/helpcenter/helpcenter.component.ts
new file mode 100644
index 0000000..6534164
--- /dev/null
+++ b/src/app/routes/extras/helpcenter/helpcenter.component.ts
@@ -0,0 +1,22 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-helpcenter',
+    templateUrl: './helpcenter.component.html'
+})
+export class HelpCenterComponent {
+    type = '';
+    q = '';
+
+    quick(key: string) {
+        this.q = key;
+        this.search();
+    }
+
+    search() {
+        this.msg.success(`���������${this.q}`);
+    }
+
+    constructor(public msg: NzMessageService) {}
+}
diff --git a/src/app/routes/extras/poi/edit/edit.component.html b/src/app/routes/extras/poi/edit/edit.component.html
new file mode 100644
index 0000000..e15d959
--- /dev/null
+++ b/src/app/routes/extras/poi/edit/edit.component.html
@@ -0,0 +1,90 @@
+<div class="modal-header">
+    <div class="modal-title">{{i.id > 0 ? '������' : '������'}}-���������������HTML���������������������</div>
+</div>
+<form #f="ngForm" (ngSubmit)="save()" nz-form [nzType]="'horizontal'">
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>���������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            {{i.user_id}}
+            <a (click)="msgSrv.info('find')">������������</a>
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.name" name="name" maxlength="30" required />
+            <p nz-form-explain>���������������������������������������������������������������������������������������������������������</p>
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.branch_name" name="branch_name" maxlength="20" required />
+            <p nz-form-explain>������������������������������������������������������������������������������������������</p>
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>���������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.geo" name="geo" maxlength="50" required />
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.address" name="address" maxlength="50" required />
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.lat" name="lat" required />
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.lng" name="lng" required />
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.tel" name="tel" maxlength="30" required />
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <nz-select [(ngModel)]="i.categories" name="categories" required [nzAllowClear]="false">
+                <nz-option
+                    *ngFor="let i of cat"
+                    [nzLabel]="i"
+                    [nzValue]="i">
+                </nz-option>
+            </nz-select>
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>���������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.recommend" name="recommend" maxlength="200" placeholder="200���������" />
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.special" name="special" maxlength="50" placeholder="50���������" />
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.introduction" name="introduction" maxlength="300" placeholder="300���������" />
+        </div>
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <input nz-input [(ngModel)]="i.open_time" name="open_time" maxlength="30" placeholder="30���������" />
+        </div>
+    </div>
+    <div nz-form-item nz-row class="mb-sm">
+        <div nz-form-label nz-col [nzSpan]="4"><label>������������</label></div>
+        <div nz-form-control nz-col [nzSpan]="8">
+            <nz-input-number [(ngModel)]="i.avg_price" name="avg_price" [nzMin]="0" [nzStep]="10"></nz-input-number>
+        </div>
+    </div>
+    <div class="modal-footer">
+        <button nz-button type="button" (click)="close()">������</button>
+        <button nz-button [disabled]="!f.form.valid || !f.form.dirty" [nzLoading]="http.loading" [nzType]="'primary'">������</button>
+    </div>
+</form>
diff --git a/src/app/routes/extras/poi/edit/edit.component.ts b/src/app/routes/extras/poi/edit/edit.component.ts
new file mode 100644
index 0000000..e892b79
--- /dev/null
+++ b/src/app/routes/extras/poi/edit/edit.component.ts
@@ -0,0 +1,38 @@
+import { NzModalSubject, NzMessageService } from 'ng-zorro-antd';
+import { HttpClient } from '@angular/common/http';
+import { Component, OnInit } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+import { ModalHelper } from '@delon/theme';
+
+@Component({
+    selector: 'app-extras-poi-edit',
+    templateUrl: './edit.component.html'
+})
+export class ExtrasPoiEditComponent implements OnInit {
+    i: any;
+    cat: string[] = [ '������', '������,������', '������,������,���������' ];
+
+    constructor(
+        private modalHelper: ModalHelper,
+        private subject: NzModalSubject,
+        public msgSrv: NzMessageService,
+        public http: _HttpClient) { }
+
+    ngOnInit() {
+        if (this.i.id > 0) {
+            this.http.get('./assets/pois.json').subscribe(res => this.i = res.data[0]);
+        }
+    }
+
+    save() {
+        this.http.get('./assets/pois.json').subscribe(() => {
+            this.msgSrv.success('���������������������������������������������');
+            this.subject.next('true');
+            this.close();
+        });
+    }
+
+    close() {
+        this.subject.destroy();
+    }
+}
diff --git a/src/app/routes/extras/poi/poi.component.html b/src/app/routes/extras/poi/poi.component.html
new file mode 100644
index 0000000..359102d
--- /dev/null
+++ b/src/app/routes/extras/poi/poi.component.html
@@ -0,0 +1,67 @@
+<div class="content__title">
+    <h1>������<small>������ <code>.simple-table</code> ������������������������������������</small></h1>
+    <button nz-button (click)="edit({id:0})" [nzType]="'primary'">������</button>
+</div>
+<form nz-form [nzLayout]="'inline'" class="search-form">
+    <div nz-form-item>
+        <div nz-form-control>
+            <nz-select [(ngModel)]="s.s" name="s" [nzAllowClear]="false">
+                <nz-option nzValue="" nzLabel="������������"></nz-option>
+                <nz-option nzValue="1" nzLabel="������"></nz-option>
+                <nz-option nzValue="2" nzLabel="���������"></nz-option>
+                <nz-option nzValue="3" nzLabel="���������"></nz-option>
+                <nz-option nzValue="10" nzLabel="���������"></nz-option>
+                <nz-option nzValue="11" nzLabel="���������"></nz-option>
+            </nz-select>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control>
+            <nz-input [(ngModel)]="s.user_id" name="user_id" nzPlaceHolder="������������"></nz-input>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control>
+            <nz-input [(ngModel)]="s.q" name="q" nzPlaceHolder="���������������������"></nz-input>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control>
+            <button nz-button (click)="load(true)">������</button>
+        </div>
+    </div>
+</form>
+<nz-table #nzTable class="simple-table"
+    [nzAjaxData]="list"
+    [nzLoading]="http.loading"
+    [nzTotal]="total"
+    [(nzPageIndex)]="s.pi"
+    [(nzPageSize)]="s.ps"
+    (nzPageIndexChange)="load()"
+    [nzBordered]="true"
+    [nzSize]="'middle'">
+    <thead nz-thead>
+        <tr>
+            <th nz-th [nzWidth]="'100px'">������</th>
+            <th nz-th>������������</th>
+            <th nz-th>���������</th>
+            <th nz-th [nzWidth]="'100px'">������</th>
+            <th nz-th [nzWidth]="'180px'"></th>
+        </tr>
+    </thead>
+    <tbody nz-tbody>
+        <tr nz-tbody-tr *ngFor="let i of nzTable.data">
+            <td>{{i.id}}</td>
+            <td>{{i.name}}</td>
+            <td>{{i.branch_name}}</td>
+            <td>{{i.status_str}}</td>
+            <td>
+                <a (click)="edit(i)">������</a>
+                <span nz-table-divider></span>
+                <a (click)="photo(i)">������</a>
+                <span nz-table-divider></span>
+                <a (click)="sku(i)">������SKU</a>
+            </td>
+        </tr>
+    </tbody>
+</nz-table>
diff --git a/src/app/routes/extras/poi/poi.component.ts b/src/app/routes/extras/poi/poi.component.ts
new file mode 100644
index 0000000..3cf0c7f
--- /dev/null
+++ b/src/app/routes/extras/poi/poi.component.ts
@@ -0,0 +1,54 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { ModalHelper } from '@delon/theme';
+import { _HttpClient } from '@delon/theme';
+import { ExtrasPoiEditComponent } from './edit/edit.component';
+
+@Component({
+    selector: 'app-extras-poi',
+    templateUrl: './poi.component.html'
+})
+export class ExtrasPoiComponent implements OnInit {
+
+    list: any[] = [];
+    s: any = {
+        pi: 1,
+        ps: 10,
+        s: ''
+    };
+    total = 0;
+
+    constructor(
+        public http: _HttpClient,
+        public msgSrv: NzMessageService,
+        private modalHelper: ModalHelper) { }
+
+    ngOnInit() {
+        this.load();
+    }
+
+    load(reload: boolean = false) {
+        if (reload) {
+            this.s.pi = 1;
+        }
+        this.http.get('./assets/pois.json', this.s).subscribe((res: any) => {
+            this.list = res.data;
+            this.total = res.total;
+        });
+    }
+
+    edit(i) {
+        this.modalHelper.static(ExtrasPoiEditComponent, { i }).subscribe(() => {
+            this.load();
+            this.msgSrv.info('���������������������������������');
+        });
+    }
+
+    photo(i) {
+        this.msgSrv.success('click photo');
+    }
+
+    sku(i) {
+        this.msgSrv.success('click sku');
+    }
+}
diff --git a/src/app/routes/extras/settings/settings.component.html b/src/app/routes/extras/settings/settings.component.html
new file mode 100644
index 0000000..4687110
--- /dev/null
+++ b/src/app/routes/extras/settings/settings.component.html
@@ -0,0 +1,230 @@
+<div nz-row [nzGutter]="24" class="py-lg">
+    <div nz-col [nzSpan]="6">
+        <nz-card nzTitle="Personal settings" nzNoPadding>
+            <a (click)="active=1" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===1}">Profile</a>
+            <a (click)="active=2" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===2}">Account</a>
+            <a (click)="active=3" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===3}">Emails</a>
+            <a (click)="active=4" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===4}">Notifications</a>
+        </nz-card>
+        <nz-card nzTitle="Developer settings" nzNoPadding>
+                <a (click)="active=5" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===5}">OAuth applications</a>
+                <a (click)="active=6" class="d-block py-sm px-md" [ngClass]="{'bg-primary-light text-white':active===6}">Personal access tokens</a>
+        </nz-card>
+    </div>
+    <div nz-col [nzSpan]="18">
+        <nz-card nzTitle="Public profile" *ngIf="active===1">
+            <div nz-row [nzGutter]="64">
+                <div nz-col [nzSpan]="16">
+                    <form nz-form [formGroup]="profileForm" (ngSubmit)="profileSave($event, profileForm.value)" [nzLayout]="'vertical'">
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="name" nz-form-item-required>name</label>
+                            </div>
+                            <div nz-form-control nz-col [nzHasFeedback]="'true'" [nzValidateStatus]="name">
+                                <nz-input formControlName="name" [nzId]="'name'"></nz-input>
+                                <div *ngIf="name.invalid && (name.dirty || name.touched)">
+                                    <div nz-form-explain *ngIf="name.errors.required">required</div>
+                                    <div nz-form-explain *ngIf="name.errors.pattern">must match pattern [-_a-zA-Z0-9]</div>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="email">email</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-select formControlName="email">
+                                    <nz-option [nzLabel]="'Select a verified email to display'" [nzValue]="''"></nz-option>
+                                    <nz-option [nzLabel]="'cipchk@qq.com'" [nzValue]="'cipchk@qq.com'"></nz-option>
+                                </nz-select>
+                                <div nz-form-explain>You can manage verified email addresses in your <a (click)="active=3">email settings</a>.</div>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="bio">Bio</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input formControlName="bio" [nzId]="'bio'" [nzType]="'textarea'" [nzRows]="'4'" [nzPlaceHolder]="'Tell us a little bit about yourself'"></nz-input>
+                                <div nz-form-explain>You can <strong>@mention</strong> other users and organizations to link to them.</div>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="url">URL</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input formControlName="url" [nzId]="'url'"></nz-input>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="company">Company</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input formControlName="company" [nzId]="'company'"></nz-input>
+                                <div nz-form-explain>You can <strong>@mention</strong> your company's GitHub organization to link it.</div>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row class="border-top-1 mt-md pt-md">
+                            <div nz-form-label nz-col>
+                                <label for="location">Location</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input formControlName="location" [nzId]="'location'"></nz-input>
+                            </div>
+                        </div>
+                        <div nz-row>
+                            <button nz-button [nzType]="'primary'" [disabled]="profileForm.invalid">Update profile</button>
+                        </div>
+                    </form>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <h4>Profile picture</h4>
+                    <img src="./assets/img/avatar.jpg" style="width: 100%;">
+                    <button nz-button class="ant-btn__block">
+                        <span>Upload new picture</span>
+                    </button>
+                </div>
+            </div>
+        </nz-card>
+        <nz-card nzTitle="Change password" *ngIf="active===2">
+            <div nz-row [nzGutter]="64">
+                <div nz-col [nzSpan]="16">
+                    <form nz-form [nzLayout]="'vertical'">
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="old_password" nz-form-item-required>Old password</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input [(ngModel)]="pwd.old_password" name="old_password" [nzId]="'old_password'" [nzType]="'password'" required></nz-input>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="new_password" nz-form-item-required>New password</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input [(ngModel)]="pwd.new_password" name="new_password" [nzId]="'new_password'" [nzType]="'password'" required></nz-input>
+                            </div>
+                        </div>
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col>
+                                <label for="confirm_new_password" nz-form-item-required>Confirm new password</label>
+                            </div>
+                            <div nz-form-control nz-col>
+                                <nz-input [(ngModel)]="pwd.confirm_new_password" name="confirm_new_password" [nzId]="'confirm_new_password'" [nzType]="'password'" required></nz-input>
+                            </div>
+                        </div>
+                        <div nz-row>
+                            <button nz-button (click)="pwdSave()" [nzType]="'primary'">Update profile</button>
+                            <a class="pl-sm" [routerLink]="['/forget']">I forgot my password</a>
+                        </div>
+                    </form>
+                </div>
+            </div>
+            <h2 class="py-md mt-lg border-bottom-1">Change username</h2>
+            <p class="py-sm">Changing your username can have unintended side effects.</p>
+            <button nz-button (click)="msg.info('to change username page')" [nzSize]="'large'">
+                <span>Change username</span>
+            </button>
+        </nz-card>
+        <nz-card nzTitle="Email" *ngIf="active===3">
+            <div class="list-group">
+                <div nz-row class="list-group-item py-md" [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                    <div nz-col [nzSpan]="12">
+                        cipchk@qq.com
+                        <nz-tooltip [nzTitle]="'This email will be used for account-related notifications (e.g. account changes, password resets, billing receipts) as well as any web-based GitHub operations (e.g. edits and merges).'">
+                            <span nz-tooltip><nz-tag [nzColor]="'#28a745'">Primary</nz-tag></span>
+                        </nz-tooltip>
+                        <nz-tooltip [nzTitle]="'This email will be used as the \'from\' address for web-based GitHub operations.'">
+                            <span nz-tooltip><nz-tag [nzColor]="'#959da5'">Public</nz-tag></span>
+                        </nz-tooltip>
+                    </div>
+                    <div nz-col [nzSpan]="12" class="text-right">
+                        <i class="anticon anticon-delete text-lg"></i>
+                    </div>
+                </div>
+            </div>
+            <h4 class="pt-md mb-sm">Add email address</h4>
+            <nz-input [nzSize]="'large'" style="width: 200px"></nz-input>
+            <button nz-button (click)="msg.info('add')" [nzSize]="'large'">
+                <span>Add</span>
+            </button>
+            <h4 class="border-top-1 py-md mt-md">Primary email address</h4>
+            <p class="mb-md">cipchk@qq.com will be used for account-related notifications and for web-based GitHub operations (e.g. edits and merges).</p>
+            <nz-select [nzSize]="'large'" [(ngModel)]="primary_email">
+                <nz-option [nzLabel]="'cipchk@qq.com'" [nzValue]="'cipchk@qq.com'"></nz-option>
+            </nz-select>
+            <button nz-button (click)="msg.info('save')" [nzSize]="'large'">
+                <span>Save</span>
+            </button>
+        </nz-card>
+        <nz-card nzTitle="Notifications" *ngIf="active===4">
+            <p class="pb-md">Choose how you receive notifications. These notification settings apply to the repositories you���re watching.</p>
+            <div class="list-group">
+                <div class="list-group-item">
+                    <h4>Automatically watch repositories</h4>
+                    <p class="py-sm">When you���re given push access to a repository, automatically receive notifications for it.</p>
+                    <label nz-checkbox [ngModel]="true">
+                        <span>Automatically watch</span>
+                    </label>
+                </div>
+                <div class="list-group-item">
+                    <h4>Participating</h4>
+                    <p class="py-sm">Notifications for the conversations you are participating in, or if someone cites you with an @mention.</p>
+                    <label nz-checkbox [ngModel]="true">
+                        <span>Email</span>
+                    </label>
+                    <label nz-checkbox [ngModel]="true">
+                        <span>Web</span>
+                    </label>
+                </div>
+                <div class="list-group-item">
+                    <h4>Watching</h4>
+                    <p class="py-sm">Notifications for all repositories or conversations you���re watching.</p>
+                    <label nz-checkbox [ngModel]="true">
+                        <span>Email</span>
+                    </label>
+                    <label nz-checkbox [ngModel]="true">
+                        <span>Web</span>
+                    </label>
+                </div>
+            </div>
+        </nz-card>
+        <nz-card nzNoPadding *ngIf="active===5" [nzBordered]="false">
+            <div class="border rounded-md text-center p-lg bg-grey-lighter">
+                <h3>No OAuth applications</h3>
+                <p class="py-md">OAuth applications are used to access the GitHub API. Read the docs to find out more.</p>
+                <button nz-button (click)="msg.inof('Register a new application')" [nzType]="'primary'" [nzSize]="'large'">
+                    <span>Register a new application</span>
+                </button>
+            </div>
+        </nz-card>
+        <nz-card nzTitle="Personal access tokens" *ngIf="active===6">
+            <ng-template #extra>
+                <button nz-button (click)="msg.info('Generate new token')" [nzSize]="'small'">
+                    <span>Generate new token</span>
+                </button>
+                <button nz-button (click)="msg.info('Revoke all')" [nzSize]="'small'" [nzType]="'danger'">
+                    <span>Revoke all</span>
+                </button>
+            </ng-template>
+            <p>Tokens you have generated that can be used to access the GitHub API.</p>
+            <div class="list-group mt-sm">
+                <div nz-row class="list-group-item" [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                    <div nz-col [nzSpan]="12">
+                        <strong>octotree</strong> ��� repo
+                    </div>
+                    <div nz-col [nzSpan]="12" class="text-right">
+                        Last used within the last day
+                        <nz-button-group>
+                            <button nz-button>Edit</button>
+                            <button nz-button [nzType]="'danger'">Delete</button>
+                        </nz-button-group>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/extras/settings/settings.component.spec.ts b/src/app/routes/extras/settings/settings.component.spec.ts
new file mode 100644
index 0000000..a322fee
--- /dev/null
+++ b/src/app/routes/extras/settings/settings.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ExtrasSettingsComponent } from './settings.component';
+
+describe('Comoponent: ExtrasSetting', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ExtrasSettingsComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ExtrasSettingsComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/extras/settings/settings.component.ts b/src/app/routes/extras/settings/settings.component.ts
new file mode 100644
index 0000000..cddcbdf
--- /dev/null
+++ b/src/app/routes/extras/settings/settings.component.ts
@@ -0,0 +1,56 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+
+@Component({
+    selector: 'app-extras-settings',
+    templateUrl: './settings.component.html'
+})
+export class ExtrasSettingsComponent implements OnInit {
+    active = 1;
+    profileForm: FormGroup;
+    pwd = {
+        old_password: '',
+        new_password: '',
+        confirm_new_password: ''
+    };
+    // Email
+    primary_email = 'cipchk@qq.com';
+
+    constructor(fb: FormBuilder, public msg: NzMessageService) {
+        this.profileForm = fb.group({
+            name: [null, Validators.compose([Validators.required, Validators.pattern(`^[-_a-zA-Z0-9]{4,20}$`)])],
+            email: '',
+            bio: [null, Validators.maxLength(160)],
+            url: '',
+            company: '',
+            location: ''
+        });
+    }
+
+    get name() { return this.profileForm.get('name'); }
+
+    profileSave(event, value) {
+        console.log('profile value', value);
+    }
+
+    pwdSave() {
+        if (!this.pwd.old_password) {
+            return this.msg.error('invalid old password');
+        }
+        if (!this.pwd.new_password) {
+            return this.msg.error('invalid new password');
+        }
+        if (!this.pwd.confirm_new_password) {
+            return this.msg.error('invalid confirm new password');
+        }
+        console.log('pwd value', this.pwd);
+    }
+
+    ngOnInit() {
+        this.profileForm.patchValue({
+            name: 'cipchk',
+            email: 'cipchk@qq.com'
+        });
+    }
+}
diff --git a/src/app/routes/forms/cropper/cropper.component.html b/src/app/routes/forms/cropper/cropper.component.html
new file mode 100644
index 0000000..2a0df38
--- /dev/null
+++ b/src/app/routes/forms/cropper/cropper.component.html
@@ -0,0 +1,35 @@
+<div class="content__title">
+    <h1>Image Cropper</h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="6">
+        <nz-card>
+            <h3 class="text-md">Select an image file</h3>
+            <button nz-button class="ant-btn__block file-upload mt-sm">
+                <input id="file1" accept type="file" (change)="fileChange($event)" />
+                <i class="anticon anticon-upload"></i><span>Upload a image</span>
+            </button>
+            <h3 class="text-md my-md">Crop type</h3>
+            <nz-radio-group [(ngModel)]="cropperSettings.rounded">
+                <label nz-radio-button [nzValue]="false"><span>Square</span></label>
+                <label nz-radio-button [nzValue]="true"><span>Circle</span></label>
+            </nz-radio-group>
+            <div class="my-md" *ngIf="data1.image">
+                <h3 class="text-md">Cropped image</h3>
+                <img [class.rounded-circle]="cropperSettings.rounded"
+                    [src]="data1.image"
+                    [width]="cropperSettings.croppedWidth"
+                    [height]="cropperSettings.croppedHeight">
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="18">
+        <div nz-row>
+            <div nz-col [nzSpan]="24">
+                <nz-card>
+                    <img-cropper #cropper [image]="data1" [settings]="cropperSettings" (onCrop)="cropped($event)"></img-cropper>
+                </nz-card>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/forms/cropper/cropper.component.spec.ts b/src/app/routes/forms/cropper/cropper.component.spec.ts
new file mode 100644
index 0000000..2822c48
--- /dev/null
+++ b/src/app/routes/forms/cropper/cropper.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { CropperComponent } from './cropper.component';
+import { ImageCropperModule } from 'ng2-img-cropper';
+
+describe('Component: Cropper', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ CropperComponent ],
+        imports: [ImageCropperModule]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(CropperComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/forms/cropper/cropper.component.ts b/src/app/routes/forms/cropper/cropper.component.ts
new file mode 100644
index 0000000..05ca704
--- /dev/null
+++ b/src/app/routes/forms/cropper/cropper.component.ts
@@ -0,0 +1,57 @@
+import { Component, ViewChild } from '@angular/core';
+import { Bounds, CropperSettings, ImageCropperComponent } from 'ng2-img-cropper';
+
+@Component({
+    selector: 'app-cropper',
+    templateUrl: './cropper.component.html'
+})
+export class CropperComponent {
+    name: string;
+    data1: any;
+    cropperSettings: CropperSettings;
+
+    @ViewChild('cropper', undefined) cropper: ImageCropperComponent;
+
+    constructor() {
+        this.name = 'ng-alain';
+        this.cropperSettings = new CropperSettings();
+
+        this.cropperSettings.noFileInput = true;
+
+        this.cropperSettings.width = 200;
+        this.cropperSettings.height = 200;
+
+        this.cropperSettings.croppedWidth = 200;
+        this.cropperSettings.croppedHeight = 200;
+
+        this.cropperSettings.canvasWidth = 460;
+        this.cropperSettings.canvasHeight = 400;
+
+        this.cropperSettings.minWidth = 100;
+        this.cropperSettings.minHeight = 100;
+
+        this.cropperSettings.cropperDrawSettings.strokeColor = 'rgba(255,255,255,1)';
+        this.cropperSettings.cropperDrawSettings.strokeWidth = 2;
+
+        this.cropperSettings.rounded = false;
+
+        this.data1 = {};
+    }
+
+    cropped(bounds: Bounds) {
+        console.log(bounds);
+    }
+
+    fileChange($event) {
+        const image: any = new Image();
+        const file: File = $event.target.files[0];
+        const myReader: FileReader = new FileReader();
+        const that = this;
+        myReader.onloadend = (loadEvent: any) => {
+            image.src = loadEvent.target.result;
+            that.cropper.setImage(image);
+        };
+
+        myReader.readAsDataURL(file);
+    }
+}
diff --git a/src/app/routes/forms/extended/extended.component.html b/src/app/routes/forms/extended/extended.component.html
new file mode 100644
index 0000000..6c1957f
--- /dev/null
+++ b/src/app/routes/forms/extended/extended.component.html
@@ -0,0 +1,39 @@
+<div class="content__title">
+    <h1>
+        Form Extended
+        <small>Native angular elements to extend the form functions</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Form elements">
+            <form nz-form>
+                <div nz-form-item nz-row [nzGutter]="8">
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label [ngStyle]="{'color': color1}">Color pickers</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="4">
+                        <nz-input [(ngModel)]="color1" name="color1" [(colorPicker)]="color1"></nz-input>
+                    </div>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label [ngStyle]="{'color': color2}">Rgba Color</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="4">
+                        <nz-input [(ngModel)]="color2" name="color2"
+                            [(colorPicker)]="color2" [cpOutputFormat]="'rgba'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row [nzGutter]="8">
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Ueditor</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <div style="line-height: initial;">
+                            the <a href="https://cipchk.github.io/ngx-ueditor/" target="_blank">demo code</a> has removed.
+                        </div>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/forms/extended/extended.component.spec.ts b/src/app/routes/forms/extended/extended.component.spec.ts
new file mode 100644
index 0000000..3b6a8f4
--- /dev/null
+++ b/src/app/routes/forms/extended/extended.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ExtendedComponent } from './extended.component';
+import { ColorPickerModule } from 'ngx-color-picker';
+
+describe('Component: FormsExtended', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ExtendedComponent ],
+        imports: [ColorPickerModule]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ExtendedComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/forms/extended/extended.component.ts b/src/app/routes/forms/extended/extended.component.ts
new file mode 100644
index 0000000..b12994c
--- /dev/null
+++ b/src/app/routes/forms/extended/extended.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-extended',
+    templateUrl: './extended.component.html'
+})
+export class ExtendedComponent {
+    color1 = '#555555';
+    color2 = '';
+}
diff --git a/src/app/routes/forms/forms.module.ts b/src/app/routes/forms/forms.module.ts
new file mode 100644
index 0000000..750dfe8
--- /dev/null
+++ b/src/app/routes/forms/forms.module.ts
@@ -0,0 +1,45 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { FileUploadModule } from 'ng2-file-upload';
+import { ColorPickerModule, ColorPickerService } from 'ngx-color-picker';
+import { ImageCropperModule } from 'ng2-img-cropper';
+
+import { SharedModule } from '@shared/shared.module';
+
+import { StandardComponent } from './standard/standard.component';
+import { ExtendedComponent } from './extended/extended.component';
+import { UploadComponent } from './upload/upload.component';
+import { CropperComponent } from './cropper/cropper.component';
+import { ValidationComponent } from './validation/validation.component';
+
+const routes: Routes = [
+    { path: 'standard', component: StandardComponent },
+    { path: 'extended', component: ExtendedComponent },
+    { path: 'upload', component: UploadComponent },
+    { path: 'cropper', component: CropperComponent },
+    { path: 'validation', component: ValidationComponent }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes),
+        ColorPickerModule,
+        FileUploadModule,
+        ImageCropperModule
+    ],
+    declarations: [
+        StandardComponent,
+        ExtendedComponent,
+        UploadComponent,
+        CropperComponent,
+        ValidationComponent
+    ],
+    exports: [
+        RouterModule
+    ],
+    entryComponents: [
+
+    ]
+})
+export class FormsModule { }
diff --git a/src/app/routes/forms/standard/standard.component.html b/src/app/routes/forms/standard/standard.component.html
new file mode 100644
index 0000000..b16e7ba
--- /dev/null
+++ b/src/app/routes/forms/standard/standard.component.html
@@ -0,0 +1,497 @@
+<div class="content__title">
+    <h1>
+        Form Elements
+        <small>Native support</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Inline Form">
+            <form nz-form [nzLayout]="'inline'">
+                <div nz-form-item>
+                    <div nz-form-control>
+                        <nz-input [nzPlaceHolder]="'username'">
+                            <ng-template #prefix><i class="anticon anticon-user"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control>
+                        <nz-input [nzType]="'password'" [nzPlaceHolder]="'Password'">
+                            <ng-template #prefix><i class="anticon anticon-lock"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control>
+                        <label nz-checkbox>
+                            <span>Remember me</span>
+                        </label>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control>
+                        <button nz-button [nzType]="'primary'">Login</button>
+                        <button nz-button>Register</button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Horizontal Form">
+            <form nz-form>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6" [nzXs]="24">
+                        <label for="h-username" nz-form-item-required>Username</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="14" [nzXs]="24">
+                        <nz-input [nzId]="'h-username'" [nzPlaceHolder]="'username'">
+                            <ng-template #prefix><i class="anticon anticon-user"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="6" [nzXs]="24">
+                        <label for="h-password" nz-form-item-required>Password</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="14" [nzXs]="24">
+                        <nz-input [nzId]="'h-password'" [nzType]="'password'" [nzPlaceHolder]="'Password'">
+                            <ng-template #prefix><i class="anticon anticon-lock"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-control nz-col [nzSpan]="14" [nzXs]="24" [nzOffset]="6">
+                        <label nz-checkbox>
+                            <span>Remember me</span>
+                        </label>
+                    </div>
+                </div>
+                <div nz-form-item nz-row class="mb0">
+                    <div nz-form-control nz-col [nzSpan]="14" [nzXs]="24" [nzOffset]="6">
+                        <button nz-button [nzType]="'primary'">Login</button>
+                        <button nz-button>Register</button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Vertical Form">
+            <form nz-form>
+                <div nz-form-item nz-row>
+                    <div nz-form-label>
+                        <label for="v-username" nz-form-item-required>Username</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-input [nzId]="'v-username'" [nzPlaceHolder]="'username'">
+                            <ng-template #prefix><i class="anticon anticon-user"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label>
+                        <label for="v-password" nz-form-item-required>Password</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-input [nzId]="'v-password'" [nzType]="'password'" [nzPlaceHolder]="'Password'">
+                            <ng-template #prefix><i class="anticon anticon-lock"></i></ng-template>
+                        </nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-control>
+                        <label nz-checkbox>
+                            <span>Remember me</span>
+                        </label>
+                    </div>
+                </div>
+                <div nz-form-item nz-row class="mb0">
+                    <div nz-form-control>
+                        <button nz-button [nzType]="'primary'">Login</button>
+                        <button nz-button>Register</button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Search Form">
+            <form nz-form [formGroup]="validateForm">
+                <div nz-row [nzGutter]="32">
+                    <div nz-col [nzSpan]="8" *ngFor="let control of controlArray" [class.d-none]="!control.show">
+                        <div nz-form-item nz-row>
+                            <div nz-form-label nz-col [nzSpan]="5">
+                                <label [attr.for]="'field' + control.index">Field {{control.index}}</label>
+                            </div>
+                            <div nz-form-control nz-col [nzSpan]="19">
+                                <nz-input [nzSize]="'large'" [nzPlaceHolder]="'placeholder'" [formControlName]="'field'+control.index" [nzId]="'field'+control.index"></nz-input>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div nz-row>
+                    <div nz-col [nzSpan]="24" class="text-right">
+                        <button nz-button [nzType]="'primary'">Search</button>
+                        <button nz-button (click)="resetForm()">Clear</button>
+                        <a class="pl-sm" (click)="toggleCollapse()">
+                            Collapse
+                            <i class="anticon" [class.anticon-down]="isCollapse" [class.anticon-up]="!isCollapse"></i>
+                        </a>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Form elements">
+            <form nz-form>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>
+                            Plain Text
+                            <nz-tooltip [nzTitle]="'What do you want other to call you'">
+                                <i nz-tooltip class="anticon anticon-question-circle-o"></i>
+                            </nz-tooltip>
+                        </label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <span nz-form-text>China</span>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Normal Text</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label for="label-focus">Label focus</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input [nzId]="'label-focus'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label nz-form-item-required>Required</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>With Help</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input></nz-input>
+                        <div nz-form-explain>longgggggggggggggggggggggggggggggggggg</div>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Placeholder</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input [nzPlaceHolder]="'placeholder'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Disabled</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input [nzDisabled]="true"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Textarea</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input [nzType]="'textarea'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Checkboxes and radios</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <label nz-checkbox>
+                            <span>Checkbox</span>
+                        </label>
+                        <nz-radio-group>
+                            <label nz-radio [nzValue]="'A'">
+                                <span>Radio A</span>
+                            </label>
+                            <label nz-radio [nzValue]="'B'">
+                                <span>Radio B</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Horizontal Checkboxes and radios</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <div class="d-block">
+                            <label nz-checkbox>
+                                <span>Checkbox</span>
+                            </label>
+                        </div>
+                        <nz-radio-group>
+                            <label nz-radio [nzValue]="'A'" class="d-block">
+                                <span>Radio A</span>
+                            </label>
+                            <label nz-radio [nzValue]="'B'" class="d-block">
+                                <span>Radio B</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Select</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-select [(ngModel)]="selectValue" name="selectValue" nzAllowClear>
+                            <nz-option
+                                *ngFor="let option of options"
+                                [nzLabel]="option.label"
+                                [nzValue]="option"
+                                [nzDisabled]="option.disabled">
+                                </nz-option>
+                        </nz-select>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Select[multiple]</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-select [nzMode]="'multiple'" nzAllowClear>
+                            <nz-option
+                                *ngFor="let option of options"
+                                [nzLabel]="option.label"
+                                [nzValue]="option">
+                                </nz-option>
+                        </nz-select>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>cascader</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-cascader
+                            [(ngModel)]="cityValue" name="city"
+                            [nzExpandTrigger]="'hover'"
+                            [nzOptions]="cities"
+                            (ngModelChange)="changeCity($event)"
+                            (nzChange)="changeCity($event)"></nz-cascader>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>DatePicker</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-datepicker></nz-datepicker>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>TimePicker</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-timepicker></nz-timepicker>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>InputNumber</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input-number [nzMax]="10" [nzMin]="1"></nz-input-number>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Switch</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-switch [nzSize]="'large'" class="mr-sm"></nz-switch>
+                        <nz-switch class="mr-sm"></nz-switch>
+                        <nz-switch [nzSize]="'small'"></nz-switch>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Slider</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="8">
+                        <nz-slider [nzMarks]="marks"></nz-slider>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Rate</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-rate [(ngModel)]="rate" name="rate" nzAllowHalf></nz-rate>
+                        <span class="ant-rate-text">{{rate}} ���</span>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Tag</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-tag [nzColor]="'pink'">pink</nz-tag>
+                        <nz-tag [nzColor]="'red'">red</nz-tag>
+                        <nz-tag [nzColor]="'orange'">orange</nz-tag>
+                        <nz-tag [nzColor]="'green'">green</nz-tag>
+                        <nz-tag [nzColor]="'cyan'" [nzClosable]="true">cyan</nz-tag>
+                        <nz-tag [nzColor]="'blue'" [nzClosable]="true">blue</nz-tag>
+                        <nz-tag [nzColor]="'purple'" [nzClosable]="true">purple</nz-tag>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Categories Tag</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-checkable-tag *ngFor="let tag of hotTags"
+                            [nzChecked]="selectedTags.indexOf(tag) > -1"
+                            (nzChange)="handleChange($event, tag)">
+                            {{tag}}
+                        </nz-checkable-tag>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Control sizing</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-input [nzPlaceHolder]="'large size'" [nzSize]="'large'"></nz-input>
+                        <nz-input [nzPlaceHolder]="'default size'"></nz-input>
+                        <nz-input [nzPlaceHolder]="'small size'" [nzSize]="'small'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row [nzGutter]="8">
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Column sizing</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="4">
+                        <nz-input [nzPlaceHolder]="'nzSm=4'"></nz-input>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="6">
+                        <nz-input [nzPlaceHolder]="'nzSm=6'"></nz-input>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="10">
+                        <nz-input [nzPlaceHolder]="'nzSm=10'"></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>radio button style</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20">
+                        <nz-radio-group>
+                            <label nz-radio-button [nzValue]="'A'">
+                                <span>Hangzhou</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'B'">
+                                <span>Shanghai</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'C'">
+                                <span>Beijing</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'D'">
+                                <span>Chengdu</span>
+                            </label>
+                        </nz-radio-group>
+                        <div class="mt-sm">
+                            <nz-radio-group>
+                                <label nz-radio-button [nzValue]="'A'">
+                                    <span>Hangzhou</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'B'" [nzDisabled]="true">
+                                    <span>Shanghai</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'C'">
+                                    <span>Beijing</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'D'">
+                                    <span>Chengdu</span>
+                                </label>
+                            </nz-radio-group>
+                        </div>
+                        <div class="mt-sm">
+                            <nz-radio-group [nzSize]="'small'">
+                                <label nz-radio-button [nzValue]="'A'" [nzDisabled]="true">
+                                    <span>Hangzhou</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'B'" [nzDisabled]="true">
+                                    <span>Shanghai</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'C'" [nzDisabled]="true">
+                                    <span>Beijing</span>
+                                </label>
+                                <label nz-radio-button [nzValue]="'D'" [nzDisabled]="true">
+                                    <span>Chengdu</span>
+                                </label>
+                            </nz-radio-group>
+                        </div>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Success</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="'success'" nzHasFeedback>
+                        <nz-input></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Fail</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="'error'" nzHasFeedback>
+                        <nz-input></nz-input>
+                        <div nz-form-explain>Should be combination of numbers & alphabets</div>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Warning</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="'warning'" nzHasFeedback>
+                        <nz-input></nz-input>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col [nzSm]="4">
+                        <label>Validating</label>
+                    </div>
+                    <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="'validating'" nzHasFeedback>
+                        <nz-input></nz-input>
+                        <div nz-form-explain>I'm the content is being validating</div>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/forms/standard/standard.component.spec.ts b/src/app/routes/forms/standard/standard.component.spec.ts
new file mode 100644
index 0000000..5002f69
--- /dev/null
+++ b/src/app/routes/forms/standard/standard.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { StandardComponent } from './standard.component';
+
+describe('Component: Standard', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ StandardComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(StandardComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/forms/standard/standard.component.ts b/src/app/routes/forms/standard/standard.component.ts
new file mode 100644
index 0000000..ec94bd9
--- /dev/null
+++ b/src/app/routes/forms/standard/standard.component.ts
@@ -0,0 +1,99 @@
+import { Component, ViewChild, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
+
+@Component({
+    selector: 'app-standard',
+    templateUrl: './standard.component.html'
+})
+export class StandardComponent implements OnInit {
+    selectValue;
+
+    options = [
+        { value: 'jack', label: 'Jack' },
+        { value: 'lucy', label: 'Lucy' },
+        { value: 'disabled', label: 'Disabled', disabled: true }
+    ];
+
+    cityValue: any[] = null;
+    cities = [{
+        value: 'zhejiang',
+        label: 'Zhejiang',
+        children: [{
+            value: 'hangzhou',
+            label: 'Hangzhou',
+            children: [{
+                value: 'xihu',
+                label: 'West Lake',
+                isLeaf: true
+            }],
+        }],
+    }, {
+        value: 'jiangsu',
+        label: 'Jiangsu',
+        children: [{
+            value: 'nanjing',
+            label: 'Nanjing',
+            children: [{
+                value: 'zhonghuamen',
+                label: 'Zhong Hua Men',
+                isLeaf: true
+            }],
+        }],
+    }];
+
+    marks = {
+        0: 'A',
+        25: 'B',
+        50: 'C',
+        75: 'D',
+        100: 'E'
+    };
+
+    rate = 3;
+
+    hotTags: string[] = ['Movie', 'Books', 'Music', 'Sports'];
+
+    selectedTags: string[] = [];
+
+    validateForm: FormGroup;
+
+    controlArray = [];
+
+    isCollapse = true;
+
+    constructor(private fb: FormBuilder) {
+        this.selectValue = this.options[0];
+    }
+
+    ngOnInit() {
+        this.validateForm = this.fb.group({});
+        for (let i = 0; i < 10; i++) {
+            this.controlArray.push({ index: i, show: i < 6 });
+            this.validateForm.addControl(`field${i}`, new FormControl());
+        }
+    }
+
+    changeCity(value) {
+        console.log(value);
+    }
+
+    handleChange(checked: boolean, tag: string): void {
+        if (checked) {
+            this.selectedTags.push(tag);
+        } else {
+            this.selectedTags = this.selectedTags.filter(t => t !== tag);
+        }
+        console.log('You are interested in: ', this.selectedTags);
+    }
+
+    toggleCollapse() {
+      this.isCollapse = !this.isCollapse;
+      this.controlArray.forEach((c, index) => {
+        c.show = this.isCollapse ? (index < 6) : true;
+      });
+    }
+    
+    resetForm() {
+      this.validateForm.reset();
+    }
+}
diff --git a/src/app/routes/forms/upload/upload.component.html b/src/app/routes/forms/upload/upload.component.html
new file mode 100644
index 0000000..332ee7f
--- /dev/null
+++ b/src/app/routes/forms/upload/upload.component.html
@@ -0,0 +1,91 @@
+<div class="content__title">
+    <h1>File Upload</h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="6">
+        <nz-card nzTitle="Select files">
+            <div ng2FileDrop [ngClass]="{'bg-grey-lighter': hasBaseDropZoneOver}" (fileOver)="fileOverBase($event)" [uploader]="uploader"
+                class="box-placeholder">
+                Base drop zone
+            </div>
+            <div ng2FileDrop [ngClass]="{'bg-grey-lighter': hasAnotherDropZoneOver}" (fileOver)="fileOverAnother($event)" [uploader]="uploader"
+                class="box-placeholder">
+                Another drop zone
+            </div>
+            <h3 class="text-md">Upload options</h3>
+            <button nz-button class="ant-btn__block file-upload mt-sm">
+                <input id="file1" accept type="file" ng2FileSelect [uploader]="uploader" multiple />
+                <i class="anticon anticon-upload"></i><span>Multiple</span>
+            </button>
+            <button nz-button class="ant-btn__block file-upload mt-sm">
+                <input id="file1" accept type="file" ng2FileSelect [uploader]="uploader" />
+                <i class="anticon anticon-upload"></i><span>Single</span>
+            </button>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="18">
+        <div nz-row>
+            <div nz-col [nzSpan]="24">
+                <nz-card nzTitle="Upload queue">
+                    <nz-table #nzTable [nzDataSource]="files" [nzCustomNoResult]="true" [nzIsPagination]="false">
+                        <div noResult>Please choose file to upload.</div>
+                        <thead nz-thead>
+                            <tr>
+                                <th nz-th><span>Name</span></th>
+                                <th nz-th><span>Size</span></th>
+                                <th nz-th><span>Progress</span></th>
+                                <th nz-th><span>Status</span></th>
+                                <th nz-th><span>Actions</span></th>
+                            </tr>
+                        </thead>
+                        <tbody nz-tbody>
+                            <tr nz-tbody-tr *ngFor="let item of nzTable.data">
+                                <td nz-td><strong>{{ item?.file?.name }}</strong></td>
+                                <td nz-td *ngIf="uploader.options.isHTML5" nowrap>{{ item?.file?.size/1024/1024 | number:'.2' }} MB</td>
+                                <td nz-td *ngIf="uploader.options.isHTML5">
+                                    <nz-progress [ngModel]="item.progress" [nzStrokeWidth]="5"></nz-progress>
+                                </td>
+                                <td nz-td class="text-center">
+                                    <span *ngIf="item.isSuccess"><nz-tag [nzColor]="'green'"></nz-tag></span>
+                                    <span *ngIf="item.isCancel" class="mr-md"><nz-tag [nzColor]="'orange'"></nz-tag></span>
+                                    <span *ngIf="item.isError"><nz-tag [nzColor]="'red'"></nz-tag></span>
+                                </td>
+                                <td nz-td nowrap>
+                                    <nz-button-group>
+                                        <button nz-button (click)="item.upload()" [nzType]="'primary'" [disabled]="item.isReady || item.isUploading || item.isSuccess">
+                                            <i class="anticon anticon-upload"></i>
+                                        </button>
+                                        <button nz-button (click)="item.cancel()" [disabled]="!item.isUploading">
+                                            <i class="anticon anticon-close"></i>
+                                        </button>
+                                        <button nz-button (click)="item.remove()">
+                                            <i class="anticon anticon-delete"></i>
+                                        </button>
+                                    </nz-button-group>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </nz-table>
+                </nz-card>
+            </div>
+        </div>
+        <div nz-row>
+            <div nz-col [nzSpan]="24">
+                <nz-card>
+                    <nz-progress [ngModel]="uploader.progress" [nzStrokeWidth]="5"></nz-progress>
+                    <nz-button-group class="mt-md d-block">
+                        <button nz-button (click)="uploader.uploadAll()" [nzType]="'primary'" [nzLoading]="uploader.isUploading" [disabled]="!uploader.getNotUploadedItems().length">
+                            <i class="anticon anticon-upload"></i><span>Upload All</span>
+                        </button>
+                        <button nz-button (click)="uploader.cancelAll()" [disabled]="!uploader.isUploading">
+                            <i class="anticon anticon-close"></i><span>Cancel All</span>
+                        </button>
+                        <button nz-button (click)="uploader.clearQueue()" [disabled]="!uploader.queue.length">
+                            <i class="anticon anticon-delete"></i><span>Remove All</span>
+                        </button>
+                    </nz-button-group>
+                </nz-card>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/forms/upload/upload.component.spec.ts b/src/app/routes/forms/upload/upload.component.spec.ts
new file mode 100644
index 0000000..a1dd701
--- /dev/null
+++ b/src/app/routes/forms/upload/upload.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { UploadComponent } from './upload.component';
+import { FileUploadModule } from 'ng2-file-upload';
+
+describe('Component: Upload', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ UploadComponent ],
+        imports: [FileUploadModule]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(UploadComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/forms/upload/upload.component.ts b/src/app/routes/forms/upload/upload.component.ts
new file mode 100644
index 0000000..a195da7
--- /dev/null
+++ b/src/app/routes/forms/upload/upload.component.ts
@@ -0,0 +1,35 @@
+import { Component } from '@angular/core';
+import { FileUploader } from 'ng2-file-upload';
+
+const URL = 'https://test.com/';
+
+@Component({
+    selector: 'app-upload',
+    templateUrl: './upload.component.html'
+})
+export class UploadComponent {
+
+    uploader: FileUploader = new FileUploader({
+        url: URL,
+        isHTML5: true
+    });
+
+    hasBaseDropZoneOver = false;
+    hasAnotherDropZoneOver = false;
+    files: any[] = [];
+
+    fileOverBase(e: any): void {
+        this.hasBaseDropZoneOver = e;
+    }
+
+    fileOverAnother(e: any): void {
+        this.hasAnotherDropZoneOver = e;
+    }
+
+    constructor() {
+        this.uploader.onAfterAddingFile = (f) => {
+            this.files = this.uploader.queue;
+            return f;
+        };
+    }
+}
diff --git a/src/app/routes/forms/validation/validation.component.html b/src/app/routes/forms/validation/validation.component.html
new file mode 100644
index 0000000..ac1b448
--- /dev/null
+++ b/src/app/routes/forms/validation/validation.component.html
@@ -0,0 +1,168 @@
+<div class="content__title">
+    <h1>
+        Form Validation
+        <small>Native Angular input validation</small>
+    </h1>
+    <div class="text-right">
+        <button nz-button (click)="loadData()" [nzLoading]="loading">
+            <span>Load User Data</span>
+        </button>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card>
+            <form nz-form [formGroup]="form" (ngSubmit)="_submitForm()">
+                <fieldset>
+                    <legend>Built-in</legend>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="nickname" nz-form-item-required>
+                                <span>
+                                    Nickname
+                                    <nz-tooltip [nzTitle]="'What do you want other to call you'">
+                                        <i nz-tooltip class="anticon anticon-question-circle-o"></i>
+                                    </nz-tooltip>
+                                </span>
+                            </label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="nickname">
+                            <nz-input formControlName="nickname" nzPlaceHolder="minlength=6" [nzId]="'nickname'"></nz-input>
+                            <ng-container *ngIf="nickname.dirty || nickname.touched">
+                                <p nz-form-explain *ngIf="nickname.errors?.required">Please input your nickname!</p>
+                                <p nz-form-explain *ngIf="nickname.errors?.checked">Only input 'cipchk'</p>
+                                <p nz-form-explain *ngIf="nickname.errors?.minlength">This field requires a min length</p>
+                            </ng-container>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="email" nz-form-item-required>E-mail</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="email">
+                            <nz-input formControlName="email" [nzId]="'email'"></nz-input>
+                            <div nz-form-explain *ngIf="(email.dirty || email.touched) && email.errors?.email">The input is not valid E-mail!</div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="password" nz-form-item-required>Password</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="password">
+                            <nz-input formControlName="password" [nzType]="'password'" [nzId]="'password'"></nz-input>
+                            <div nz-form-explain *ngIf="(password.dirty || password.touched) && password.errors?.required">Please input your password!</div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="checkPassword" nz-form-item-required>Confirm Password</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="checkPassword">
+                            <nz-input formControlName="checkPassword" [nzType]="'password'" [nzId]="'checkPassword'"></nz-input>
+                            <ng-container *ngIf="checkPassword.dirty || checkPassword.touched">
+                                <p nz-form-explain *ngIf="checkPassword.errors?.required">Please confirm your password!</p>
+                                <p nz-form-explain *ngIf="checkPassword.errors?.checked">Two passwords that you enter is inconsistent!</p>
+                            </ng-container>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="phoneNumber" nz-form-item-required>Phone Number</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="phoneNumber">
+                            <nz-input-group [nzCompact]="true">
+                            <nz-select formControlName="phoneNumberPrefix" style="width: 25%;">
+                                <nz-option [nzLabel]="'+86'" [nzValue]="'+86'"></nz-option>
+                                <nz-option [nzLabel]="'+87'" [nzValue]="'+87'"></nz-option>
+                            </nz-select>
+                            <input formControlName="phoneNumber" id="'phoneNumber'" nz-input style="width: 75%;">
+                            </nz-input-group>
+                            <div nz-form-explain *ngIf="(phoneNumber.dirty || phoneNumber.touched) && phoneNumber.errors?.required">Please input your phone number!</div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="website" nz-form-item-required>Website</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="website">
+                            <nz-input formControlName="website" [nzId]="'website'"></nz-input>
+                            <div nz-form-explain *ngIf="(website.dirty || website.touched) && website.errors?.required">Please input website!</div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label nz-form-item-required>Status</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="status">
+                            <nz-radio-group formControlName="status">
+                                <label nz-radio [nzValue]="'normal'">
+                                    <span>Normal</span>
+                                </label>
+                                <label nz-radio [nzValue]="'lock'">
+                                    <span>Lock</span>
+                                </label>
+                                <label nz-radio [nzValue]="'deleted'">
+                                    <span>Deleted</span>
+                                </label>
+                            </nz-radio-group>
+                            <div nz-form-explain *ngIf="(status.dirty || status.touched) && status.errors?.required">Please choose status!</div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label nz-form-item-required>date</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20">
+                            <div nz-col [nzSpan]="4">
+                                <div nz-form-control [nzValidateStatus]="start">
+                                    <nz-datepicker formControlName="start"></nz-datepicker>
+                                    <div nz-form-explain *ngIf="(start.dirty || start.touched) && start.errors?.required">Select date</div>
+                                </div>
+                            </div>
+                            <div nz-col [nzSpan]="1"><p nz-form-split>-</p></div>
+                            <div nz-col [nzSpan]="4">
+                                <div nz-form-control [nzValidateStatus]="end">
+                                    <nz-datepicker formControlName="end"></nz-datepicker>
+                                    <div nz-form-explain *ngIf="(end.dirty || end.touched) && end.errors?.required">Select date</div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col [nzSm]="4">
+                            <label for="captcha" nz-form-item-required>Captcha</label>
+                        </div>
+                        <div nz-form-control nz-col [nzSm]="20" [nzValidateStatus]="captcha">
+                            <div nz-row [nzGutter]="8">
+                                <div nz-col [nzSpan]="12">
+                                    <nz-input formControlName="captcha" [nzId]="'captcha'"></nz-input>
+                                </div>
+                                <div nz-col [nzSpan]="12">
+                                    <button nz-button (click)="getCaptcha($event)">Get captcha</button>
+                                </div>
+                            </div>
+                            <div nz-form-extra>We must make sure that your are a human.</div>
+                            <div nz-form-explain *ngIf="(captcha.dirty || captcha.touched) && captcha.errors?.required">Please input the captcha you got!</div>
+                        </div>
+                    </div>
+                </fieldset>
+                <fieldset>
+                    <legend>Extended</legend>
+                </fieldset>
+                <div nz-form-item nz-row>
+                    <div nz-form-control nz-col [nzSpan]="20" [nzOffset]="4">
+                        <label nz-checkbox formControlName="agree">
+                            <span>I have read the <a>agreement</a></span>
+                        </label>
+                    </div>
+                </div>
+                <div nz-form-item nz-row class="mb0">
+                    <div nz-form-control nz-col [nzSpan]="20" [nzOffset]="4">
+                        <button nz-button [nzType]="'primary'" [disabled]="form.invalid">Register</button>
+                        <button nz-button (click)="form.reset()">Reset</button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/forms/validation/validation.component.spec.ts b/src/app/routes/forms/validation/validation.component.spec.ts
new file mode 100644
index 0000000..0a28446
--- /dev/null
+++ b/src/app/routes/forms/validation/validation.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ValidationComponent } from './validation.component';
+
+describe('Component: Validation', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ValidationComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ValidationComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/forms/validation/validation.component.ts b/src/app/routes/forms/validation/validation.component.ts
new file mode 100644
index 0000000..8bf5b5e
--- /dev/null
+++ b/src/app/routes/forms/validation/validation.component.ts
@@ -0,0 +1,115 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators, FormControl, AsyncValidatorFn, AbstractControl } from '@angular/forms';
+import { Observable } from 'rxjs/Observable';
+import { ArrayObservable } from 'rxjs/observable/ArrayObservable';
+import { map, delay, debounceTime } from 'rxjs/operators';
+
+const USERDATA = {
+    nickname: 'test',
+    email: 'cipchk@qq.com',
+    password: '123',
+    checkPassword: '123',
+    phoneNumberPrefix: '+86',
+    phoneNumber: '123',
+    website: 'http://asdfblog.com',
+    captcha: '123',
+    agree: true,
+    start: new Date(),
+    end: new Date()
+};
+
+@Component({
+    selector: 'app-validation',
+    templateUrl: './validation.component.html'
+})
+export class ValidationComponent implements OnInit {
+    form: FormGroup;
+    loading = false;
+
+    _submitForm() {
+        // tslint:disable-next-line:forin
+        for (const i in this.form.controls) {
+            this.form.controls[i].markAsDirty();
+        }
+        console.log('log', this.form.value);
+        if (this.form.valid) {
+            this.msg.success('Successed!');
+        } else {
+            this.msg.error('Fail!');
+        }
+    }
+
+    nicknameValidator = (control: FormControl): Observable<any>  => {
+        return control.valueChanges.pipe(
+            debounceTime(500),
+            map((value) => {
+                if (value !== 'cipchk') {
+                    control.setErrors({ checked: true, error: true });
+                    return ;
+                }
+                control.setErrors(null);
+            })
+        );
+    }
+
+    confirmationValidator = (control: FormControl): { [s: string]: boolean } => {
+        if (!control.value) {
+            return { required: true };
+        } else if (control.value !== this.form.controls['password'].value) {
+            return { confirm: true, error: true };
+        }
+    }
+
+    getFormControl(name: string) {
+        return this.form.controls[name];
+    }
+
+    ngOnInit() {
+        this.form = this.fb.group({
+            email: [null, [Validators.email]],
+            password: [null, [Validators.required]],
+            checkPassword: [null, Validators.compose([Validators.required, this.confirmationValidator])],
+            nickname: [null, Validators.compose([Validators.required, Validators.minLength(6)]), this.nicknameValidator.bind(this)],
+            phoneNumberPrefix: ['+86', [Validators.required]],
+            phoneNumber: [null, [Validators.required]],
+            website: ['asdf', [Validators.required]],
+            start: [null, [Validators.required]],
+            end: [null, [Validators.required]],
+            status: [null, [Validators.required]],
+            captcha: [null, [Validators.required]],
+            agree: [true, [Validators.requiredTrue]]
+        }, );
+    }
+
+    //#region get form fields
+    get email() { return this.form.controls.email; }
+    get password() { return this.form.controls.password; }
+    get checkPassword() { return this.form.controls.checkPassword; }
+    get nickname() { return this.form.controls.nickname; }
+    get phoneNumberPrefix() { return this.form.controls.phoneNumberPrefix; }
+    get phoneNumber() { return this.form.controls.phoneNumber; }
+    get website() { return this.form.controls.website; }
+    get start() { return this.form.controls.start; }
+    get summary() { return this.form.controls.summary; }
+    get end() { return this.form.controls.end; }
+    get status() { return this.form.controls.status; }
+    get captcha() { return this.form.controls.captcha; }
+    get agree() { return this.form.controls.agree; }
+    //#endregion
+
+    loadData() {
+        this.loading = true;
+        ArrayObservable.of(USERDATA).pipe(delay(1000))
+            .subscribe(data => {
+                this.loading = false;
+                this.form.reset(data);
+            });
+    }
+
+    getCaptcha(e: MouseEvent) {
+        e.preventDefault();
+    }
+
+    constructor(private fb: FormBuilder, private msg: NzMessageService) { }
+}
diff --git a/src/app/routes/logics/acl/acl.component.html b/src/app/routes/logics/acl/acl.component.html
new file mode 100644
index 0000000..a8ea0d4
--- /dev/null
+++ b/src/app/routes/logics/acl/acl.component.html
@@ -0,0 +1,30 @@
+<div class="content__title">
+    <h1>
+        ACL ������������ <small>������������������������������ACLService���������������������������������������������������������������������������������������������������ACLService���Route Guard���������������������</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="8">
+    <div nz-col [nzSpan]="8">
+        <nz-card nzTitle="������">
+            <button nz-button (click)="toggleFull()">
+                <span>{{ full ? '������' : '������'}}������</span>
+            </button>
+            <p class="pt-md">������������������������������������������������������</p>
+        </nz-card>
+    </div>
+    <div nz-col [nzSpan]="8">
+        <nz-card nzTitle="������[role-a]">
+            <button nz-button (click)="toggleRoleA()">
+                <span>{{ roleA.length > 0 ? '������' : '������'}}������</span>
+            </button>
+        </nz-card>
+    </div>
+    <div nz-col [nzSpan]="8">
+        <nz-card nzTitle="������[role-b]">
+            <button nz-button (click)="toggleRoleB()">
+                <span>{{ roleB.length > 0 ? '������' : '������'}}������</span>
+            </button>
+        </nz-card>
+    </div>
+</div>
+
diff --git a/src/app/routes/logics/acl/acl.component.spec.ts b/src/app/routes/logics/acl/acl.component.spec.ts
new file mode 100644
index 0000000..a7e555c
--- /dev/null
+++ b/src/app/routes/logics/acl/acl.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ACLComponent } from './acl.component';
+
+describe('Comoponent: ACL', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ACLComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ACLComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/logics/acl/acl.component.ts b/src/app/routes/logics/acl/acl.component.ts
new file mode 100644
index 0000000..0b1f7a2
--- /dev/null
+++ b/src/app/routes/logics/acl/acl.component.ts
@@ -0,0 +1,46 @@
+import { Component } from '@angular/core';
+import { ACLService } from '@delon/acl';
+import { MenuService } from '@delon/theme';
+
+@Component({
+    selector: 'app-acl',
+    templateUrl: './acl.component.html'
+})
+export class ACLComponent {
+
+    full = true;
+    roleA = '';
+    roleB = '';
+
+    constructor(
+        private aclService: ACLService,
+        private menuSrv: MenuService) { }
+
+    private reMenu() {
+        this.menuSrv.resume((item) => {
+            item.hide = item.acl && !this.aclService.can(item.acl);
+        });
+    }
+
+    toggleFull() {
+        this.full = !this.full;
+        this.aclService.setFull(this.full);
+        this.reMenu();
+    }
+
+    toggleRoleA() {
+        this.full = false;
+        this.roleA = this.roleA.length > 0 ? '' : 'role-a';
+        this.aclService.setFull(this.full);
+        this.aclService.setRole([this.roleA]);
+        this.reMenu();
+    }
+
+    toggleRoleB() {
+        this.full = false;
+        this.roleB = this.roleB.length > 0 ? '' : 'role-b';
+        this.aclService.setFull(this.full);
+        this.aclService.setRole([this.roleB]);
+        this.reMenu();
+    }
+}
diff --git a/src/app/routes/logics/downfile/downfile.component.html b/src/app/routes/logics/downfile/downfile.component.html
new file mode 100644
index 0000000..5b20d5a
--- /dev/null
+++ b/src/app/routes/logics/downfile/downfile.component.html
@@ -0,0 +1,7 @@
+<div class="content__title">
+    <h1>Download a file</h1>
+</div>
+<nz-card nzTitle="DEMO">
+    <button nz-button *ngFor="let i of fileTypes" class="mr-sm"
+        down-file [http-data]="data" http-url="assets/demo{{i}}" file-name="demo������">{{i}}</button>
+</nz-card>
diff --git a/src/app/routes/logics/downfile/downfile.component.spec.ts b/src/app/routes/logics/downfile/downfile.component.spec.ts
new file mode 100644
index 0000000..e7c0891
--- /dev/null
+++ b/src/app/routes/logics/downfile/downfile.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { DownFileComponent } from './downfile.component';
+
+describe('Comoponent: DownFile', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ DownFileComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(DownFileComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/logics/downfile/downfile.component.ts b/src/app/routes/logics/downfile/downfile.component.ts
new file mode 100644
index 0000000..4bfd767
--- /dev/null
+++ b/src/app/routes/logics/downfile/downfile.component.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-down-file',
+    templateUrl: './downfile.component.html'
+})
+export class DownFileComponent {
+
+    fileTypes = ['.xlsx', '.docx', '.pptx', '.pdf'];
+
+    data = {
+        otherdata: 1,
+        time: new Date()
+    };
+
+}
diff --git a/src/app/routes/logics/guard/admin.component.ts b/src/app/routes/logics/guard/admin.component.ts
new file mode 100644
index 0000000..4174971
--- /dev/null
+++ b/src/app/routes/logics/guard/admin.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-guard-admin',
+    template: `
+    <p>���������������������������</p>
+    `
+})
+export class GuardAdminComponent {}
diff --git a/src/app/routes/logics/guard/auth.component.ts b/src/app/routes/logics/guard/auth.component.ts
new file mode 100644
index 0000000..c8844a7
--- /dev/null
+++ b/src/app/routes/logics/guard/auth.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-guard-auth',
+    template: `
+    <p>������������������������������������</p>
+    `
+})
+export class GuardAuthComponent {}
diff --git a/src/app/routes/logics/guard/can-admin.provide.ts b/src/app/routes/logics/guard/can-admin.provide.ts
new file mode 100644
index 0000000..ff2e4d0
--- /dev/null
+++ b/src/app/routes/logics/guard/can-admin.provide.ts
@@ -0,0 +1,28 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Injectable } from '@angular/core';
+import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { Observable } from 'rxjs/Observable';
+import { UserService } from './user.service';
+
+@Injectable()
+export class CanAdminProvide implements CanActivate {
+
+    constructor(private userSrv: UserService, private msg: NzMessageService) {}
+
+    canActivate(
+        route: ActivatedRouteSnapshot,
+        state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
+        return new Observable((observer) => {
+            if (this.userSrv.hasRole('admin')) {
+                observer.next(true);
+                observer.complete();
+                return;
+            }
+
+            this.msg.error('������������');
+            observer.next(false);
+            observer.complete();
+        });
+    }
+
+}
diff --git a/src/app/routes/logics/guard/can-auth.provide.ts b/src/app/routes/logics/guard/can-auth.provide.ts
new file mode 100644
index 0000000..30a4e68
--- /dev/null
+++ b/src/app/routes/logics/guard/can-auth.provide.ts
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { Observable } from 'rxjs/Observable';
+import { UserService } from './user.service';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Injectable()
+export class CanAuthProvide implements CanActivate {
+
+    constructor(private userSrv: UserService, private msg: NzMessageService) {}
+
+    canActivate(
+        route: ActivatedRouteSnapshot,
+        state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
+        return new Observable((observer) => {
+            if (this.userSrv.isLogin) {
+                observer.next(true);
+                observer.complete();
+                return;
+            }
+
+            this.msg.error('������������');
+            observer.next(false);
+            observer.complete();
+        });
+    }
+
+}
diff --git a/src/app/routes/logics/guard/can-leave.provide.ts b/src/app/routes/logics/guard/can-leave.provide.ts
new file mode 100644
index 0000000..95f7662
--- /dev/null
+++ b/src/app/routes/logics/guard/can-leave.provide.ts
@@ -0,0 +1,33 @@
+import { Injectable } from '@angular/core';
+import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { GuardComponent } from './guard.component';
+import { Observable } from 'rxjs/Observable';
+import { NzModalService } from 'ng-zorro-antd';
+
+@Injectable()
+export class CanLeaveProvide implements CanDeactivate<GuardComponent> {
+    constructor (private confirmSrv: NzModalService) {}
+
+    canDeactivate(
+        component: GuardComponent,
+        currentRoute: ActivatedRouteSnapshot,
+        currentState: RouterStateSnapshot,
+        nextState?: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
+        return new Observable((observer) => {
+            this.confirmSrv.confirm({
+                title: '���������������������',
+                content: '���������������������������������������������������������������������',
+                okText: '������',
+                cancelText: '������',
+                onOk: () => {
+                    observer.next(true);
+                    observer.complete();
+                },
+                onCancel: () => {
+                    observer.next(false);
+                    observer.complete();
+                }
+            });
+        });
+    }
+}
diff --git a/src/app/routes/logics/guard/guard.component.html b/src/app/routes/logics/guard/guard.component.html
new file mode 100644
index 0000000..b695f7c
--- /dev/null
+++ b/src/app/routes/logics/guard/guard.component.html
@@ -0,0 +1,29 @@
+<div class="content__title">
+    <h1>
+        ������������
+    </h1>
+</div>
+<nz-button-group>
+    <button nz-button [routerLink]="['/logics/guard/leave']">
+        <span>���������������</span>
+    </button>
+    <button nz-button [routerLink]="['/logics/guard/auth']">
+        <span>���������������</span>
+    </button>
+    <button nz-button [routerLink]="['/logics/guard/admin']">
+        <span>���������������������</span>
+    </button>
+</nz-button-group>
+<nz-button-group>
+    <button nz-button (click)="toggleLogin()">
+        <span>���������{{ userSrv.isLogin ? '���' : '���' }}���������</span>
+    </button>
+    <button nz-button (click)="toggleRule()">
+        <span>���������{{ !userSrv.hasRole('admin') ? '���������' : '������' }}���</span>
+    </button>
+</nz-button-group>
+<p class="mb-lg">
+    ���������������{{ userSrv.isLogin ? '���' : '���' }}������<br>
+    ���������{{ userSrv.hasRole('admin') ? '���������' : '������' }}
+</p>
+<router-outlet></router-outlet>
diff --git a/src/app/routes/logics/guard/guard.component.spec.ts b/src/app/routes/logics/guard/guard.component.spec.ts
new file mode 100644
index 0000000..9c5b36c
--- /dev/null
+++ b/src/app/routes/logics/guard/guard.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { GuardComponent } from './guard.component';
+import { UserService } from './user.service';
+
+describe('Comoponent: Guard', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ GuardComponent ],
+        providers: [ UserService]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(GuardComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/logics/guard/guard.component.ts b/src/app/routes/logics/guard/guard.component.ts
new file mode 100644
index 0000000..4f0d1f8
--- /dev/null
+++ b/src/app/routes/logics/guard/guard.component.ts
@@ -0,0 +1,32 @@
+import { Router } from '@angular/router';
+import { UserService } from './user.service';
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-guard',
+    templateUrl: './guard.component.html'
+})
+export class GuardComponent {
+    constructor(public userSrv: UserService, private router: Router) {}
+
+    toggleLogin() {
+        if (this.userSrv.isLogin) {
+            this.userSrv.logout();
+        } else {
+            this.userSrv.login('admin');
+        }
+
+        this.router.navigate([ '/logics/guard' ]);
+    }
+
+    toggleRule() {
+        if (this.userSrv.hasRole('admin')) {
+            this.userSrv.login('employee');
+        } else {
+            this.userSrv.login('admin');
+        }
+
+        this.router.navigate([ '/logics/guard' ]);
+    }
+}
diff --git a/src/app/routes/logics/guard/leave.component.ts b/src/app/routes/logics/guard/leave.component.ts
new file mode 100644
index 0000000..cadbd2c
--- /dev/null
+++ b/src/app/routes/logics/guard/leave.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'app-guard-leave',
+    template: `
+    <p>���������������������</p>
+    <button nz-button [nzType]="'primary'" [routerLink]="['/logics/guard']">
+        <span>������������</span>
+    </button>
+    `
+})
+export class GuardLeaveComponent {}
diff --git a/src/app/routes/logics/guard/user.service.ts b/src/app/routes/logics/guard/user.service.ts
new file mode 100644
index 0000000..0919fc2
--- /dev/null
+++ b/src/app/routes/logics/guard/user.service.ts
@@ -0,0 +1,44 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class UserService {
+
+    private _isLogin = false;
+
+    private _user = '';
+
+    private _role: string[] = [];
+
+    private _token = '';
+
+    get isLogin(): boolean {
+        return this._isLogin;
+    }
+
+    get token(): string {
+        return this._token;
+    }
+
+    hasRole(name: 'admin' | 'employee'): boolean {
+        return this._role.includes(name);
+    }
+
+    login(user: string) {
+        this._user = user;
+        // mock
+        if (user === 'admin') {
+            this._role = [ 'admin' ];
+        } else {
+            this._role = [ 'employee' ];
+        }
+        this._isLogin = true;
+        this._token = '' + Math.random();
+        console.log(user, this._isLogin, this._role);
+    }
+
+    logout() {
+        this._user = '';
+        this._isLogin = false;
+        this._token = '';
+    }
+}
diff --git a/src/app/routes/logics/logics.module.ts b/src/app/routes/logics/logics.module.ts
new file mode 100644
index 0000000..648b9a3
--- /dev/null
+++ b/src/app/routes/logics/logics.module.ts
@@ -0,0 +1,48 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { GuardComponent } from './guard/guard.component';
+import { CanLeaveProvide } from './guard/can-leave.provide';
+import { UserService } from './guard/user.service';
+import { CanAuthProvide } from './guard/can-auth.provide';
+import { CanAdminProvide } from './guard/can-admin.provide';
+import { GuardAdminComponent } from './guard/admin.component';
+import { GuardAuthComponent } from './guard/auth.component';
+import { GuardLeaveComponent } from './guard/leave.component';
+import { ACLComponent } from './acl/acl.component';
+import { DownFileComponent } from 'app/routes/logics/downfile/downfile.component';
+
+const routes: Routes = [
+    {
+        path: 'guard',
+        component: GuardComponent,
+        children: [
+            { path: 'leave', component: GuardLeaveComponent, canDeactivate: [ CanLeaveProvide ] },
+            { path: 'auth', component: GuardAuthComponent, canActivate: [ CanAuthProvide ] },
+            { path: 'admin', component: GuardAdminComponent, canActivate: [ CanAdminProvide ] }
+        ]
+    },
+    { path: 'acl', component: ACLComponent },
+    { path: 'downfile', component: DownFileComponent }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    providers: [ UserService, CanLeaveProvide, CanAuthProvide, CanAdminProvide ],
+    declarations: [
+        GuardComponent,
+        GuardLeaveComponent,
+        GuardAdminComponent,
+        GuardAuthComponent,
+        ACLComponent,
+        DownFileComponent
+    ],
+    exports: [
+        RouterModule
+    ]
+})
+export class LogicsModule { }
diff --git a/src/app/routes/maps/baidu/baidu.component.html b/src/app/routes/maps/baidu/baidu.component.html
new file mode 100644
index 0000000..c38dc74
--- /dev/null
+++ b/src/app/routes/maps/baidu/baidu.component.html
@@ -0,0 +1,25 @@
+<div class="content__title">
+    <h1>
+        Baidu Maps
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Basic Map">
+            <ng-template #extra>
+                <nz-button-group [nzSize]="'small'">
+                    <button nz-button (click)="panTo()">
+                        <span>Change Center</span>
+                    </button>
+                    <button nz-button (click)="zoom()">
+                        <span>Change Zoom</span>
+                    </button>
+                </nz-button-group>
+                <button nz-button (click)="infoWindow()" [nzSize]="'small'">
+                    <span>new infomation window</span>
+                </button>
+            </ng-template>
+            <abm-map #map [options]="options" (ready)="onReady($event)" style="height:500px;"></abm-map>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/maps/baidu/baidu.component.spec.ts b/src/app/routes/maps/baidu/baidu.component.spec.ts
new file mode 100644
index 0000000..f9a43a8
--- /dev/null
+++ b/src/app/routes/maps/baidu/baidu.component.spec.ts
@@ -0,0 +1,22 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { MapsBaiduComponent } from './baidu.component';
+import { AbmModule } from 'angular-baidu-maps';
+
+describe('Component: MapsBaidu', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ MapsBaiduComponent ],
+        imports: [
+            AbmModule.forRoot({
+                apiKey: 'p3HIQIqLqKVQOXao1IiLp5O0eTFakjEP' // app key������������
+            })
+        ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(MapsBaiduComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/maps/baidu/baidu.component.ts b/src/app/routes/maps/baidu/baidu.component.ts
new file mode 100644
index 0000000..65005ea
--- /dev/null
+++ b/src/app/routes/maps/baidu/baidu.component.ts
@@ -0,0 +1,70 @@
+import { Component, OnInit, ViewEncapsulation, AfterViewInit, ViewChild, ElementRef, NgZone, OnDestroy } from '@angular/core';
+import { AbmComponent } from 'angular-baidu-maps';
+
+declare const BMap: any;
+declare const BMAP_SATELLITE_MAP: any;
+
+@Component({
+    selector: 'app-maps-baidu',
+    templateUrl: './baidu.component.html'
+})
+export class MapsBaiduComponent implements OnDestroy {
+
+    options: any = {};
+    status = '';
+    @ViewChild('map') mapComp: AbmComponent;
+    satelliteOptions: any;
+    private mapSatellite: any;
+
+    constructor(private el: ElementRef, private zone: NgZone) { }
+
+    private _map: any;
+    onReady(map: any) {
+        this._map = map;
+        map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);
+        map.addControl(new BMap.MapTypeControl());
+        map.setCurrentCity('������');
+        map.enableScrollWheelZoom(true);
+        this.status = '������������';
+        // ������������������
+        map.addEventListener('tilesloaded', () => {
+            this.status = '������������������';
+        });
+        map.addEventListener('click', this._click.bind(this));
+    }
+
+    _click(e: any) {
+        this.status = `${e.point.lng}, ${e.point.lat}, ${+new Date}`;
+    }
+
+    panTo() {
+        this._map.panTo(new BMap.Point(116.404, 39.715));
+    }
+
+    zoom() {
+        this._map.setZoom((this._map.getZoom() + 1) % 17);
+    }
+
+    infoWindow() {
+        const infoWin = new BMap.InfoWindow('������������������������������������������88���������������������������', {
+            width: 200,     // ������������������
+            height: 100,     // ������������������
+            title: '���������������������', // ������������������
+            enableMessage: true, // ���������������������������������
+            message: '������������������������������������������������������������������������~'
+        });
+        this._map.openInfoWindow(infoWin, this._map.getCenter());
+    }
+
+    // ������
+    onReadySatellite(map: any) {
+        map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);
+        map.setMapType(BMAP_SATELLITE_MAP);
+        this.mapSatellite = map;
+    }
+
+    ngOnDestroy(): void {
+        this._map.removeEventListener('click', this._click.bind(this));
+    }
+
+}
diff --git a/src/app/routes/maps/maps.module.ts b/src/app/routes/maps/maps.module.ts
new file mode 100644
index 0000000..f7b0c67
--- /dev/null
+++ b/src/app/routes/maps/maps.module.ts
@@ -0,0 +1,38 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { AbmModule } from 'angular-baidu-maps';
+import { AqmModule } from 'angular-qq-maps';
+
+import { SharedModule } from '@shared/shared.module';
+
+import { MapsQQComponent } from './qq/qq.component';
+import { MapsBaiduComponent } from './baidu/baidu.component';
+
+const routes: Routes = [
+    { path: 'qq', component: MapsQQComponent },
+    { path: 'baidu', component: MapsBaiduComponent }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes),
+        AbmModule.forRoot({
+            apiKey: 'p3HIQIqLqKVQOXao1IiLp5O0eTFakjEP' // app key������������
+        }),
+        AqmModule.forRoot({
+            apiKey: 'I3TBZ-QTN3J-MWPFI-FERMS-IBOCQ-LBBWY' // app key������������
+        })
+    ],
+    declarations: [
+        MapsQQComponent,
+        MapsBaiduComponent
+    ],
+    exports: [
+        RouterModule
+    ],
+    entryComponents: [
+
+    ]
+})
+export class MapsModule { }
diff --git a/src/app/routes/maps/qq/qq.component.html b/src/app/routes/maps/qq/qq.component.html
new file mode 100644
index 0000000..03d4b12
--- /dev/null
+++ b/src/app/routes/maps/qq/qq.component.html
@@ -0,0 +1,25 @@
+<div class="content__title">
+    <h1>
+        QQ Maps
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="QQ Map">
+            <ng-template #extra>
+                <nz-button-group [nzSize]="'small'">
+                    <button nz-button (click)="panTo()">
+                        <span>Change Center</span>
+                    </button>
+                    <button nz-button (click)="zoom()">
+                        <span>Change Zoom</span>
+                    </button>
+                </nz-button-group>
+                <button nz-button (click)="infoWindow()" [nzSize]="'small'">
+                    <span>new infomation window</span>
+                </button>
+            </ng-template>
+            <aqm-map #map [options]="options" (ready)="onReady($event)" style="height:500px;"></aqm-map>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/maps/qq/qq.component.spec.ts b/src/app/routes/maps/qq/qq.component.spec.ts
new file mode 100644
index 0000000..d144623
--- /dev/null
+++ b/src/app/routes/maps/qq/qq.component.spec.ts
@@ -0,0 +1,22 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { MapsQQComponent } from './qq.component';
+import { AqmModule } from 'angular-qq-maps';
+
+describe('Component: MapsQQ', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ MapsQQComponent ],
+        imports: [
+            AqmModule.forRoot({
+                apiKey: 'I3TBZ-QTN3J-MWPFI-FERMS-IBOCQ-LBBWY' // app key������������
+            })
+        ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(MapsQQComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/maps/qq/qq.component.ts b/src/app/routes/maps/qq/qq.component.ts
new file mode 100644
index 0000000..c515c7a
--- /dev/null
+++ b/src/app/routes/maps/qq/qq.component.ts
@@ -0,0 +1,72 @@
+import { Component, ViewChild, ElementRef, NgZone, OnDestroy } from '@angular/core';
+import { AqmComponent } from 'angular-qq-maps';
+
+declare const qq: any;
+
+@Component({
+    selector: 'app-maps-qq',
+    templateUrl: './qq.component.html'
+})
+export class MapsQQComponent implements OnDestroy {
+    options: any = {};
+    status = '';
+    @ViewChild('map') mapComp: AqmComponent;
+    satelliteOptions: any;
+    private mapSatellite: any;
+
+    constructor(private el: ElementRef, private zone: NgZone) { }
+
+    private map: any;
+    onReady(mapNative: any) {
+        mapNative.setOptions({
+            zoom: 12,
+            center: new qq.maps.LatLng(39.916527, 116.397128)
+        });
+        this.map = mapNative;
+        this.status = '������������';
+        // ������������������
+        qq.maps.event.addListener(this.map, 'click', (event: any) => {
+            // tslint:disable-next-line:no-unused-expression
+            new qq.maps.Marker({
+                position: event.latLng,
+                map: this.map
+            });
+            this.zone.run(() => {
+                this.status = `click ${+new Date}`;
+            });
+        });
+    }
+
+    panTo() {
+        this.map.panTo(new qq.maps.LatLng(39.9, 116.4));
+    }
+
+    zoom() {
+        this.map.zoomTo((this.map.getZoom() + 1) % 17);
+    }
+
+    infoWindow() {
+        const infoWin = new qq.maps.InfoWindow({
+            map: this.map
+        });
+        infoWin.open();
+        infoWin.setContent('Hello world');
+        infoWin.setPosition(this.map.getCenter());
+    }
+
+    // ������
+    onReadySatellite(mapNative: any) {
+        mapNative.setOptions({
+            zoom: 14,
+            center: new qq.maps.LatLng(39.916527, 116.397128),
+            mapTypeId: qq.maps.MapTypeId.SATELLITE
+        });
+        this.mapSatellite = mapNative;
+    }
+
+    ngOnDestroy(): void {
+        ['click'].forEach(eventName => {
+            qq.maps.event.clearListeners(this.map, eventName);
+        });
+    }
+}
diff --git a/src/app/routes/pages/404/404.component.html b/src/app/routes/pages/404/404.component.html
new file mode 100644
index 0000000..6e697d7
--- /dev/null
+++ b/src/app/routes/pages/404/404.component.html
@@ -0,0 +1,28 @@
+<div class="wrapper">
+    <div class="abs-center width-lg">
+        <!-- START panel-->
+        <div class="text-center mb-lg">
+            <div class="text-lg mb-lg">404</div>
+            <p class="lead m0">We couldn't find this page.</p>
+            <p>The page you are looking for does not exists.</p>
+        </div>
+        <div class="m-lg">
+            <nz-input [nzType]="'search'" [nzPlaceHolder]="'try with search'"></nz-input>
+        </div>
+        <nz-breadcrumb nzSeparator="|" class="ant-breadcrumb__last-item-no-bold text-center">
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/home'">Go to App</a>
+            </nz-breadcrumb-item>
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/login'">Login</a>
+            </nz-breadcrumb-item>
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/register'">Register</a>
+            </nz-breadcrumb-item>
+        </nz-breadcrumb>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/404/404.component.spec.ts b/src/app/routes/pages/404/404.component.spec.ts
new file mode 100644
index 0000000..1798523
--- /dev/null
+++ b/src/app/routes/pages/404/404.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { Page404Component } from './404.component';
+
+describe('Pages: 404', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ Page404Component ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(Page404Component);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/404/404.component.ts b/src/app/routes/pages/404/404.component.ts
new file mode 100644
index 0000000..034fcc4
--- /dev/null
+++ b/src/app/routes/pages/404/404.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-404',
+  templateUrl: './404.component.html'
+})
+export class Page404Component {
+
+    constructor(public settings: SettingsService) {}
+
+}
diff --git a/src/app/routes/pages/500/500.component.html b/src/app/routes/pages/500/500.component.html
new file mode 100644
index 0000000..193c983
--- /dev/null
+++ b/src/app/routes/pages/500/500.component.html
@@ -0,0 +1,28 @@
+<div class="wrapper">
+    <div class="abs-center width-lg">
+        <div class="text-center mb-lg mt-lg">
+            <div class="mb-lg">
+                <em class="fa fa-wrench fa-5x text-grey"></em>
+            </div>
+            <div class="text-lg mb-lg">500</div>
+            <p class="lead m0">Oh! Something went wrong :(</p>
+            <p>Don't worry, we're now checking this.</p>
+            <p>In the meantime, please try one of those links below or come back in a moment</p>
+        </div>
+        <nz-breadcrumb nzSeparator="|" class="ant-breadcrumb__last-item-no-bold text-center">
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/home'">Go to App</a>
+            </nz-breadcrumb-item>
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/login'">Login</a>
+            </nz-breadcrumb-item>
+            <nz-breadcrumb-item>
+                <a class="text-muted" [routerLink]="'/register'">Register</a>
+            </nz-breadcrumb-item>
+        </nz-breadcrumb>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/500/500.component.spec.ts b/src/app/routes/pages/500/500.component.spec.ts
new file mode 100644
index 0000000..88b0ff0
--- /dev/null
+++ b/src/app/routes/pages/500/500.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { Page500Component } from './500.component';
+
+describe('Pages: 500', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ Page500Component ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(Page500Component);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/500/500.component.ts b/src/app/routes/pages/500/500.component.ts
new file mode 100644
index 0000000..2887c1c
--- /dev/null
+++ b/src/app/routes/pages/500/500.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-500',
+  templateUrl: './500.component.html'
+})
+export class Page500Component {
+
+    constructor(public settings: SettingsService) {}
+
+}
diff --git a/src/app/routes/pages/forget/forget.component.html b/src/app/routes/pages/forget/forget.component.html
new file mode 100644
index 0000000..bb04cf0
--- /dev/null
+++ b/src/app/routes/pages/forget/forget.component.html
@@ -0,0 +1,32 @@
+<div class="wrapper">
+    <div class="abs-center mt-lg width-lg">
+        <nz-card [nzTitle]="nzTitle" [nzBordered]="false" class="ant-card__primary ant-card__title-img">
+            <ng-template #nzTitle>
+                <div class="text-center"><img src="./assets/img/logo.svg" style="height:20px;"></div>
+            </ng-template>
+            <form nz-form [formGroup]="valForm" (ngSubmit)="submit()" role="form">
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.email">
+                        <nz-input formControlName="email" [nzPlaceHolder]="'������'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-mail"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.email.dirty&&valForm.controls.email.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-row>
+                    <div nz-col [nzSpan]="24">
+                        <button nz-button [disabled]="!valForm.valid" [nzType]="'danger'" [nzSize]="'large'" class="ant-btn__block">
+                            <span>������������</span>
+                        </button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/forget/forget.component.spec.ts b/src/app/routes/pages/forget/forget.component.spec.ts
new file mode 100644
index 0000000..f52295b
--- /dev/null
+++ b/src/app/routes/pages/forget/forget.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { ForgetComponent } from './forget.component';
+
+describe('Pages: forget', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ ForgetComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(ForgetComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/forget/forget.component.ts b/src/app/routes/pages/forget/forget.component.ts
new file mode 100644
index 0000000..00d058a
--- /dev/null
+++ b/src/app/routes/pages/forget/forget.component.ts
@@ -0,0 +1,30 @@
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-forget',
+  templateUrl: './forget.component.html'
+})
+export class ForgetComponent {
+  valForm: FormGroup;
+
+  constructor(public settings: SettingsService, fb: FormBuilder, private router: Router) {
+    this.valForm = fb.group({
+      email: [null, Validators.compose([Validators.required, Validators.email])]
+    });
+  }
+
+  submit() {
+    // tslint:disable-next-line:forin
+    for (const i in this.valForm.controls) {
+      this.valForm.controls[i].markAsDirty();
+    }
+    if (this.valForm.valid) {
+      console.log('Valid!');
+      console.log(this.valForm.value);
+      this.router.navigate(['dashboard']);
+    }
+  }
+}
diff --git a/src/app/routes/pages/lock/lock.component.html b/src/app/routes/pages/lock/lock.component.html
new file mode 100644
index 0000000..0ed076a
--- /dev/null
+++ b/src/app/routes/pages/lock/lock.component.html
@@ -0,0 +1,36 @@
+<div class="wrapper">
+    <div class="abs-center width-lg">
+        <div class="py-lg text-center">
+            <nz-avatar [nzIcon]="'user'" [nzSize]="'large'"></nz-avatar>
+        </div>
+        <nz-card [nzBordered]="false">
+            <p class="mb-sm">������������������������������</p>
+            <form nz-form [formGroup]="valForm" (ngSubmit)="submit()" role="form">
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.password">
+                        <nz-input formControlName="password" [nzPlaceHolder]="'password'" [nzType]="'password'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-lock"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.password.dirty&&valForm.controls.password.hasError('required')">This field is required</div>
+                    </div>
+                </div>
+                <div nz-row nzType="flex" nzAlign="middle">
+                    <div nz-col [nzSpan]="12">
+                        <a [routerLink]="['/forget']">���������������</a>
+                    </div>
+                    <div nz-col [nzSpan]="12" style="text-align:right;">
+                        <button nz-button [disabled]="!valForm.valid" [nzType]="'primary'" [nzSize]="'large'">
+                            <span>������</span>
+                        </button>
+                    </div>
+                </div>
+            </form>
+        </nz-card>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/lock/lock.component.spec.ts b/src/app/routes/pages/lock/lock.component.spec.ts
new file mode 100644
index 0000000..ab2408e
--- /dev/null
+++ b/src/app/routes/pages/lock/lock.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { LockComponent } from './lock.component';
+
+describe('Pages: lock', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ LockComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(LockComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/lock/lock.component.ts b/src/app/routes/pages/lock/lock.component.ts
new file mode 100644
index 0000000..46c00e8
--- /dev/null
+++ b/src/app/routes/pages/lock/lock.component.ts
@@ -0,0 +1,30 @@
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-lock',
+  templateUrl: './lock.component.html'
+})
+export class LockComponent {
+  valForm: FormGroup;
+
+  constructor(public settings: SettingsService, fb: FormBuilder, private router: Router) {
+    this.valForm = fb.group({
+      password: [null, Validators.required]
+    });
+  }
+
+  submit() {
+    // tslint:disable-next-line:forin
+    for (const i in this.valForm.controls) {
+      this.valForm.controls[i].markAsDirty();
+    }
+    if (this.valForm.valid) {
+      console.log('Valid!');
+      console.log(this.valForm.value);
+      this.router.navigate(['dashboard']);
+    }
+  }
+}
diff --git a/src/app/routes/pages/login/login.component.html b/src/app/routes/pages/login/login.component.html
new file mode 100644
index 0000000..24b3dc6
--- /dev/null
+++ b/src/app/routes/pages/login/login.component.html
@@ -0,0 +1,62 @@
+<div class="wrapper">
+    <div class="abs-center mt-lg width-lg">
+        <nz-card [nzTitle]="nzTitle" [nzBordered]="false" class="ant-card__primary ant-card__title-img">
+            <ng-template #nzTitle>
+                <div class="text-center"><img src="./assets/img/logo.svg" style="height:20px;"></div>
+            </ng-template>
+            <form nz-form [formGroup]="valForm" (ngSubmit)="submit()" role="form">
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.email">
+                        <nz-input formControlName="email" [nzPlaceHolder]="'������'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-mail"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.email.dirty&&valForm.controls.email.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.password">
+                        <nz-input formControlName="password" [nzPlaceHolder]="'������'" [nzType]="'password'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-lock"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.password.dirty&&valForm.controls.password.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-col [nzSpan]="12">
+                        <label nz-checkbox formControlName="remember_me">
+                            <span>������������</span>
+                        </label>
+                    </div>
+                    <div nz-col [nzSpan]="12" class="text-right">
+                        <a [routerLink]="['/forget']">���������������</a>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-col [nzSpan]="24">
+                        <button nz-button [disabled]="!valForm.valid" [nzType]="'primary'" [nzSize]="'large'" class="ant-btn__block">
+                            <span>������</span>
+                        </button>
+                    </div>
+                </div>
+            </form>
+            <div nz-form-item nz-row>
+                <div nz-col [nzSpan]="24" class="text-center">���</div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="24">
+                    <button nz-button [routerLink]="['/register']" [nzType]="'default'" [nzSize]="'large'" class="ant-btn__block">
+                        <span>������������</span>
+                    </button>
+                </div>
+            </div>
+        </nz-card>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/login/login.component.spec.ts b/src/app/routes/pages/login/login.component.spec.ts
new file mode 100644
index 0000000..956237b
--- /dev/null
+++ b/src/app/routes/pages/login/login.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { LoginComponent } from './login.component';
+
+describe('Pages: login', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ LoginComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(LoginComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/login/login.component.ts b/src/app/routes/pages/login/login.component.ts
new file mode 100644
index 0000000..7eb4c0f
--- /dev/null
+++ b/src/app/routes/pages/login/login.component.ts
@@ -0,0 +1,32 @@
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-login',
+  templateUrl: './login.component.html'
+})
+export class LoginComponent {
+  valForm: FormGroup;
+
+  constructor(public settings: SettingsService, fb: FormBuilder, private router: Router) {
+    this.valForm = fb.group({
+      email: [null, Validators.compose([Validators.required, Validators.email])],
+      password: [null, Validators.required],
+      remember_me: [null]
+    });
+  }
+
+  submit() {
+    // tslint:disable-next-line:forin
+    for (const i in this.valForm.controls) {
+      this.valForm.controls[i].markAsDirty();
+    }
+    if (this.valForm.valid) {
+      console.log('Valid!');
+      console.log(this.valForm.value);
+      this.router.navigate(['dashboard']);
+    }
+  }
+}
diff --git a/src/app/routes/pages/maintenance/maintenance.component.html b/src/app/routes/pages/maintenance/maintenance.component.html
new file mode 100644
index 0000000..3a29d4e
--- /dev/null
+++ b/src/app/routes/pages/maintenance/maintenance.component.html
@@ -0,0 +1,13 @@
+<div class="wrapper">
+    <div class="abs-center">
+        <div class="text-center mv-lg">
+            <h1 class="mb-lg">
+                <sup><em class="fa fa-cog fa-2x fa-spin text-info"></em></sup>
+                <em class="fa fa-cog fa-5x fa-spin text-error"></em>
+                <em class="fa fa-cog fa-lg fa-spin text-success"></em>
+            </h1>
+            <div class="text-bold text-lg mb-lg">SITE IS UNDER MAINTENANCE</div>
+            <p class="lead m0">We'll back online shortly!</p>
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/maintenance/maintenance.component.spec.ts b/src/app/routes/pages/maintenance/maintenance.component.spec.ts
new file mode 100644
index 0000000..f9dd2c3
--- /dev/null
+++ b/src/app/routes/pages/maintenance/maintenance.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { MaintenanceComponent } from './maintenance.component';
+
+describe('Pages: 404', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ MaintenanceComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(MaintenanceComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/maintenance/maintenance.component.ts b/src/app/routes/pages/maintenance/maintenance.component.ts
new file mode 100644
index 0000000..2f1e577
--- /dev/null
+++ b/src/app/routes/pages/maintenance/maintenance.component.ts
@@ -0,0 +1,8 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-pages-maintenance',
+  templateUrl: './maintenance.component.html'
+})
+export class MaintenanceComponent {
+}
diff --git a/src/app/routes/pages/pages.module.ts b/src/app/routes/pages/pages.module.ts
new file mode 100644
index 0000000..2aa7929
--- /dev/null
+++ b/src/app/routes/pages/pages.module.ts
@@ -0,0 +1,28 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SharedModule } from '@shared/shared.module';
+
+import { LoginComponent } from './login/login.component';
+import { LockComponent } from './lock/lock.component';
+import { RegisterComponent } from './register/register.component';
+import { ForgetComponent } from './forget/forget.component';
+import { MaintenanceComponent } from './maintenance/maintenance.component';
+import { Page404Component } from './404/404.component';
+import { Page500Component } from './500/500.component';
+
+@NgModule({
+  imports: [
+    SharedModule
+  ],
+  declarations: [
+    LoginComponent,
+    LockComponent,
+    RegisterComponent,
+    ForgetComponent,
+    MaintenanceComponent,
+    Page404Component,
+    Page500Component
+  ]
+})
+export class PagesModule { }
diff --git a/src/app/routes/pages/register/register.component.html b/src/app/routes/pages/register/register.component.html
new file mode 100644
index 0000000..10b0253
--- /dev/null
+++ b/src/app/routes/pages/register/register.component.html
@@ -0,0 +1,69 @@
+<div class="wrapper">
+    <div class="abs-center mt-lg width-lg">
+        <nz-card [nzTitle]="nzTitle" [nzBordered]="false" class="ant-card__primary ant-card__title-img">
+            <ng-template #nzTitle>
+                <div class="text-center"><img src="./assets/img/logo.svg" style="height:20px;"></div>
+            </ng-template>
+            <form nz-form [formGroup]="valForm" (ngSubmit)="submit()" role="form">
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.email">
+                        <nz-input formControlName="email" [nzPlaceHolder]="'������'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-mail"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.email.dirty&&valForm.controls.email.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.mobile">
+                        <nz-input formControlName="mobile" [nzPlaceHolder]="'���������'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-mobile"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.mobile.dirty&&valForm.controls.mobile.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-form-item>
+                    <div nz-form-control [nzValidateStatus]="valForm.controls.password">
+                        <nz-input formControlName="password" [nzPlaceHolder]="'������'" [nzType]="'password'" [nzSize]="'large'">
+                            <ng-template #suffix>
+                                <i class="anticon anticon-lock"></i>
+                            </ng-template>
+                        </nz-input>
+                        <div nz-form-explain *ngIf="valForm.controls.password.dirty&&valForm.controls.password.hasError('required')">������������</div>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-col [nzSpan]="24">
+                        <label nz-checkbox formControlName="agreed">
+                            <span>������������������</span>
+                        </label>
+                    </div>
+                </div>
+                <div nz-form-item nz-row>
+                    <div nz-col [nzSpan]="24">
+                        <button nz-button [disabled]="!valForm.valid" [nzType]="'primary'" [nzSize]="'large'" class="ant-btn__block">
+                            <span>������</span>
+                        </button>
+                    </div>
+                </div>
+            </form>
+            <div nz-form-item nz-row>
+                <div nz-col [nzSpan]="24" class="text-center">���</div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="24">
+                    <button nz-button [routerLink]="['/login']" [nzType]="'default'" [nzSize]="'large'" class="ant-btn__block">
+                        <span>������</span>
+                    </button>
+                </div>
+            </div>
+        </nz-card>
+        <div class="p-lg text-center text-sm">
+            &copy; {{ settings.app.year }} - {{ settings.app.name }}
+            <br> {{ settings.app.description }}
+        </div>
+    </div>
+</div>
diff --git a/src/app/routes/pages/register/register.component.spec.ts b/src/app/routes/pages/register/register.component.spec.ts
new file mode 100644
index 0000000..b6cab95
--- /dev/null
+++ b/src/app/routes/pages/register/register.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { RegisterComponent } from './register.component';
+
+describe('Pages: register', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ RegisterComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(RegisterComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/pages/register/register.component.ts b/src/app/routes/pages/register/register.component.ts
new file mode 100644
index 0000000..074ec79
--- /dev/null
+++ b/src/app/routes/pages/register/register.component.ts
@@ -0,0 +1,34 @@
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'app-pages-register',
+  templateUrl: './register.component.html'
+})
+export class RegisterComponent {
+  valForm: FormGroup;
+
+  constructor(public settings: SettingsService, fb: FormBuilder, private router: Router) {
+    this.valForm = fb.group({
+      email: [null, Validators.compose([Validators.required, Validators.email])],
+      mobile: [null, Validators.compose([Validators.required, Validators.pattern('^1[0-9]{10}$')])],
+      password: [null, Validators.required],
+      agreed: [null, Validators.required]
+    });
+
+  }
+
+  submit() {
+    // tslint:disable-next-line:forin
+    for (const i in this.valForm.controls) {
+      this.valForm.controls[i].markAsDirty();
+    }
+    if (this.valForm.valid) {
+      console.log('Valid!');
+      console.log(this.valForm.value);
+      this.router.navigate(['dashboard']);
+    }
+  }
+}
diff --git a/src/app/routes/pro/exception/403.component.ts b/src/app/routes/pro/exception/403.component.ts
new file mode 100644
index 0000000..4e08122
--- /dev/null
+++ b/src/app/routes/pro/exception/403.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'pro-exception-403',
+    template: `<exception type="403" style="min-height: 500px; height: 80%;"></exception>`
+})
+export class ProException403Component {}
diff --git a/src/app/routes/pro/exception/404.component.ts b/src/app/routes/pro/exception/404.component.ts
new file mode 100644
index 0000000..28aab6e
--- /dev/null
+++ b/src/app/routes/pro/exception/404.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'pro-exception-404',
+    template: `<exception type="404" style="min-height: 500px; height: 80%;"></exception>`
+})
+export class ProException404Component {}
diff --git a/src/app/routes/pro/exception/500.component.ts b/src/app/routes/pro/exception/500.component.ts
new file mode 100644
index 0000000..acec79b
--- /dev/null
+++ b/src/app/routes/pro/exception/500.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'pro-exception-500',
+    template: `<exception type="500" style="min-height: 500px; height: 80%;"></exception>`
+})
+export class ProException500Component {}
diff --git a/src/app/routes/pro/form/advanced-form/advanced-form.component.html b/src/app/routes/pro/form/advanced-form/advanced-form.component.html
new file mode 100644
index 0000000..be609b0
--- /dev/null
+++ b/src/app/routes/pro/form/advanced-form/advanced-form.component.html
@@ -0,0 +1,246 @@
+<pro-header [title]="'������������'">
+    <ng-template #content>������������������������������������������������������������������������������������������������������������������������������������������</ng-template>
+</pro-header>
+<form nz-form [formGroup]="form" (ngSubmit)="_submitForm()" [nzLayout]="'vertical'">
+    <nz-card [nzBordered]="false" nzTitle="������������">
+        <div nz-row [nzGutter]="16">
+            <div nz-col nzMd="6" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������</label></div>
+                    <div nz-form-control nz-col nzHasFeedback [nzValidateStatus]="name">
+                        <nz-input formControlName="name" nzPlaceHolder="���������������������" nzSize="large"></nz-input>
+                        <p nz-form-explain *ngIf="(name.dirty || name.touched) && name.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:6, offset:2}" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control nz-col nzHasFeedback [nzValidateStatus]="url">
+                        <nz-input formControlName="url" nzPlaceHolder="���������" nzSize="large">
+                            <ng-template #addOnBefore>http://</ng-template>
+                            <ng-template #addOnAfter>.com</ng-template>
+                        </nz-input>
+                        <p nz-form-explain *ngIf="(url.dirty || url.touched) && url.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:8, offset:2}" nzSm="24" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="owner">
+                        <nz-select formControlName="owner" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true" nzSize="large">
+                            <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+                            </nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(owner.dirty || owner.touched) && owner.errors?.required">
+                            ������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div nz-row [nzGutter]="16">
+            <div nz-col nzMd="6" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="approver">
+                        <nz-select formControlName="approver" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true" nzSize="large">
+                            <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+                            </nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(approver.dirty || approver.touched) && approver.errors?.required">
+                            ������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:6, offset:2}" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control>
+                        <div nz-col [nzSpan]="11">
+                            <div nz-form-item nz-row>
+                                <div nz-form-control [nzValidateStatus]="time_start">
+                                    <nz-datepicker formControlName="time_start" [nzPlaceHolder]="'������������'"></nz-datepicker>
+                                    <p nz-form-explain *ngIf="(time_start.dirty || time_start.touched) && time_start.errors?.required">
+                                        ���������������������
+                                    </p>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-col [nzSpan]="2">
+                            <p nz-form-split>-</p>
+                        </div>
+                        <div nz-col [nzSpan]="11">
+                            <div nz-form-item nz-row>
+                                <div nz-form-control [nzValidateStatus]="time_end">
+                                    <nz-datepicker formControlName="time_end" [nzPlaceHolder]="'������������'"></nz-datepicker>
+                                    <p nz-form-explain *ngIf="(time_end.dirty || time_end.touched) && time_end.errors?.required">
+                                        ���������������������
+                                    </p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:8, offset:2}" nzSm="24" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="type">
+                        <nz-select formControlName="type" nzSize="large" [nzShowSearch]="true" [nzPlaceHolder]="'���������������������'">
+                            <nz-option [nzLabel]="'������'" [nzValue]="'private'"></nz-option>
+                            <nz-option [nzLabel]="'������'" [nzValue]="'public'"></nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(type.dirty || type.touched) && type.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </nz-card>
+    <nz-card [nzBordered]="false" nzTitle="������������">
+        <div nz-row [nzGutter]="16">
+            <div nz-col nzMd="6" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������</label></div>
+                    <div nz-form-control nz-col nzHasFeedback [nzValidateStatus]="name2">
+                        <nz-input formControlName="name2" nzPlaceHolder="������������������" nzSize="large"></nz-input>
+                        <p nz-form-explain *ngIf="(name2.dirty || name2.touched) && name2.errors?.required">
+                            ������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:6, offset:2}" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control nz-col nzHasFeedback [nzValidateStatus]="summary">
+                        <nz-input formControlName="summary" [nzType]="'textarea'" [nzAutosize]="true" nzPlaceHolder="���������������������" nzSize="large"></nz-input>
+                        <p nz-form-explain *ngIf="(summary.dirty || summary.touched) && summary.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:8, offset:2}" nzSm="24" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="owner2">
+                        <nz-select formControlName="owner2" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true" nzSize="large">
+                            <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+                            </nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(owner2.dirty || owner2.touched) && owner2.errors?.required">
+                            ������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div nz-row [nzGutter]="16">
+            <div nz-col nzMd="6" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>���������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="approver2">
+                        <nz-select formControlName="approver2" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true" nzSize="large">
+                            <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+                            </nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(approver2.dirty || approver2.touched) && approver2.errors?.required">
+                            ������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:6, offset:2}" nzSm="12" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="time">
+                        <nz-timepicker formControlName="time" nzPlaceHolder="���������" nzSize="large"></nz-timepicker>
+                        <p nz-form-explain *ngIf="(time.dirty || time.touched) && time.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzMd]="{span:8, offset:2}" nzSm="24" nzXs="24">
+                <div nz-form-item nz-row>
+                    <div nz-form-label nz-col><label>������������</label></div>
+                    <div nz-form-control nz-col [nzValidateStatus]="type2">
+                        <nz-select formControlName="type2" nzSize="large" [nzShowSearch]="true" [nzPlaceHolder]="'���������������������'">
+                            <nz-option [nzLabel]="'������'" [nzValue]="'private'"></nz-option>
+                            <nz-option [nzLabel]="'������'" [nzValue]="'public'"></nz-option>
+                        </nz-select>
+                        <p nz-form-explain *ngIf="(type2.dirty || type2.touched) && type2.errors?.required">
+                            ���������������������
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </nz-card>
+    <nz-card [nzBordered]="false" nzTitle="������������">
+        <nz-table formArrayName="items" [nzDataSource]="items.value" [nzIsPagination]="false">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th>������������</th>
+                    <th nz-th>������</th>
+                    <th nz-th>������������</th>
+                    <th nz-th>������</th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let item of items.controls; let i = index" [formGroupName]="i">
+                    <td nz-td>
+                        <span *ngIf="editIndex!==i">{{items.value[i].name}}</span>
+                        <span *ngIf="editIndex===i" nz-form-control [nzValidateStatus]="item.controls.name">
+                            <nz-input formControlName="name" nzPlaceHolder="���������������������" nzSize="large"></nz-input>
+                        </span>
+                    </td>
+                    <td nz-td>
+                        <span *ngIf="editIndex!==i">{{items.value[i].workId}}</span>
+                        <span *ngIf="editIndex===i" nz-form-control [nzValidateStatus]="item.controls.workId">
+                            <nz-input formControlName="workId" nzPlaceHolder="���������������" nzSize="large"></nz-input>
+                        </span>
+                    </td>
+                    <td nz-td>
+                        <span *ngIf="editIndex!==i">{{items.value[i].department}}</span>
+                        <span *ngIf="editIndex===i" nz-form-control [nzValidateStatus]="item.controls.department">
+                            <nz-input formControlName="department" nzPlaceHolder="���������������������" nzSize="large"></nz-input>
+                        </span>
+                    </td>
+                    <td nz-td>
+                        <span *ngIf="editIndex!==i">
+                            <a (click)="edit(i)">������</a>
+                            <span nz-table-divider></span>
+                            <nz-popconfirm (nzOnConfirm)="del(i)" [nzTitle]="'������������������������'">
+                                <a nz-popconfirm>������</a>
+                            </nz-popconfirm>
+                        </span>
+                        <span *ngIf="editIndex===i">
+                            <a (click)="save(i)">������</a>
+                            <span nz-table-divider></span>
+                            <nz-popconfirm (nzOnConfirm)="cancel(i)" [nzTitle]="'������������������������'">
+                                <a nz-popconfirm>������</a>
+                            </nz-popconfirm>
+                        </span>
+                    </td>
+                </tr>
+            </tbody>
+        </nz-table>
+        <button *ngIf="editIndex===-1" nz-button [nzType]="'dashed'" [nzSize]="'large'" (click)="add()" class="ant-btn__block mt-md">
+            <i class="anticon anticon-plus"></i>
+            <span>������������</span>
+        </button>
+    </nz-card>
+    <footer-toolbar errorCollect>
+        <button nz-button [nzType]="'primary'" nzSize="large">������</button>
+    </footer-toolbar>
+</form>
diff --git a/src/app/routes/pro/form/advanced-form/advanced-form.component.ts b/src/app/routes/pro/form/advanced-form/advanced-form.component.ts
new file mode 100644
index 0000000..6a80322
--- /dev/null
+++ b/src/app/routes/pro/form/advanced-form/advanced-form.component.ts
@@ -0,0 +1,127 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators, FormArray } from '@angular/forms';
+
+@Component({
+    selector: 'app-advanced-form',
+    templateUrl: './advanced-form.component.html'
+})
+export class AdvancedFormComponent implements OnInit {
+    editIndex = -1;
+    editObj = {};
+
+    form: FormGroup;
+    users: any[] = [
+        { value: 'xiao', label: '���������' },
+        { value: 'mao', label: '���������' }
+    ];
+
+    constructor(private fb: FormBuilder) {}
+
+    ngOnInit() {
+        this.form = this.fb.group({
+            name: [null, [Validators.required]],
+            url: [null, [Validators.required]],
+            owner: [undefined, [Validators.required]],
+            approver : [null, [Validators.required]],
+            time_start : [null, [Validators.required]],
+            time_end : [null, [Validators.required]],
+            type : [null, [Validators.required]],
+            name2 : [null, [Validators.required]],
+            summary : [null, [Validators.required]],
+            owner2 : [null, [Validators.required]],
+            approver2 : [null, [Validators.required]],
+            time : [null, [Validators.required]],
+            type2 : [null, [Validators.required]],
+            items: this.fb.array([])
+        });
+        const userList = [
+            {
+                key: '1',
+                workId: '00001',
+                name: 'John Brown',
+                department: 'New York No. 1 Lake Park',
+            }, {
+                key: '2',
+                workId: '00002',
+                name: 'Jim Green',
+                department: 'London No. 1 Lake Park',
+            }, {
+                key: '3',
+                workId: '00003',
+                name: 'Joe Black',
+                department: 'Sidney No. 1 Lake Park',
+            }
+        ];
+        userList.forEach(i => {
+            const field = this.createUser();
+            field.patchValue(i);
+            this.items.push(field);
+        });
+    }
+
+    createUser(): FormGroup {
+        return this.fb.group({
+            key: [ null ],
+            workId: [ null, [ Validators.required ] ],
+            name: [ null, [ Validators.required ] ],
+            department: [ null, [ Validators.required ] ]
+        });
+    }
+
+    //#region get form fields
+    get name() { return this.form.controls.name; }
+    get url() { return this.form.controls.url; }
+    get owner() { return this.form.controls.owner; }
+    get approver() { return this.form.controls.approver; }
+    get time_start() { return this.form.controls.time_start; }
+    get time_end() { return this.form.controls.time_end; }
+    get type() { return this.form.controls.type; }
+    get name2() { return this.form.controls.name2; }
+    get summary() { return this.form.controls.summary; }
+    get owner2() { return this.form.controls.owner2; }
+    get approver2() { return this.form.controls.approver2; }
+    get time() { return this.form.controls.time; }
+    get type2() { return this.form.controls.type2; }
+    get items() { return this.form.controls.items as FormArray; }
+    //#endregion
+
+    add() {
+        this.items.push(this.createUser());
+        this.edit(this.items.length - 1);
+    }
+
+    del(index: number) {
+        this.items.removeAt(index);
+    }
+
+    edit(index: number) {
+        if (this.editIndex !== -1 && this.editObj) {
+            this.items.at(this.editIndex).patchValue(this.editObj);
+        }
+        this.editObj = { ...this.items.at(index).value };
+        this.editIndex = index;
+    }
+
+    save(index: number) {
+        this.items.at(index).markAsDirty();
+        if (this.items.at(index).invalid) return ;
+        this.editIndex = -1;
+    }
+
+    cancel(index: number) {
+        if (!this.items.at(index).value.key) {
+            this.del(index);
+        } else {
+            this.items.at(index).patchValue(this.editObj);
+        }
+        this.editIndex = -1;
+    }
+
+    _submitForm() {
+        console.log(this.form.value);
+        for (const i in this.form.controls) {
+            this.form.controls[ i ].markAsDirty();
+        }
+        if (this.form.invalid) return ;
+    }
+}
diff --git a/src/app/routes/pro/form/step-form/step-form.component.html b/src/app/routes/pro/form/step-form/step-form.component.html
new file mode 100644
index 0000000..a019205
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.html
@@ -0,0 +1,17 @@
+<pro-header [title]="'������������'">
+    <ng-template #content>������������������������������������������������������������������������������������������</ng-template>
+</pro-header>
+<nz-card [nzBordered]="false" [nzNoHovering]="true">
+    <ng-template #body>
+        <nz-steps [(nzCurrent)]="item.step">
+            <nz-step nzTitle="������������������"></nz-step>
+            <nz-step nzTitle="������������������"></nz-step>
+            <nz-step nzTitle="������"></nz-step>
+        </nz-steps>
+        <app-step1 *ngIf="item.step==0"></app-step1>
+        <app-step2 *ngIf="item.step==1"></app-step2>
+        <app-step3 *ngIf="item.step==2"></app-step3>
+    </ng-template>
+</nz-card>
+
+
diff --git a/src/app/routes/pro/form/step-form/step-form.component.less b/src/app/routes/pro/form/step-form/step-form.component.less
new file mode 100644
index 0000000..63c927c
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.less
@@ -0,0 +1,29 @@
+:host {
+	display: block;
+	::ng-deep {
+		.ant-steps {
+			max-width: 750px;
+			margin: 16px auto;
+        }
+
+        [nz-form] {
+            margin: 40px auto 0;
+            max-width: 500px;
+        }
+
+		app-step3 {
+			display: block;
+			text-align: center;
+			width: 72%;
+			max-width: 560px;
+			margin: 0 auto;
+		}
+
+		.extra {
+			background: #fafafa;
+			padding: 24px 40px;
+			border-radius: 2px;
+			text-align: left;
+		}
+	}
+}
diff --git a/src/app/routes/pro/form/step-form/step-form.component.ts b/src/app/routes/pro/form/step-form/step-form.component.ts
new file mode 100644
index 0000000..7ee6e30
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.ts
@@ -0,0 +1,17 @@
+import { Component, AfterViewInit, ViewEncapsulation } from '@angular/core';
+import { TransferService } from './transfer.service';
+
+@Component({
+    selector: 'app-step-form',
+    templateUrl: './step-form.component.html',
+    styleUrls: [ './step-form.component.less' ],
+    providers: [ TransferService ]
+})
+export class StepFormComponent implements AfterViewInit {
+
+    constructor(public item: TransferService) {}
+
+    ngAfterViewInit() {
+        console.log('item', this.item);
+    }
+}
diff --git a/src/app/routes/pro/form/step-form/step1.component.ts b/src/app/routes/pro/form/step-form/step1.component.ts
new file mode 100644
index 0000000..b6f255a
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step1.component.ts
@@ -0,0 +1,107 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { TransferService } from './transfer.service';
+
+@Component({
+    selector: 'app-step1',
+    template: `
+    <form nz-form [formGroup]="form" (ngSubmit)="_submitForm()">
+        <div nz-form-item nz-row>
+            <div nz-form-label nz-col [nzSm]="4">
+                <label for="pay_account" nz-form-item-required>������������</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="20">
+                <nz-select formControlName="pay_account" nzSize="large" nzId="pay_account">
+                    <nz-option [nzLabel]="item.pay_account" [nzValue]="item.pay_account"></nz-option>
+                </nz-select>
+            </div>
+        </div>
+        <div nz-form-item nz-row>
+            <div nz-form-label nz-col [nzSm]="4">
+                <label for="receiver_account" nz-form-item-required>������������</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="receiver_account">
+                <nz-input-group [nzCompact]="true">
+                    <nz-select formControlName="receiver_type" nzSize="large" style="width: 25%;">
+                        <nz-option [nzLabel]="'���������'" [nzValue]="'alipay'"></nz-option>
+                        <nz-option [nzLabel]="'������������'" [nzValue]="'bank'"></nz-option>
+                    </nz-select>
+                    <input formControlName="receiver_account" nzSize="large" id="'receiver_account'" nz-input style="width: 75%;">
+                </nz-input-group>
+                <p nz-form-explain *ngIf="(receiver_account.dirty || receiver_account.touched) && receiver_account.errors?.required">
+                    ���������������������
+                </p>
+            </div>
+        </div>
+        <div nz-form-item nz-row>
+            <div nz-form-label nz-col [nzSm]="4">
+                <label for="receiver_name" nz-form-item-required>������������</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="receiver_name">
+                <nz-input formControlName="receiver_name" nzSize="large" [nzId]="'receiver_name'"></nz-input>
+                <ng-container *ngIf="receiver_name.dirty || receiver_name.touched">
+                    <p nz-form-explain *ngIf="receiver_name.errors?.required">���������������������</p>
+                    <p nz-form-explain *ngIf="receiver_name.errors?.minlength">������2���������������</p>
+                </ng-container>
+            </div>
+        </div>
+        <div nz-form-item nz-row>
+            <div nz-form-label nz-col [nzSm]="4">
+                <label for="amount" nz-form-item-required>������������</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="amount">
+                <nz-input formControlName="amount" nzSize="large" [nzId]="'amount'">
+                    <ng-template #prefix>���</ng-template>
+                </nz-input>
+                <ng-container *ngIf="amount.dirty || amount.touched">
+                    <p nz-form-explain *ngIf="amount.errors?.required">���������������������</p>
+                    <p nz-form-explain *ngIf="amount.errors?.pattern">������������������������</p>
+                    <p nz-form-explain *ngIf="amount.errors?.min">������������1���������</p>
+                    <p nz-form-explain *ngIf="amount.errors?.max">������������100���������</p>
+                </ng-container>
+            </div>
+        </div>
+        <div nz-form-item nz-row>
+            <div nz-form-control nz-col [nzSpan]="20" [nzOffset]="4">
+                <button nz-button [nzType]="'primary'" nzSize="large" [disabled]="form.invalid">���������</button>
+            </div>
+        </div>
+    </form>
+    <div class="border-top-1 mt-lg px-lg text-grey-dark">
+        <h3 class="h3 my-md">������</h3>
+        <h4 class="h4 mb-sm">������������������������</h4>
+        <p class="mb-sm">������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
+        <h4 class="h4 mb-sm">������������������</h4>
+        <p>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
+    </div>
+    `
+})
+export class Step1Component implements OnInit {
+    form: FormGroup;
+
+    constructor(private fb: FormBuilder, public item: TransferService) {}
+
+    ngOnInit() {
+        this.form = this.fb.group({
+            pay_account: [null, Validators.compose([Validators.required, Validators.email])],
+            receiver_type: [null, [Validators.required]],
+            receiver_account: [null, [Validators.required]],
+            receiver_name: [null, Validators.compose([Validators.required, Validators.minLength(2)])],
+            amount: [null, Validators.compose([Validators.required, Validators.pattern(`[0-9]+`), Validators.min(1), Validators.max(10000 * 100)])]
+        });
+        this.form.patchValue(this.item);
+    }
+
+    //#region get form fields
+    get pay_account() { return this.form.controls['pay_account']; }
+    get receiver_type() { return this.form.controls['receiver_type']; }
+    get receiver_account() { return this.form.controls['receiver_account']; }
+    get receiver_name() { return this.form.controls['receiver_name']; }
+    get amount() { return this.form.controls['amount']; }
+    //#endregion
+
+    _submitForm() {
+        this.item = Object.assign(this.item, this.form.value);
+        ++this.item.step;
+    }
+}
diff --git a/src/app/routes/pro/form/step-form/step2.component.ts b/src/app/routes/pro/form/step-form/step2.component.ts
new file mode 100644
index 0000000..8f4fa03
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step2.component.ts
@@ -0,0 +1,81 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { TransferService } from './transfer.service';
+
+@Component({
+    selector: 'app-step2',
+    template: `
+    <form nz-form [formGroup]="form" (ngSubmit)="_submitForm()">
+        <nz-alert class="pb-lg" [nzMessage]="'���������������������������������������������������������������������'" [nzShowIcon]="true" [nzCloseable]="true"></nz-alert>
+        <div nz-form-item nz-row class="mb-sm">
+            <div nz-form-label nz-col [nzSm]="4"><label>������������</label></div>
+            <div nz-form-control nz-col [nzSm]="20"><span nz-form-text>{{item.pay_account}}</span></div>
+        </div>
+        <div nz-form-item nz-row class="mb-sm">
+            <div nz-form-label nz-col [nzSm]="4"><label>������������</label></div>
+            <div nz-form-control nz-col [nzSm]="20"><span nz-form-text>{{item.receiver_type==='alipay' ? '���������' : '������'}}</span></div>
+        </div>
+        <div nz-form-item nz-row class="mb-sm">
+            <div nz-form-label nz-col [nzSm]="4"><label>������������</label></div>
+            <div nz-form-control nz-col [nzSm]="20"><span nz-form-text>{{item.receiver_account}}</span></div>
+        </div>
+        <div nz-form-item nz-row class="mb-sm">
+            <div nz-form-label nz-col [nzSm]="4"><label>���������������</label></div>
+            <div nz-form-control nz-col [nzSm]="20"><span nz-form-text>{{item.receiver_name}}</span></div>
+        </div>
+        <div nz-form-item nz-row class="mb-sm">
+            <div nz-form-label nz-col [nzSm]="4"><label>������������</label></div>
+            <div nz-form-control nz-col [nzSm]="20">
+                <strong class="text-lg" nz-form-text>{{item.amount}}</strong>
+            </div>
+        </div>
+        <div nz-form-item nz-row class="border-top-1 mt-lg pt-lg">
+            <div nz-form-label nz-col [nzSm]="4">
+                <label for="password" nz-form-item-required>������������</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="20" nzHasFeedback [nzValidateStatus]="password">
+                <nz-input formControlName="password" nzSize="large" nzType="password" nzId="password"></nz-input>
+                <ng-container *ngIf="password.dirty || password.touched">
+                    <p nz-form-explain *ngIf="password.errors?.required">���������������</p>
+                    <p nz-form-explain *ngIf="password.errors?.minlength">������6������������</p>
+                </ng-container>
+            </div>
+        </div>
+        <div nz-form-item nz-row>
+            <div nz-form-control nz-col [nzSpan]="20" [nzOffset]="4">
+                <button nz-button [nzType]="'primary'" nzSize="large" [nzLoading]="loading" [disabled]="form.invalid">������</button>
+                <button nz-button (click)="prev()" nzSize="large">���������</button>
+            </div>
+        </div>
+    </form>
+    `
+})
+export class Step2Component implements OnInit {
+    form: FormGroup;
+    loading = false;
+
+    constructor(private fb: FormBuilder, public item: TransferService) {}
+
+    ngOnInit() {
+        this.form = this.fb.group({
+            password: [null, Validators.compose([Validators.required, Validators.minLength(6)])]
+        });
+        this.form.patchValue(this.item);
+    }
+
+    //#region get form fields
+    get password() { return this.form.controls.password; }
+    //#endregion
+
+    _submitForm() {
+        this.loading = true;
+        setTimeout(() => {
+            this.loading = false;
+            ++this.item.step;
+        }, 1000 * 2);
+    }
+
+    prev() {
+        --this.item.step;
+    }
+}
diff --git a/src/app/routes/pro/form/step-form/step3.component.ts b/src/app/routes/pro/form/step-form/step3.component.ts
new file mode 100644
index 0000000..ee2c386
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step3.component.ts
@@ -0,0 +1,42 @@
+import { Component } from '@angular/core';
+import { TransferService } from './transfer.service';
+
+@Component({
+    selector: 'app-step3',
+    template: `
+    <div class="icon pt-md"><i class="anticon anticon-check-circle text-success icon-lg"></i></div>
+    <h1 class="h2 pt-md">������������</h1>
+    <p class="pt-md text-grey">������������������������</p>
+    <div class="extra mt-md">
+        <div nz-row class="mb-md">
+            <div nz-col [nzSm]="8" class="text-right">���������������</div>
+            <div nz-col [nzSm]="16">{{item.pay_account}}</div>
+        </div>
+        <div nz-row class="mb-md">
+            <div nz-col [nzSm]="8" class="text-right">���������������</div>
+            <div nz-col [nzSm]="16">{{item.receiver_type_str}}</div>
+        </div>
+        <div nz-row class="mb-md">
+            <div nz-col [nzSm]="8" class="text-right">���������������</div>
+            <div nz-col [nzSm]="16">{{item.receiver_account}}</div>
+        </div>
+        <div nz-row class="mb-md">
+            <div nz-col [nzSm]="8" class="text-right">������������������</div>
+            <div nz-col [nzSm]="16">{{item.receiver_name}}</div>
+        </div>
+        <div nz-row>
+            <div nz-col [nzSm]="8" class="text-right">���������������</div>
+            <div nz-col [nzSm]="16"><strong class="text-lg pr-sm">{{item.amount}}</strong>���</div>
+        </div>
+    </div>
+    <div nz-row class="my-md py-md">
+        <div nz-col>
+            <button nz-button (click)="item.again()" nzSize="large" [nzType]="'primary'">������������</button>
+            <button nz-button nzSize="large" class="ml-sm">������������</button>
+        </div>
+    </div>
+    `
+})
+export class Step3Component {
+    constructor(public item: TransferService) {}
+}
diff --git a/src/app/routes/pro/form/step-form/transfer.service.ts b/src/app/routes/pro/form/step-form/transfer.service.ts
new file mode 100644
index 0000000..827964e
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/transfer.service.ts
@@ -0,0 +1,54 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class TransferService {
+
+    step: 0 | 1 | 2 = 1;
+
+    /**
+     * ������������
+     */
+    pay_account: string;
+
+    /**
+     * ������������������
+     */
+    receiver_type: 'alipay' | 'bank';
+
+    get receiver_type_str() {
+        return this.receiver_type === 'alipay' ? '���������' : '������';
+    }
+
+    /**
+     * ������������
+     */
+    receiver_account: string;
+
+    /**
+     * ������������
+     */
+    receiver_name: string;
+
+    /**
+     * ������
+     */
+    amount: number;
+
+    /**
+     * ������������
+     */
+    password = '123456';
+
+    again() {
+        this.step = 0;
+        this.pay_account = 'ant-design@alipay.com';
+        this.receiver_type = 'alipay';
+        this.receiver_account = 'test@example.com';
+        this.receiver_name = 'asdf';
+        this.amount = 500;
+    }
+
+    constructor() {
+        this.again();
+    }
+}
diff --git a/src/app/routes/pro/list/basic-list/basic-list.component.html b/src/app/routes/pro/list/basic-list/basic-list.component.html
new file mode 100644
index 0000000..8eb4d70
--- /dev/null
+++ b/src/app/routes/pro/list/basic-list/basic-list.component.html
@@ -0,0 +1,88 @@
+<pro-header></pro-header>
+<nz-card [nzBordered]="false">
+    <div nz-row>
+        <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+            <p class="text-grey-dark">������������</p>
+            <p class="display-2">8���������</p>
+            <em></em>
+        </div>
+        <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+            <p class="text-grey-dark">������������������������������</p>
+            <p class="display-2">32������</p>
+            <em></em>
+        </div>
+        <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+            <p class="text-grey-dark">���������������������</p>
+            <p class="display-2">24���������</p>
+        </div>
+    </div>
+</nz-card>
+<nz-card [nzBordered]="false">
+    <div class="d-flex align-items-center mb-lg">
+        <h3 class="flex-1 text-lg">������������</h3>
+        <div>
+            <nz-radio-group [(ngModel)]="q.status" [nzSize]="'large'" class="mr-md">
+                <label nz-radio-button [nzValue]="'all'">
+                    <span>������</span>
+                </label>
+                <label nz-radio-button [nzValue]="'progress'">
+                    <span>���������</span>
+                </label>
+                <label nz-radio-button [nzValue]="'waiting'">
+                    <span>���������</span>
+                </label>
+            </nz-radio-group>
+            <nz-input [nzType]="'search'" [nzPlaceHolder]="'���������'" [(ngModel)]="q.q" [nzSize]="'large'" style="width: 272px"></nz-input>
+        </div>
+    </div>
+    <button nz-button (click)="msg.success('add')" [nzType]="'dashed'" [nzSize]="'large'" class="ant-btn__block mb-sm">
+        <i class="anticon anticon-plus"></i><span>������</span>
+    </button>
+    <nz-list [nzDataSource]="data" [nzLoading]="loading">
+        <ng-template #item let-item>
+            <nz-list-item [nzContent]="nzContent">
+                <nz-list-item-action><a (click)="msg.success('���������' + item.title)">������</a></nz-list-item-action>
+                <nz-list-item-action>
+                    <nz-dropdown>
+                        <a class="ant-dropdown-link" nz-dropdown>
+                            ������ <i class="anticon anticon-down"></i>
+                        </a>
+                        <ul nz-menu>
+                            <li nz-menu-item (click)="msg.success('���������' + item.title)">������</li>
+                            <li nz-menu-item (click)="msg.success('���������' + item.title)">������</li>
+                        </ul>
+                    </nz-dropdown>
+                </nz-list-item-action>
+                <nz-list-item-meta
+                    [nzTitle]="nzTitle"
+                    [nzDescription]="item.subDescription"
+                    [nzAvatar]="nzAvatar">
+                    <ng-template #nzTitle>
+                        <a href="{{item.href" target="_blank">{{item.title}}</a>
+                    </ng-template>
+                    <ng-template #nzAvatar>
+                        <nz-avatar [nzSrc]="item.logo" [nzSize]="'large'" [nzShape]="'square'"></nz-avatar>
+                    </ng-template>
+                </nz-list-item-meta>
+                <ng-template #nzContent>
+                    <div class="width-md">
+                        <div class="d-flex text-grey-dark">
+                            <div class="flex-1">
+                                Owner
+                                <p>{{item.owner}}</p>
+                            </div>
+                            <div class="text-right">
+                                ������������
+                                <p>{{item.createdAt | _date}}</p>
+                            </div>
+                        </div>
+                        <nz-progress [ngModel]="item.percent" [nzStatus]="item.status" [nzStrokeWidth]="6"></nz-progress>
+                    </div>
+                </ng-template>
+            </nz-list-item>
+        </ng-template>
+        <ng-template #pagination>
+            <nz-pagination [nzTotal]="50" [nzPageSize]="5" [nzSize]="'large'" (nzPageIndexChange)="getData()"></nz-pagination>
+        </ng-template>
+    </nz-list>
+</nz-card>
diff --git a/src/app/routes/pro/list/basic-list/basic-list.component.less b/src/app/routes/pro/list/basic-list/basic-list.component.less
new file mode 100644
index 0000000..66c0e84
--- /dev/null
+++ b/src/app/routes/pro/list/basic-list/basic-list.component.less
@@ -0,0 +1,21 @@
+.header-info {
+    position: relative;
+    text-align: center;
+    > em {
+        background-color: #e8e8e8;
+        position: absolute;
+        height: 56px;
+        width: 1px;
+        top: 0;
+        right: 0;
+    }
+}
+
+@media screen and (max-width: 576px) {
+    .header-info {
+        margin-bottom: 16px;
+        > em {
+            display: none;
+        }
+    }
+}
diff --git a/src/app/routes/pro/list/basic-list/basic-list.component.ts b/src/app/routes/pro/list/basic-list/basic-list.component.ts
new file mode 100644
index 0000000..e97af3e
--- /dev/null
+++ b/src/app/routes/pro/list/basic-list/basic-list.component.ts
@@ -0,0 +1,30 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getFakeList } from '../../../../../../_mock/api.service';
+
+@Component({
+    selector: 'pro-basic-list',
+    templateUrl: './basic-list.component.html',
+    styleUrls: [ './basic-list.component.less' ]
+})
+export class ProBasicListComponent implements OnInit {
+    q: any = {
+        status: 'all'
+    };
+    loading = false;
+    data: any[] = [];
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.getData();
+    }
+
+    getData() {
+        this.loading = true;
+        setTimeout(() => {
+            this.data = getFakeList(5);
+            this.loading = false;
+        }, 1000);
+    }
+}
diff --git a/src/app/routes/pro/list/card-list/card-list.component.html b/src/app/routes/pro/list/card-list/card-list.component.html
new file mode 100644
index 0000000..6b1e69f
--- /dev/null
+++ b/src/app/routes/pro/list/card-list/card-list.component.html
@@ -0,0 +1,44 @@
+<pro-header [title]="'������������'">
+    <ng-template #extra>
+        <div style="margin-top: -60px; text-align: center; width: 195px;">
+            <img class="img-fluid" src="https://gw.alipayobjects.com/zos/rmsportal/RzwpdLnhmvDJToTdfDPe.png">
+        </div>
+    </ng-template>
+    <ng-template #content>
+        <p>������������������������������������������ ant.design���������������������������������������������������������������������������������������������������������������</p>
+        <div class="d-flex pt-md">
+            <a class="d-flex pr-lg">
+                <img class="pr-sm" src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg" />������������
+            </a>
+            <a class="d-flex pr-lg">
+                <img class="pr-sm" src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg" />������������
+            </a>
+            <a class="d-flex">
+                <img class="pr-sm" src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg" />������������
+            </a>
+        </div>
+    </ng-template>
+</pro-header>
+<nz-list [nzLoading]="loading" [nzDataSource]="list"
+         [nzGrid]="{gutter: 24, lg: 8, md: 12, sm: 24, xs: 24 }">
+    <ng-template #item let-item>
+        <nz-list-item>
+            <button *ngIf="item === null" nz-button (click)="msg.success('add')" [nzType]="'dashed'" style="width: 100%; height: 183px;">
+                <i class="anticon anticon-plus"></i><span>������������</span>
+            </button>
+            <nz-card nzHoverable *ngIf="item !== null">
+                <nz-card-action><a (click)="msg.success('������������' + item.id);">���������</a></nz-card-action>
+                <nz-card-action><a (click)="msg.success('������������' + item.id);">���������</a></nz-card-action>
+                <nz-card-meta
+                    [nzAvatar]="item.avatar"
+                    [nzTitle]="nzTitle"
+                    [nzDescription]="nzDescription">
+                    <ng-template #nzTitle><a (click)="msg.success('���������' + item.id);">{{item.title}}</a></ng-template>
+                    <ng-template #nzDescription>
+                        <ellipsis>{{item.description}}</ellipsis>
+                    </ng-template>
+                </nz-card-meta>
+            </nz-card>
+        </nz-list-item>
+    </ng-template>
+</nz-list>
diff --git a/src/app/routes/pro/list/card-list/card-list.component.ts b/src/app/routes/pro/list/card-list/card-list.component.ts
new file mode 100644
index 0000000..9c810cf
--- /dev/null
+++ b/src/app/routes/pro/list/card-list/card-list.component.ts
@@ -0,0 +1,29 @@
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getFakeList } from '../../../../../../_mock/api.service';
+
+@Component({
+    selector: 'pro-list-card-list',
+    templateUrl: './card-list.component.html',
+    styles: [`
+    :host ::ng-deep .ant-card-meta-title {
+        margin-bottom: 12px;
+    }
+    `],
+    encapsulation: ViewEncapsulation.Emulated
+})
+export class ProCardListComponent implements OnInit {
+
+    list: any[] = [ null ];
+
+    loading = true;
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        setTimeout(() => {
+            this.list = this.list.concat(getFakeList(8));
+            this.loading = false;
+        }, 1000);
+    }
+}
diff --git a/src/app/routes/pro/list/cover-card-list/cover-card-list.component.html b/src/app/routes/pro/list/cover-card-list/cover-card-list.component.html
new file mode 100644
index 0000000..b617e9f
--- /dev/null
+++ b/src/app/routes/pro/list/cover-card-list/cover-card-list.component.html
@@ -0,0 +1,76 @@
+<pro-header [title]="'������������'">
+    <ng-template #content>
+        <div class="text-center">
+            <nz-input [nzType]="'search'" [nzSize]="'large'" [nzPlaceHolder]="'���������'" style="width: 520px;"></nz-input>
+        </div>
+    </ng-template>
+    <ng-template #tab>
+        <nz-tabset [nzSize]="'default'" [nzSelectedIndex]="2">
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/search']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/filter-card-list']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/cover-card-list']">������</a></ng-template></nz-tab>
+        </nz-tabset>
+    </ng-template>
+</pro-header>
+<nz-card [nzBordered]="false">
+    <form nz-form [nzLayout]="'inline'">
+        <standard-form-row [title]="'������������'" block style="padding-bottom: 11px">
+            <div nz-form-item>
+                <div nz-form-control>
+                    <tag-select>
+                        <nz-checkable-tag *ngFor="let i of categories; let idx = index" [nzChecked]="i.value" (nzChange)="changeCategory($event, idx)">
+                            {{i.text}}
+                        </nz-checkable-tag>
+                    </tag-select>
+                </div>
+            </div>
+        </standard-form-row>
+        <standard-form-row [title]="'������������'" grid last>
+            <div nz-row [nzGutter]="16">
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">������������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'������'" [nzValue]="'lisa'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">���������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </standard-form-row>
+    </form>
+</nz-card>
+<nz-list [nzLoading]="loading" [nzDataSource]="list"
+         [nzGrid]="{gutter: 24, lg: 6, md: 8, sm: 12, xs: 24 }">
+    <ng-template #item let-item>
+        <nz-list-item>
+            <nz-card nzHoverable>
+                <ng-template #cover><img alt="{{item.title}}" src="{{item.cover}}"></ng-template>
+                <nz-card-meta
+                    [nzTitle]="nzTitle"
+                    [nzDescription]="item.subDescription">
+                    <ng-template #nzTitle><a (click)="msg.success('���������' + item.id);">{{item.title}}</a></ng-template>
+                </nz-card-meta>
+                <div class="card-item-content">
+                    <span class="text-grey">{{item.updatedAt}}</span>
+                    <avatar-list size="mini">
+                        <avatar-list-item *ngFor="let m of item.members"
+                                            [src]="m.avatar"
+                                            [tips]="m.name"></avatar-list-item>
+                    </avatar-list>
+                </div>
+            </nz-card>
+        </nz-list-item>
+    </ng-template>
+</nz-list>
diff --git a/src/app/routes/pro/list/cover-card-list/cover-card-list.component.ts b/src/app/routes/pro/list/cover-card-list/cover-card-list.component.ts
new file mode 100644
index 0000000..39b3ab8
--- /dev/null
+++ b/src/app/routes/pro/list/cover-card-list/cover-card-list.component.ts
@@ -0,0 +1,81 @@
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import * as moment from 'moment';
+import { getFakeList } from '../../../../../../_mock/api.service';
+
+@Component({
+    selector: 'pro-list-cover-card-list',
+    templateUrl: './cover-card-list.component.html',
+    styles: [`
+    :host ::ng-deep .ant-card-meta-title {
+        margin-bottom: 4px;
+    }
+    :host ::ng-deep nz-list nz-card {
+        margin-bottom: 0 !important;
+    }
+    :host ::ng-deep .card-item-content {
+        display: flex;
+        margin-top: 16px;
+        margin-bottom: -4px;
+        line-height: 20px;
+        height: 20px;
+        justify-content: space-between;
+    }
+    `],
+    encapsulation: ViewEncapsulation.Emulated
+})
+export class ProCoverCardListComponent implements OnInit {
+    q: any = {
+        ps: 8,
+        categories: [],
+        owners: [ 'zxx' ]
+    };
+
+    list: any[] = [ ];
+
+    loading = true;
+
+    // region: cateogry
+    categories = [
+        { id: 0, text: '������', value: false },
+        { id: 1, text: '���������', value: false },
+        { id: 2, text: '���������', value: false },
+        { id: 3, text: '���������', value: false },
+        { id: 4, text: '���������', value: false },
+        { id: 5, text: '���������', value: false },
+        { id: 6, text: '���������', value: false },
+        { id: 7, text: '���������', value: false },
+        { id: 8, text: '���������', value: false },
+        { id: 9, text: '���������', value: false },
+        { id: 10, text: '���������', value: false },
+        { id: 11, text: '������������', value: false },
+        { id: 12, text: '������������', value: false }
+    ];
+
+    changeCategory(status: boolean, idx: number) {
+        if (idx === 0) {
+            this.categories.map(i => i.value = status);
+        } else {
+            this.categories[idx].value = status;
+        }
+        this.getData();
+    }
+    // endregion
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.getData();
+    }
+
+    getData() {
+        this.loading = true;
+        setTimeout(() => {
+            this.list = this.list.concat(getFakeList(this.q.ps)).map(item => {
+                if (item.updatedAt) item.updatedAt = moment(item.updatedAt).fromNow();
+                return item;
+            });
+            this.loading = false;
+        }, 1000);
+    }
+}
diff --git a/src/app/routes/pro/list/filter-card-list/filter-card-list.component.html b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.html
new file mode 100644
index 0000000..d0c3f9f
--- /dev/null
+++ b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.html
@@ -0,0 +1,92 @@
+<pro-header [title]="'������������'">
+    <ng-template #content>
+        <div class="text-center">
+            <nz-input [nzType]="'search'" [nzSize]="'large'" [nzPlaceHolder]="'���������'" style="width: 520px;"></nz-input>
+        </div>
+    </ng-template>
+    <ng-template #tab>
+        <nz-tabset [nzSize]="'default'" [nzSelectedIndex]="1">
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/search']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/filter-card-list']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/cover-card-list']">������</a></ng-template></nz-tab>
+        </nz-tabset>
+    </ng-template>
+</pro-header>
+<nz-card [nzBordered]="false">
+    <form nz-form [nzLayout]="'inline'">
+        <standard-form-row [title]="'������������'" block style="padding-bottom: 11px">
+            <div nz-form-item>
+                <div nz-form-control>
+                    <tag-select>
+                        <nz-checkable-tag *ngFor="let i of categories; let idx = index" [nzChecked]="i.value" (nzChange)="changeCategory($event, idx)">
+                            {{i.text}}
+                        </nz-checkable-tag>
+                    </tag-select>
+                </div>
+            </div>
+        </standard-form-row>
+        <standard-form-row [title]="'������������'" grid last>
+            <div nz-row [nzGutter]="16">
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'���������'" [nzValue]="'lisa'"></nz-option>
+                                <nz-option [nzLabel]="'������'" [nzValue]="'libai'"></nz-option>
+                                <nz-option [nzLabel]="'������'" [nzValue]="'daji'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">���������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+                                <nz-option [nzLabel]="'������'" [nzValue]="'normal'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </standard-form-row>
+    </form>
+</nz-card>
+<nz-list [nzLoading]="loading" [nzDataSource]="list"
+         [nzGrid]="{gutter: 24, lg: 6, md: 6, sm: 8, xs: 12 }">
+    <ng-template #item let-item>
+        <nz-list-item>
+            <nz-card nzHoverable>
+                <nz-card-action>
+                    <nz-tooltip [nzTitle]="'������'"><i nz-tooltip class="anticon anticon-download"></i></nz-tooltip>
+                </nz-card-action>
+                <nz-card-action>
+                    <nz-tooltip [nzTitle]="'������'"><i nz-tooltip class="anticon anticon-edit"></i></nz-tooltip>
+                </nz-card-action>
+                <nz-card-action>
+                    <nz-tooltip [nzTitle]="'������'"><i nz-tooltip class="anticon anticon-share-alt"></i></nz-tooltip>
+                </nz-card-action>
+                <nz-card-action>
+                    <nz-dropdown [nzPlacement]="'bottomLeft'">
+                        <i nz-dropdown class="anticon anticon-ellipsis"></i>
+                        <ul nz-menu>
+                            <li nz-menu-item>1st menu item</li>
+                            <li nz-menu-item>2st menu item</li>
+                            <li nz-menu-item>3st menu item</li>
+                        </ul>
+                    </nz-dropdown>
+                </nz-card-action>
+                <nz-card-meta
+                    [nzTitle]="item.title"
+                    [nzAvatar]="item.avatar">
+                </nz-card-meta>
+                <div class="card-info d-flex">
+                    <div><p>������������</p><p [innerHTML]="item.activeUser"></p></div>
+                    <div><p>������������</p><p>{{item.newUser | number: '3.'}}</p></div>
+                </div>
+            </nz-card>
+        </nz-list-item>
+    </ng-template>
+</nz-list>
diff --git a/src/app/routes/pro/list/filter-card-list/filter-card-list.component.less b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.less
new file mode 100644
index 0000000..f9b29cb
--- /dev/null
+++ b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.less
@@ -0,0 +1,35 @@
+:host ::ng-deep {
+	nz-list nz-card {
+		margin-bottom: 0 !important;
+		width: 100%;
+	}
+	.card-info {
+		zoom: 1;
+		margin-top: 16px;
+		margin-left: 40px;
+		& > div {
+			position: relative;
+			text-align: left;
+			float: left;
+			width: 50%;
+			p {
+				line-height: 32px;
+				font-size: 24px;
+				em {
+					position: relative;
+					top: -2px;
+					font-size: 14px;
+					font-style: normal;
+					line-height: 20px;
+					margin-left: 2px;
+				}
+			}
+			p:first-child {
+                color: rgba(0, 0, 0, 0.45);
+				font-size: 12px;
+				line-height: 20px;
+				margin-bottom: 4px;
+			}
+		}
+	}
+}
diff --git a/src/app/routes/pro/list/filter-card-list/filter-card-list.component.ts b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.ts
new file mode 100644
index 0000000..c15df86
--- /dev/null
+++ b/src/app/routes/pro/list/filter-card-list/filter-card-list.component.ts
@@ -0,0 +1,80 @@
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import * as moment from 'moment';
+import { getFakeList } from '../../../../../../_mock/api.service';
+
+@Component({
+    selector: 'pro-list-filter-card-list',
+    templateUrl: './filter-card-list.component.html',
+    styleUrls: [ './filter-card-list.component.less' ],
+    encapsulation: ViewEncapsulation.Emulated
+})
+export class ProFilterCardListComponent implements OnInit {
+    q: any = {
+        ps: 8,
+        categories: [],
+        owners: [ 'zxx' ]
+    };
+
+    list: any[] = [ ];
+
+    loading = true;
+
+    // region: cateogry
+    categories = [
+        { id: 0, text: '������', value: false },
+        { id: 1, text: '���������', value: false },
+        { id: 2, text: '���������', value: false },
+        { id: 3, text: '���������', value: false },
+        { id: 4, text: '���������', value: false },
+        { id: 5, text: '���������', value: false },
+        { id: 6, text: '���������', value: false },
+        { id: 7, text: '���������', value: false },
+        { id: 8, text: '���������', value: false },
+        { id: 9, text: '���������', value: false },
+        { id: 10, text: '���������', value: false },
+        { id: 11, text: '������������', value: false },
+        { id: 12, text: '������������', value: false }
+    ];
+
+    changeCategory(status: boolean, idx: number) {
+        if (idx === 0) {
+            this.categories.map(i => i.value = status);
+        } else {
+            this.categories[idx].value = status;
+        }
+        this.getData();
+    }
+    // endregion
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.getData();
+    }
+
+    getData() {
+        this.loading = true;
+        setTimeout(() => {
+            this.list = this.list.concat(getFakeList(this.q.ps)).map(item => {
+                if (item.updatedAt) item.updatedAt = moment(item.updatedAt).fromNow();
+                item.activeUser = this.formatWan(item.activeUser);
+                return item;
+            });
+            this.loading = false;
+        }, 1000);
+    }
+
+
+    private formatWan(val) {
+        const v = val * 1;
+        if (!v || isNaN(v)) return '';
+
+        let result = val;
+        if (val > 10000) {
+            result = Math.floor(val / 10000);
+            result = `${result}<em>���</em>`;
+        }
+        return result;
+    }
+}
diff --git a/src/app/routes/pro/list/search/search.component.html b/src/app/routes/pro/list/search/search.component.html
new file mode 100644
index 0000000..7ee7cd8
--- /dev/null
+++ b/src/app/routes/pro/list/search/search.component.html
@@ -0,0 +1,100 @@
+<pro-header [title]="'������������'">
+    <ng-template #content>
+        <div class="text-center">
+            <nz-input [nzType]="'search'" [nzSize]="'large'" [nzPlaceHolder]="'���������'" style="width: 520px;"></nz-input>
+        </div>
+    </ng-template>
+    <ng-template #tab>
+        <nz-tabset [nzSize]="'default'" [nzSelectedIndex]="0">
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/search']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/filter-card-list']">������</a></ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading><a [routerLink]="['/pro/list/cover-card-list']">������</a></ng-template></nz-tab>
+        </nz-tabset>
+    </ng-template>
+</pro-header>
+<nz-card [nzBordered]="false">
+    <form nz-form [nzLayout]="'inline'">
+        <standard-form-row [title]="'������������'" block style="padding-bottom: 11px">
+            <div nz-form-item>
+                <div nz-form-control>
+                    <tag-select>
+                        <nz-checkable-tag *ngFor="let i of categories; let idx = index" [nzChecked]="i.value" (nzChange)="changeCategory($event, idx)">
+                            {{i.text}}
+                        </nz-checkable-tag>
+                    </tag-select>
+                </div>
+            </div>
+        </standard-form-row>
+        <standard-form-row [title]="'owner'" grid>
+            <div nz-form-item>
+                <div nz-form-control>
+                    <nz-select [(ngModel)]="q.owners" name="owners" [nzSize]="'large'" [nzMode]="'tags'" style="width: 286px;">
+                        <nz-option *ngFor="let i of owners" [nzLabel]="i.name" [nzValue]="i.id"></nz-option>
+                    </nz-select>
+                    <a class="ml-sm" (click)="setOwner()">���������������</a>
+                </div>
+            </div>
+        </standard-form-row>
+        <standard-form-row [title]="'������������'" grid last>
+            <div nz-row [nzGutter]="16">
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">������������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'������'" [nzValue]="'lisa'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+                    <div nz-form-item nz-row>
+                        <div nz-form-label nz-col><label for="rate">���������</label></div>
+                        <div nz-form-control nz-col nzXs="24" nzSm="24" nzMd="12">
+                            <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" [nzSize]="'large'" style="width: 200px;">
+                                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+                            </nz-select>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </standard-form-row>
+    </form>
+</nz-card>
+<nz-card [nzBordered]="false">
+    <nz-list
+        nzSize="large"
+        nzItemLayout="vertical"
+        [nzLoading]="loading"
+        [nzDataSource]="list">
+        <ng-template #item let-item>
+            <nz-list-item [nzContent]="nzContent" [nzExtra]="nzExtra">
+                <nz-list-item-action><i class="anticon anticon-star-o mr-sm"></i>{{item.star}}</nz-list-item-action>
+                <nz-list-item-action><i class="anticon anticon-like-o mr-sm"></i>{{item.like}}</nz-list-item-action>
+                <nz-list-item-action><i class="anticon anticon-message mr-sm"></i>{{item.message}}</nz-list-item-action>
+                <ng-template #nzExtra><div style="width: 272px; height: 1px;"></div></ng-template>
+                <nz-list-item-meta [nzTitle]="nzTitle" [nzDescription]="nzDescription">
+                    <ng-template #nzTitle><a href="{{item.href}}" target="_blank">{{item.title}}</a></ng-template>
+                    <ng-template #nzDescription>
+                        <nz-tag>Alain</nz-tag><nz-tag>ng-zorro-antd</nz-tag><nz-tag>Ant Design</nz-tag>
+                    </ng-template>
+                </nz-list-item-meta>
+                <ng-template #nzContent>
+                    <p>{{item.content}}</p>
+                    <div class="mt-md d-flex">
+                        <nz-avatar [nzSrc]="item.avatar" [nzSize]="'small'" class="mr-sm"></nz-avatar>
+                        <a href="{{item.href}}" target="_blank">{{item.owner}}</a>
+                        <span class="px-sm">���������</span>
+                        <a href="{{item.href}}" target="_blank">{{item.href}}</a>
+                        <time class="pl-md text-grey" title="{{item.updatedAt}}">{{item.updatedAt | _date}}</time>
+                    </div>
+                </ng-template>
+            </nz-list-item>
+        </ng-template>
+        <ng-template #loadMore>
+            <div class="text-center mt-md">
+                <button nz-button (click)="getData()" [nzLoading]="loading" [nzType]="'dashed'" [nzSize]="'large'" style="min-width:200px">������������</button>
+            </div>
+        </ng-template>
+    </nz-list>
+</nz-card>
diff --git a/src/app/routes/pro/list/search/search.component.less b/src/app/routes/pro/list/search/search.component.less
new file mode 100644
index 0000000..e4e73c4
--- /dev/null
+++ b/src/app/routes/pro/list/search/search.component.less
@@ -0,0 +1,4 @@
+@import '"~@delon/theme/styles/antd/themes/default.less';
+
+:host {
+}
diff --git a/src/app/routes/pro/list/search/search.component.ts b/src/app/routes/pro/list/search/search.component.ts
new file mode 100644
index 0000000..27109aa
--- /dev/null
+++ b/src/app/routes/pro/list/search/search.component.ts
@@ -0,0 +1,85 @@
+import { Component, ViewEncapsulation, OnInit } from '@angular/core';
+import { getFakeList } from '../../../../../../_mock/api.service';
+
+@Component({
+    selector: 'pro-list-search',
+    templateUrl: './search.component.html',
+    styleUrls: ['./search.component.less']
+})
+export class ProSearchComponent implements OnInit {
+    q: any = {
+        ps: 5,
+        categories: [],
+        owners: [ 'zxx' ]
+    };
+
+    list: any[] = [];
+    loading = false;
+
+    // region: cateogry
+    categories = [
+        { id: 0, text: '������', value: false },
+        { id: 1, text: '���������', value: false },
+        { id: 2, text: '���������', value: false },
+        { id: 3, text: '���������', value: false },
+        { id: 4, text: '���������', value: false },
+        { id: 5, text: '���������', value: false },
+        { id: 6, text: '���������', value: false },
+        { id: 7, text: '���������', value: false },
+        { id: 8, text: '���������', value: false },
+        { id: 9, text: '���������', value: false },
+        { id: 10, text: '���������', value: false },
+        { id: 11, text: '������������', value: false },
+        { id: 12, text: '������������', value: false }
+    ];
+
+    changeCategory(status: boolean, idx: number) {
+        if (idx === 0) {
+            this.categories.map(i => i.value = status);
+        } else {
+            this.categories[idx].value = status;
+        }
+    }
+    // endregion
+
+    // region: owners
+    owners = [
+        {
+            id: 'wzj',
+            name: '���������',
+        },
+        {
+            id: 'wjh',
+            name: '���������',
+        },
+        {
+            id: 'zxx',
+            name: '���������',
+        },
+        {
+            id: 'zly',
+            name: '���������',
+        },
+        {
+            id: 'ym',
+            name: '������',
+        }
+    ];
+
+    setOwner() {
+        this.q.owners = [`wzj`];
+    }
+    // endregion
+
+    ngOnInit() {
+        this.getData();
+    }
+
+    getData() {
+        this.loading = true;
+        setTimeout(() => {
+            this.list = this.list.concat(getFakeList(this.q.ps));
+            this.loading = false;
+        }, 500);
+    }
+}
diff --git a/src/app/routes/pro/list/table-list/table-list.component.html b/src/app/routes/pro/list/table-list/table-list.component.html
new file mode 100644
index 0000000..5c40e1e
--- /dev/null
+++ b/src/app/routes/pro/list/table-list/table-list.component.html
@@ -0,0 +1,162 @@
+<pro-header [title]="'������������'"></pro-header>
+<nz-card [nzBordered]="false">
+    <form nz-form (ngSubmit)="getData()" [nzLayout]="'inline'">
+        <div nz-row [nzGutter]="24">
+            <div nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="no">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-input [(ngModel)]="q.no" name="no" [nzSize]="'large'" [nzPlaceHolder]="'���������'" nzId="no"></nz-input>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="status">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-select [(ngModel)]="q.status" name="status" nzId="status" [nzPlaceHolder]="'���������'" [nzShowSearch]="true" [nzSize]="'large'">
+                            <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+                        </nz-select>
+                    </div>
+                </div>
+            </div>
+            <div *ngIf="expandForm" nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="callNo">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-input [nzSize]="'large'" nzId="callNo"></nz-input>
+                    </div>
+                </div>
+            </div>
+            <div *ngIf="expandForm" nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="updatedAt">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-datepicker [nzSize]="'large'" [nzPlaceHolder]="'���������������������'" nzId="updatedAt" class="d-block"></nz-datepicker>
+                    </div>
+                </div>
+            </div>
+            <div *ngIf="expandForm" nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="status2">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-select [nzPlaceHolder]="'���������'" nzId="status2" [nzShowSearch]="true" [nzSize]="'large'">
+                            <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+                        </nz-select>
+                    </div>
+                </div>
+            </div>
+            <div *ngIf="expandForm" nz-col [nzSpan]="8" class="mb-md">
+                <div nz-form-item class="d-flex">
+                    <div nz-form-label><label for="status3">������������</label></div>
+                    <div nz-form-control class="flex-1">
+                        <nz-select [nzPlaceHolder]="'���������'" nzId="status3" [nzShowSearch]="true" [nzSize]="'large'">
+                            <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+                        </nz-select>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzSpan]="expandForm ? 24 : 8" class="mb-md" [class.text-right]="expandForm">
+                <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="loading" [nzSize]="'large'">������</button>
+                <button nz-button type="reset" (click)="getData()" [nzSize]="'large'" class="mx-sm">������</button>
+                <a (click)="expandForm=!expandForm">
+                    {{expandForm ? '������' : '������'}}
+                    <i class="anticon" [class.anticon-down]="!expandForm" [class.anticon-up]="expandForm"></i>
+                </a>
+            </div>
+        </div>
+    </form>
+    <div class="mb-md">
+        <button nz-button (click)="add()" [nzType]="'primary'" [nzSize]="'large'">
+            <i class="anticon anticon-plus"></i><span>������</span>
+        </button>
+        <ng-container *ngIf="selectedRows.length > 0">
+            <button nz-button [nzSize]="'large'">������������</button>
+            <nz-dropdown [nzPlacement]="'bottomLeft'">
+                <button nz-button nz-dropdown [nzSize]="'large'">
+                    ������������ <i class="anticon anticon-down"></i>
+                </button>
+                <ul nz-menu>
+                    <li nz-menu-item (click)="remove()">������</li>
+                    <li nz-menu-item (click)="approval()">������������</li>
+                </ul>
+            </nz-dropdown>
+        </ng-container>
+    </div>
+    <div class="mb-md">
+        <nz-alert [nzType]="'info'" [nzShowIcon]="true">
+            <span alert-body>
+                ��������� <strong class="text-primary">{{selectedRows.length}}</strong> ���&nbsp;&nbsp;
+                ������������������ <strong>{{totalCallNo}}</strong> ���
+                <a *ngIf="totalCallNo > 0" (click)="clear()" class="ml-lg">������</a>
+            </span>
+        </nz-alert>
+    </div>
+    <nz-table #nzTable [nzDataSource]="data" [nzPageSize]="q.ps" [nzLoading]="loading"
+                (nzDataChange)="dataChange($event)"
+                (nzPageIndexChange)="pageChange($event)">
+        <thead nz-thead>
+            <tr>
+                <th nz-th [nzCheckbox]="true">
+                    <label nz-checkbox [(ngModel)]="allChecked" [nzIndeterminate]="indeterminate"
+                        (ngModelChange)="checkAll($event)"></label>
+                </th>
+                <th nz-th><span>������������</span></th>
+                <th nz-th><span>������</span></th>
+                <th nz-th>
+                    <span>������������������</span>
+                    <nz-table-sort [(nzValue)]="sortMap.callNo" (nzValueChange)="sort('callNo',$event)"></nz-table-sort>
+                </th>
+                <th nz-th>
+                    <span>������</span>
+                    <nz-dropdown [nzTrigger]="'click'">
+                        <i class="anticon anticon-filter" nz-dropdown></i>
+                        <ul nz-menu>
+                            <li nz-menu-item *ngFor="let i of status">
+                                <label nz-checkbox [(ngModel)]="i.value"><span>{{i.text}}</span></label>
+                            </li>
+                        </ul>
+                        <div nz-table-filter>
+                            <span nz-table-filter-confirm (click)="getData()">������</span>
+                            <span nz-table-filter-clear (click)="reset(status)">������</span>
+                        </div>
+                    </nz-dropdown>
+                </th>
+                <th nz-th>
+                    <span>������������</span>
+                    <nz-table-sort [(nzValue)]="sortMap.updatedAt" (nzValueChange)="sort('updatedAt',$event)"></nz-table-sort>
+                </th>
+                <th nz-th><span>������</span></th>
+            </tr>
+        </thead>
+        <tbody nz-tbody>
+            <tr nz-tbody-tr *ngFor="let i of nzTable.data">
+                <td nz-td [nzCheckbox]="true">
+                    <label nz-checkbox [nzDisabled]="i.disabled" [(ngModel)]="i.checked" (ngModelChange)="refreshStatus($event)">
+                    </label>
+                </td>
+                <td nz-td>{{i.no}}</td>
+                <td nz-td>{{i.description}}</td>
+                <td nz-td class="text-center">{{i.callNo}} ���</td>
+                <td nz-td><nz-badge [nzStatus]="i.statusType" [nzText]="i.statusText"></nz-badge></td>
+                <td nz-td>{{i.updatedAt | _date}}</td>
+                <td nz-td>
+                    <a (click)="msg.success('������' + i.no)">������</a>
+                    <span nz-table-divider></span>
+                    <a (click)="msg.success('������������' + i.no)">������������</a>
+                </td>
+            </tr>
+        </tbody>
+    </nz-table>
+</nz-card>
+<nz-modal [nzVisible]="modalVisible" [nzTitle]="'������������'" [nzConfirmLoading]="loading" [nzContent]="modalContent"
+    (nzOnCancel)="modalVisible=false" (nzOnOk)="save()">
+    <ng-template #modalContent>
+        <div nz-form-item class="d-flex">
+            <div nz-form-label><label for="no">������</label></div>
+            <div nz-form-control class="flex-1">
+                <nz-input [(ngModel)]="description" name="description" [nzSize]="'large'" [nzPlaceHolder]="'���������'" nzId="no"></nz-input>
+            </div>
+        </div>
+    </ng-template>
+</nz-modal>
diff --git a/src/app/routes/pro/list/table-list/table-list.component.ts b/src/app/routes/pro/list/table-list/table-list.component.ts
new file mode 100644
index 0000000..473c4ef
--- /dev/null
+++ b/src/app/routes/pro/list/table-list/table-list.component.ts
@@ -0,0 +1,127 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getRule, saveRule, removeRule } from '../../../../../../_mock/rule.service';
+
+@Component({
+    selector: 'pro-table-list',
+    templateUrl: './table-list.component.html'
+})
+export class ProTableListComponent implements OnInit {
+    q: any = {
+        pi: 1,
+        ps: 10,
+        sorter: '',
+        status: -1,
+        statusList: []
+    };
+    data: any[] = [];
+    loading = false;
+    selectedRows: any[] = [];
+    curRows: any[] = [];
+    totalCallNo = 0;
+    allChecked = false;
+    indeterminate = false;
+    status = [
+        { text: '������', value: false, type: 'default' },
+        { text: '���������', value: false, type: 'processing' },
+        { text: '���������', value: false, type: 'success' },
+        { text: '������', value: false, type: 'error' }
+    ];
+    sortMap: any = {};
+    expandForm = false;
+    modalVisible = false;
+    description = '';
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.getData();
+    }
+
+    getData() {
+        this.pageChange(1).then(() => {
+            this.q.statusList = this.status.map((i, index) => i.value ? index : -1).filter(w => w !== -1);
+            if (this.q.status && this.q.status > -1) this.q.statusList.push(this.q.status);
+            console.log(this.q);
+            this.data = getRule(this.q).map(i => {
+                const statusItem = this.status[i.status];
+                i.statusText = statusItem.text;
+                i.statusType = statusItem.type;
+                return i;
+            });
+        });
+    }
+
+    add() {
+        this.modalVisible = true;
+        this.description = '';
+    }
+
+    save() {
+        this.loading = true;
+        saveRule(this.description);
+        this.getData();
+        setTimeout(() => this.modalVisible = false, 500);
+    }
+
+    remove() {
+        this.selectedRows.forEach(i => removeRule(i.no));
+        this.getData();
+        this.clear();
+    }
+
+    approval() {
+        this.msg.success(`��������� ${this.selectedRows.length} ���`);
+    }
+
+    clear() {
+        this.selectedRows = [];
+        this.totalCallNo = 0;
+        this.data.forEach(i => i.checked = false);
+        this.refreshStatus();
+    }
+
+    checkAll(value: boolean) {
+        this.curRows.forEach(i => {
+            if (!i.disabled) i.checked = value;
+        });
+        this.refreshStatus();
+    }
+
+    refreshStatus() {
+        const allChecked = this.curRows.every(value => value.disabled || value.checked);
+        const allUnChecked = this.curRows.every(value => value.disabled || !value.checked);
+        this.allChecked = allChecked;
+        this.indeterminate = (!allChecked) && (!allUnChecked);
+        this.selectedRows = this.data.filter(value => value.checked);
+        this.totalCallNo = this.selectedRows.reduce((total, cv) => total + cv.callNo, 0);
+    }
+
+    sort(field: string, value: any) {
+        this.sortMap = {};
+        this.sortMap[field] = value;
+        this.q.sorter = value ? `${field}_${value}` : '';
+        this.getData();
+    }
+
+    dataChange(res: any) {
+        this.curRows = res;
+        this.refreshStatus();
+    }
+
+    pageChange(pi: number): Promise<any> {
+        this.q.pi = pi;
+        this.loading = true;
+        return new Promise((resolve) => {
+            setTimeout(() => {
+                this.loading = false;
+                resolve();
+            }, 500);
+        });
+    }
+
+    reset(ls: any[]) {
+        for (const item of ls) item.value = false;
+        this.getData();
+    }
+}
diff --git a/src/app/routes/pro/pro.module.ts b/src/app/routes/pro/pro.module.ts
new file mode 100644
index 0000000..e95b1ac
--- /dev/null
+++ b/src/app/routes/pro/pro.module.ts
@@ -0,0 +1,97 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { StepFormComponent } from './form/step-form/step-form.component';
+import { Step1Component } from './form/step-form/step1.component';
+import { Step2Component } from './form/step-form/step2.component';
+import { Step3Component } from './form/step-form/step3.component';
+import { AdvancedFormComponent } from './form/advanced-form/advanced-form.component';
+import { ProTableListComponent } from './list/table-list/table-list.component';
+import { ProBasicListComponent } from './list/basic-list/basic-list.component';
+import { ProCardListComponent } from './list/card-list/card-list.component';
+import { ProCoverCardListComponent } from './list/cover-card-list/cover-card-list.component';
+import { ProFilterCardListComponent } from './list/filter-card-list/filter-card-list.component';
+import { ProSearchComponent } from './list/search/search.component';
+import { ProProfileBaseComponent } from './profile/basic/basic.component';
+import { ProProfileAdvancedComponent } from './profile/advanced/advanced.component';
+import { ProResultSuccessComponent } from './result/success/success.component';
+import { ProResultFailComponent } from './result/fail/fail.component';
+import { ProException403Component } from './exception/403.component';
+import { ProException404Component } from './exception/404.component';
+import { ProException500Component } from './exception/500.component';
+
+const routes: Routes = [
+    {
+        path: 'form',
+        children: [
+            { path: 'step-form', component: StepFormComponent },
+            { path: 'advanced-form', component: AdvancedFormComponent }
+        ]
+    },
+    {
+        path: 'list',
+        children: [
+            { path: 'table-list', component: ProTableListComponent },
+            { path: 'basic-list', component: ProBasicListComponent },
+            { path: 'card-list', component: ProCardListComponent },
+            { path: 'cover-card-list', component: ProCoverCardListComponent },
+            { path: 'filter-card-list', component: ProFilterCardListComponent },
+            { path: 'search', component: ProSearchComponent }
+        ]
+    },
+    {
+        path: 'profile',
+        children: [
+            { path: 'basic', component: ProProfileBaseComponent },
+            { path: 'advanced', component: ProProfileAdvancedComponent }
+        ]
+    },
+    {
+        path: 'result',
+        children: [
+            { path: 'success', component: ProResultSuccessComponent },
+            { path: 'fail', component: ProResultFailComponent }
+        ]
+    },
+    {
+        path: 'exception',
+        children: [
+            { path: '403', component: ProException403Component },
+            { path: '404', component: ProException404Component },
+            { path: '500', component: ProException500Component }
+        ]
+    }
+];
+
+const COMPONENTS_NOROUNT = [ Step1Component, Step2Component, Step3Component ];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    declarations: [
+        StepFormComponent,
+        AdvancedFormComponent,
+        ProTableListComponent,
+        ProBasicListComponent,
+        ProCardListComponent,
+        ProCoverCardListComponent,
+        ProFilterCardListComponent,
+        ProSearchComponent,
+        ProProfileBaseComponent,
+        ProProfileAdvancedComponent,
+        ProResultSuccessComponent,
+        ProResultFailComponent,
+        ProException403Component,
+        ProException404Component,
+        ProException500Component,
+        ...COMPONENTS_NOROUNT
+    ],
+    entryComponents: COMPONENTS_NOROUNT,
+    exports: [
+        RouterModule
+    ]
+})
+export class ProModule { }
diff --git a/src/app/routes/pro/profile/advanced/advanced.component.html b/src/app/routes/pro/profile/advanced/advanced.component.html
new file mode 100644
index 0000000..cb86700
--- /dev/null
+++ b/src/app/routes/pro/profile/advanced/advanced.component.html
@@ -0,0 +1,192 @@
+<pro-header [title]="'���������234231029431'">
+    <ng-template #logo><img src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png"></ng-template>
+    <ng-template #action>
+        <nz-button-group [nzSize]="'large'">
+            <button nz-button>������</button>
+            <button nz-button>������</button>
+        </nz-button-group>
+        <nz-dropdown class="mx-sm">
+            <button nz-button nz-dropdown [nzSize]="'large'"><i class="anticon anticon-ellipsis"></i></button>
+            <ul nz-menu>
+                <li nz-menu-item>���������</li>
+                <li nz-menu-item>���������</li>
+                <li nz-menu-item>���������</li>
+            </ul>
+        </nz-dropdown>
+        <button nz-button [nzType]="'primary'" [nzSize]="'large'">���������</button>
+    </ng-template>
+    <ng-template #content>
+        <desc-list size="small" col="2">
+            <desc-list-item term="���������">���������</desc-list-item>
+            <desc-list-item term="������������">XX ������</desc-list-item>
+            <desc-list-item term="������������">2017-07-07</desc-list-item>
+            <desc-list-item term="������������"><a (click)="msg.success('yes')">12421</a></desc-list-item>
+            <desc-list-item term="������������">2017-07-07 ~ 2017-08-08</desc-list-item>
+            <desc-list-item term="������">������������������������������</desc-list-item>
+        </desc-list>
+    </ng-template>
+    <ng-template #extra>
+        <div nz-row>
+            <div nz-col nzXs="24" nzSm="12">
+                <p class="text-grey">������</p>
+                <p class="text-lg">���������</p>
+            </div>
+            <div nz-col nzXs="24" nzSm="12">
+                <p class="text-grey">������������</p>
+                <p class="text-lg">�� 568.08</p>
+            </div>
+        </div>
+    </ng-template>
+    <ng-template #tab>
+        <nz-tabset [nzSize]="'default'">
+            <nz-tab><ng-template #nzTabHeading>������</ng-template></nz-tab>
+            <nz-tab><ng-template #nzTabHeading>������</ng-template></nz-tab>
+        </nz-tabset>
+    </ng-template>
+</pro-header>
+<nz-card [nzBordered]="false" class="mb-lg" nzTitle="������������">
+    <nz-steps [nzCurrent]="1">
+        <nz-step [nzTitle]="'������������'" [nzDescription]="createDesc">
+            <ng-template #createDesc>
+                <p class="my-sm">���������<nz-icon nzType="dingding-o" class="ml-sm"></nz-icon></p>
+                <p>2016-12-12 12:32</p>
+            </ng-template>
+        </nz-step>
+        <nz-step [nzTitle]="'������������'" [nzDescription]="checkedDesc">
+            <ng-template #checkedDesc>
+                <p class="my-sm">���������<nz-icon nzType="dingding-o" style="color: #00A0E9" class="ml-sm"></nz-icon></p>
+                <a (click)="msg.success('click')">���������</a>
+            </ng-template>
+        </nz-step>
+        <nz-step [nzTitle]="'������������'"></nz-step>
+        <nz-step [nzTitle]="'������'"></nz-step>
+    </nz-steps>
+    <div class="steps-content"></div>
+</nz-card>
+<nz-card [nzBordered]="false" nzTitle="������������" class="mb-lg">
+    <desc-list class="mb-lg">
+        <desc-list-item term="������������">���������</desc-list-item>
+        <desc-list-item term="������������">32943898021309809423</desc-list-item>
+        <desc-list-item term="���������">3321944288191034921</desc-list-item>
+        <desc-list-item term="������������">18112345678</desc-list-item>
+        <desc-list-item term="������������">��������� 18100000000 ������������������������������������������������������������</desc-list-item>
+    </desc-list>
+    <desc-list class="mb-lg" title="���������">
+        <desc-list-item term="������������">725</desc-list-item>
+        <desc-list-item term="���������������������">2017-08-08</desc-list-item>
+        <desc-list-item>&nbsp;</desc-list-item>
+        <desc-list-item [term]="term">
+            <ng-template #term>
+                ������������
+                <nz-tooltip [nzTitle]="'������������'">
+                    <span nz-tooltip><i class="anticon anticon-info-circle-o"></i></span>
+                </nz-tooltip>
+            </ng-template>
+            725
+        </desc-list-item>
+        <desc-list-item term="���������������������">2017-08-08</desc-list-item>
+    </desc-list>
+    <h4 class="mb-md">���������</h4>
+    <nz-card nzType="inner" nzTitle="������������������">
+        <desc-list size="small" title="���������" class="mb-md">
+            <desc-list-item term="���������">���������</desc-list-item>
+            <desc-list-item term="���������">1234567</desc-list-item>
+            <desc-list-item term="������������">XX������ - YY���</desc-list-item>
+            <desc-list-item term="������������">2017-08-08</desc-list-item>
+            <desc-list-item term="������">������������������������������������������������������������������������������������������������...</desc-list-item>
+        </desc-list>
+        <nz-divider class="mb-md"></nz-divider>
+        <desc-list size="small" title="���������" col="1" class="mb-md">
+            <desc-list-item term="������">
+            Citrullus lanatus (Thunb.) Matsum. et Nakai������������������������������������������������������������������������..
+            </desc-list-item>
+        </desc-list>
+        <nz-divider class="mb-md"></nz-divider>
+        <desc-list size="small" title="���������">
+            <desc-list-item term="���������">���������</desc-list-item>
+            <desc-list-item term="���������">1234568</desc-list-item>
+        </desc-list>
+    </nz-card>
+</nz-card>
+<nz-card [nzBordered]="false" nzTitle="���������������������������" class="mb-lg">
+    <div class="no-data">
+        <i class="anticon anticon-frown-o"></i>������������
+    </div>
+</nz-card>
+<nz-card [nzBordered]="false">
+    <nz-card-tab nzTabHeading="���������������">
+        <nz-table [nzDataSource]="data.advancedOperation1" [nzIsPagination]="false">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>���������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������</span></th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of data.advancedOperation1">
+                    <td nz-td>{{i.type}}</td>
+                    <td nz-td>{{i.name}}</td>
+                    <td nz-td>
+                        <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+                        <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+                    </td>
+                    <td nz-td>{{i.updatedAt | _date}}</td>
+                    <td nz-td>{{i.memo}}</td>
+                </tr>
+            </tbody>
+        </nz-table>
+    </nz-card-tab>
+    <nz-card-tab nzTabHeading="���������������">
+        <nz-table [nzDataSource]="data.advancedOperation2" [nzIsPagination]="false">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>���������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������</span></th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of data.advancedOperation2">
+                    <td nz-td>{{i.type}}</td>
+                    <td nz-td>{{i.name}}</td>
+                    <td nz-td>
+                        <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+                        <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+                    </td>
+                    <td nz-td>{{i.updatedAt | _date}}</td>
+                    <td nz-td>{{i.memo}}</td>
+                </tr>
+            </tbody>
+        </nz-table>
+    </nz-card-tab>
+    <nz-card-tab nzTabHeading="���������������">
+        <nz-table [nzDataSource]="data.advancedOperation3" [nzIsPagination]="false">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>���������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������</span></th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of data.advancedOperation3">
+                    <td nz-td>{{i.type}}</td>
+                    <td nz-td>{{i.name}}</td>
+                    <td nz-td>
+                        <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+                        <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+                    </td>
+                    <td nz-td>{{i.updatedAt | _date}}</td>
+                    <td nz-td>{{i.memo}}</td>
+                </tr>
+            </tbody>
+        </nz-table>
+    </nz-card-tab>
+</nz-card>
diff --git a/src/app/routes/pro/profile/advanced/advanced.component.ts b/src/app/routes/pro/profile/advanced/advanced.component.ts
new file mode 100644
index 0000000..e7f9b1f
--- /dev/null
+++ b/src/app/routes/pro/profile/advanced/advanced.component.ts
@@ -0,0 +1,21 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getProfileAdvancedData } from '../../../../../../_mock/profile.service';
+
+@Component({
+    selector: 'pro-profile-advanced',
+    templateUrl: './advanced.component.html'
+})
+export class ProProfileAdvancedComponent implements OnInit {
+    data = {
+        advancedOperation1: [],
+        advancedOperation2: [],
+        advancedOperation3: []
+    };
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.data = getProfileAdvancedData();
+    }
+}
diff --git a/src/app/routes/pro/profile/basic/basic.component.html b/src/app/routes/pro/profile/basic/basic.component.html
new file mode 100644
index 0000000..1a2020f
--- /dev/null
+++ b/src/app/routes/pro/profile/basic/basic.component.html
@@ -0,0 +1,75 @@
+<pro-header [title]="'���������������'"></pro-header>
+<nz-card [nzNoHovering]="true" [nzBordered]="false">
+    <ng-template #body>
+        <desc-list size="large" title="������������" class="mb-lg">
+            <desc-list-item term="������������">1000000000</desc-list-item>
+            <desc-list-item term="������">���������</desc-list-item>
+            <desc-list-item term="������������">1234123421</desc-list-item>
+            <desc-list-item term="���������">3214321432</desc-list-item>
+        </desc-list>
+        <nz-divider class="mb-lg"></nz-divider>
+        <desc-list size="large" title="������������" class="mb-lg">
+          <desc-list-item term="������������">���������</desc-list-item>
+          <desc-list-item term="������������">18100000000</desc-list-item>
+          <desc-list-item term="������������">������������</desc-list-item>
+          <desc-list-item term="������������">������������������������������������18���</desc-list-item>
+          <desc-list-item term="������">���</desc-list-item>
+        </desc-list>
+        <nz-divider class="mb-lg"></nz-divider>
+        <div class="text-lg mb-md">������������</div>
+        <nz-table [nzDataSource]="data.basicGoods" [nzLoading]="basicLoading" [nzIsPagination]="false" class="d-block mb-lg">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th class="text-right"><span>������</span></th>
+                    <th nz-th class="text-right"><span>���������������</span></th>
+                    <th nz-th class="text-right"><span>������</span></th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of data.basicGoods">
+                    <td nz-td><a (click)="msg.success(i.id)">{{i.id}}</a></td>
+                    <td nz-td>{{i.name}}</td>
+                    <td nz-td>{{i.barcode}}</td>
+                    <td nz-td class="text-right">{{i.price}}</td>
+                    <td nz-td class="text-right">{{i.num}}</td>
+                    <td nz-td class="text-right">{{i.amount}}</td>
+                </tr>
+                <tr nz-tbody-tr>
+                    <td nz-td>������</td>
+                    <td nz-td></td>
+                    <td nz-td></td>
+                    <td nz-td class="text-right"></td>
+                    <td nz-td class="text-right"><strong>{{basicNum}}</strong></td>
+                    <td nz-td class="text-right"><strong>{{amountNum}}</strong></td>
+                </tr>
+            </tbody>
+        </nz-table>
+        <div class="text-lg mb-md">������������</div>
+        <nz-table [nzDataSource]="data.basicProgress" [nzLoading]="basicLoading" [nzIsPagination]="false">
+            <thead nz-thead>
+                <tr>
+                    <th nz-th><span>������</span></th>
+                    <th nz-th><span>������������</span></th>
+                    <th nz-th><span>������</span></th>
+                    <th nz-th><span>���������ID</span></th>
+                    <th nz-th><span>������</span></th>
+                </tr>
+            </thead>
+            <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of data.basicProgress">
+                    <td nz-td>{{i.time}}</td>
+                    <td nz-td>{{i.rate}}</td>
+                    <td nz-td>
+                        <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+                        <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+                    </td>
+                    <td nz-td>{{i.operator}}</td>
+                    <td nz-td>{{i.cost}}</td>
+                </tr>
+            </tbody>
+        </nz-table>
+    </ng-template>
+</nz-card>
diff --git a/src/app/routes/pro/profile/basic/basic.component.ts b/src/app/routes/pro/profile/basic/basic.component.ts
new file mode 100644
index 0000000..33d16d2
--- /dev/null
+++ b/src/app/routes/pro/profile/basic/basic.component.ts
@@ -0,0 +1,26 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getProfileBasicData } from '../../../../../../_mock/profile.service';
+
+@Component({
+    selector: 'pro-profile-basic',
+    templateUrl: './basic.component.html'
+})
+export class ProProfileBaseComponent implements OnInit {
+
+    basicLoading = true;
+    basicNum = 0;
+    amountNum = 0;
+    data = {};
+
+    constructor(public msg: NzMessageService) {}
+
+    ngOnInit() {
+        this.data = getProfileBasicData();
+        (<any>this.data).basicGoods.forEach(item => {
+            this.basicNum += Number(item.num);
+            this.amountNum += Number(item.amount);
+        });
+        setTimeout(() => this.basicLoading = false, 500);
+    }
+}
diff --git a/src/app/routes/pro/result/fail/fail.component.html b/src/app/routes/pro/result/fail/fail.component.html
new file mode 100644
index 0000000..ee53a19
--- /dev/null
+++ b/src/app/routes/pro/result/fail/fail.component.html
@@ -0,0 +1,21 @@
+<pro-header></pro-header>
+<nz-card [nzBordered]="false">
+    <result
+        type="error"
+        [title]="'������������'"
+        description="������������������������������������������������������"
+        [extra]="resultExtra">
+        <ng-template #resultExtra>
+            <div class="mb-md text-lg">������������������������������������</div>
+            <div class="mb-md">
+                <nz-icon class="text-error pr-sm" nzType="close-circle-o"></nz-icon>������������������������
+                <a class="ml-md">������������ <nz-icon class="pl-sm" nzType="right"></nz-icon></a>
+            </div>
+            <div>
+                <nz-icon class="text-error pr-sm" nzType="close-circle-o"></nz-icon>������������������������������������
+                <a class="ml-md">������������<nz-icon class="pl-sm" nzType="right"></nz-icon></a>
+            </div>
+        </ng-template>
+        <button nz-button [nzType]="'primary'" [nzSize]="'large'">������������</button>
+    </result>
+</nz-card>
diff --git a/src/app/routes/pro/result/fail/fail.component.ts b/src/app/routes/pro/result/fail/fail.component.ts
new file mode 100644
index 0000000..ef19d64
--- /dev/null
+++ b/src/app/routes/pro/result/fail/fail.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+    selector: 'pro-result-fail',
+    templateUrl: './fail.component.html'
+})
+export class ProResultFailComponent {
+
+}
diff --git a/src/app/routes/pro/result/success/success.component.html b/src/app/routes/pro/result/success/success.component.html
new file mode 100644
index 0000000..e66c30d
--- /dev/null
+++ b/src/app/routes/pro/result/success/success.component.html
@@ -0,0 +1,30 @@
+<pro-header></pro-header>
+<nz-card [nzBordered]="false">
+    <result
+        type="success"
+        [title]="'������������'"
+        description="��������������������������������������������������������������������������������������������������� Message ���������������������������������������������������������������������������������������������������x������������������������������������������������������������������������������������"
+        [extra]="resultExtra">
+        <ng-template #resultExtra>
+            <nz-steps [nzCurrent]="1">
+                <nz-step [nzTitle]="'������������'" [nzDescription]="createDesc">
+                    <ng-template #createDesc>
+                        <p class="my-sm">���������<nz-icon nzType="dingding-o" class="ml-sm"></nz-icon></p>
+                        <p>2016-12-12 12:32</p>
+                    </ng-template>
+                </nz-step>
+                <nz-step [nzTitle]="'������������'" [nzDescription]="checkedDesc">
+                    <ng-template #checkedDesc>
+                        <p class="my-sm">���������<nz-icon nzType="dingding-o" style="color: #00A0E9" class="ml-sm"></nz-icon></p>
+                        <a (click)="msg.success('click')">���������</a>
+                    </ng-template>
+                </nz-step>
+                <nz-step [nzTitle]="'������������'"></nz-step>
+                <nz-step [nzTitle]="'������'"></nz-step>
+            </nz-steps>
+        </ng-template>
+        <button nz-button [nzType]="'primary'" [nzSize]="'large'">������������</button>
+        <button nz-button [nzSize]="'large'">������������</button>
+        <button nz-button [nzSize]="'large'">��� ���</button>
+    </result>
+</nz-card>
diff --git a/src/app/routes/pro/result/success/success.component.ts b/src/app/routes/pro/result/success/success.component.ts
new file mode 100644
index 0000000..b17740c
--- /dev/null
+++ b/src/app/routes/pro/result/success/success.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+    selector: 'pro-result-success',
+    templateUrl: './success.component.html'
+})
+export class ProResultSuccessComponent {
+    constructor(public msg: NzMessageService) {}
+}
diff --git a/src/app/routes/pro/user/index.md b/src/app/routes/pro/user/index.md
new file mode 100644
index 0000000..7c985c7
--- /dev/null
+++ b/src/app/routes/pro/user/index.md
@@ -0,0 +1 @@
+��������� `routes.module.ts` ������������
diff --git a/src/app/routes/pro/user/login/login.component.html b/src/app/routes/pro/user/login/login.component.html
new file mode 100644
index 0000000..c1f5449
--- /dev/null
+++ b/src/app/routes/pro/user/login/login.component.html
@@ -0,0 +1,92 @@
+<form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form">
+    <nz-tabset [nzAnimated]="false" class="tabs" (nzSelectChange)="switch($event)">
+        <nz-tab>
+            <ng-template #nzTabHeading>������������������</ng-template>
+            <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
+            <div nz-form-item>
+                <div nz-form-control [nzValidateStatus]="userName">
+                    <nz-input formControlName="userName" [nzPlaceHolder]="'admin'" [nzSize]="'large'">
+                        <ng-template #prefix>
+                            <i class="anticon anticon-user"></i>
+                        </ng-template>
+                    </nz-input>
+                    <ng-container *ngIf="userName.dirty || userName.touched">
+                        <p nz-form-explain *ngIf="userName.errors?.required">���������������������</p>
+                        <p nz-form-explain *ngIf="userName.errors?.minlength">������������������</p>
+                    </ng-container>
+                </div>
+            </div>
+            <div nz-form-item>
+                <div nz-form-control [nzValidateStatus]="password">
+                    <nz-input formControlName="password" [nzPlaceHolder]="'888888'" [nzType]="'password'" [nzSize]="'large'">
+                        <ng-template #prefix>
+                            <i class="anticon anticon-lock"></i>
+                        </ng-template>
+                    </nz-input>
+                    <div nz-form-explain *ngIf="(password.dirty || password.touched) && password.errors?.required">������������������</div>
+                </div>
+            </div>
+        </nz-tab>
+        <nz-tab>
+            <ng-template #nzTabHeading>���������������</ng-template>
+            <div nz-form-item>
+                <div nz-form-control [nzValidateStatus]="mobile">
+                    <nz-input formControlName="mobile" [nzPlaceHolder]="'���������'" [nzSize]="'large'">
+                        <ng-template #prefix>
+                            <i class="anticon anticon-user"></i>
+                        </ng-template>
+                    </nz-input>
+                    <ng-container *ngIf="mobile.dirty || mobile.touched">
+                        <p nz-form-explain *ngIf="mobile.errors?.required">���������������������</p>
+                        <p nz-form-explain *ngIf="mobile.errors?.pattern">������������������������</p>
+                    </ng-container>
+                </div>
+            </div>
+            <div nz-form-item>
+                <div nz-form-control [nzValidateStatus]="captcha">
+                    <div nz-row [nzGutter]="8">
+                        <div nz-col [nzSpan]="16">
+                            <nz-input formControlName="captcha" [nzPlaceHolder]="'���������'" [nzSize]="'large'">
+                                <ng-template #prefix>
+                                    <i class="anticon anticon-mail"></i>
+                                </ng-template>
+                            </nz-input>
+                        </div>
+                        <div nz-col [nzSpan]="8">
+                            <button nz-button (click)="getCaptcha()" [disabled]="count" [nzSize]="'large'" class="ant-btn__block">{{ count ? count + 's' : '���������������' }}</button>
+                        </div>
+                    </div>
+                    <div nz-form-explain *ngIf="(mobile.dirty || mobile.touched) && mobile.errors?.required">���������������������</div>
+                </div>
+            </div>
+        </nz-tab>
+    </nz-tabset>
+    <div nz-form-item nz-row>
+        <div nz-col [nzSpan]="12">
+            <label nz-checkbox formControlName="remember">
+                <span>������������</span>
+            </label>
+        </div>
+        <div nz-col [nzSpan]="12" class="text-right">
+            <a class="forgot" (click)="msg.error('���������������')">���������������</a>
+        </div>
+    </div>
+    <div nz-form-item>
+        <button nz-button [nzType]="'primary'" [nzLoading]="loading" [nzSize]="'large'" class="ant-btn__block">
+            <span>������</span>
+        </button>
+    </div>
+</form>
+<div class="other">
+    ������������������
+    <nz-tooltip [nzTitle]="'in fact Auth0 via window'">
+        <span nz-tooltip class="icon-alipay" (click)="open('auth0', 'window')"></span>
+    </nz-tooltip>
+    <nz-tooltip [nzTitle]="'in fact Github via redirect'">
+        <span nz-tooltip class="icon-taobao" (click)="open('github')"></span>
+    </nz-tooltip>
+    <nz-tooltip [nzTitle]="'���������������'">
+        <span nz-tooltip class="icon-weibo" (click)="open('weibo', 'window')"></span>
+    </nz-tooltip>
+    <a class="register" routerLink="/pro/user/register">������������</a>
+</div>
diff --git a/src/app/routes/pro/user/login/login.component.less b/src/app/routes/pro/user/login/login.component.less
new file mode 100644
index 0000000..601a0a3
--- /dev/null
+++ b/src/app/routes/pro/user/login/login.component.less
@@ -0,0 +1,75 @@
+@import '~@delon/theme/styles/antd/themes/default.less';
+
+:host {
+	display: block;
+	width: 368px;
+	margin: 0 auto;
+
+	::ng-deep {
+		.tabs {
+			padding: 0 2px;
+			margin: 0 -2px;
+			.ant-tabs-tab {
+				font-size: 16px;
+				line-height: 24px;
+			}
+			.ant-input-affix-wrapper .ant-input:not(:first-child) {
+				padding-left: 34px;
+			}
+		}
+
+		.ant-tabs .ant-tabs-bar {
+			border-bottom: 0;
+			margin-bottom: 24px;
+			text-align: center;
+		}
+
+		.ant-form-item {
+			margin-bottom: 24px;
+        }
+
+        .icon-alipay, .icon-taobao, .icon-weibo {
+            display: inline-block;
+            width: 24px;
+            height: 24px;
+            background: url('https://gw.alipayobjects.com/zos/rmsportal/itDzjUnkelhQNsycranf.svg');
+            margin-left: 16px;
+            vertical-align: middle;
+            cursor: pointer;
+        }
+
+        .icon-alipay {
+            background-position: -24px 0;
+
+            &:hover {
+                background-position: 0 0;
+            }
+        }
+
+        .icon-taobao {
+            background-position: -24px -24px;
+
+            &:hover {
+                background-position: 0 -24px;
+            }
+        }
+
+        .icon-weibo {
+            background-position: -24px -48px;
+
+            &:hover {
+                background-position: 0 -48px;
+            }
+        }
+
+        .other {
+            text-align: left;
+            margin-top: 24px;
+            line-height: 22px;
+
+            .register {
+            float: right;
+            }
+        }
+	}
+}
diff --git a/src/app/routes/pro/user/login/login.component.ts b/src/app/routes/pro/user/login/login.component.ts
new file mode 100644
index 0000000..50b3319
--- /dev/null
+++ b/src/app/routes/pro/user/login/login.component.ts
@@ -0,0 +1,141 @@
+import { SettingsService } from '@delon/theme';
+import { Component, OnDestroy, Inject } from '@angular/core';
+import { Router } from '@angular/router';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { NzMessageService } from 'ng-zorro-antd';
+import { SocialService, SocialOpenType, ITokenService, DA_SERVICE_TOKEN } from '@delon/auth';
+import { environment } from '../../../../../environments/environment';
+
+@Component({
+    selector: 'pro-user-login',
+    templateUrl: './login.component.html',
+    styleUrls: [ './login.component.less' ],
+    providers: [ SocialService ]
+})
+export class ProUserLoginComponent implements OnDestroy {
+
+    form: FormGroup;
+    error = '';
+    type = 0;
+    loading = false;
+
+    constructor(
+        fb: FormBuilder,
+        private router: Router,
+        public msg: NzMessageService,
+        private settingsService: SettingsService,
+        private socialService: SocialService,
+        @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {
+        this.form = fb.group({
+            userName: [null, [Validators.required, Validators.minLength(5)]],
+            password: [null, Validators.required],
+            mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]],
+            captcha: [null, [Validators.required]],
+            remember: [true]
+        });
+    }
+
+    // region: fields
+
+    get userName() { return this.form.controls.userName; }
+    get password() { return this.form.controls.password; }
+    get mobile() { return this.form.controls.mobile; }
+    get captcha() { return this.form.controls.captcha; }
+
+    // endregion
+
+    switch(ret: any) {
+        this.type = ret.index;
+    }
+
+    // region: get captcha
+
+    count = 0;
+    interval$: any;
+
+    getCaptcha() {
+        this.count = 59;
+        this.interval$ = setInterval(() => {
+            this.count -= 1;
+            if (this.count <= 0)
+                clearInterval(this.interval$);
+        }, 1000);
+    }
+
+    // endregion
+
+    submit() {
+        this.error = '';
+        if (this.type === 0) {
+            this.userName.markAsDirty();
+            this.password.markAsDirty();
+            if (this.userName.invalid || this.password.invalid) return;
+        } else {
+            this.mobile.markAsDirty();
+            this.captcha.markAsDirty();
+            if (this.mobile.invalid || this.captcha.invalid) return;
+        }
+        // mock http
+        this.loading = true;
+        setTimeout(() => {
+            this.loading = false;
+            if (this.type === 0) {
+                if (this.userName.value !== 'admin' || this.password.value !== '888888') {
+                    this.error = `���������������������`;
+                    return;
+                }
+            }
+
+            this.tokenService.set({
+                token: '123456789',
+                name: this.userName.value,
+                email: `cipchk@qq.com`,
+                id: 10000,
+                time: +new Date
+            });
+            this.router.navigate(['/']);
+        }, 1000);
+    }
+
+    // region: social
+
+    open(type: string, openType: SocialOpenType = 'href') {
+        let url = ``;
+        let callback = ``;
+        if (environment.production)
+            callback = 'https://cipchk.github.io/ng-alain/callback/' + type;
+        else
+            callback = 'http://localhost:4200/callback/' + type;
+        switch (type) {
+            case 'auth0':
+                url = `//cipchk.auth0.com/login?client=8gcNydIDzGBYxzqV0Vm1CX_RXH-wsWo5&redirect_uri=${decodeURIComponent(callback)}`;
+                break;
+            case 'github':
+                url = `//github.com/login/oauth/authorize?client_id=9d6baae4b04a23fcafa2&response_type=code&redirect_uri=${decodeURIComponent(callback)}`;
+                break;
+            case 'weibo':
+                url = `https://api.weibo.com/oauth2/authorize?client_id=1239507802&response_type=code&redirect_uri=${decodeURIComponent(callback)}`;
+                break;
+        }
+        if (openType === 'window') {
+            this.socialService.login(url, '/', {
+                type: 'window'
+            }).subscribe(res => {
+                if (res) {
+                    this.settingsService.setUser(res);
+                    this.router.navigateByUrl('/');
+                }
+            });
+        } else {
+            this.socialService.login(url, '/', {
+                type: 'href'
+            });
+        }
+    }
+
+    // endregion
+
+    ngOnDestroy(): void {
+        if (this.interval$) clearInterval(this.interval$);
+    }
+}
diff --git a/src/app/routes/pro/user/register-result/register-result.component.html b/src/app/routes/pro/user/register-result/register-result.component.html
new file mode 100644
index 0000000..cbe0490
--- /dev/null
+++ b/src/app/routes/pro/user/register-result/register-result.component.html
@@ -0,0 +1,10 @@
+<result
+    type="success"
+    [title]="title"
+    description="������������������������������������������������������������24������������������������������������������������������������������������">
+    <ng-template #title>
+        <div class="title">���������������ng-alain@example.com ������������</div>
+    </ng-template>
+    <button (click)="msg.success('email')" nz-button [nzType]="'primary'" [nzSize]="'large'">������������</button>
+    <button routerLink="/" nz-button [nzSize]="'large'">������������</button>
+</result>
diff --git a/src/app/routes/pro/user/register-result/register-result.component.less b/src/app/routes/pro/user/register-result/register-result.component.less
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/app/routes/pro/user/register-result/register-result.component.less
diff --git a/src/app/routes/pro/user/register-result/register-result.component.ts b/src/app/routes/pro/user/register-result/register-result.component.ts
new file mode 100644
index 0000000..f391c4e
--- /dev/null
+++ b/src/app/routes/pro/user/register-result/register-result.component.ts
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+    selector: 'pro-user-register-result',
+    templateUrl: './register-result.component.html',
+    styleUrls: [ './register-result.component.less' ]
+})
+export class ProUserRegisterResultComponent {
+    constructor(public msg: NzMessageService) {}
+}
diff --git a/src/app/routes/pro/user/register/register.component.html b/src/app/routes/pro/user/register/register.component.html
new file mode 100644
index 0000000..115cd94
--- /dev/null
+++ b/src/app/routes/pro/user/register/register.component.html
@@ -0,0 +1,94 @@
+<h3>������</h3>
+<form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form">
+    <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
+    <div nz-form-item>
+        <div nz-form-control [nzValidateStatus]="mail">
+            <nz-input formControlName="mail" [nzPlaceHolder]="'������'" [nzSize]="'large'">
+                <ng-template #prefix>
+                    <i class="anticon anticon-user"></i>
+                </ng-template>
+            </nz-input>
+            <ng-container *ngIf="mail.dirty || mail.touched">
+                <p nz-form-explain *ngIf="mail.errors?.required">������������������������</p>
+                <p nz-form-explain *ngIf="mail.errors?.email">���������������������������</p>
+            </ng-container>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control [nzValidateStatus]="password">
+            <nz-popover [nzPlacement]="'right'" [nzTrigger]="'focus'" [(nzVisible)]="visible" nzOverlayClassName="register-password-cdk" [nzOverlayStyle]="{'width.px': 240}">
+                <nz-input nz-popover formControlName="password" [nzPlaceHolder]="'������6���������������������������'" [nzType]="'password'" [nzSize]="'large'">
+                    <ng-template #prefix>
+                        <i class="anticon anticon-lock"></i>
+                    </ng-template>
+                </nz-input>
+                <div nz-form-explain *ngIf="(password.dirty || password.touched) && password.errors?.required">������������������</div>
+                <ng-template #nzTemplate>
+                    <div style="padding: 4px 0">
+                        <ng-container [ngSwitch]="status">
+                            <div *ngSwitchCase="'ok'" class="success">������������</div>
+                            <div *ngSwitchCase="'pass'" class="warning">������������</div>
+                            <div *ngSwitchDefault class="error">���������������</div>
+                        </ng-container>
+                        <div class="progress-{{status}}">
+                            <nz-progress
+                                [(ngModel)]="progress" [ngModelOptions]="{standalone: true}"
+                                [nzStatus]="passwordProgressMap[status]"
+                                [nzStrokeWidth]="6"
+                                [nzShowInfo]="false"></nz-progress>
+                        </div>
+                        <p class="mt-sm">��������������� 6 ������������������������������������������������������</p>
+                    </div>
+                </ng-template>
+            </nz-popover>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control [nzValidateStatus]="confirm">
+            <nz-input formControlName="confirm" [nzPlaceHolder]="'������������'" [nzType]="'password'" [nzSize]="'large'">
+                <ng-template #prefix>
+                    <i class="anticon anticon-lock"></i>
+                </ng-template>
+            </nz-input>
+            <ng-container *ngIf="confirm.dirty || confirm.touched">
+                <p nz-form-explain *ngIf="confirm.errors?.required">������������������</p>
+                <p nz-form-explain *ngIf="confirm.errors?.equar">���������������������������������</p>
+            </ng-container>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control [nzValidateStatus]="mobile">
+            <nz-input-group [nzSize]="'large'" [nzCompact]="true">
+                <nz-select formControlName="mobilePrefix" style="width: 25%;">
+                    <nz-option [nzLabel]="'+86'" [nzValue]="'+86'"></nz-option>
+                    <nz-option [nzLabel]="'+87'" [nzValue]="'+87'"></nz-option>
+                </nz-select>
+                <input formControlName="mobile" id="'11���������������'" nz-input style="width: 75%;">
+            </nz-input-group>
+            <div nz-form-explain *ngIf="(mobile.dirty || mobile.touched) && mobile.errors?.required">���������������������</div>
+        </div>
+    </div>
+    <div nz-form-item>
+        <div nz-form-control [nzValidateStatus]="captcha">
+            <div nz-row [nzGutter]="8">
+                <div nz-col [nzSpan]="16">
+                    <nz-input formControlName="captcha" [nzPlaceHolder]="'���������'" [nzSize]="'large'">
+                        <ng-template #prefix>
+                            <i class="anticon anticon-mail"></i>
+                        </ng-template>
+                    </nz-input>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <button nz-button (click)="getCaptcha()" [disabled]="count" [nzSize]="'large'" class="ant-btn__block">{{ count ? count + 's' : '���������������' }}</button>
+                </div>
+            </div>
+            <div nz-form-explain *ngIf="(captcha.dirty || captcha.touched) && captcha.errors?.required">���������������������</div>
+        </div>
+    </div>
+    <div nz-form-item>
+        <button nz-button [nzType]="'primary'" [nzLoading]="loading" [nzSize]="'large'" class="submit">
+            <span>������</span>
+        </button>
+        <a class="login" routerLink="/pro/user/login">������������������������</a>
+    </div>
+</form>
diff --git a/src/app/routes/pro/user/register/register.component.less b/src/app/routes/pro/user/register/register.component.less
new file mode 100644
index 0000000..16a09f7
--- /dev/null
+++ b/src/app/routes/pro/user/register/register.component.less
@@ -0,0 +1,54 @@
+@import '~@delon/theme/styles/antd/themes/default.less';
+
+:host {
+	display: block;
+	width: 368px;
+	margin: 0 auto;
+
+	::ng-deep {
+		.ant-form-item {
+			margin-bottom: 24px;
+		}
+
+		h3 {
+			font-size: 16px;
+			margin-bottom: 20px;
+        }
+
+        .submit {
+            width: 50%;
+        }
+
+        .login {
+            float: right;
+            line-height: @btn-height-lg;
+        }
+	}
+}
+
+
+::ng-deep {
+    .register-password-cdk {
+        .success, .warning, .error {
+            transition: color .3s;
+        }
+
+        .success {
+            color: @success-color;
+        }
+
+        .warning {
+            color: @warning-color;
+        }
+
+        .error {
+            color: @error-color;
+        }
+
+        .progress-pass > .progress {
+            .ant-progress-bg {
+                background-color: @warning-color;
+            }
+        }
+    }
+}
diff --git a/src/app/routes/pro/user/register/register.component.ts b/src/app/routes/pro/user/register/register.component.ts
new file mode 100644
index 0000000..31d91a4
--- /dev/null
+++ b/src/app/routes/pro/user/register/register.component.ts
@@ -0,0 +1,102 @@
+import { Component, OnDestroy } from '@angular/core';
+import { Router } from '@angular/router';
+import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+    selector: 'pro-user-register',
+    templateUrl: './register.component.html',
+    styleUrls: [ './register.component.less' ]
+})
+export class ProUserRegisterComponent implements OnDestroy {
+
+    form: FormGroup;
+    error = '';
+    type = 0;
+    loading = false;
+    visible = false;
+    status = 'pool';
+    progress = 0;
+    passwordProgressMap = {
+        ok: 'success',
+        pass: 'normal',
+        pool: 'exception'
+    };
+
+    constructor(fb: FormBuilder, private router: Router, public msg: NzMessageService) {
+        this.form = fb.group({
+            mail: [null, [Validators.email]],
+            password: [null, [Validators.required, Validators.minLength(6), ProUserRegisterComponent.checkPassword.bind(this)]],
+            confirm: [null, [Validators.required, Validators.minLength(6), ProUserRegisterComponent.passwordEquar]],
+            mobilePrefix: [ '+86' ],
+            mobile: [null, [Validators.required, Validators.pattern(/^1\d{10}$/)]],
+            captcha: [null, [Validators.required]]
+        });
+    }
+
+    static checkPassword(control: FormControl) {
+        if (!control) return null;
+        const self: any = this;
+        self.visible = !!control.value;
+        if (control.value && control.value.length > 9)
+            self.status = 'ok';
+        else if (control.value && control.value.length > 5)
+            self.status = 'pass';
+        else
+            self.status = 'pool';
+
+        if (self.visible) self.progress = control.value.length * 10 > 100 ? 100 : control.value.length * 10;
+    }
+
+    static passwordEquar(control: FormControl) {
+        if (!control || !control.parent) return null;
+        if (control.value !== control.parent.get('password').value) {
+            return { equar: true };
+        }
+        return null;
+    }
+
+    // region: fields
+
+    get mail() { return this.form.controls.mail; }
+    get password() { return this.form.controls.password; }
+    get confirm() { return this.form.controls.confirm; }
+    get mobile() { return this.form.controls.mobile; }
+    get captcha() { return this.form.controls.captcha; }
+
+    // endregion
+
+    // region: get captcha
+
+    count = 0;
+    interval$: any;
+
+    getCaptcha() {
+        this.count = 59;
+        this.interval$ = setInterval(() => {
+            this.count -= 1;
+            if (this.count <= 0)
+                clearInterval(this.interval$);
+        }, 1000);
+    }
+
+    // endregion
+
+    submit() {
+        this.error = '';
+        for (const i in this.form.controls) {
+            this.form.controls[i].markAsDirty();
+        }
+        if (this.form.invalid) return;
+        // mock http
+        this.loading = true;
+        setTimeout(() => {
+            this.loading = false;
+            this.router.navigate(['/pro/user/register-result']);
+        }, 1000);
+    }
+
+    ngOnDestroy(): void {
+        if (this.interval$) clearInterval(this.interval$);
+    }
+}
diff --git a/src/app/routes/routes.module.ts b/src/app/routes/routes.module.ts
index a621ee2..2dc45b2 100644
--- a/src/app/routes/routes.module.ts
+++ b/src/app/routes/routes.module.ts
@@ -1,10 +1,41 @@
 import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
+import { RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+import { PagesModule } from './pages/pages.module';
+import { environment } from '../../environments/environment';
+
+import { routes } from './routes';
+import { DashboardV1Component } from './dashboard/v1/v1.component';
+import { DashboardAnalysisComponent } from './dashboard/analysis/analysis.component';
+import { DashboardMonitorComponent } from './dashboard/monitor/monitor.component';
+import { DashboardWorkplaceComponent } from './dashboard/workplace/workplace.component';
+import { CallbackComponent } from './callback/callback.component';
+
+// pro
+import { ProUserLoginComponent } from './pro/user/login/login.component';
+import { ProUserRegisterComponent } from './pro/user/register/register.component';
+import { ProUserRegisterResultComponent } from './pro/user/register-result/register-result.component';
 
 @NgModule({
-  imports: [
-    CommonModule
-  ],
-  declarations: []
+    imports: [
+        SharedModule,
+        RouterModule.forRoot(routes, { useHash: environment.useHash }),
+        PagesModule
+    ],
+    declarations: [
+        DashboardV1Component,
+        DashboardAnalysisComponent,
+        DashboardMonitorComponent,
+        DashboardWorkplaceComponent,
+        CallbackComponent,
+        // pro
+        ProUserLoginComponent,
+        ProUserRegisterComponent,
+        ProUserRegisterResultComponent
+    ],
+    exports: [
+        RouterModule
+    ]
 })
-export class RoutesModule { }
+
+export class RoutesModule {}
diff --git a/src/app/routes/routes.ts b/src/app/routes/routes.ts
new file mode 100644
index 0000000..8bfbb54
--- /dev/null
+++ b/src/app/routes/routes.ts
@@ -0,0 +1,71 @@
+import { LayoutComponent } from '../layout/layout.component';
+import { LayoutFullScreenComponent } from '../layout/fullscreen/fullscreen.component';
+import { LoginComponent } from './pages/login/login.component';
+import { LockComponent } from './pages/lock/lock.component';
+import { RegisterComponent } from './pages/register/register.component';
+import { ForgetComponent } from './pages/forget/forget.component';
+import { MaintenanceComponent } from './pages/maintenance/maintenance.component';
+import { Page404Component } from './pages/404/404.component';
+import { Page500Component } from './pages/500/500.component';
+import { DashboardV1Component } from './dashboard/v1/v1.component';
+import { DashboardAnalysisComponent } from './dashboard/analysis/analysis.component';
+import { DashboardMonitorComponent } from './dashboard/monitor/monitor.component';
+import { DashboardWorkplaceComponent } from './dashboard/workplace/workplace.component';
+import { CallbackComponent } from './callback/callback.component';
+// pro
+import { ProUserLayoutComponent } from '../layout/pro/user/user.component';
+import { ProUserLoginComponent } from './pro/user/login/login.component';
+import { ProUserRegisterComponent } from './pro/user/register/register.component';
+import { ProUserRegisterResultComponent } from './pro/user/register-result/register-result.component';
+
+export const routes = [
+    {
+        path: '',
+        component: LayoutComponent,
+        children: [
+            { path: '', redirectTo: 'dashboard/v1', pathMatch: 'full' },
+            { path: 'dashboard', redirectTo: 'dashboard/v1', pathMatch: 'full' },
+            { path: 'dashboard/v1', component: DashboardV1Component, data: { translate: 'dashboard_v1' } },
+            { path: 'dashboard/analysis', component: DashboardAnalysisComponent, data: { translate: 'dashboard_analysis' } },
+            { path: 'dashboard/monitor', component: DashboardMonitorComponent, data: { translate: 'dashboard_monitor' } },
+            { path: 'dashboard/workplace', component: DashboardWorkplaceComponent, data: { translate: 'dashboard_workplace' } },
+            { path: 'widgets', loadChildren: './widgets/widgets.module#WidgetsModule' },
+            { path: 'elements', loadChildren: './elements/elements.module#ElementsModule' },
+            { path: 'forms', loadChildren: './forms/forms.module#FormsModule' },
+            { path: 'charts', loadChildren: './charts/charts.module#ChartsModule' },
+            { path: 'tables', loadChildren: './tables/tables.module#TablesModule' },
+            { path: 'maps', loadChildren: './maps/maps.module#MapsModule' },
+            { path: 'logics', loadChildren: './logics/logics.module#LogicsModule' },
+            { path: 'extras', loadChildren: './extras/extras.module#ExtrasModule' },
+            { path: 'pro', loadChildren: './pro/pro.module#ProModule' }
+        ]
+    },
+    // ������������
+    {
+        path: 'data-v',
+        component: LayoutFullScreenComponent,
+        children: [
+            { path: '', loadChildren: './data-v/data-v.module#DataVModule' }
+        ]
+    },
+    // pro ���������������������������������������������������������������Angular������������������������������������������������������
+    {
+        path: 'pro/user',
+        component: ProUserLayoutComponent,
+        children: [
+            { path: 'login', component: ProUserLoginComponent },
+            { path: 'register', component: ProUserRegisterComponent },
+            { path: 'register-result', component: ProUserRegisterResultComponent }
+        ]
+    },
+    // ���������������Layout
+    { path: 'callback/:type', component: CallbackComponent },
+    { path: 'register', component: RegisterComponent, data: { translate: 'register' } },
+    { path: 'login', component: LoginComponent, data: { title: 'login' } },
+    { path: 'forget', component: ForgetComponent, data: { translate: 'forget' } },
+    { path: 'lock', component: LockComponent, data: { translate: 'lock' } },
+    { path: 'maintenance', component: MaintenanceComponent },
+    { path: '404', component: Page404Component },
+    { path: '500', component: Page500Component },
+    { path: '**', redirectTo: 'dashboard' }
+];
diff --git a/src/app/routes/tables/full/full.component.html b/src/app/routes/tables/full/full.component.html
new file mode 100644
index 0000000..424aa23
--- /dev/null
+++ b/src/app/routes/tables/full/full.component.html
@@ -0,0 +1,153 @@
+<div class="content__title">
+    <h1>
+        A Full Demo Tables
+    </h1>
+</div>
+<nz-card>
+    <form nz-form>
+        <div nz-row nz-form-item [nzGutter]="16">
+            <div nz-form-label nz-col [nzSm]="2">
+                <label for="name">Name</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="5">
+                <nz-input [(ngModel)]="args.name" name="name" [nzId]="'name'"></nz-input>
+            </div>
+            <div nz-form-label nz-col [nzSm]="2">
+                <label>Created</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="8">
+                <div nz-row>
+                    <div nz-form-control nz-col [nzSpan]="11">
+                        <nz-datepicker [(ngModel)]="args.created_begin" name="created_begin" [nzPlaceHolder]="'begin'"></nz-datepicker>
+                    </div>
+                    <div nz-col [nzSpan]="1">
+                        <p nz-form-split>-</p>
+                    </div>
+                    <div nz-form-control nz-col [nzSpan]="11">
+                        <nz-datepicker [(ngModel)]="args.created_end" name="created_end" [nzPlaceHolder]="'end'"></nz-datepicker>
+                    </div>
+                </div>
+            </div>
+            <div nz-form-label nz-col [nzSm]="2">
+                <label>Gender</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="5">
+                <nz-dropdown>
+                    <a class="ant-dropdown-link" nz-dropdown>
+                        {{args.gender ? args.gender : 'unlimit'}} <i class="anticon anticon-down"></i>
+                    </a>
+                    <ul nz-menu>
+                        <li nz-menu-item (click)="args.gender=''">unlimit</li>
+                        <li nz-menu-item (click)="args.gender='male'">male</li>
+                        <li nz-menu-item (click)="args.gender='female'">female</li>
+                    </ul>
+                </nz-dropdown>
+                <span class="text-grey-light">(only valid)</span>
+            </div>
+        </div>
+        <div nz-row nz-form-item [nzGutter]="16" class="mb0">
+            <div nz-form-label nz-col [nzSm]="2">
+                <label for="userid">User ID</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="5">
+                <nz-input [(ngModel)]="args.userid" name="userid" [nzId]="'userid'" [nzPlaceHolder]="'placeholder'"></nz-input>
+            </div>
+            <div nz-form-label nz-col [nzSm]="2">
+                <label>Modified</label>
+            </div>
+            <div nz-form-control nz-col [nzSm]="8">
+                <div nz-row>
+                    <div nz-form-control nz-col [nzSpan]="11">
+                        <nz-datepicker [(ngModel)]="args.modified_begin" name="modified_begin" [nzPlaceHolder]="'begin'"></nz-datepicker>
+                    </div>
+                    <div nz-col [nzSpan]="1">
+                        <p nz-form-split>-</p>
+                    </div>
+                    <div nz-form-control nz-col [nzSpan]="11">
+                        <nz-datepicker [(ngModel)]="args.modified_end" name="modified_end" [nzPlaceHolder]="'end'"></nz-datepicker>
+                    </div>
+                </div>
+            </div>
+            <div nz-col [nzSm]="5" [nzOffset]="2">
+                <button nz-button [nzType]="'primary'" (click)="load(1)" [nzLoading]="loading"><span>Search</span></button>
+                <button nz-button (click)="clear()" [disabled]="loading">Clear</button>
+            </div>
+        </div>
+    </form>
+</nz-card>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card>
+            <div class="mb-sm text-right">
+                <nz-dropdown>
+                    <button nz-button nz-dropdown [disabled]="!_allChecked && !_indeterminate">
+                        <span>Export</span> <i class="anticon anticon-down"></i>
+                    </button>
+                    <ul nz-menu>
+                        <li nz-menu-item>Excel</li>
+                        <li nz-menu-item>JSON</li>
+                        <li nz-menu-item>PNG</li>
+                    </ul>
+                </nz-dropdown>
+            </div>
+            <nz-table #nzTable
+                [nzAjaxData]="list"
+                [nzShowSizeChanger]="true"
+                [nzLoading]="loading"
+                [nzTotal]="total"
+                [(nzPageIndex)]="pi"
+                (nzPageIndexChange)="load()"
+                [(nzPageSize)]="ps"
+                (nzPageSizeChange)="load()">
+                <thead nz-thead>
+                    <tr>
+                        <th nz-th [nzCheckbox]="true">
+                            <label nz-checkbox
+                                [(ngModel)]="_allChecked" [nzIndeterminate]="_indeterminate"
+                                (ngModelChange)="_checkAll()">
+                            </label>
+                        </th>
+                        <th nz-th><span>Avatar</span></th>
+                        <th nz-th><span>Name</span></th>
+                        <th nz-th><span>Age</span></th>
+                        <th nz-th><span>Email</span></th>
+                        <th nz-th><span>Event</span></th>
+                        <th nz-th><span>Price</span></th>
+                        <th nz-th><span>Registered</span></th>
+                        <th nz-th><span>Actions</span></th>
+                    </tr>
+                </thead>
+                <tbody nz-tbody>
+                    <tr nz-tbody-tr *ngFor="let data of nzTable.data">
+                        <td nz-td [nzCheckbox]="true">
+                            <label nz-checkbox [(ngModel)]="data.checked"
+                                (ngModelChange)="refChecked()">
+                            </label>
+                        </td>
+                        <td nz-td>
+                            <nz-avatar [nzSrc]="data.picture.thumbnail" [nzSize]="'large'"></nz-avatar>
+                        </td>
+                        <td nz-td>{{data.name.first}} {{data.name.last}}</td>
+                        <td nz-td>
+                            <nz-tag *ngIf="data.gender=='female'" [nzColor]="'pink'">female</nz-tag>
+                            <nz-tag *ngIf="data.gender=='male'" [nzColor]="'green'">male</nz-tag>
+                        </td>
+                        <td nz-td>{{data.email}}</td>
+                        <td nz-td style="width: 90px">
+                            <mini-bar height="30" theme="mini" color="#999" borderWidth="3" [padding]="[36, 50, 30, 0]" [data]="events"></mini-bar>
+                        </td>
+                        <td nz-td>{{data.price | _currency}}</td>
+                        <td nz-td>{{data.registered | _date: 'YYYY���MM���DD���'}}</td>
+                        <td nz-td>
+                            <a (click)="showMsg('Edit')">Edit</a>
+                            <span nz-table-divider></span>
+                            <nz-popconfirm [nzTitle]="'Are you sure���'" [nzOkText]="'ok'" [nzCancelText]="'cancel'" (nzOnConfirm)="showMsg('has deleted')" (nzOnCancel)="showMsg('cancel delete')">
+                                <a nz-popconfirm>Delete</a>
+                            </nz-popconfirm>
+                        </td>
+                    </tr>
+                </tbody>
+            </nz-table>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/tables/full/full.component.spec.ts b/src/app/routes/tables/full/full.component.spec.ts
new file mode 100644
index 0000000..9788592
--- /dev/null
+++ b/src/app/routes/tables/full/full.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { TableFullComponent } from './full.component';
+import { RandomUserService } from '../randomUser.service';
+
+describe('Component: TableFull', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [TableFullComponent],
+        providers: [RandomUserService]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(TableFullComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/tables/full/full.component.ts b/src/app/routes/tables/full/full.component.ts
new file mode 100644
index 0000000..88f55f7
--- /dev/null
+++ b/src/app/routes/tables/full/full.component.ts
@@ -0,0 +1,73 @@
+import { Component, OnInit } from '@angular/core';
+import { RandomUserService } from '../randomUser.service';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-table-full',
+    templateUrl: './full.component.html'
+})
+export class TableFullComponent implements OnInit {
+
+    pi = 1;
+    ps = 10;
+    total = 200; // mock total
+    list = [];
+    loading = false;
+    args: any = { };
+    _indeterminate = false;
+    _allChecked = false;
+
+    events = [...getFakeChartData.visitData.slice(0, 6)].map(item => {
+        item.x = item.x.substring(5);
+        return item;
+    });
+
+    load(pi?: number) {
+        if (typeof pi !== 'undefined') {
+            this.pi = pi || 1;
+        }
+
+        this.loading = true;
+        this._allChecked = false;
+        this._indeterminate = false;
+        this._randomUser.getUsers(this.pi, this.ps, this.args)
+            .map(data => {
+                data.results.forEach(item => {
+                    item.checked = false;
+                    item.price = +((Math.random() * (10000000 - 100)) + 100).toFixed(2);
+                });
+                return data;
+            })
+            .subscribe(data => {
+                this.loading = false;
+                this.list = data.results;
+            });
+    }
+
+    clear() {
+        this.args = {};
+        this.load(1);
+    }
+
+    _checkAll() {
+        this.list.forEach(item => item.checked = this._allChecked);
+        this.refChecked();
+    }
+    refChecked() {
+        const checkedCount = this.list.filter(w => w.checked).length;
+        this._allChecked = checkedCount === this.list.length;
+        this._indeterminate = this._allChecked ? false : checkedCount > 0;
+    }
+
+    constructor(private _randomUser: RandomUserService, private message: NzMessageService) {
+    }
+
+    ngOnInit() {
+        this.load();
+    }
+
+    showMsg(msg: string) {
+        this.message.info(msg);
+    }
+}
diff --git a/src/app/routes/tables/randomUser.service.ts b/src/app/routes/tables/randomUser.service.ts
new file mode 100644
index 0000000..3946db7
--- /dev/null
+++ b/src/app/routes/tables/randomUser.service.ts
@@ -0,0 +1,27 @@
+import { Injectable } from '@angular/core';
+import { Observable } from 'rxjs/Observable';
+import { catchError } from 'rxjs/operators';
+import { _HttpClient } from '@delon/theme';
+
+@Injectable()
+export class RandomUserService {
+    randomUserUrl = 'https://api.randomuser.me/';
+
+    getUsers(PageIndex = 1, pageSize = 10, args?: any) {
+        return this.http
+            .get(this.randomUserUrl, { results: pageSize, page: PageIndex, _allow_anonymous: true })
+            .pipe(catchError(this.handleError));
+    }
+
+    handleError(error: any) {
+        const errMsg = (error.message) ? error.message :
+            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
+        console.error(errMsg); // log to console instead
+        return Observable.throw(errMsg);
+    }
+
+    constructor(private http: _HttpClient) {
+    }
+
+
+}
diff --git a/src/app/routes/tables/standard/standard.component.html b/src/app/routes/tables/standard/standard.component.html
new file mode 100644
index 0000000..ef5c1c3
--- /dev/null
+++ b/src/app/routes/tables/standard/standard.component.html
@@ -0,0 +1,257 @@
+<div class="content__title">
+    <h1>
+        Tables
+        <small>Native support</small>
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Basic">
+            <nz-table [nzDataSource]="data" [nzPageSize]="10">
+                <thead nz-thead>
+                    <tr>
+                        <th nz-th><span>Name</span></th>
+                        <th nz-th><span>Age</span></th>
+                        <th nz-th><span>Address</span></th>
+                        <th nz-th><span>Action</span></th>
+                    </tr>
+                </thead>
+                <tbody nz-tbody>
+                    <tr nz-tbody-tr *ngFor="let data of data">
+                        <td nz-td>{{data.name}}</td>
+                        <td nz-td>{{data.age}}</td>
+                        <td nz-td>{{data.address}}</td>
+                        <td nz-td>
+                            <span>
+                                <a>Action</a>
+                                <span nz-table-divider></span>
+                                <a>Delete</a>
+                                <span nz-table-divider></span>
+                                <nz-dropdown>
+                                    <a class="ant-dropdown-link" nz-dropdown>
+                                        More<i class="anticon anticon-down"></i>
+                                    </a>
+                                    <ul nz-menu>
+                                        <li nz-menu-item>1st menu item</li>
+                                        <li nz-menu-item>2st menu item</li>
+                                        <li nz-menu-item>3st menu item</li>
+                                    </ul>
+                                </nz-dropdown>
+                            </span>
+                        </td>
+                    </tr>
+                </tbody>
+            </nz-table>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Sort">
+            <nz-table [nzDataSource]="data" [nzPageSize]="10">
+                <thead nz-thead>
+                    <tr>
+                        <th nz-th><span>Name</span></th>
+                        <th nz-th><span>Age<nz-table-sort [(nzValue)]="ageSort" (nzValueChange)="ageSortChange($event)"></nz-table-sort></span></th>
+                        <th nz-th><span>Address</span></th>
+                    </tr>
+                </thead>
+                <tbody nz-tbody>
+                    <tr nz-tbody-tr *ngFor="let data of data">
+                        <td nz-td>{{data.name}}</td>
+                        <td nz-td>{{data.age}}</td>
+                        <td nz-td>{{data.address}}</td>
+                    </tr>
+                </tbody>
+            </nz-table>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Selection">
+            <nz-table [nzDataSource]="data" [nzPageSize]="10" (nzDataChange)="_displayDataChange($event)" (nzPageIndexChange)="_refreshStatus()" (nzPageSizeChange)="_refreshStatus()">
+                <thead nz-thead>
+                    <tr>
+                        <th nz-th [nzCheckbox]="true">
+                            <label nz-checkbox [(ngModel)]="_allChecked" [nzIndeterminate]="_indeterminate" (ngModelChange)="_checkAll($event)">
+                            </label>
+                        </th>
+                        <th nz-th><span>Name</span></th>
+                        <th nz-th><span>Age</span></th>
+                        <th nz-th><span>Address</span></th>
+                    </tr>
+                </thead>
+                <tbody nz-tbody>
+                    <tr nz-tbody-tr *ngFor="let data of data">
+                        <td nz-td [nzCheckbox]="true">
+                            <label nz-checkbox [(ngModel)]="data.checked" (ngModelChange)="_refreshStatus($event)">
+                            </label>
+                        </td>
+                        <td nz-td>{{data.name}}</td>
+                        <td nz-td>{{data.age}}</td>
+                        <td nz-td>{{data.address}}</td>
+                    </tr>
+                </tbody>
+            </nz-table>
+        </nz-card>
+    </div>
+    <div nz-col [nzMd]="12">
+        <nz-card nzTitle="Ajax">
+            <nz-table #nzTable2
+                [nzAjaxData]="_ajaxDataSet"
+                [nzShowSizeChanger]="true"
+                [nzLoading]="_ajaxLoading"
+                [nzTotal]="_total"
+                [(nzPageIndex)]="_current"
+                (nzPageIndexChange)="_ajaxRefreshData()"
+                [(nzPageSize)]="_pageSize"
+                (nzPageSizeChange)="_ajaxRefreshData()">
+                <thead nz-thead>
+                <tr>
+                    <th nz-th><span>Name</span></th>
+                    <th nz-th><span>Age</span></th>
+                    <th nz-th><span>Email</span></th>
+                </tr>
+                </thead>
+                <tbody nz-tbody>
+                <tr nz-tbody-tr *ngFor="let i of nzTable2.data">
+                    <td nz-td>
+                        <a>{{i.name.first}} {{i.name.last}}</a>
+                    </td>
+                    <td nz-td>{{i.gender}}</td>
+                    <td nz-td>{{i.email}}</td>
+                </tr>
+                </tbody>
+            </nz-table>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzMd]="24">
+        <nz-card nzTitle="Dynamic Settings">
+            <form nz-form [nzLayout]="'inline'" class="mb-sm">
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Bordered</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_bordered" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Loading</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_loading" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Pagination</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_pagination" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Title</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_title" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Column Header</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_header" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Footer</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_footer" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>Size</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-radio-group [(ngModel)]="_size" [ngModelOptions]="{standalone: true}">
+                            <label nz-radio-button [nzValue]="'default'">
+                                <span>Default</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'middle'">
+                                <span>Middle</span>
+                            </label>
+                            <label nz-radio-button [nzValue]="'small'">
+                                <span>Small</span>
+                            </label>
+                        </nz-radio-group>
+                    </div>
+                </div>
+                <div nz-row nz-form-item>
+                    <div nz-form-label>
+                        <label>No Result</label>
+                    </div>
+                    <div nz-form-control>
+                        <nz-switch [(ngModel)]="_noresult" (ngModelChange)="_toggleData()" [ngModelOptions]="{standalone: true}"></nz-switch>
+                    </div>
+                </div>
+            </form>
+            <nz-table
+                #nzTable
+                [nzDataSource]="_dataSet"
+                [nzPageSize]="10"
+                [nzBordered]="_bordered"
+                [nzLoading]="_loading"
+                [nzIsPagination]="_pagination"
+                [nzShowFooter]="_footer"
+                [nzShowTitle]="_title"
+                [nzSize]="_size">
+                <span nz-table-title>Here is Title</span>
+                <thead nz-thead *ngIf="_header">
+                    <tr>
+                        <th nz-th><span>Name</span></th>
+                        <th nz-th><span>Age</span></th>
+                        <th nz-th><span>Address</span></th>
+                        <th nz-th><span>Action</span></th>
+                    </tr>
+                </thead>
+                <tbody nz-tbody>
+                    <tr nz-tbody-tr *ngFor="let data of nzTable.data">
+                        <td nz-td>{{data.name}}</td>
+                        <td nz-td>{{data.age}}</td>
+                        <td nz-td>{{data.address}}</td>
+                        <td nz-td>
+                            <span>
+                                <a>Action ��� {{data.name}}</a>
+                                <span nz-table-divider></span>
+                                <nz-popconfirm [nzTitle]="'Are you sure���'" [nzOkText]="'ok'" [nzCancelText]="'cancel'" (nzOnConfirm)="confirm()" (nzOnCancel)="cancel()">
+                                    <a nz-popconfirm>Delete</a>
+                                </nz-popconfirm>
+                                <span nz-table-divider></span>
+                                <nz-dropdown>
+                                    <a class="ant-dropdown-link" nz-dropdown>
+                                        More actions <i class="anticon anticon-down"></i>
+                                    </a>
+                                    <ul nz-menu>
+                                        <li nz-menu-item>1st menu item</li>
+                                        <li nz-menu-item>2st menu item</li>
+                                        <li nz-menu-item>3st menu item</li>
+                                    </ul>
+                                </nz-dropdown>
+                            </span>
+                        </td>
+                    </tr>
+                </tbody>
+                <span nz-table-footer>Here is footer</span>
+            </nz-table>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/tables/standard/standard.component.spec.ts b/src/app/routes/tables/standard/standard.component.spec.ts
new file mode 100644
index 0000000..52a5b69
--- /dev/null
+++ b/src/app/routes/tables/standard/standard.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { TableStandardComponent } from './standard.component';
+import { RandomUserService } from '../randomUser.service';
+
+describe('Component: TableStandard', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [TableStandardComponent],
+        providers: [RandomUserService]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(TableStandardComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/tables/standard/standard.component.ts b/src/app/routes/tables/standard/standard.component.ts
new file mode 100644
index 0000000..f7733b7
--- /dev/null
+++ b/src/app/routes/tables/standard/standard.component.ts
@@ -0,0 +1,137 @@
+// tslint:disable:member-ordering
+import { Component, OnInit } from '@angular/core';
+import { RandomUserService } from '../randomUser.service';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+    selector: 'app-table-standard',
+    templateUrl: './standard.component.html'
+})
+export class TableStandardComponent implements OnInit {
+
+    data = [
+        {
+            key: '1',
+            name: 'John Brown',
+            age: 32,
+            address: 'New York No. 1 Lake Park',
+        }, {
+            key: '2',
+            name: 'Jim Green',
+            age: 42,
+            address: 'London No. 1 Lake Park',
+        }, {
+            key: '3',
+            name: 'Joe Black',
+            age: 32,
+            address: 'Sidney No. 1 Lake Park',
+        }
+    ];
+
+    ageSort = '';
+
+    ageSortChange($event) {
+        if ($event === 'ascend') {
+            this.data = [...this.data.sort((a, b) => {
+                return a.age - b.age;
+            })];
+        } else if ($event === 'descend') {
+            this.data = [...this.data.sort((a, b) => {
+                return b.age - a.age;
+            })];
+        }
+    }
+
+    _allChecked = false;
+    _indeterminate = false;
+    _displayData = [];
+
+    _displayDataChange($event) {
+        this._displayData = $event;
+        this._refreshStatus();
+    }
+
+    _refreshStatus() {
+        const allChecked = this._displayData.every(value => value.checked === true);
+        const allUnChecked = this._displayData.every(value => !value.checked);
+        this._allChecked = allChecked;
+        this._indeterminate = (!allChecked) && (!allUnChecked);
+    }
+
+    _checkAll(value) {
+        if (value) {
+            this._displayData.forEach(data => {
+                data.checked = true;
+            });
+        } else {
+            this._displayData.forEach(data => {
+                data.checked = false;
+            });
+        }
+        this._refreshStatus();
+    }
+
+    // ajax
+    _current = 1;
+    _pageSize = 3;
+    _total = 1;
+    _ajaxDataSet = [];
+    _ajaxLoading = true;
+
+    constructor(private _randomUser: RandomUserService, private message: NzMessageService) { }
+
+    _ajaxRefreshData = () => {
+        this._ajaxLoading = true;
+        this._randomUser.getUsers(this._current, this._pageSize).subscribe((data: any) => {
+            this._ajaxLoading = false;
+            this._total = 200;
+            this._ajaxDataSet = data.results;
+        });
+    }
+
+    ngOnInit() {
+        this._ajaxRefreshData();
+
+        this._genData();
+    }
+
+    // dynamic
+    _dataSet = [];
+    _bordered = false;
+    _loading = false;
+    _pagination = true;
+    _header = true;
+    _title = true;
+    _footer = true;
+    _size = 'small';
+    _noresult = false;
+
+    _toggleData() {
+        if (this._noresult) {
+            this._dataSet = [];
+        } else {
+            this._genData();
+        }
+    }
+
+    _genData() {
+        this._dataSet = [];
+        for (let i = 1; i <= 10; i++) {
+            this._dataSet.push({
+                key: i,
+                name: 'John Brown',
+                age: `${i}2`,
+                address: `New York No. ${i} Lake Park`,
+                description: `My name is John Brown, I am ${i}2 years old, living in New York No. ${i} Lake Park.`,
+            });
+        }
+    }
+
+    cancel = function () {
+        this.message.info('click cancel');
+    };
+
+    confirm = () => {
+        this.message.success('click confirm');
+    }
+}
diff --git a/src/app/routes/tables/tables.module.ts b/src/app/routes/tables/tables.module.ts
new file mode 100644
index 0000000..f8d8188
--- /dev/null
+++ b/src/app/routes/tables/tables.module.ts
@@ -0,0 +1,32 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SharedModule } from '@shared/shared.module';
+
+import { TableStandardComponent } from './standard/standard.component';
+import { RandomUserService } from './randomUser.service';
+import { TableFullComponent } from './full/full.component';
+
+const routes: Routes = [
+    { path: 'standard', component: TableStandardComponent },
+    { path: 'full', component: TableFullComponent }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    providers: [ RandomUserService ],
+    declarations: [
+        TableStandardComponent,
+        TableFullComponent
+    ],
+    exports: [
+        RouterModule
+    ],
+    entryComponents: [
+
+    ]
+})
+export class TablesModule { }
diff --git a/src/app/routes/widgets/widgets.module.ts b/src/app/routes/widgets/widgets.module.ts
new file mode 100644
index 0000000..835789f
--- /dev/null
+++ b/src/app/routes/widgets/widgets.module.ts
@@ -0,0 +1,23 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { WidgetsComponent } from './widgets/widgets.component';
+
+const routes: Routes = [
+  { path: '', component: WidgetsComponent }
+];
+
+@NgModule({
+  imports: [
+    SharedModule,
+    RouterModule.forChild(routes)
+  ],
+  declarations: [
+    WidgetsComponent
+  ],
+  exports: [
+    RouterModule
+  ]
+})
+export class WidgetsModule { }
diff --git a/src/app/routes/widgets/widgets/widgets.component.html b/src/app/routes/widgets/widgets/widgets.component.html
new file mode 100644
index 0000000..7f046f3
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.html
@@ -0,0 +1,770 @@
+<div class="content__title">
+    <h1>
+        Widgets
+    </h1>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card>
+            <div class="text-right text-grey"><i class="fa fa-gamepad fa-2x"></i></div>
+            <h3 class="h3">99.999</h3>
+            <p class="text-grey">Games played last month</p>
+            <nz-progress [nzStatus]="'active'" [ngModel]="60" [nzShowInfo]="false" [nzStrokeWidth]="5"></nz-progress>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card>
+            <div class="text-right text-grey"><i class="fa fa-coffee fa-2x"></i></div>
+            <h3 class="h3">300</h3>
+            <p class="text-grey">Coffee cups per day</p>
+            <nz-progress [nzStatus]="'success'" [ngModel]="30" [nzShowInfo]="false" [nzStrokeWidth]="5"></nz-progress>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card>
+            <div class="text-right text-grey"><i class="fa fa-upload fa-2x"></i></div>
+            <h3 class="h3">1000 Gb</h3>
+            <p class="text-grey">Average Monthly Uploads</p>
+            <nz-progress [nzStatus]="'exception'" [ngModel]="10" [nzShowInfo]="false" [nzStrokeWidth]="5"></nz-progress>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card nzNoPadding>
+            <div nz-row>
+                <div nz-col [nzSpan]="12" class="border-right-1 border-bottom-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center text-red">
+                            <i class="fa fa-users fa-2x"></i>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">10k</h4>
+                            <p class="text-grey">VISITORS</p>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col [nzSpan]="12" class="border-bottom-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center text-pink">
+                            <i class="fa fa-music fa-2x"></i>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">100%</h4>
+                            <p class="text-grey">VOLUME</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="12" class="border-right-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center text-grey">
+                            <i class="fa fa-code-fork fa-2x"></i>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">150</h4>
+                            <p class="text-grey">FORKS</p>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col [nzSpan]="12">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center text-green">
+                            <i class="fa fa-inbox fa-2x"></i>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">10</h4>
+                            <p class="text-grey">MESSAGES</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+        <nz-card nzNoPadding>
+            <div nz-row>
+                <div nz-col [nzSpan]="12" class="border-right-1 border-bottom-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center">
+                            <mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">10k</h4>
+                            <p class="text-grey">VISITORS</p>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col [nzSpan]="12" class="border-bottom-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center">
+                            <mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">100%</h4>
+                            <p class="text-grey">VOLUME</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div nz-row>
+                <div nz-col [nzSpan]="12" class="border-right-1">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center">
+                            <mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">150</h4>
+                            <p class="text-grey">FORKS</p>
+                        </div>
+                    </div>
+                </div>
+                <div nz-col [nzSpan]="12">
+                    <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                        <div nz-col [nzSpan]="12" class="text-center">
+                            <mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+                        </div>
+                        <div nz-col [nzSpan]="12" class="py-md">
+                            <h4 class="h4">10</h4>
+                            <p class="text-grey">MESSAGES</p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card nzNoPadding>
+            <div class="half-float half-float-md">
+                <img src="./assets/img/half-float-bg-1.jpg">
+                <div class="half-float-bottom rounded-circle bg-grey-lighter">
+                    <img class="p-sm" src="./assets/img/1.png">
+                </div>
+            </div>
+            <div class="text-center">
+                <h3 class="h3">cipchk</h3>
+                <p class="text-grey">Lead director</p>
+                <p class="p-sm">Voluptate velit id mollit ex. Anim labore non dolore ad cupidatat aute reprehenderit ullamco culpa esse. Esse exercitation laboris culpa ipsum pariatur mollit minim culpa magna.</p>
+            </div>
+            <div class="text-center bg-grey-darker text-white">
+                <div nz-row>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">400</h3>
+                        <p>Photos</p>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">2000</h3>
+                        <p>Likes</p>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">500</h3>
+                        <p>Following</p>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8">
+        <nz-card nzNoPadding>
+            <div class="text-center bg-center py-lg text-white" style="background-image: url('./assets/img/bg9.jpg')">
+                <nz-avatar [nzSrc]="'./assets/img/1.png'" [nzSize]="'large'"></nz-avatar>
+                <h3 class="text-white">cipchk</h3>
+                <p>
+                    <i class="fa fa-github fa-fw"></i>
+                    @cipchk
+                </p>
+            </div>
+            <div class="text-center bg-grey-darker text-white">
+                <div nz-row>
+                    <div nz-col [nzSpan]="8" class="py-md">
+                        <a (click)="msg.success('to twitter')"><i class="fa fa-twitter fa-2x"></i></a>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-md">
+                        <a (click)="msg.success('to facebook')"><i class="fa fa-facebook fa-2x"></i></a>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-md">
+                        <a (click)="msg.success('comment')"><i class="fa fa-comments fa-2x"></i></a>
+                    </div>
+                </div>
+            </div>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <i class="fa fa-fw fa-clock-o text-grey"></i>
+                </div>
+                <div nz-col [nzSpan]="17">Recent Activity</div>
+                <div nz-col [nzSpan]="3"><nz-tag [nzColor]="'blue'">350</nz-tag></div>
+            </div>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <i class="fa fa-fw fa-user text-grey"></i>
+                </div>
+                <div nz-col [nzSpan]="17">Following</div>
+                <div nz-col [nzSpan]="3"><nz-tag [nzColor]="'pink'">150</nz-tag></div>
+            </div>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <i class="fa fa-fw fa-folder-open-o text-grey"></i>
+                </div>
+                <div nz-col [nzSpan]="17">Photos</div>
+                <div nz-col [nzSpan]="3"><nz-tag [nzColor]="'green'">100</nz-tag></div>
+            </div>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <i class="fa fa-fw fa-folder-open-o text-grey"></i>
+                </div>
+                <div nz-col [nzSpan]="17">Article</div>
+                <div nz-col [nzSpan]="3"><nz-tag [nzColor]="'purple'">100</nz-tag></div>
+            </div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-primary rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">123,456</div>
+                <p class="text-nowrap">Website Traffics</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-success rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">234,567K</div>
+                <p class="text-nowrap">Website Impressions</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-orange rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">$458,778</div>
+                <p class="text-nowrap">Total Sales</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-pink rounded-md">
+            <div nz-col nzSpan="12" class="p-md text-white">
+                <div class="h2 mt0">456</div>
+                <p class="text-nowrap">Support Tickets</p>
+            </div>
+            <div nz-col nzSpan="12">
+                <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-primary text-center rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-white">
+                <i class="fa fa-users fa-2x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-white py-md">
+                <h3 class="h3">10k</h3>
+                <p class="text-grey-dark">VISITORS</p>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-pink text-center rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-white">
+                <i class="fa fa-music fa-2x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-white py-md">
+                <h3 class="h3">100%</h3>
+                <p class="text-grey-dark">VOLUME</p>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-grey-darker text-center rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-white">
+                <i class="fa fa-code-fork fa-2x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-white py-md">
+                <h3 class="h3">150</h3>
+                <p class="text-grey-dark">FORKS</p>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-green text-center rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-white">
+                <i class="fa fa-inbox fa-2x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-white py-md">
+                <h3 class="h3">10</h3>
+                <p class="text-grey-dark">NEW MESSAGES</p>
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-green-dark text-white rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-center">
+                <i class="icon-share fa-3x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-green-light p-md">
+                <h2 class="h2 text-white">150</h2>
+                <p class="text-lg text-uppercase">New connections</p>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-red-dark text-white rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-center">
+                <i class="icon-star fa-3x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-red-light p-md">
+                <h2 class="h2 text-white">7000</h2>
+                <p class="text-lg text-uppercase">RATINGS RECEIVED</p>
+            </div>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-warning-dark text-white rounded-md">
+            <div nz-col nzSpan="8" class="p-md text-center">
+                <i class="icon-trophy fa-3x"></i>
+            </div>
+            <div nz-col nzSpan="16" class="bg-warning-light p-md">
+                <h2 class="h2 text-white">15</h2>
+                <p class="text-lg text-uppercase">ACHIEVEMENTS</p>
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-green text-white text-center rounded-md">
+            <div nz-col nzSpan="10" class="p-md">
+                <i class="fa fa-tasks fa-5x"></i>
+            </div>
+            <div nz-col nzSpan="14" class="py-md">
+                <h1 class="text-white">120</h1>
+                <p>New Tasks!</p>
+            </div>
+            <a nz-col nzSpan="24" (click)="msg.info('view')" class="d-block p-sm bg-grey-darker text-white">
+                <div class="float-left">View Details</div>
+                <div class="float-right"><i class="fa fa-chevron-circle-right"></i></div>
+            </a>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-primary text-white text-center rounded-md">
+            <div nz-col nzSpan="10" class="p-md">
+                <i class="fa fa-comments fa-5x"></i>
+            </div>
+            <div nz-col nzSpan="14" class="py-md">
+                <h1 class="text-white">36</h1>
+                <p>New Comments!</p>
+            </div>
+            <a nz-col nzSpan="24" (click)="msg.info('view')" class="d-block p-sm bg-grey-darker text-white">
+                <div class="float-left">View Details</div>
+                <div class="float-right"><i class="fa fa-chevron-circle-right"></i></div>
+            </a>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-warning text-white text-center rounded-md">
+            <div nz-col nzSpan="10" class="p-md">
+                <i class="fa fa-shopping-cart fa-5x"></i>
+            </div>
+            <div nz-col nzSpan="14" class="py-md">
+                <h1 class="text-white">110</h1>
+                <p>New Orders!</p>
+            </div>
+            <a nz-col nzSpan="24" (click)="msg.info('view')" class="d-block p-sm bg-grey-darker text-white">
+                <div class="float-left">View Details</div>
+                <div class="float-right"><i class="fa fa-chevron-circle-right"></i></div>
+            </a>
+        </div>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+        <div nz-row nzType="flex" nzAlign="middle" class="bg-red text-white text-center rounded-md">
+            <div nz-col nzSpan="10" class="p-md">
+                <i class="fa fa-support fa-5x"></i>
+            </div>
+            <div nz-col nzSpan="14" class="py-md">
+                <h1 class="text-white">19</h1>
+                <p>Support Tickets!</p>
+            </div>
+            <a nz-col nzSpan="24" (click)="msg.info('view')" class="d-block p-sm bg-grey-darker text-white">
+                <div class="float-left">View Details</div>
+                <div class="float-right"><i class="fa fa-chevron-circle-right"></i></div>
+            </a>
+        </div>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="8">
+        <nz-card nzTitle="������">
+            <ng-template #extra><a (click)="msg.info('������������')">������������</a></ng-template>
+            <div class="pb-md">
+                <i class="anticon anticon-check-circle-o text-green"></i> ��������� 16 ���
+                <i class="anticon anticon-check-circle-o pl-md"></i> ��������� 4 ���
+            </div>
+            <nz-carousel class="nz-carousel__dot-blue">
+                <div nz-carousel-content>
+                    <div nz-row [nzGutter]="24" class="mb-md">
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-laptop display-2 text-blue"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">������������������</h4>
+                                    <p class="text-grey">Register Server</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-rocket display-2 text-red"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">������������</h4>
+                                    <p class="text-grey">Msg Broker</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div nz-row [nzGutter]="24">
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-usb display-2 text-purple"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">���������������������</h4>
+                                    <p class="text-grey">DRM</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-fork display-2 text-pink"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">���������������������</h4>
+                                    <p class="text-grey">ZDC</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div nz-carousel-content>
+                    <div nz-row [nzGutter]="24" class="mb-md">
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-laptop display-2 text-blue"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">������������������</h4>
+                                    <p class="text-grey">Register Server</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-rocket display-2 text-red"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">������������</h4>
+                                    <p class="text-grey">Msg Broker</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div nz-row [nzGutter]="24">
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-usb display-2 text-purple"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">���������������������</h4>
+                                    <p class="text-grey">DRM</p>
+                                </div>
+                            </div>
+                        </div>
+                        <div nz-col [nzSpan]="12">
+                            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                                <div nz-col [nzSpan]="8">
+                                    <i class="anticon anticon-fork display-2 text-pink"></i>
+                                </div>
+                                <div nz-col [nzSpan]="16">
+                                    <h4 class="fs-md text-blue">���������������������</h4>
+                                    <p class="text-grey">ZDC</p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </nz-carousel>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="8">
+        <nz-card nzTitle="���������������">
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+                <div nz-col [nzSpan]="4">
+                    <i class="anticon anticon-database display-1"></i>
+                </div>
+                <div nz-col [nzSpan]="15">
+                    <h3 class="font-weight-bold">���������������</h3>
+                    <div class="pt-sm text-grey-dark">
+                        <nz-badge [nzStatus]="'error'"></nz-badge>
+                        ���������������������
+                    </div>
+                </div>
+                <div nz-col [nzSpan]="5" class="text-right">
+                    <button nz-button (click)="msg.info('Apply')" [nzType]="'default'" [nzSize]="'large'">
+                        <span>������</span>
+                    </button>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="8">
+        <nz-card nzTitle="������ 1" nzNoPadding>
+            <ng-template #extra>
+                <nz-tooltip [nzTitle]="'������������'">
+                    <span nz-tooltip><i class="anticon anticon-shopping-cart display-3"></i></span>
+                </nz-tooltip>
+            </ng-template>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" [nzGutter]="8">
+                <div nz-col [nzSpan]="12" class="text-center">
+                    ������������ <strong class="display-1 text-blur">12</strong>
+                </div>
+                <div nz-col [nzSpan]="12" class="my-md pl-md border-left-1">
+                    <div class="pb-sm">
+                        <nz-badge [nzStatus]="'success'"></nz-badge>
+                        ��������� <strong class="text-green">2</strong>
+                    </div>
+                    <div class="pb-sm">
+                        <nz-badge [nzStatus]="'default'"></nz-badge>
+                        ������������ <strong class="text-grey">0</strong>
+                    </div>
+                    <div class="pb-sm">
+                        <nz-badge [nzStatus]="'error'"></nz-badge>
+                        ������������ <strong class="text-red">0</strong>
+                    </div>
+                    <div class="pb-sm">
+                        <nz-badge [nzStatus]="'error'"></nz-badge>
+                        ��������� <strong class="text-red">1</strong>
+                    </div>
+                </div>
+            </div>
+            <div nz-row class="text-center border-top-1">
+                <div nz-col [nzSpan]="8" class="bg-grey-lighter-h py-sm point">
+                    ������ <strong class="text-blue">18</strong>
+                </div>
+                <div nz-col [nzSpan]="8" class="bg-grey-lighter-h py-sm point">
+                    ������ <strong>0</strong>
+                </div>
+                <div nz-col [nzSpan]="8" class="bg-grey-lighter-h py-sm point">
+                    ������ <strong class="text-blue">2</strong>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col [nzXs]="24" [nzMd]="12" class="mb-md">
+        <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="bg-white py-md rounded-md">
+            <div nz-col [nzSpan]="3" class="text-center">
+                <span class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon bg-primary">
+                    <i class="icon-speedometer"></i>
+                </span>
+            </div>
+            <div nz-col [nzSpan]="6">
+                <strong class="display-2">10</strong> ���
+                <p class="text-grey">������������������</p>
+            </div>
+            <div nz-col [nzSpan]="5">
+                <nz-badge [nzStatus]="'success'"></nz-badge>
+                ���������
+                <span class="display-3 text-grey-dark">3</span>
+            </div>
+            <div nz-col [nzSpan]="5">
+                <nz-badge [nzStatus]="'processing'"></nz-badge>
+                ������������
+                <span class="display-3 text-grey-dark">5</span>
+            </div>
+            <div nz-col [nzSpan]="5">
+                <nz-badge [nzStatus]="'error'"></nz-badge>
+                ���������
+                <span class="display-3 text-grey-dark">2</span>
+            </div>
+        </div>
+    </div>
+    <div nz-col [nzXs]="24" [nzMd]="12" class="mb-md">
+        <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="bg-white rounded-md border p-md">
+            <div nz-col [nzSpan]="16">
+                ������������������������������
+            </div>
+            <div nz-col [nzSpan]="8" class="text-right">
+                <nz-popconfirm [(nzVisible)]="like" [nzPlacement]="'top'"
+                    [nzTitle]="'������������������������������������'"
+                    [nzOkText]="'������������'" [nzCancelText]="'������������'"
+                    (nzOnConfirm)="msg.success('������������')" (nzOnCancel)="msg.error('������������')"
+                    style="display:inline-block;padding-top:15px;">
+                    <span nz-popconfirm></span>
+                </nz-popconfirm>
+                <span class="pr-lg">
+                    <i class="anticon anticon-like display-3 point" [class.text-primary]="like" (click)="like=!like"></i> ���
+                </span>
+                <i class="anticon anticon-dislike display-3 point" [class.text-primary]="dislike" (click)="dislike=!dislike"></i> ���
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row [nzGutter]="16">
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <nz-card nzNoPadding class="bg-green rounded-md">
+            <div class="p-md">
+                <div class="h5 pb-sm text-white">Received all time</div>
+                <mini-area
+                    color="#fff"
+                    height="46"
+                    [data]="data.visitData"></mini-area>
+            </div>
+            <div class="text-center bg-grey-darker text-white">
+                <div nz-row>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">400</h3>
+                        <p>Photos</p>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">2000</h3>
+                        <p>Likes</p>
+                    </div>
+                    <div nz-col [nzSpan]="8" class="py-sm">
+                        <h3 class="text-white">500</h3>
+                        <p>Following</p>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <nz-card nzNoPadding class="bg-green rounded-md">
+            <div class="p-md">
+                <div class="h5 pb-sm text-white">Monthly incomes</div>
+                <mini-area
+                    color="#fff"
+                    height="46"
+                    [data]="data.visitData"></mini-area>
+            </div>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="bg-grey-darker py-sm text-center">
+                <div nz-col [nzSpan]="16">
+                    <mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></mini-bar>
+                </div>
+                <div nz-col [nzSpan]="8">
+                    <p class="text-white">+150</p>
+                    <p class="text-grey">From last month</p>
+                </div>
+            </div>
+            <div class="py-sm text-center bg-white text-grey">
+                <div nz-row>
+                    <div nz-col [nzSpan]="12">
+                        <p class="text-grey-dark">Gross income</p>
+                        <h4 class="h4">12000</h4>
+                    </div>
+                    <div nz-col [nzSpan]="12">
+                        <p class="text-grey-dark">Net income</p>
+                        <h4 class="h4">5100</h4>
+                    </div>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+        <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="rounded-md bg-blue">
+            <div nz-col nzSpan="16">
+                <img class="img-fluid align-middle" src="./assets/img/bg1.jpg" alt="" />
+            </div>
+            <div nz-col nzSpan="8" class="text-white text-center">
+                <h2 class="h1 text-white">11��</h2>
+                <p class="py-sm">Cold</p>
+                <i class="fa fa-sun-o fa-2x"></i>
+            </div>
+        </div>
+    </div>
+</div>
+<div nz-row nzGutter="16">
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card class="ant-card__img">
+            <img class="img" src="//os.alipayobjects.com/rmsportal/GhjqstwSgxBXrZS.png">
+            <div class="p-md">
+                <h3 class="h3">ANT DESIGN</h3>
+                <p class="text-grey">A UI Design Language</p>
+                <ol class="list-styled text-lg pt-md">
+                    <li>Designed by experienced team, and showcase dozens of inspiring projects.</li>
+                    <li>Provide solutions for usual problems that may be encountered while developing enterprise-like complex UIs.</li>
+                    <li>Dozens of flexible and practical reusable components that increase your productivity.</li>
+                </ol>
+                <p class="pt-md">
+                    <a class="text-grey" href="//ng.ant.design" target="_blank">View Site...</a>
+                </p>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card [nzTitle]="nzTitle" nzNoPadding>
+            <ng-template #nzTitle>
+                Recent Posts
+                <small class="text-sm font-weight-normal">Venenatis portauam Inceptos ameteiam</small>
+            </ng-template>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point"
+                *ngFor="let item of todoData">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <nz-avatar [nzSrc]="'./assets/img/' + item.avatar + '.png'" [nzSize]="'large'"></nz-avatar>
+                </div>
+                <div nz-col [nzSpan]="20">
+                    <strong>{{item.name}}</strong>
+                    <p>{{item.content}}</p>
+                </div>
+            </div>
+        </nz-card>
+    </div>
+    <div nz-col nzXs="24" nzMd="12">
+        <nz-card nzTitle="Todo lists" nzNoPadding>
+            <div nz-row [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'" class="py-sm bg-grey-lighter-h point"
+                *ngFor="let item of todoData">
+                <div nz-col [nzSpan]="4" class="text-center">
+                    <nz-avatar [nzSrc]="'./assets/img/' + item.avatar + '.png'" [nzSize]="'large'"></nz-avatar>
+                </div>
+                <div nz-col [nzSpan]="18">
+                    <strong>{{item.name}}</strong>
+                    <p [class.text-deleted]="item.completed">{{item.content}}</p>
+                </div>
+                <div nz-col [nzSpan]="2" class="text-right pr-md">
+                    <nz-dropdown [nzPlacement]="'topRight'">
+                        <i nz-dropdown class="icon-options-vertical"></i>
+                        <ul nz-menu>
+                            <li nz-menu-item *ngIf="item.completed" (click)="item.completed=false">Active</li>
+                            <li nz-menu-item *ngIf="!item.completed" (click)="item.completed=true">Completed</li>
+                            <li nz-menu-item (click)="todoData.splice(todoData.indexOf(item), 1)">Delted</li>
+                        </ul>
+                    </nz-dropdown>
+
+                </div>
+            </div>
+        </nz-card>
+    </div>
+</div>
diff --git a/src/app/routes/widgets/widgets/widgets.component.less b/src/app/routes/widgets/widgets/widgets.component.less
new file mode 100644
index 0000000..11362e0
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.less
@@ -0,0 +1,5 @@
+nz-carousel {
+    .slick-dots {
+        bottom: -10px !important;
+    }
+}
diff --git a/src/app/routes/widgets/widgets/widgets.component.spec.ts b/src/app/routes/widgets/widgets/widgets.component.spec.ts
new file mode 100644
index 0000000..57851c0
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '../../../../testing/common.spec';
+
+import { WidgetsComponent } from './widgets.component';
+
+describe('Comoponent: Widgets', () => {
+    setUpTestBed(<TestModuleMetadata>{
+        declarations: [ WidgetsComponent ]
+    });
+
+    it('should create an instance', () => {
+        const fixture = TestBed.createComponent(WidgetsComponent);
+        const comp = fixture.debugElement.componentInstance;
+        expect(comp).toBeTruthy();
+    });
+});
diff --git a/src/app/routes/widgets/widgets/widgets.component.ts b/src/app/routes/widgets/widgets/widgets.component.ts
new file mode 100644
index 0000000..a2048ba
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.ts
@@ -0,0 +1,31 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component } from '@angular/core';
+import { getFakeChartData } from '../../../../../_mock/chart.service';
+
+@Component({
+    selector: 'app-widgets',
+    templateUrl: './widgets.component.html',
+    styleUrls: ['./widgets.component.less']
+})
+export class WidgetsComponent {
+
+    webSite = [ ...getFakeChartData.visitData.slice(0, 10) ];
+    data = getFakeChartData;
+
+    todoData: any[] = [
+        { completed: true, avatar: '1', name: '���������', content: `������������������������������������������` },
+        { completed: false, avatar: '2', name: '������������', content: `���������������������������������������` },
+        { completed: false, avatar: '3', name: 'cipchk', content: `this world was never meant for one as beautiful as you.` },
+        { completed: false, avatar: '4', name: 'Kent', content: `my heart is beating with hers` },
+        { completed: false, avatar: '5', name: 'Are you', content: `They always said that I love beautiful girl than my friends` },
+        { completed: false, avatar: '6', name: 'Forever', content: `Walking through green fields ���sunshine in my eyes.` }
+    ];
+
+    like = false;
+
+    dislike = false;
+
+    constructor(public msg: NzMessageService) {
+
+    }
+}
diff --git a/src/assets/app-data.json b/src/assets/app-data.json
new file mode 100644
index 0000000..817647b
--- /dev/null
+++ b/src/assets/app-data.json
@@ -0,0 +1,408 @@
+{
+    "app": {
+        "name": "Alain",
+        "description": "Ng-zorro admin panel front-end framework"
+    },
+    "user": {
+        "name": "Admin",
+        "avatar": "./assets/img/zorro.svg",
+        "email": "cipchk@qq.com"
+    },
+    "menu": [{
+        "text": "���������",
+        "translate": "main_navigation",
+        "group": true,
+        "children": [{
+            "text": "���������",
+            "translate": "dashboard",
+            "link": "/dashboard",
+            "icon": "icon-speedometer",
+            "children": [{
+                "text": "���������V1",
+                "link": "/dashboard/v1",
+                "translate": "dashboard_v1"
+            }, {
+                "text": "���������",
+                "link": "/dashboard/analysis",
+                "translate": "dashboard_analysis"
+            }, {
+                "text": "Monitor",
+                "link": "/dashboard/monitor",
+                "translate": "dashboard_monitor"
+            }, {
+                "text": "Workplace",
+                "link": "/dashboard/workplace",
+                "translate": "dashboard_workplace"
+            }]
+        }, {
+            "text": "������������",
+            "translate": "shortcut",
+            "icon": "icon-rocket",
+            "shortcut_root": true,
+            "children": []
+        }, {
+            "text": "���������",
+            "translate": "widgets",
+            "link": "/widgets",
+            "icon": "icon-grid",
+            "badge": 2
+        }]
+    }, {
+        "text": "������",
+        "translate": "component",
+        "group": true,
+        "children": [{
+            "text": "������������",
+            "translate": "elements",
+            "link": "/elements",
+            "icon": "icon-chemistry",
+            "acl": "role-a",
+            "children": [{
+                "text": "������",
+                "link": "/elements/buttons",
+                "translate": "buttons",
+                "shortcut": true
+            }, {
+                "text": "Notification",
+                "link": "/elements/notification",
+                "translate": "notification",
+                "shortcut": true
+            }, {
+                "text": "Modal",
+                "link": "/elements/modal",
+                "translate": "modal"
+            }, {
+                "text": "SweetAlert",
+                "link": "/elements/sweetalert",
+                "translate": "sweetalert"
+            }, {
+                "text": "Tree Antd",
+                "link": "/elements/tree-antd",
+                "translate": "tree-antd"
+            }, {
+                "text": "Sortable",
+                "link": "/elements/sortable",
+                "translate": "sortable"
+            }, {
+                "text": "Spin",
+                "link": "/elements/spin",
+                "translate": "spin"
+            }, {
+                "text": "Dropdown",
+                "link": "/elements/dropdown",
+                "translate": "dropdown"
+            }, {
+                "text": "Grid",
+                "link": "/elements/grid",
+                "translate": "grid"
+            }, {
+                "text": "Grid Masonry",
+                "link": "/elements/gridmasonry",
+                "translate": "gridmasonry"
+            }, {
+                "text": "Typography",
+                "link": "/elements/typography",
+                "translate": "typography"
+            }, {
+                "text": "Font Icons",
+                "link": "/elements/iconsfont",
+                "translate": "iconsfont"
+            }, {
+                "text": "Colors",
+                "link": "/elements/colors",
+                "translate": "colors"
+            }]
+        }, {
+            "text": "������",
+            "translate": "forms",
+            "link": "/forms",
+            "icon": "icon-note",
+            "acl": "role-a",
+            "children": [{
+                "text": "������",
+                "link": "/forms/standard",
+                "translate": "standard"
+            }, {
+                "text": "������",
+                "link": "/forms/extended",
+                "translate": "extended"
+            }, {
+                "text": "������",
+                "link": "/forms/validation",
+                "translate": "validation"
+            }, {
+                "text": "������",
+                "link": "/forms/upload",
+                "translate": "upload",
+                "shortcut": true
+            }, {
+                "text": "������������",
+                "link": "/forms/cropper",
+                "translate": "cropper"
+            }]
+        }, {
+            "text": "Charts",
+            "translate": "charts",
+            "link": "/charts",
+            "icon": "icon-graph",
+            "acl": "role-a",
+            "children": [{
+                "text": "G2",
+                "link": "/charts/g2"
+            }]
+        }, {
+            "text": "������",
+            "translate": "tables",
+            "link": "/tables",
+            "icon": "icon-grid",
+            "acl": "role-b",
+            "children": [{
+                "text": "������",
+                "link": "/tables/standard",
+                "translate": "standard"
+            }, {
+                "text": "Full",
+                "link": "/tables/full",
+                "translate": "full"
+            }]
+        }, {
+            "text": "������",
+            "translate": "maps",
+            "link": "/maps",
+            "icon": "icon-map",
+            "acl": "role-b",
+            "children": [{
+                "text": "QQ",
+                "link": "/maps/qq",
+                "translate": "qq"
+            }, {
+                "text": "Baidu",
+                "link": "/maps/baidu",
+                "translate": "baidu"
+            }]
+        }]
+    }, {
+        "text": "Pro",
+        "translate": "pro",
+        "group": true,
+        "children": [{
+            "text": "Form Page",
+            "translate": "form",
+            "link": "/pro/form",
+            "icon": "icon-note",
+            "children": [{
+                "text": "Step Form",
+                "link": "/pro/form/step-form",
+                "translate": "step-form"
+            }, {
+                "text": "Advanced Form",
+                "link": "/pro/form/advanced-form",
+                "translate": "advanced-form"
+            }]
+        }, {
+            "text": "List",
+            "translate": "pro-list",
+            "link": "/pro/list",
+            "icon": "icon-grid",
+            "children": [{
+                "text": "Table List",
+                "link": "/pro/list/table-list",
+                "translate": "pro-table-list"
+            }, {
+                "text": "Basic List",
+                "link": "/pro/list/basic-list",
+                "translate": "pro-basic-list"
+            }, {
+                "text": "Card List",
+                "link": "/pro/list/card-list",
+                "translate": "pro-card-list"
+            }, {
+                "text": "Cover Card List",
+                "link": "/pro/list/cover-card-list",
+                "translate": "pro-cover-card-list"
+            }, {
+                "text": "Filter Card List",
+                "link": "/pro/list/filter-card-list",
+                "translate": "pro-filter-card-list"
+            }, {
+                "text": "Search",
+                "link": "/pro/list/search",
+                "translate": "pro-search"
+            }]
+        }, {
+            "text": "Profile",
+            "translate": "pro-profile",
+            "link": "/pro/profile",
+            "icon": "icon-book-open",
+            "children": [{
+                "text": "Basic",
+                "link": "/pro/profile/basic",
+                "translate": "pro-profile-basic"
+            }, {
+                "text": "Advanced",
+                "link": "/pro/profile/advanced",
+                "translate": "pro-profile-advanced"
+            }]
+        }, {
+            "text": "Result",
+            "translate": "pro-result",
+            "link": "/pro/result",
+            "icon": "icon-check",
+            "children": [{
+                "text": "Success",
+                "link": "/pro/result/success",
+                "translate": "pro-result-success"
+            }, {
+                "text": "Fail",
+                "link": "/pro/result/fail",
+                "translate": "pro-result-fail"
+            }]
+        }, {
+            "text": "Exception",
+            "translate": "pro-exception",
+            "link": "/pro/exception",
+            "icon": "icon-fire",
+            "children": [{
+                "text": "403",
+                "link": "/pro/exception/403"
+            }, {
+                "text": "404",
+                "link": "/pro/exception/404"
+            }, {
+                "text": "500",
+                "link": "/pro/exception/500"
+            }]
+        }, {
+            "text": "User",
+            "translate": "pro-user",
+            "link": "/pro/user",
+            "icon": "icon-user",
+            "children": [{
+                "text": "login",
+                "link": "/pro/user/login",
+                "translate": "pro-login"
+            }, {
+                "text": "register",
+                "link": "/pro/user/register",
+                "translate": "pro-register"
+            }, {
+                "text": "register result",
+                "link": "/pro/user/register-result",
+                "translate": "pro-register-result"
+            }]
+        }]
+    }, {
+        "text": "More",
+        "translate": "more",
+        "group": true,
+        "children": [{
+            "text": "Common Logics",
+            "translate": "logics",
+            "link": "/logics",
+            "icon": "icon-compass",
+            "children": [{
+                "text": "ACL",
+                "link": "/logics/acl",
+                "translate": "acl"
+            },
+            {
+                "text": "Route Guard",
+                "link": "/logics/guard",
+                "translate": "guard",
+                "acl": "admin"
+            },
+            {
+                "text": "Down File",
+                "link": "/logics/downfile",
+                "translate": "downfile",
+                "shortcut": true
+            }]
+        }, {
+            "text": "Report",
+            "translate": "report",
+            "icon": "anticon anticon-cloud-o",
+            "children": [{
+                "text": "Relation",
+                "link": "/data-v/relation",
+                "translate": "relation",
+                "target": "_blank",
+                "shortcut": true
+            }]
+        }, {
+            "text": "Pages",
+            "translate": "pages",
+            "link": "/pages",
+            "icon": "icon-doc",
+            "acl": "admin",
+            "children": [{
+                "text": "Login",
+                "link": "/login",
+                "translate": "m-login"
+            }, {
+                "text": "Register",
+                "link": "/register",
+                "translate": "m-register"
+            }, {
+                "text": "Forget",
+                "link": "/forget",
+                "translate": "m-forget"
+            }, {
+                "text": "Lock",
+                "link": "/lock",
+                "translate": "m-lock"
+            }, {
+                "text": "404",
+                "link": "/404"
+            }, {
+                "text": "500",
+                "link": "/500"
+            }, {
+                "text": "Maintenance",
+                "link": "/maintenance",
+                "translate": "maintenance"
+            }]
+        }, {
+            "text": "Extras",
+            "translate": "extras",
+            "link": "/extras",
+            "icon": "icon-cup",
+            "children": [{
+                "text": "Blog",
+                "link": "/extras/blog",
+                "translate": "blog",
+                "children": [{
+                    "text": "List",
+                    "link": "/extras/blog/list",
+                    "translate": "list",
+                    "badge": 1,
+                    "badge_dot": true
+                },{
+                    "text": "Comment",
+                    "link": "/extras/blog/comment",
+                    "translate": "comment"
+                },{
+                    "text": "Post",
+                    "link": "/extras/blog/post",
+                    "translate": "post"
+                },{
+                    "text": "WebSite",
+                    "externalLink": "//github.com/cipchk/ng-alain",
+                    "target": "_blank",
+                    "translate": "website"
+                }]
+            }, {
+                "text": "Help Center",
+                "link": "/extras/helpcenter",
+                "translate": "helpcenter"
+            }, {
+                "text": "Settings",
+                "link": "/extras/settings",
+                "translate": "settings"
+            }, {
+                "text": "Poi",
+                "link": "/extras/poi",
+                "translate": "poi"
+            }]
+        }]
+    }]
+}
diff --git a/src/assets/demo.docx b/src/assets/demo.docx
new file mode 100644
index 0000000..06974cc
--- /dev/null
+++ b/src/assets/demo.docx
Binary files differ
diff --git a/src/assets/demo.pdf b/src/assets/demo.pdf
new file mode 100644
index 0000000..73d3d8c
--- /dev/null
+++ b/src/assets/demo.pdf
Binary files differ
diff --git a/src/assets/demo.pptx b/src/assets/demo.pptx
new file mode 100644
index 0000000..e794dac
--- /dev/null
+++ b/src/assets/demo.pptx
Binary files differ
diff --git a/src/assets/demo.xlsx b/src/assets/demo.xlsx
new file mode 100644
index 0000000..6741fb4
--- /dev/null
+++ b/src/assets/demo.xlsx
Binary files differ
diff --git a/src/assets/environments/environment.chore.ts b/src/assets/environments/environment.chore.ts
new file mode 100644
index 0000000..bb3034e
--- /dev/null
+++ b/src/assets/environments/environment.chore.ts
@@ -0,0 +1,6 @@
+export const environment = {
+    SERVER_URL: `./`,
+    production: true,
+    hmr: false,
+    useHash: false
+};
diff --git a/src/assets/environments/environment.hmr.ts b/src/assets/environments/environment.hmr.ts
new file mode 100644
index 0000000..687d0b9
--- /dev/null
+++ b/src/assets/environments/environment.hmr.ts
@@ -0,0 +1,6 @@
+export const environment = {
+    SERVER_URL: `./`,
+    production: true,
+    hmr: true,
+    useHash: true
+};
diff --git a/src/assets/environments/environment.prod.ts b/src/assets/environments/environment.prod.ts
new file mode 100644
index 0000000..3f794b3
--- /dev/null
+++ b/src/assets/environments/environment.prod.ts
@@ -0,0 +1,6 @@
+export const environment = {
+    SERVER_URL: `./`,
+    production: true,
+    hmr: false,
+    useHash: true
+};
diff --git a/src/assets/environments/environment.ts b/src/assets/environments/environment.ts
new file mode 100644
index 0000000..45c90c7
--- /dev/null
+++ b/src/assets/environments/environment.ts
@@ -0,0 +1,11 @@
+// The file contents for the current environment will overwrite these during build.
+// The build system defaults to the dev environment which uses `environment.ts`, but if you do
+// `ng build --env=prod` then `environment.prod.ts` will be used instead.
+// The list of which env maps to which file can be found in `.angular-cli.json`.
+
+export const environment = {
+    SERVER_URL: `./`,
+    production: false,
+    hmr: false,
+    useHash: true
+};
diff --git a/src/assets/iconsfont.json b/src/assets/iconsfont.json
new file mode 100644
index 0000000..0d6771e
--- /dev/null
+++ b/src/assets/iconsfont.json
@@ -0,0 +1,2310 @@
+[{
+        "title": "antd: Directional Icons",
+        "prefix": "anticon anticon-",
+        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
+        "list": [{
+            "k": "step-backward"
+        }, {
+            "k": "step-forward"
+        }, {
+            "k": "fast-backward"
+        }, {
+            "k": "fast-forward"
+        }, {
+            "k": "shrink"
+        }, {
+            "k": "arrows-alt"
+        }, {
+            "k": "down"
+        }, {
+            "k": "up"
+        }, {
+            "k": "left"
+        }, {
+            "k": "right"
+        }, {
+            "k": "caret-up"
+        }, {
+            "k": "caret-down"
+        }, {
+            "k": "caret-left"
+        }, {
+            "k": "caret-right"
+        }, {
+            "k": "up-circle"
+        }, {
+            "k": "down-circle"
+        }, {
+            "k": "left-circle"
+        }, {
+            "k": "right-circle"
+        }, {
+            "k": "up-circle-o"
+        }, {
+            "k": "down-circle-o"
+        }, {
+            "k": "right-circle-o"
+        }, {
+            "k": "left-circle-o"
+        }, {
+            "k": "double-right"
+        }, {
+            "k": "double-left"
+        }, {
+            "k": "verticle-left"
+        }, {
+            "k": "verticle-right"
+        }, {
+            "k": "forward"
+        }, {
+            "k": "backward"
+        }, {
+            "k": "rollback"
+        }, {
+            "k": "enter"
+        }, {
+            "k": "retweet"
+        }, {
+            "k": "swap"
+        }, {
+            "k": "swap-left"
+        }, {
+            "k": "swap-right"
+        }, {
+            "k": "arrow-up"
+        }, {
+            "k": "arrow-down"
+        }, {
+            "k": "arrow-left"
+        }, {
+            "k": "arrow-right"
+        }, {
+            "k": "play-circle"
+        }, {
+            "k": "play-circle-o"
+        }, {
+            "k": "up-square"
+        }, {
+            "k": "down-square"
+        }, {
+            "k": "left-square"
+        }, {
+            "k": "right-square"
+        }, {
+            "k": "up-square-o"
+        }, {
+            "k": "down-square-o"
+        }, {
+            "k": "left-square-o"
+        }, {
+            "k": "right-square-o"
+        }, {
+            "k": "login"
+        }, {
+            "k": "logout"
+        }, {
+            "k": "menu-fold"
+        }, {
+            "k": "menu-unfold"
+        }]
+    },
+    {
+        "title": "antd: Suggested Icons",
+        "prefix": "anticon anticon-",
+        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
+        "list": [{
+            "k": "question"
+        }, {
+            "k": "question-circle-o"
+        }, {
+            "k": "question-circle"
+        }, {
+            "k": "plus"
+        }, {
+            "k": "plus-circle-o"
+        }, {
+            "k": "plus-circle"
+        }, {
+            "k": "pause"
+        }, {
+            "k": "pause-circle-o"
+        }, {
+            "k": "pause-circle"
+        }, {
+            "k": "minus"
+        }, {
+            "k": "minus-circle-o"
+        }, {
+            "k": "minus-circle"
+        }, {
+            "k": "plus-square"
+        }, {
+            "k": "plus-square-o"
+        }, {
+            "k": "minus-square"
+        }, {
+            "k": "minus-square-o"
+        }, {
+            "k": "info"
+        }, {
+            "k": "info-circle-o"
+        }, {
+            "k": "info-circle"
+        }, {
+            "k": "exclamation"
+        }, {
+            "k": "exclamation-circle-o"
+        }, {
+            "k": "exclamation-circle"
+        }, {
+            "k": "close"
+        }, {
+            "k": "close-circle"
+        }, {
+            "k": "close-circle-o"
+        }, {
+            "k": "close-square"
+        }, {
+            "k": "close-square-o"
+        }, {
+            "k": "check"
+        }, {
+            "k": "check-circle"
+        }, {
+            "k": "check-circle-o"
+        }, {
+            "k": "check-square"
+        }, {
+            "k": "check-square-o"
+        }, {
+            "k": "clock-circle-o"
+        }, {
+            "k": "clock-circle"
+        }]
+    },
+    {
+        "title": "antd: Application Icons",
+        "prefix": "anticon anticon-",
+        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
+        "list": [{
+            "k": "android"
+        }, {
+            "k": "android-o"
+        }, {
+            "k": "apple"
+        }, {
+            "k": "apple-o"
+        }, {
+            "k": "windows"
+        }, {
+            "k": "windows-o"
+        }, {
+            "k": "ie"
+        }, {
+            "k": "chrome"
+        }, {
+            "k": "github"
+        }, {
+            "k": "aliwangwang"
+        }, {
+            "k": "aliwangwang-o"
+        }, {
+            "k": "dingding"
+        }, {
+            "k": "dingding-o"
+        }]
+    },
+    {
+        "title": "antd: Application Icons",
+        "prefix": "anticon anticon-",
+        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
+        "list": [{
+            "k": "lock"
+        }, {
+            "k": "unlock"
+        }, {
+            "k": "area-chart"
+        }, {
+            "k": "pie-chart"
+        }, {
+            "k": "bar-chart"
+        }, {
+            "k": "dot-chart"
+        }, {
+            "k": "bars"
+        }, {
+            "k": "book"
+        }, {
+            "k": "calendar"
+        }, {
+            "k": "cloud"
+        }, {
+            "k": "cloud-download"
+        }, {
+            "k": "code"
+        }, {
+            "k": "code-o"
+        }, {
+            "k": "copy"
+        }, {
+            "k": "credit-card"
+        }, {
+            "k": "delete"
+        }, {
+            "k": "desktop"
+        }, {
+            "k": "download"
+        }, {
+            "k": "edit"
+        }, {
+            "k": "ellipsis"
+        }, {
+            "k": "file"
+        }, {
+            "k": "file-text"
+        }, {
+            "k": "file-unknown"
+        }, {
+            "k": "file-pdf"
+        }, {
+            "k": "file-excel"
+        }, {
+            "k": "file-jpg"
+        }, {
+            "k": "file-ppt"
+        }, {
+            "k": "file-add"
+        }, {
+            "k": "folder"
+        }, {
+            "k": "folder-open"
+        }, {
+            "k": "folder-add"
+        }, {
+            "k": "hdd"
+        }, {
+            "k": "frown"
+        }, {
+            "k": "frown-o"
+        }, {
+            "k": "meh"
+        }, {
+            "k": "meh-o"
+        }, {
+            "k": "smile"
+        }, {
+            "k": "smile-o"
+        }, {
+            "k": "inbox"
+        }, {
+            "k": "laptop"
+        }, {
+            "k": "appstore-o"
+        }, {
+            "k": "appstore"
+        }, {
+            "k": "line-chart"
+        }, {
+            "k": "link"
+        }, {
+            "k": "mail"
+        }, {
+            "k": "mobile"
+        }, {
+            "k": "notification"
+        }, {
+            "k": "paper-clip"
+        }, {
+            "k": "picture"
+        }, {
+            "k": "poweroff"
+        }, {
+            "k": "reload"
+        }, {
+            "k": "search"
+        }, {
+            "k": "setting"
+        }, {
+            "k": "share-alt"
+        }, {
+            "k": "shopping-cart"
+        }, {
+            "k": "tablet"
+        }, {
+            "k": "tag"
+        }, {
+            "k": "tag-o"
+        }, {
+            "k": "tags"
+        }, {
+            "k": "tags-o"
+        }, {
+            "k": "to-top"
+        }, {
+            "k": "upload"
+        }, {
+            "k": "user"
+        }, {
+            "k": "video-camera"
+        }, {
+            "k": "home"
+        }, {
+            "k": "loading"
+        }, {
+            "k": "loading-3-quarters"
+        }, {
+            "k": "cloud-upload-o"
+        }, {
+            "k": "cloud-download-o"
+        }, {
+            "k": "cloud-upload"
+        }, {
+            "k": "cloud-o"
+        }, {
+            "k": "star-o"
+        }, {
+            "k": "star"
+        }, {
+            "k": "heart-o"
+        }, {
+            "k": "heart"
+        }, {
+            "k": "environment"
+        }, {
+            "k": "environment-o"
+        }, {
+            "k": "eye"
+        }, {
+            "k": "eye-o"
+        }, {
+            "k": "camera"
+        }, {
+            "k": "camera-o"
+        }, {
+            "k": "save"
+        }, {
+            "k": "team"
+        }, {
+            "k": "solution"
+        }, {
+            "k": "phone"
+        }, {
+            "k": "filter"
+        }, {
+            "k": "exception"
+        }, {
+            "k": "export"
+        }, {
+            "k": "customer-service"
+        }, {
+            "k": "qrcode"
+        }, {
+            "k": "scan"
+        }, {
+            "k": "like"
+        }, {
+            "k": "like-o"
+        }, {
+            "k": "dislike"
+        }, {
+            "k": "dislike-o"
+        }, {
+            "k": "message"
+        }, {
+            "k": "pay-circle"
+        }, {
+            "k": "pay-circle-o"
+        }, {
+            "k": "calculator"
+        }, {
+            "k": "pushpin"
+        }, {
+            "k": "pushpin-o"
+        }, {
+            "k": "bulb"
+        }, {
+            "k": "select"
+        }, {
+            "k": "switcher"
+        }, {
+            "k": "rocket"
+        }, {
+            "k": "bell"
+        }, {
+            "k": "disconnect"
+        }, {
+            "k": "database"
+        }, {
+            "k": "compass"
+        }, {
+            "k": "barcode"
+        }, {
+            "k": "hourglass"
+        }, {
+            "k": "key"
+        }, {
+            "k": "flag"
+        }, {
+            "k": "layout"
+        }, {
+            "k": "printer"
+        }, {
+            "k": "sound"
+        }, {
+            "k": "usb"
+        }, {
+            "k": "skin"
+        }, {
+            "k": "tool"
+        }, {
+            "k": "sync"
+        }, {
+            "k": "wifi"
+        }, {
+            "k": "car"
+        }, {
+            "k": "schedule"
+        }, {
+            "k": "user-add"
+        }, {
+            "k": "user-delete"
+        }, {
+            "k": "usergroup-add"
+        }, {
+            "k": "usergroup-delete"
+        }, {
+            "k": "man"
+        }, {
+            "k": "woman"
+        }, {
+            "k": "shop"
+        }, {
+            "k": "gift"
+        }, {
+            "k": "idcard"
+        }, {
+            "k": "medicine-box"
+        }, {
+            "k": "red-envelope"
+        }, {
+            "k": "coffee"
+        }, {
+            "k": "copyright"
+        }, {
+            "k": "trademark"
+        }, {
+            "k": "safety"
+        }, {
+            "k": "wallet"
+        }, {
+            "k": "bank"
+        }, {
+            "k": "trophy"
+        }, {
+            "k": "contacts"
+        }, {
+            "k": "global"
+        }, {
+            "k": "shake"
+        }, {
+            "k": "api"
+        }, {
+            "k": "fork"
+        }]
+    },
+    {
+        "title": "antd: Brand and Logos",
+        "prefix": "anticon anticon-",
+        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
+        "list": [{
+            "k": "android"
+        }, {
+            "k": "android-o"
+        }, {
+            "k": "apple"
+        }, {
+            "k": "apple-o"
+        }, {
+            "k": "windows"
+        }, {
+            "k": "windows-o"
+        }, {
+            "k": "ie"
+        }, {
+            "k": "chrome"
+        }, {
+            "k": "github"
+        }, {
+            "k": "aliwangwang"
+        }, {
+            "k": "aliwangwang-o"
+        }, {
+            "k": "dingding"
+        }, {
+            "k": "dingding-o"
+        }]
+    },
+    {
+        "title": "Simple Line icons",
+        "prefix": "icon-",
+        "tpl": "<i class=\"icon-{0}\"></i>",
+        "list": [{
+            "k": "user"
+        }, {
+            "k": "people"
+        }, {
+            "k": "user-female"
+        }, {
+            "k": "user-follow"
+        }, {
+            "k": "user-following"
+        }, {
+            "k": "user-unfollow"
+        }, {
+            "k": "login"
+        }, {
+            "k": "logout"
+        }, {
+            "k": "emotsmile"
+        }, {
+            "k": "phone"
+        }, {
+            "k": "call-end"
+        }, {
+            "k": "call-in"
+        }, {
+            "k": "call-out"
+        }, {
+            "k": "map"
+        }, {
+            "k": "location-pin"
+        }, {
+            "k": "direction"
+        }, {
+            "k": "directions"
+        }, {
+            "k": "compass"
+        }, {
+            "k": "layers"
+        }, {
+            "k": "menu"
+        }, {
+            "k": "list"
+        }, {
+            "k": "options-vertical"
+        }, {
+            "k": "options"
+        }, {
+            "k": "arrow-down"
+        }, {
+            "k": "arrow-left"
+        }, {
+            "k": "arrow-right"
+        }, {
+            "k": "arrow-up"
+        }, {
+            "k": "arrow-up-circle"
+        }, {
+            "k": "arrow-left-circle"
+        }, {
+            "k": "arrow-right-circle"
+        }, {
+            "k": "arrow-down-circle"
+        }, {
+            "k": "check"
+        }, {
+            "k": "clock"
+        }, {
+            "k": "plus"
+        }, {
+            "k": "close"
+        }, {
+            "k": "trophy"
+        }, {
+            "k": "screen-smartphone"
+        }, {
+            "k": "screen-desktop"
+        }, {
+            "k": "plane"
+        }, {
+            "k": "notebook"
+        }, {
+            "k": "mustache"
+        }, {
+            "k": "mouse"
+        }, {
+            "k": "magnet"
+        }, {
+            "k": "energy"
+        }, {
+            "k": "disc"
+        }, {
+            "k": "cursor"
+        }, {
+            "k": "cursor-move"
+        }, {
+            "k": "crop"
+        }, {
+            "k": "chemistry"
+        }, {
+            "k": "speedometer"
+        }, {
+            "k": "shield"
+        }, {
+            "k": "screen-tablet"
+        }, {
+            "k": "magic-wand"
+        }, {
+            "k": "hourglass"
+        }, {
+            "k": "graduation"
+        }, {
+            "k": "ghost"
+        }, {
+            "k": "game-controller"
+        }, {
+            "k": "fire"
+        }, {
+            "k": "eyeglass"
+        }, {
+            "k": "envelope-open"
+        }, {
+            "k": "envelope-letter"
+        }, {
+            "k": "bell"
+        }, {
+            "k": "badge"
+        }, {
+            "k": "anchor"
+        }, {
+            "k": "wallet"
+        }, {
+            "k": "vector"
+        }, {
+            "k": "speech"
+        }, {
+            "k": "puzzle"
+        }, {
+            "k": "printer"
+        }, {
+            "k": "present"
+        }, {
+            "k": "playlist"
+        }, {
+            "k": "pin"
+        }, {
+            "k": "picture"
+        }, {
+            "k": "handbag"
+        }, {
+            "k": "globe-alt"
+        }, {
+            "k": "globe"
+        }, {
+            "k": "folder-alt"
+        }, {
+            "k": "folder"
+        }, {
+            "k": "film"
+        }, {
+            "k": "feed"
+        }, {
+            "k": "drop"
+        }, {
+            "k": "drawar"
+        }, {
+            "k": "docs"
+        }, {
+            "k": "doc"
+        }, {
+            "k": "diamond"
+        }, {
+            "k": "cup"
+        }, {
+            "k": "calculator"
+        }, {
+            "k": "bubbles"
+        }, {
+            "k": "briefcase"
+        }, {
+            "k": "book-open"
+        }, {
+            "k": "basket-loaded"
+        }, {
+            "k": "basket"
+        }, {
+            "k": "bag"
+        }, {
+            "k": "action-undo"
+        }, {
+            "k": "action-redo"
+        }, {
+            "k": "wrench"
+        }, {
+            "k": "umbrella"
+        }, {
+            "k": "trash"
+        }, {
+            "k": "tag"
+        }, {
+            "k": "support"
+        }, {
+            "k": "frame"
+        }, {
+            "k": "size-fullscreen"
+        }, {
+            "k": "size-actual"
+        }, {
+            "k": "shuffle"
+        }, {
+            "k": "share-alt"
+        }, {
+            "k": "share"
+        }, {
+            "k": "rocket"
+        }, {
+            "k": "question"
+        }, {
+            "k": "pie-chart"
+        }, {
+            "k": "pencil"
+        }, {
+            "k": "note"
+        }, {
+            "k": "loop"
+        }, {
+            "k": "home"
+        }, {
+            "k": "grid"
+        }, {
+            "k": "graph"
+        }, {
+            "k": "microphone"
+        }, {
+            "k": "music-tone-alt"
+        }, {
+            "k": "music-tone"
+        }, {
+            "k": "earphones-alt"
+        }, {
+            "k": "earphones"
+        }, {
+            "k": "equalizer"
+        }, {
+            "k": "like"
+        }, {
+            "k": "dislike"
+        }, {
+            "k": "control-start"
+        }, {
+            "k": "control-rewind"
+        }, {
+            "k": "control-play"
+        }, {
+            "k": "control-pause"
+        }, {
+            "k": "control-forward"
+        }, {
+            "k": "control-end"
+        }, {
+            "k": "volume-1"
+        }, {
+            "k": "volume-2"
+        }, {
+            "k": "volume-off"
+        }, {
+            "k": "calendar"
+        }, {
+            "k": "bulb"
+        }, {
+            "k": "chart"
+        }, {
+            "k": "ban"
+        }, {
+            "k": "bubble"
+        }, {
+            "k": "camrecorder"
+        }, {
+            "k": "camera"
+        }, {
+            "k": "cloud-download"
+        }, {
+            "k": "cloud-upload"
+        }, {
+            "k": "envelope"
+        }, {
+            "k": "eye"
+        }, {
+            "k": "flag"
+        }, {
+            "k": "heart"
+        }, {
+            "k": "info"
+        }, {
+            "k": "key"
+        }, {
+            "k": "link"
+        }, {
+            "k": "lock"
+        }, {
+            "k": "lock-open"
+        }, {
+            "k": "magnifier"
+        }, {
+            "k": "magnifier-add"
+        }, {
+            "k": "magnifier-remove"
+        }, {
+            "k": "paper-clip"
+        }, {
+            "k": "paper-plane"
+        }, {
+            "k": "power"
+        }, {
+            "k": "refresh"
+        }, {
+            "k": "reload"
+        }, {
+            "k": "settings"
+        }, {
+            "k": "star"
+        }, {
+            "k": "symble-female"
+        }, {
+            "k": "symbol-male"
+        }, {
+            "k": "target"
+        }, {
+            "k": "credit-card"
+        }, {
+            "k": "paypal"
+        }, {
+            "k": "social-tumblr"
+        }, {
+            "k": "social-twitter"
+        }, {
+            "k": "social-facebook"
+        }, {
+            "k": "social-instagram"
+        }, {
+            "k": "social-linkedin"
+        }, {
+            "k": "social-pinterest"
+        }, {
+            "k": "social-github"
+        }, {
+            "k": "social-gplus"
+        }, {
+            "k": "social-reddit"
+        }, {
+            "k": "social-skype"
+        }, {
+            "k": "social-dribbble"
+        }, {
+            "k": "social-behance"
+        }, {
+            "k": "social-foursqare"
+        }, {
+            "k": "social-soundcloud"
+        }, {
+            "k": "social-spotify"
+        }, {
+            "k": "social-stumbleupon"
+        }, {
+            "k": "social-youtube"
+        }, {
+            "k": "social-dropbox"
+        }]
+    },
+    {
+        "title": "fa: Web Application Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "adjust"
+        }, {
+            "k": "anchor"
+        }, {
+            "k": "archive"
+        }, {
+            "k": "area-chart"
+        }, {
+            "k": "arrows"
+        }, {
+            "k": "arrows-h"
+        }, {
+            "k": "arrows-v"
+        }, {
+            "k": "asterisk"
+        }, {
+            "k": "at"
+        }, {
+            "k": "automobile",
+            "a": true
+        }, {
+            "k": "ban"
+        }, {
+            "k": "bank",
+            "a": true
+        }, {
+            "k": "bar-chart"
+        }, {
+            "k": "bar-chart-o",
+            "a": true
+        }, {
+            "k": "barcode"
+        }, {
+            "k": "bars"
+        }, {
+            "k": "beer"
+        }, {
+            "k": "bell"
+        }, {
+            "k": "bell-o"
+        }, {
+            "k": "bell-slash"
+        }, {
+            "k": "bell-slash-o"
+        }, {
+            "k": "bicycle"
+        }, {
+            "k": "binoculars"
+        }, {
+            "k": "birthday-cake"
+        }, {
+            "k": "bolt"
+        }, {
+            "k": "bomb"
+        }, {
+            "k": "book"
+        }, {
+            "k": "bookmark"
+        }, {
+            "k": "bookmark-o"
+        }, {
+            "k": "briefcase"
+        }, {
+            "k": "bug"
+        }, {
+            "k": "building"
+        }, {
+            "k": "building-o"
+        }, {
+            "k": "bullhorn"
+        }, {
+            "k": "bullseye"
+        }, {
+            "k": "bus"
+        }, {
+            "k": "cab",
+            "a": true
+        }, {
+            "k": "calculator"
+        }, {
+            "k": "calendar"
+        }, {
+            "k": "calendar-o"
+        }, {
+            "k": "camera"
+        }, {
+            "k": "camera-retro"
+        }, {
+            "k": "car"
+        }, {
+            "k": "caret-square-o-down"
+        }, {
+            "k": "caret-square-o-left"
+        }, {
+            "k": "caret-square-o-right"
+        }, {
+            "k": "caret-square-o-up"
+        }, {
+            "k": "cc"
+        }, {
+            "k": "certificate"
+        }, {
+            "k": "check"
+        }, {
+            "k": "check-circle"
+        }, {
+            "k": "check-circle-o"
+        }, {
+            "k": "check-square"
+        }, {
+            "k": "check-square-o"
+        }, {
+            "k": "child"
+        }, {
+            "k": "circle"
+        }, {
+            "k": "circle-o"
+        }, {
+            "k": "circle-o-notch"
+        }, {
+            "k": "circle-thin"
+        }, {
+            "k": "clock-o"
+        }, {
+            "k": "close",
+            "a": true
+        }, {
+            "k": "cloud"
+        }, {
+            "k": "cloud-download"
+        }, {
+            "k": "cloud-upload"
+        }, {
+            "k": "code"
+        }, {
+            "k": "code-fork"
+        }, {
+            "k": "coffee"
+        }, {
+            "k": "cog"
+        }, {
+            "k": "cogs"
+        }, {
+            "k": "comment"
+        }, {
+            "k": "comment-o"
+        }, {
+            "k": "comments"
+        }, {
+            "k": "comments-o"
+        }, {
+            "k": "compass"
+        }, {
+            "k": "copyright"
+        }, {
+            "k": "credit-card"
+        }, {
+            "k": "crop"
+        }, {
+            "k": "crosshairs"
+        }, {
+            "k": "cube"
+        }, {
+            "k": "cubes"
+        }, {
+            "k": "cutlery"
+        }, {
+            "k": "dashboard",
+            "a": true
+        }, {
+            "k": "database"
+        }, {
+            "k": "desktop"
+        }, {
+            "k": "dot-circle-o"
+        }, {
+            "k": "download"
+        }, {
+            "k": "edit",
+            "a": true
+        }, {
+            "k": "ellipsis-h"
+        }, {
+            "k": "ellipsis-v"
+        }, {
+            "k": "envelope"
+        }, {
+            "k": "envelope-o"
+        }, {
+            "k": "envelope-square"
+        }, {
+            "k": "eraser"
+        }, {
+            "k": "exchange"
+        }, {
+            "k": "exclamation"
+        }, {
+            "k": "exclamation-circle"
+        }, {
+            "k": "exclamation-triangle"
+        }, {
+            "k": "external-link"
+        }, {
+            "k": "external-link-square"
+        }, {
+            "k": "eye"
+        }, {
+            "k": "eye-slash"
+        }, {
+            "k": "eyedropper"
+        }, {
+            "k": "fax"
+        }, {
+            "k": "female"
+        }, {
+            "k": "fighter-jet"
+        }, {
+            "k": "file-archive-o"
+        }, {
+            "k": "file-audio-o"
+        }, {
+            "k": "file-code-o"
+        }, {
+            "k": "file-excel-o"
+        }, {
+            "k": "file-image-o"
+        }, {
+            "k": "file-movie-o",
+            "a": true
+        }, {
+            "k": "file-pdf-o"
+        }, {
+            "k": "file-photo-o",
+            "a": true
+        }, {
+            "k": "file-picture-o",
+            "a": true
+        }, {
+            "k": "file-powerpoint-o"
+        }, {
+            "k": "file-sound-o",
+            "a": true
+        }, {
+            "k": "file-video-o"
+        }, {
+            "k": "file-word-o"
+        }, {
+            "k": "file-zip-o",
+            "a": true
+        }, {
+            "k": "film"
+        }, {
+            "k": "filter"
+        }, {
+            "k": "fire"
+        }, {
+            "k": "fire-extinguisher"
+        }, {
+            "k": "flag"
+        }, {
+            "k": "flag-checkered"
+        }, {
+            "k": "flag-o"
+        }, {
+            "k": "flash",
+            "a": true
+        }, {
+            "k": "flask"
+        }, {
+            "k": "folder"
+        }, {
+            "k": "folder-o"
+        }, {
+            "k": "folder-open"
+        }, {
+            "k": "folder-open-o"
+        }, {
+            "k": "frown-o"
+        }, {
+            "k": "futbol-o"
+        }, {
+            "k": "gamepad"
+        }, {
+            "k": "gavel"
+        }, {
+            "k": "gear",
+            "a": true
+        }, {
+            "k": "gears",
+            "a": true
+        }, {
+            "k": "gift"
+        }, {
+            "k": "glass"
+        }, {
+            "k": "globe"
+        }, {
+            "k": "graduation-cap"
+        }, {
+            "k": "group",
+            "a": true
+        }, {
+            "k": "hdd-o"
+        }, {
+            "k": "headphones"
+        }, {
+            "k": "heart"
+        }, {
+            "k": "heart-o"
+        }, {
+            "k": "history"
+        }, {
+            "k": "home"
+        }, {
+            "k": "image",
+            "a": true
+        }, {
+            "k": "inbox"
+        }, {
+            "k": "info"
+        }, {
+            "k": "info-circle"
+        }, {
+            "k": "institution",
+            "a": true
+        }, {
+            "k": "key"
+        }, {
+            "k": "keyboard-o"
+        }, {
+            "k": "language"
+        }, {
+            "k": "laptop"
+        }, {
+            "k": "leaf"
+        }, {
+            "k": "legal",
+            "a": true
+        }, {
+            "k": "lemon-o"
+        }, {
+            "k": "level-down"
+        }, {
+            "k": "level-up"
+        }, {
+            "k": "life-bouy",
+            "a": true
+        }, {
+            "k": "life-buoy",
+            "a": true
+        }, {
+            "k": "life-ring"
+        }, {
+            "k": "life-saver",
+            "a": true
+        }, {
+            "k": "lightbulb-o"
+        }, {
+            "k": "line-chart"
+        }, {
+            "k": "location-arrow"
+        }, {
+            "k": "lock"
+        }, {
+            "k": "magic"
+        }, {
+            "k": "magnet"
+        }, {
+            "k": "mail-forward",
+            "a": true
+        }, {
+            "k": "mail-reply",
+            "a": true
+        }, {
+            "k": "mail-reply-all",
+            "a": true
+        }, {
+            "k": "male"
+        }, {
+            "k": "map-marker"
+        }, {
+            "k": "meh-o"
+        }, {
+            "k": "microphone"
+        }, {
+            "k": "microphone-slash"
+        }, {
+            "k": "minus"
+        }, {
+            "k": "minus-circle"
+        }, {
+            "k": "minus-square"
+        }, {
+            "k": "minus-square-o"
+        }, {
+            "k": "mobile"
+        }, {
+            "k": "mobile-phone",
+            "a": true
+        }, {
+            "k": "money"
+        }, {
+            "k": "moon-o"
+        }, {
+            "k": "mortar-board",
+            "a": true
+        }, {
+            "k": "music"
+        }, {
+            "k": "navicon",
+            "a": true
+        }, {
+            "k": "newspaper-o"
+        }, {
+            "k": "paint-brush"
+        }, {
+            "k": "paper-plane"
+        }, {
+            "k": "paper-plane-o"
+        }, {
+            "k": "paw"
+        }, {
+            "k": "pencil"
+        }, {
+            "k": "pencil-square"
+        }, {
+            "k": "pencil-square-o"
+        }, {
+            "k": "phone"
+        }, {
+            "k": "phone-square"
+        }, {
+            "k": "photo",
+            "a": true
+        }, {
+            "k": "picture-o"
+        }, {
+            "k": "pie-chart"
+        }, {
+            "k": "plane"
+        }, {
+            "k": "plug"
+        }, {
+            "k": "plus"
+        }, {
+            "k": "plus-circle"
+        }, {
+            "k": "plus-square"
+        }, {
+            "k": "plus-square-o"
+        }, {
+            "k": "power-off"
+        }, {
+            "k": "print"
+        }, {
+            "k": "puzzle-piece"
+        }, {
+            "k": "qrcode"
+        }, {
+            "k": "question"
+        }, {
+            "k": "question-circle"
+        }, {
+            "k": "quote-left"
+        }, {
+            "k": "quote-right"
+        }, {
+            "k": "random"
+        }, {
+            "k": "recycle"
+        }, {
+            "k": "refresh"
+        }, {
+            "k": "remove",
+            "a": true
+        }, {
+            "k": "reorder",
+            "a": true
+        }, {
+            "k": "reply"
+        }, {
+            "k": "reply-all"
+        }, {
+            "k": "retweet"
+        }, {
+            "k": "road"
+        }, {
+            "k": "rocket"
+        }, {
+            "k": "rss"
+        }, {
+            "k": "rss-square"
+        }, {
+            "k": "search"
+        }, {
+            "k": "search-minus"
+        }, {
+            "k": "search-plus"
+        }, {
+            "k": "send",
+            "a": true
+        }, {
+            "k": "send-o",
+            "a": true
+        }, {
+            "k": "share"
+        }, {
+            "k": "share-alt"
+        }, {
+            "k": "share-alt-square"
+        }, {
+            "k": "share-square"
+        }, {
+            "k": "share-square-o"
+        }, {
+            "k": "shield"
+        }, {
+            "k": "shopping-cart"
+        }, {
+            "k": "sign-in"
+        }, {
+            "k": "sign-out"
+        }, {
+            "k": "signal"
+        }, {
+            "k": "sitemap"
+        }, {
+            "k": "sliders"
+        }, {
+            "k": "smile-o"
+        }, {
+            "k": "soccer-ball-o",
+            "a": true
+        }, {
+            "k": "sort"
+        }, {
+            "k": "sort-alpha-asc"
+        }, {
+            "k": "sort-alpha-desc"
+        }, {
+            "k": "sort-amount-asc"
+        }, {
+            "k": "sort-amount-desc"
+        }, {
+            "k": "sort-asc"
+        }, {
+            "k": "sort-desc"
+        }, {
+            "k": "sort-down",
+            "a": true
+        }, {
+            "k": "sort-numeric-asc"
+        }, {
+            "k": "sort-numeric-desc"
+        }, {
+            "k": "sort-up",
+            "a": true
+        }, {
+            "k": "space-shuttle"
+        }, {
+            "k": "spinner"
+        }, {
+            "k": "spoon"
+        }, {
+            "k": "square"
+        }, {
+            "k": "square-o"
+        }, {
+            "k": "star"
+        }, {
+            "k": "star-half"
+        }, {
+            "k": "star-half-empty",
+            "a": true
+        }, {
+            "k": "star-half-full",
+            "a": true
+        }, {
+            "k": "star-half-o"
+        }, {
+            "k": "star-o"
+        }, {
+            "k": "suitcase"
+        }, {
+            "k": "sun-o"
+        }, {
+            "k": "support",
+            "a": true
+        }, {
+            "k": "tablet"
+        }, {
+            "k": "tachometer"
+        }, {
+            "k": "tag"
+        }, {
+            "k": "tags"
+        }, {
+            "k": "tasks"
+        }, {
+            "k": "taxi"
+        }, {
+            "k": "terminal"
+        }, {
+            "k": "thumb-tack"
+        }, {
+            "k": "thumbs-down"
+        }, {
+            "k": "thumbs-o-down"
+        }, {
+            "k": "thumbs-o-up"
+        }, {
+            "k": "thumbs-up"
+        }, {
+            "k": "ticket"
+        }, {
+            "k": "times"
+        }, {
+            "k": "times-circle"
+        }, {
+            "k": "times-circle-o"
+        }, {
+            "k": "tint"
+        }, {
+            "k": "toggle-down",
+            "a": true
+        }, {
+            "k": "toggle-left",
+            "a": true
+        }, {
+            "k": "toggle-off"
+        }, {
+            "k": "toggle-on"
+        }, {
+            "k": "toggle-right",
+            "a": true
+        }, {
+            "k": "toggle-up",
+            "a": true
+        }, {
+            "k": "trash"
+        }, {
+            "k": "trash-o"
+        }, {
+            "k": "tree"
+        }, {
+            "k": "trophy"
+        }, {
+            "k": "truck"
+        }, {
+            "k": "tty"
+        }, {
+            "k": "umbrella"
+        }, {
+            "k": "university"
+        }, {
+            "k": "unlock"
+        }, {
+            "k": "unlock-alt"
+        }, {
+            "k": "unsorted",
+            "a": true
+        }, {
+            "k": "upload"
+        }, {
+            "k": "user"
+        }, {
+            "k": "users"
+        }, {
+            "k": "video-camera"
+        }, {
+            "k": "volume-down"
+        }, {
+            "k": "volume-off"
+        }, {
+            "k": "volume-up"
+        }, {
+            "k": "warning",
+            "a": true
+        }, {
+            "k": "wheelchair"
+        }, {
+            "k": "wifi"
+        }, {
+            "k": "wrench"
+        }]
+    },
+    {
+        "title": "fa: File Type Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "file"
+        }, {
+            "k": "file-archive-o"
+        }, {
+            "k": "file-audio-o"
+        }, {
+            "k": "file-code-o"
+        }, {
+            "k": "file-excel-o"
+        }, {
+            "k": "file-image-o"
+        }, {
+            "k": "file-movie-o",
+            "a": true
+        }, {
+            "k": "file-o"
+        }, {
+            "k": "file-pdf-o"
+        }, {
+            "k": "file-photo-o",
+            "a": true
+        }, {
+            "k": "file-picture-o",
+            "a": true
+        }, {
+            "k": "file-powerpoint-o"
+        }, {
+            "k": "file-sound-o",
+            "a": true
+        }, {
+            "k": "file-text"
+        }, {
+            "k": "file-text-o"
+        }, {
+            "k": "file-video-o"
+        }, {
+            "k": "file-word-o"
+        }, {
+            "k": "file-zip-o",
+            "a": true
+        }]
+    },
+    {
+        "title": "fa: Spinner Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "tip": "These icons work great with the <code>fa-spin</code> class.",
+        "list": [{
+            "k": "circle-o-notch"
+        }, {
+            "k": "cog"
+        }, {
+            "k": "gear",
+            "a": true
+        }, {
+            "k": "refresh"
+        }, {
+            "k": "spinner"
+        }]
+    },
+    {
+        "title": "fa: Form Control Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "check-square"
+        }, {
+            "k": "check-square-o"
+        }, {
+            "k": "circle"
+        }, {
+            "k": "circle-o"
+        }, {
+            "k": "dot-circle-o"
+        }, {
+            "k": "minus-square"
+        }, {
+            "k": "minus-square-o"
+        }, {
+            "k": "plus-square"
+        }, {
+            "k": "plus-square-o"
+        }, {
+            "k": "square"
+        }, {
+            "k": "square-o"
+        }]
+    },
+    {
+        "title": "fa: Payment Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "cc-amex"
+        }, {
+            "k": "cc-discover"
+        }, {
+            "k": "cc-mastercard"
+        }, {
+            "k": "cc-paypal"
+        }, {
+            "k": "cc-stripe"
+        }, {
+            "k": "cc-visa"
+        }, {
+            "k": "credit-card"
+        }, {
+            "k": "google-wallet"
+        }, {
+            "k": "paypal"
+        }]
+    },
+    {
+        "title": "fa: Chart Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "area-chart"
+        }, {
+            "k": "bar-chart"
+        }, {
+            "k": "bar-chart-o",
+            "a": true
+        }, {
+            "k": "line-chart"
+        }, {
+            "k": "pie-chart"
+        }]
+    },
+    {
+        "title": "fa: Currency Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "bitcoin",
+            "a": true
+        }, {
+            "k": "btc"
+        }, {
+            "k": "cny",
+            "a": true
+        }, {
+            "k": "dollar",
+            "a": true
+        }, {
+            "k": "eur"
+        }, {
+            "k": "euro",
+            "a": true
+        }, {
+            "k": "gbp"
+        }, {
+            "k": "ils"
+        }, {
+            "k": "inr"
+        }, {
+            "k": "jpy"
+        }, {
+            "k": "krw"
+        }, {
+            "k": "money"
+        }, {
+            "k": "rmb",
+            "a": true
+        }, {
+            "k": "rouble",
+            "a": true
+        }, {
+            "k": "rub"
+        }, {
+            "k": "ruble",
+            "a": true
+        }, {
+            "k": "rupee",
+            "a": true
+        }, {
+            "k": "shekel",
+            "a": true
+        }, {
+            "k": "sheqel",
+            "a": true
+        }, {
+            "k": "try"
+        }, {
+            "k": "turkish-lira",
+            "a": true
+        }, {
+            "k": "usd"
+        }, {
+            "k": "won",
+            "a": true
+        }, {
+            "k": "yen",
+            "a": true
+        }]
+    },
+    {
+        "title": "fa: Text Editor Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "align-center"
+        }, {
+            "k": "align-justify"
+        }, {
+            "k": "align-left"
+        }, {
+            "k": "align-right"
+        }, {
+            "k": "bold"
+        }, {
+            "k": "chain",
+            "a": true
+        }, {
+            "k": "chain-broken"
+        }, {
+            "k": "clipboard"
+        }, {
+            "k": "columns"
+        }, {
+            "k": "copy",
+            "a": true
+        }, {
+            "k": "cut",
+            "a": true
+        }, {
+            "k": "dedent",
+            "a": true
+        }, {
+            "k": "eraser"
+        }, {
+            "k": "file"
+        }, {
+            "k": "file-o"
+        }, {
+            "k": "file-text"
+        }, {
+            "k": "file-text-o"
+        }, {
+            "k": "files-o"
+        }, {
+            "k": "floppy-o"
+        }, {
+            "k": "font"
+        }, {
+            "k": "header"
+        }, {
+            "k": "indent"
+        }, {
+            "k": "italic"
+        }, {
+            "k": "link"
+        }, {
+            "k": "list"
+        }, {
+            "k": "list-alt"
+        }, {
+            "k": "list-ol"
+        }, {
+            "k": "list-ul"
+        }, {
+            "k": "outdent"
+        }, {
+            "k": "paperclip"
+        }, {
+            "k": "paragraph"
+        }, {
+            "k": "paste",
+            "a": true
+        }, {
+            "k": "repeat"
+        }, {
+            "k": "rotate-left",
+            "a": true
+        }, {
+            "k": "rotate-right",
+            "a": true
+        }, {
+            "k": "save",
+            "a": true
+        }, {
+            "k": "scissors"
+        }, {
+            "k": "strikethrough"
+        }, {
+            "k": "subscript"
+        }, {
+            "k": "superscript"
+        }, {
+            "k": "table"
+        }, {
+            "k": "text-height"
+        }, {
+            "k": "text-width"
+        }, {
+            "k": "th"
+        }, {
+            "k": "th-large"
+        }, {
+            "k": "th-list"
+        }, {
+            "k": "underline"
+        }, {
+            "k": "undo"
+        }, {
+            "k": "unlink",
+            "a": true
+        }]
+    },
+    {
+        "title": "fa: Directional Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "angle-double-down"
+        }, {
+            "k": "angle-double-left"
+        }, {
+            "k": "angle-double-right"
+        }, {
+            "k": "angle-double-up"
+        }, {
+            "k": "angle-down"
+        }, {
+            "k": "angle-left"
+        }, {
+            "k": "angle-right"
+        }, {
+            "k": "angle-up"
+        }, {
+            "k": "arrow-circle-down"
+        }, {
+            "k": "arrow-circle-left"
+        }, {
+            "k": "arrow-circle-o-down"
+        }, {
+            "k": "arrow-circle-o-left"
+        }, {
+            "k": "arrow-circle-o-right"
+        }, {
+            "k": "arrow-circle-o-up"
+        }, {
+            "k": "arrow-circle-right"
+        }, {
+            "k": "arrow-circle-up"
+        }, {
+            "k": "arrow-down"
+        }, {
+            "k": "arrow-left"
+        }, {
+            "k": "arrow-right"
+        }, {
+            "k": "arrow-up"
+        }, {
+            "k": "arrows"
+        }, {
+            "k": "arrows-alt"
+        }, {
+            "k": "arrows-h"
+        }, {
+            "k": "arrows-v"
+        }, {
+            "k": "caret-down"
+        }, {
+            "k": "caret-left"
+        }, {
+            "k": "caret-right"
+        }, {
+            "k": "caret-square-o-down"
+        }, {
+            "k": "caret-square-o-left"
+        }, {
+            "k": "caret-square-o-right"
+        }, {
+            "k": "caret-square-o-up"
+        }, {
+            "k": "caret-up"
+        }, {
+            "k": "chevron-circle-down"
+        }, {
+            "k": "chevron-circle-left"
+        }, {
+            "k": "chevron-circle-right"
+        }, {
+            "k": "chevron-circle-up"
+        }, {
+            "k": "chevron-down"
+        }, {
+            "k": "chevron-left"
+        }, {
+            "k": "chevron-right"
+        }, {
+            "k": "chevron-up"
+        }, {
+            "k": "hand-o-down"
+        }, {
+            "k": "hand-o-left"
+        }, {
+            "k": "hand-o-right"
+        }, {
+            "k": "hand-o-up"
+        }, {
+            "k": "long-arrow-down"
+        }, {
+            "k": "long-arrow-left"
+        }, {
+            "k": "long-arrow-right"
+        }, {
+            "k": "long-arrow-up"
+        }, {
+            "k": "toggle-down",
+            "a": true
+        }, {
+            "k": "toggle-left",
+            "a": true
+        }, {
+            "k": "toggle-right",
+            "a": true
+        }, {
+            "k": "toggle-up",
+            "a": true
+        }]
+    },
+    {
+        "title": "fa: Video Player Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "arrows-alt"
+        }, {
+            "k": "backward"
+        }, {
+            "k": "compress"
+        }, {
+            "k": "eject"
+        }, {
+            "k": "expand"
+        }, {
+            "k": "fast-backward"
+        }, {
+            "k": "fast-forward"
+        }, {
+            "k": "forward"
+        }, {
+            "k": "pause"
+        }, {
+            "k": "play"
+        }, {
+            "k": "play-circle"
+        }, {
+            "k": "play-circle-o"
+        }, {
+            "k": "step-backward"
+        }, {
+            "k": "step-forward"
+        }, {
+            "k": "stop"
+        }, {
+            "k": "youtube-play"
+        }]
+    },
+    {
+        "title": "fa: Brand Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "adn"
+        }, {
+            "k": "android"
+        }, {
+            "k": "angellist"
+        }, {
+            "k": "apple"
+        }, {
+            "k": "behance"
+        }, {
+            "k": "behance-square"
+        }, {
+            "k": "bitbucket"
+        }, {
+            "k": "bitbucket-square"
+        }, {
+            "k": "bitcoin",
+            "a": true
+        }, {
+            "k": "btc"
+        }, {
+            "k": "cc-amex"
+        }, {
+            "k": "cc-discover"
+        }, {
+            "k": "cc-mastercard"
+        }, {
+            "k": "cc-paypal"
+        }, {
+            "k": "cc-stripe"
+        }, {
+            "k": "cc-visa"
+        }, {
+            "k": "codepen"
+        }, {
+            "k": "css3"
+        }, {
+            "k": "delicious"
+        }, {
+            "k": "deviantart"
+        }, {
+            "k": "digg"
+        }, {
+            "k": "dribbble"
+        }, {
+            "k": "dropbox"
+        }, {
+            "k": "drupal"
+        }, {
+            "k": "empire"
+        }, {
+            "k": "facebook"
+        }, {
+            "k": "facebook-square"
+        }, {
+            "k": "flickr"
+        }, {
+            "k": "foursquare"
+        }, {
+            "k": "ge",
+            "a": true
+        }, {
+            "k": "git"
+        }, {
+            "k": "git-square"
+        }, {
+            "k": "github"
+        }, {
+            "k": "github-alt"
+        }, {
+            "k": "github-square"
+        }, {
+            "k": "gittip"
+        }, {
+            "k": "google"
+        }, {
+            "k": "google-plus"
+        }, {
+            "k": "google-plus-square"
+        }, {
+            "k": "google-wallet"
+        }, {
+            "k": "hacker-news"
+        }, {
+            "k": "html5"
+        }, {
+            "k": "instagram"
+        }, {
+            "k": "ioxhost"
+        }, {
+            "k": "joomla"
+        }, {
+            "k": "jsfiddle"
+        }, {
+            "k": "lastfm"
+        }, {
+            "k": "lastfm-square"
+        }, {
+            "k": "linkedin"
+        }, {
+            "k": "linkedin-square"
+        }, {
+            "k": "linux"
+        }, {
+            "k": "maxcdn"
+        }, {
+            "k": "meanpath"
+        }, {
+            "k": "openid"
+        }, {
+            "k": "pagelines"
+        }, {
+            "k": "paypal"
+        }, {
+            "k": "pied-piper"
+        }, {
+            "k": "pied-piper-alt"
+        }, {
+            "k": "pinterest"
+        }, {
+            "k": "pinterest-square"
+        }, {
+            "k": "qq"
+        }, {
+            "k": "ra",
+            "a": true
+        }, {
+            "k": "rebel"
+        }, {
+            "k": "reddit"
+        }, {
+            "k": "reddit-square"
+        }, {
+            "k": "renren"
+        }, {
+            "k": "share-alt"
+        }, {
+            "k": "share-alt-square"
+        }, {
+            "k": "skype"
+        }, {
+            "k": "slack"
+        }, {
+            "k": "slideshare"
+        }, {
+            "k": "soundcloud"
+        }, {
+            "k": "spotify"
+        }, {
+            "k": "stack-exchange"
+        }, {
+            "k": "stack-overflow"
+        }, {
+            "k": "steam"
+        }, {
+            "k": "steam-square"
+        }, {
+            "k": "stumbleupon"
+        }, {
+            "k": "stumbleupon-circle"
+        }, {
+            "k": "tencent-weibo"
+        }, {
+            "k": "trello"
+        }, {
+            "k": "tumblr"
+        }, {
+            "k": "tumblr-square"
+        }, {
+            "k": "twitch"
+        }, {
+            "k": "twitter"
+        }, {
+            "k": "twitter-square"
+        }, {
+            "k": "vimeo-square"
+        }, {
+            "k": "vine"
+        }, {
+            "k": "vk"
+        }, {
+            "k": "wechat",
+            "a": true
+        }, {
+            "k": "weibo"
+        }, {
+            "k": "weixin"
+        }, {
+            "k": "windows"
+        }, {
+            "k": "wordpress"
+        }, {
+            "k": "xing"
+        }, {
+            "k": "xing-square"
+        }, {
+            "k": "yahoo"
+        }, {
+            "k": "yelp"
+        }, {
+            "k": "youtube"
+        }, {
+            "k": "youtube-play"
+        }, {
+            "k": "youtube-square"
+        }]
+    },
+    {
+        "title": "fa: Medical Icons",
+        "prefix": "fa fa-",
+        "tpl": "<i class=\"fa fa-{0}\"></i>",
+        "list": [{
+            "k": "ambulance"
+        }, {
+            "k": "h-square"
+        }, {
+            "k": "hospital-o"
+        }, {
+            "k": "medkit"
+        }, {
+            "k": "plus-square"
+        }, {
+            "k": "stethoscope"
+        }, {
+            "k": "user-md"
+        }, {
+            "k": "wheelchair"
+        }]
+    }
+]
diff --git a/src/assets/img/1.png b/src/assets/img/1.png
new file mode 100644
index 0000000..8f6d2d6
--- /dev/null
+++ b/src/assets/img/1.png
Binary files differ
diff --git a/src/assets/img/2.png b/src/assets/img/2.png
new file mode 100644
index 0000000..a59195e
--- /dev/null
+++ b/src/assets/img/2.png
Binary files differ
diff --git a/src/assets/img/3.png b/src/assets/img/3.png
new file mode 100644
index 0000000..b0f9da8
--- /dev/null
+++ b/src/assets/img/3.png
Binary files differ
diff --git a/src/assets/img/4.png b/src/assets/img/4.png
new file mode 100644
index 0000000..0058dc3
--- /dev/null
+++ b/src/assets/img/4.png
Binary files differ
diff --git a/src/assets/img/5.png b/src/assets/img/5.png
new file mode 100644
index 0000000..3cccf6a
--- /dev/null
+++ b/src/assets/img/5.png
Binary files differ
diff --git a/src/assets/img/6.png b/src/assets/img/6.png
new file mode 100644
index 0000000..58601a0
--- /dev/null
+++ b/src/assets/img/6.png
Binary files differ
diff --git a/src/assets/img/avatar.jpg b/src/assets/img/avatar.jpg
new file mode 100644
index 0000000..ebc92fb
--- /dev/null
+++ b/src/assets/img/avatar.jpg
Binary files differ
diff --git a/src/assets/img/bg1.jpg b/src/assets/img/bg1.jpg
new file mode 100644
index 0000000..0c1ae55
--- /dev/null
+++ b/src/assets/img/bg1.jpg
Binary files differ
diff --git a/src/assets/img/bg10.jpg b/src/assets/img/bg10.jpg
new file mode 100644
index 0000000..9e1c545
--- /dev/null
+++ b/src/assets/img/bg10.jpg
Binary files differ
diff --git a/src/assets/img/bg2.jpg b/src/assets/img/bg2.jpg
new file mode 100644
index 0000000..d2de98e
--- /dev/null
+++ b/src/assets/img/bg2.jpg
Binary files differ
diff --git a/src/assets/img/bg3.jpg b/src/assets/img/bg3.jpg
new file mode 100644
index 0000000..bb0773a
--- /dev/null
+++ b/src/assets/img/bg3.jpg
Binary files differ
diff --git a/src/assets/img/bg4.jpg b/src/assets/img/bg4.jpg
new file mode 100644
index 0000000..7b2fdac
--- /dev/null
+++ b/src/assets/img/bg4.jpg
Binary files differ
diff --git a/src/assets/img/bg5.jpg b/src/assets/img/bg5.jpg
new file mode 100644
index 0000000..b56fa75
--- /dev/null
+++ b/src/assets/img/bg5.jpg
Binary files differ
diff --git a/src/assets/img/bg6.jpg b/src/assets/img/bg6.jpg
new file mode 100644
index 0000000..5774f15
--- /dev/null
+++ b/src/assets/img/bg6.jpg
Binary files differ
diff --git a/src/assets/img/bg7.jpg b/src/assets/img/bg7.jpg
new file mode 100644
index 0000000..6aac586
--- /dev/null
+++ b/src/assets/img/bg7.jpg
Binary files differ
diff --git a/src/assets/img/bg8.jpg b/src/assets/img/bg8.jpg
new file mode 100644
index 0000000..0956df3
--- /dev/null
+++ b/src/assets/img/bg8.jpg
Binary files differ
diff --git a/src/assets/img/bg9.jpg b/src/assets/img/bg9.jpg
new file mode 100644
index 0000000..1fd1286
--- /dev/null
+++ b/src/assets/img/bg9.jpg
Binary files differ
diff --git a/src/assets/img/half-float-bg-1.jpg b/src/assets/img/half-float-bg-1.jpg
new file mode 100644
index 0000000..4f0af59
--- /dev/null
+++ b/src/assets/img/half-float-bg-1.jpg
Binary files differ
diff --git a/src/assets/img/logo-color.svg b/src/assets/img/logo-color.svg
new file mode 100644
index 0000000..8944a81
--- /dev/null
+++ b/src/assets/img/logo-color.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="222px" height="222px" viewBox="-4.092 0 222 222" enable-background="new -4.092 0 222 222"
+	 xml:space="preserve">
+<defs>
+</defs>
+<path fill="#F0776F" d="M195.333,129.506c-0.446,0-0.893,0-1.488-0.148c-6.399-0.744-11.013-6.548-10.269-12.947l6.994-57.891
+	c0.447-3.721-1.785-7.293-5.208-8.483l-47.176-16.816c-6.103-2.232-9.228-8.78-7.144-14.882c2.232-6.102,8.78-9.227,14.882-7.144
+	l47.176,16.816c13.989,4.911,22.472,18.603,20.687,33.336l-6.995,57.891C206.197,125.042,201.137,129.506,195.333,129.506z"/>
+<path fill="#F0776F" d="M104.851,222.222c-5.209,0-10.417-1.34-15.329-4.019l-61.016-33.931
+	c-8.781-4.911-14.733-13.691-15.924-23.663L0.23,60.007c-1.786-14.733,6.995-28.723,20.983-33.634L96.665,0.627
+	c6.102-2.083,12.799,1.19,14.882,7.292c2.084,6.103-1.19,12.799-7.292,14.883L28.803,48.547c-3.572,1.191-5.804,4.763-5.357,8.632
+	l12.352,100.603c0.298,2.53,1.786,4.762,4.018,6.102l61.016,33.931c2.381,1.34,5.358,1.34,7.739,0l66.076-36.163
+	c2.232-1.19,3.87-3.571,4.167-6.102c0.744-6.399,6.549-11.013,12.948-10.269c6.398,0.744,11.012,6.548,10.269,12.947
+	c-1.191,9.971-7.293,18.9-16.073,23.812l-66.076,36.163C115.268,220.882,110.059,222.222,104.851,222.222z"/>
+<path fill="#F0776F" d="M157.086,131.441l-37.8-68.309l-0.149-0.149c-2.679-4.613-7.738-7.59-13.096-7.59s-10.417,2.977-13.096,7.59
+	l-37.8,68.458c-2.828,5.208-1.042,11.607,4.167,14.436c5.208,2.827,11.608,1.041,14.436-4.167l7.292-13.245h50.004l7.292,13.245
+	c1.935,3.571,5.506,5.506,9.376,5.506c1.785,0,3.571-0.446,5.06-1.339C157.979,143.049,159.914,136.501,157.086,131.441z
+	 M92.796,107.183l13.245-23.96l13.245,23.96H92.796z"/>
+</svg>
diff --git a/src/assets/img/logo-full.svg b/src/assets/img/logo-full.svg
new file mode 100644
index 0000000..c7d8318
--- /dev/null
+++ b/src/assets/img/logo-full.svg
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="552px" height="222px" viewBox="-4.092 0 552 222" enable-background="new -4.092 0 552 222"
+	 xml:space="preserve">
+<defs>
+</defs>
+<path fill="#FFFFFF" d="M195.333,129.506c-0.446,0-0.893,0-1.488-0.148c-6.399-0.744-11.013-6.548-10.269-12.947l6.994-57.891
+	c0.447-3.721-1.785-7.293-5.208-8.483l-47.176-16.816c-6.103-2.232-9.228-8.78-7.144-14.882c2.232-6.102,8.78-9.227,14.882-7.144
+	l47.176,16.816c13.989,4.911,22.472,18.603,20.687,33.336l-6.995,57.891C206.197,125.042,201.137,129.506,195.333,129.506z"/>
+<path fill="#FFFFFF" d="M104.851,222.222c-5.209,0-10.417-1.34-15.329-4.019l-61.016-33.931
+	c-8.781-4.911-14.733-13.691-15.924-23.663L0.23,60.007c-1.786-14.733,6.995-28.723,20.983-33.634L96.665,0.627
+	c6.102-2.083,12.799,1.19,14.882,7.292c2.084,6.103-1.19,12.799-7.292,14.883L28.803,48.547c-3.572,1.191-5.804,4.763-5.357,8.632
+	l12.352,100.603c0.298,2.53,1.786,4.762,4.018,6.102l61.016,33.931c2.381,1.34,5.358,1.34,7.739,0l66.076-36.163
+	c2.232-1.19,3.87-3.571,4.167-6.102c0.744-6.399,6.549-11.013,12.948-10.269c6.398,0.744,11.012,6.548,10.269,12.947
+	c-1.191,9.971-7.293,18.9-16.073,23.812l-66.076,36.163C115.268,220.882,110.059,222.222,104.851,222.222z"/>
+<path fill="#FFFFFF" d="M157.086,131.441l-37.8-68.309l-0.149-0.149c-2.679-4.613-7.738-7.59-13.096-7.59s-10.417,2.977-13.096,7.59
+	l-37.8,68.458c-2.828,5.208-1.042,11.607,4.167,14.436c5.208,2.827,11.608,1.041,14.436-4.167l7.292-13.245h50.004l7.292,13.245
+	c1.935,3.571,5.506,5.506,9.376,5.506c1.785,0,3.571-0.446,5.06-1.339C157.979,143.049,159.914,136.501,157.086,131.441z
+	 M92.796,107.183l13.245-23.96l13.245,23.96H92.796z"/>
+<path fill="#FFFFFF" d="M252.497,113.075c17.46-47.694,32.79-79.42,47.481-97.305c6.813,1.277,21.506,9.794,23.848,13.414
+	c-22.144,26.189-38.113,54.934-52.166,93.898c-11.923,33.216-18.311,60.896-18.311,78.78c0,4.897,0,5.11,0.213,6.175
+	c-3.833-0.426-7.026-2.129-7.878-4.045c-0.64-1.491-3.833-4.897-5.75-6.175c-2.555-1.703-4.471-9.795-4.471-18.95
+	C235.464,166.518,241.639,142.884,252.497,113.075z"/>
+<path fill="#FFFFFF" d="M374.289,113.926c-11.498,23.847-19.376,48.972-19.376,63.451c0,7.878,1.704,13.414,5.536,15.543
+	c-3.406,2.129-9.581,3.833-13.84,3.833c-7.665,0-11.498-5.11-11.498-15.757c0-7.878,2.769-19.376,8.092-33.216
+	c-11.498,25.977-30.235,47.269-43.437,49.398c-10.433-0.426-17.672-11.072-17.672-25.764c0-31.726,30.66-75.161,53.655-76.439
+	c5.749,1.491,15.331,11.498,15.97,16.821c-22.783,3.62-50.676,41.307-50.676,67.496c0,2.981,1.065,4.472,2.981,5.11
+	c8.304-1.703,18.524-13.627,33.854-39.178c5.962-10.007,14.479-25.977,20.653-38.751
+	C364.495,106.474,374.502,111.158,374.289,113.926z"/>
+<path fill="#FFFFFF" d="M391.749,137.773c1.277-5.536,7.452-27.68,20.228-34.067c4.685,1.064,14.266,5.749,19.802,14.053
+	c-12.988,14.479-16.82,29.596-24.061,48.333c-2.98,7.878-6.174,17.034-6.387,23.209c0,5.109,0,7.026-1.278,7.026
+	c-2.129,0-15.543-5.536-15.543-18.099C384.51,173.331,386.213,163.324,391.749,137.773z M425.816,81.988
+	c-1.49-1.491-2.555-4.685-2.555-7.026c0-4.897,2.98-18.737,6.601-27.893c6.601,0,21.505,8.517,25.764,14.905
+	c-6.388,5.961-21.932,24.912-24.061,29.596c-3.407-0.639-6.388-3.407-6.388-5.749C425.178,84.969,425.391,83.691,425.816,81.988z"/>
+<path fill="#FFFFFF" d="M486.712,109.668c-6.388,15.543-28.745,45.778-30.448,58.766c8.943-9.581,23.422-27.467,28.318-32.576
+	c10.859-11.498,30.874-32.577,44.714-32.577c7.239,0,12.35,6.175,15.117,11.498c0,0.639-2.342,0.852-6.175,5.323
+	c-7.665,10.007-22.144,38.113-22.144,55.573c0,7.026,1.916,8.304,5.323,8.304c2.98,0,7.026-2.13,8.942-2.13
+	c1.064,0.64,1.916,2.981,1.916,4.259c-4.258,3.833-13.414,8.729-18.311,8.729c-16.396,0-20.228-10.007-20.228-22.569
+	c0-7.026,1.916-15.756,11.71-38.326c-0.639,0-8.942,4.046-17.246,12.137c-13.201,12.775-23.209,24.486-34.28,39.816
+	c-6.175,8.729-10.859,15.33-14.266,17.247c-5.962-3.407-8.517-10.221-9.795-16.608c0-10.646,6.388-34.493,15.97-56.424
+	c10.858-24.912,20.866-39.816,23.208-40.881C476.491,91.569,483.73,100.299,486.712,109.668z"/>
+</svg>
diff --git a/src/assets/img/logo.svg b/src/assets/img/logo.svg
new file mode 100644
index 0000000..28fa8f6
--- /dev/null
+++ b/src/assets/img/logo.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="222px" height="222px" viewBox="-4.092 0 222 222" enable-background="new -4.092 0 222 222"
+	 xml:space="preserve">
+<defs>
+</defs>
+<path fill="#FFFFFF" d="M195.333,129.506c-0.446,0-0.893,0-1.488-0.148c-6.399-0.744-11.013-6.548-10.269-12.947l6.994-57.891
+	c0.447-3.721-1.785-7.293-5.208-8.483l-47.176-16.816c-6.103-2.232-9.228-8.78-7.144-14.882c2.232-6.102,8.78-9.227,14.882-7.144
+	l47.176,16.816c13.989,4.911,22.472,18.603,20.687,33.336l-6.995,57.891C206.197,125.042,201.137,129.506,195.333,129.506z"/>
+<path fill="#FFFFFF" d="M104.851,222.222c-5.209,0-10.417-1.34-15.329-4.019l-61.016-33.931
+	c-8.781-4.911-14.733-13.691-15.924-23.663L0.23,60.007c-1.786-14.733,6.995-28.723,20.983-33.634L96.665,0.627
+	c6.102-2.083,12.799,1.19,14.882,7.292c2.084,6.103-1.19,12.799-7.292,14.883L28.803,48.547c-3.572,1.191-5.804,4.763-5.357,8.632
+	l12.352,100.603c0.298,2.53,1.786,4.762,4.018,6.102l61.016,33.931c2.381,1.34,5.358,1.34,7.739,0l66.076-36.163
+	c2.232-1.19,3.87-3.571,4.167-6.102c0.744-6.399,6.549-11.013,12.948-10.269c6.398,0.744,11.012,6.548,10.269,12.947
+	c-1.191,9.971-7.293,18.9-16.073,23.812l-66.076,36.163C115.268,220.882,110.059,222.222,104.851,222.222z"/>
+<path fill="#FFFFFF" d="M157.086,131.441l-37.8-68.309l-0.149-0.149c-2.679-4.613-7.738-7.59-13.096-7.59s-10.417,2.977-13.096,7.59
+	l-37.8,68.458c-2.828,5.208-1.042,11.607,4.167,14.436c5.208,2.827,11.608,1.041,14.436-4.167l7.292-13.245h50.004l7.292,13.245
+	c1.935,3.571,5.506,5.506,9.376,5.506c1.785,0,3.571-0.446,5.06-1.339C157.979,143.049,159.914,136.501,157.086,131.441z
+	 M92.796,107.183l13.245-23.96l13.245,23.96H92.796z"/>
+</svg>
diff --git a/src/assets/img/zorro.svg b/src/assets/img/zorro.svg
new file mode 100644
index 0000000..059bf56
--- /dev/null
+++ b/src/assets/img/zorro.svg
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="������_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 400 400" style="enable-background:new 0 0 400 400;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:url(#SVGID_1_);}
+	.st1{fill:url(#SVGID_2_);}
+	.st2{fill:url(#SVGID_3_);}
+</style>
+<g>
+	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="215.0983" y1="173.3861" x2="271.3071" y2="173.3861">
+		<stop  offset="3.215440e-02" style="stop-color:#F0776F"/>
+		<stop  offset="1" style="stop-color:#F0606F"/>
+	</linearGradient>
+	<path class="st0" d="M258.7,213.4c-0.3,0-0.6,0-1-0.1c-4.3-0.5-7.4-4.4-6.9-8.7l4.7-38.9c0.3-2.5-1.2-4.9-3.5-5.7l-31.7-11.3
+		c-4.1-1.5-6.2-5.9-4.8-10c1.5-4.1,5.9-6.2,10-4.8l31.7,11.3c9.4,3.3,15.1,12.5,13.9,22.4l-4.7,38.9
+		C266,210.4,262.6,213.4,258.7,213.4z"/>
+	<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="127.4784" y1="201.0843" x2="263.3311" y2="201.0843">
+		<stop  offset="0" style="stop-color:#6EB4E0"/>
+		<stop  offset="1" style="stop-color:#1588E0"/>
+	</linearGradient>
+	<path class="st1" d="M197.9,275.7c-3.5,0-7-0.9-10.3-2.7l-41-22.8c-5.9-3.3-9.9-9.2-10.7-15.9l-8.3-67.6
+		c-1.2-9.9,4.7-19.3,14.1-22.6l50.7-17.3c4.1-1.4,8.6,0.8,10,4.9c1.4,4.1-0.8,8.6-4.9,10l-50.7,17.3c-2.4,0.8-3.9,3.2-3.6,5.8
+		l8.3,67.6c0.2,1.7,1.2,3.2,2.7,4.1l41,22.8c1.6,0.9,3.6,0.9,5.2,0l44.4-24.3c1.5-0.8,2.6-2.4,2.8-4.1c0.5-4.3,4.4-7.4,8.7-6.9
+		c4.3,0.5,7.4,4.4,6.9,8.7c-0.8,6.7-4.9,12.7-10.8,16l-44.4,24.3C204.9,274.8,201.4,275.7,197.9,275.7z"/>
+	<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="163.5466" y1="194.4135" x2="233.869" y2="194.4135">
+		<stop  offset="3.215440e-02" style="stop-color:#F0776F"/>
+		<stop  offset="1" style="stop-color:#F0606F"/>
+	</linearGradient>
+	<path class="st2" d="M233,214.7l-25.4-45.9l-0.1-0.1c-1.8-3.1-5.2-5.1-8.8-5.1c-3.6,0-7,2-8.8,5.1l-25.4,46
+		c-1.9,3.5-0.7,7.8,2.8,9.7c3.5,1.9,7.8,0.7,9.7-2.8l4.9-8.9h33.6l4.9,8.9c1.3,2.4,3.7,3.7,6.3,3.7c1.2,0,2.4-0.3,3.4-0.9
+		C233.6,222.5,234.9,218.1,233,214.7z M189.8,198.4l8.9-16.1l8.9,16.1H189.8z"/>
+</g>
+</svg>
diff --git a/src/assets/pois.json b/src/assets/pois.json
new file mode 100644
index 0000000..721280f
--- /dev/null
+++ b/src/assets/pois.json
@@ -0,0 +1,59 @@
+{
+    "total": 2,
+    "data": [{
+            "id": 10000,
+            "user_id": 1,
+            "name": "������������",
+            "branch_name": "������������",
+            "geo": 310105,
+            "country": "������",
+            "province": "������",
+            "city": "���������",
+            "district": "���������",
+            "address": "������������",
+            "tel": "15900000000",
+            "categories": "������,������,���������",
+            "lng": 121.41707989151003,
+            "lat": 31.218656214644792,
+            "recommend": "���������",
+            "special": "������������",
+            "introduction": "������������",
+            "open_time": "������������",
+            "avg_price": 260,
+            "reason": null,
+            "status": 1,
+            "status_str": "���������",
+            "status_wx": 1,
+            "modified": 1505826527288,
+            "created": 1505826527288
+        },
+        {
+            "id": 10001,
+            "user_id": 2,
+            "name": "������������2",
+            "branch_name": "������������2",
+            "geo": 310105,
+            "country": "������",
+            "province": "������",
+            "city": "���������",
+            "district": "���������",
+            "address": "������������",
+            "tel": "15900000000",
+            "categories": "������,������,���������",
+            "lng": 121.41707989151003,
+            "lat": 31.218656214644792,
+            "recommend": "���������",
+            "special": "������������",
+            "introduction": "������������",
+            "open_time": "������������",
+            "avg_price": 260,
+            "reason": null,
+            "status": 1,
+            "status_str": "���������",
+            "status_wx": 1,
+            "modified": 1505826527288,
+            "created": 1505826527288
+        }
+    ]
+
+}
diff --git a/src/environments/environment.chore.ts b/src/environments/environment.chore.ts
new file mode 100644
index 0000000..bb3034e
--- /dev/null
+++ b/src/environments/environment.chore.ts
@@ -0,0 +1,6 @@
+export const environment = {
+    SERVER_URL: `./`,
+    production: true,
+    hmr: false,
+    useHash: false
+};
diff --git a/src/environments/environment.hmr.ts b/src/environments/environment.hmr.ts
new file mode 100644
index 0000000..687d0b9
--- /dev/null
+++ b/src/environments/environment.hmr.ts
@@ -0,0 +1,6 @@
+export const environment = {
+    SERVER_URL: `./`,
+    production: true,
+    hmr: true,
+    useHash: true
+};
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index ab89b16..3f794b3 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -1,4 +1,6 @@
 export const environment = {
-  SERVER_URL: `./`,
-  production: true
+    SERVER_URL: `./`,
+    production: true,
+    hmr: false,
+    useHash: true
 };
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index a94cd62..45c90c7 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -4,6 +4,8 @@
 // The list of which env maps to which file can be found in `.angular-cli.json`.
 
 export const environment = {
-  SERVER_URL: `./`,
-  production: false
+    SERVER_URL: `./`,
+    production: false,
+    hmr: false,
+    useHash: true
 };
diff --git a/src/hmr.ts b/src/hmr.ts
new file mode 100644
index 0000000..9919565
--- /dev/null
+++ b/src/hmr.ts
@@ -0,0 +1,20 @@
+import { NgModuleRef, ApplicationRef } from '@angular/core';
+import { createNewHosts } from '@angularclass/hmr';
+
+export const hmrBootstrap = (module: any, bootstrap: () => Promise<NgModuleRef<any>>) => {
+  let ngModule: NgModuleRef<any>;
+  module.hot.accept();
+  bootstrap().then(mod => {
+    if ((<any>window).appBootstrap) {
+      (<any>window).appBootstrap();
+    }
+    ngModule = mod;
+  });
+  module.hot.dispose(() => {
+    const appRef: ApplicationRef = ngModule.injector.get(ApplicationRef);
+    const elements = appRef.components.map(c => c.location.nativeElement);
+    const makeVisible = createNewHosts(elements);
+    ngModule.destroy();
+    makeVisible();
+  });
+};
diff --git a/src/main.ts b/src/main.ts
index 91ec6da..eac1183 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,12 +1,36 @@
-import { enableProdMode } from '@angular/core';
+import { enableProdMode, ViewEncapsulation } from '@angular/core';
 import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 
 import { AppModule } from './app/app.module';
 import { environment } from './environments/environment';
 
+import { hmrBootstrap } from './hmr';
+
+import { preloaderFinished } from '@delon/theme';
+preloaderFinished();
+
 if (environment.production) {
   enableProdMode();
 }
 
-platformBrowserDynamic().bootstrapModule(AppModule)
-  .catch(err => console.log(err));
+const bootstrap = () => {
+    return platformBrowserDynamic().bootstrapModule(AppModule, {
+        defaultEncapsulation: ViewEncapsulation.Emulated,
+        preserveWhitespaces: false
+    });
+};
+
+if (environment.hmr) {
+  if (module['hot']) {
+      hmrBootstrap(module, bootstrap);
+  } else {
+      console.error('HMR is not enabled for webpack-dev-server!');
+      console.log('Are you using the --hmr flag for ng serve?');
+  }
+} else {
+  bootstrap().then(() => {
+    if ((<any>window).appBootstrap) {
+      (<any>window).appBootstrap();
+    }
+  });
+}
diff --git a/tsconfig.json b/tsconfig.json
index 0656b07..9b73cb0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -17,10 +17,10 @@
     ],
     "baseUrl": "src/",
     "paths": {
-      "@shared": [ "app/shared" ],
-      "@shared/*": [ "app/shared/*" ],
-      "@core": [ "app/core/" ],
-      "@core/*": [ "app/core/*" ]
+        "@shared": [ "app/shared" ],
+        "@shared/*": [ "app/shared/*" ],
+        "@core": [ "app/core/" ],
+        "@core/*": [ "app/core/*" ]
     }
   }
 }
diff --git a/tslint.json b/tslint.json
index a2e30ef..54f1235 100644
--- a/tslint.json
+++ b/tslint.json
@@ -10,16 +10,12 @@
       true,
       "check-space"
     ],
-    "curly": true,
-    "deprecation": {
-      "severity": "warn"
-    },
+    "curly": false,
     "eofline": true,
-    "forin": true,
+    "forin": false,
     "import-blacklist": [
       true,
-      "rxjs",
-      "rxjs/Rx"
+      "rxjs"
     ],
     "import-spacing": true,
     "indent": [
@@ -29,12 +25,12 @@
     "interface-over-type-literal": true,
     "label-position": true,
     "max-line-length": [
-      true,
+      false,
       140
     ],
     "member-access": false,
     "member-ordering": [
-      true,
+      false,
       {
         "order": [
           "static-field",
@@ -45,7 +41,7 @@
       }
     ],
     "no-arg": true,
-    "no-bitwise": true,
+    "no-bitwise": false,
     "no-console": [
       true,
       "debug",
@@ -70,7 +66,7 @@
     "no-string-literal": false,
     "no-string-throw": true,
     "no-switch-case-fall-through": true,
-    "no-trailing-whitespace": true,
+    "no-trailing-whitespace": false,
     "no-unnecessary-initializer": true,
     "no-unused-expression": true,
     "no-use-before-declare": true,
@@ -119,26 +115,28 @@
       "check-type"
     ],
     "directive-selector": [
-      true,
+      false,
       "attribute",
       "app",
       "camelCase"
     ],
     "component-selector": [
-      true,
+      false,
       "element",
       "app",
       "kebab-case"
     ],
-    "no-output-on-prefix": true,
     "use-input-property-decorator": true,
     "use-output-property-decorator": true,
     "use-host-property-decorator": true,
-    "no-input-rename": true,
-    "no-output-rename": true,
+    "no-input-rename": false,
+    "no-output-rename": false,
     "use-life-cycle-interface": true,
     "use-pipe-transform-interface": true,
     "component-class-suffix": true,
-    "directive-class-suffix": true
+    "directive-class-suffix": true,
+    "no-access-missing-member": true,
+    "templates-use-public": true,
+    "invoke-injectable": true
   }
 }

--
Gitblit v1.8.0