From 12b04f145bae740e1971036b1e2dfc1bc224d17b Mon Sep 17 00:00:00 2001
From: fengxiang <110431245@qq.com>
Date: Wed, 11 Jul 2018 14:38:47 +0800
Subject: [PATCH] Revert "框架调整"

---
 src/app/routes/data-v/relation/relation.component.html                 |    0 
 src/app/routes/style/typography/typography.component.html              |  130 
 src/app/routes/delon/acl/acl.component.html                            |   43 
 src/app/routes/widgets/widgets/widgets.component.less                  |   11 
 src/app/routes/passport/register/register.component.html               |   85 
 src/app/routes/pro/form/basic-form/basic-form.component.html           |   78 
 src/app/layout/default/header/header.component.html                    |   30 
 src/app/routes/extras/settings/settings.component.spec.ts              |   16 
 src/app/routes/pro/form/step-form/step-form.component.html             |   13 
 src/app/routes/data-v/data-v.module.ts                                 |   11 
 src/app/routes/style/style.module.ts                                   |   20 
 src/app/routes/delon/cache/cache.component.ts                          |   24 
 src/app/routes/extras/settings/settings.component.ts                   |   64 
 src/app/routes/pro/pro-routing.module.ts                               |   65 
 src/app/routes/passport/lock/lock.component.spec.ts                    |   16 
 src/app/routes/delon/util/util.component.ts                            |   47 
 src/app/routes/delon/guard/admin.component.ts                          |    9 
 src/app/routes/delon/guard/leave.component.ts                          |   12 
 src/app/routes/pro/form/advanced-form/advanced-form.component.ts       |  156 +
 src/app/routes/dashboard/monitor/monitor.component.html                |   78 
 src/app/routes/style/typography/typography.component.spec.ts           |   18 
 src/app/routes/widgets/widgets/widgets.component.html                  |  797 +++++
 src/index.html                                                         |    2 
 src/app/routes/pro/list/basic-list/basic-list.component.html           |   91 
 src/app/routes/style/colors/colors.component.ts                        |   20 
 src/app/routes/delon/downfile/downfile.component.ts                    |   14 
 src/app/routes/passport/register/register.component.ts                 |  133 
 src/app/routes/dashboard/monitor/monitor.component.ts                  |   99 
 src/app/routes/pro/form/advanced-form/advanced-form.component.html     |  218 +
 src/app/routes/pro/list/basic-list/basic-list.component.ts             |   30 
 src/app/routes/data-v/data-v-routing.module.ts                         |   11 
 src/app/routes/passport/login/login.component.ts                       |  181 +
 src/app/routes/pro/list/basic-list/basic-list.component.less           |   21 
 src/app/routes/delon/xlsx/xlsx.component.ts                            |   50 
 src/app/routes/dashboard/analysis/analysis.component.html              |  226 +
 src/app/routes/delon/downfile/downfile.component.spec.ts               |   16 
 src/app/routes/pro/list/card-list/card-list.component.ts               |   31 
 src/app/routes/delon/xlsx/xlsx.component.html                          |   14 
 src/app/routes/pro/profile/basic/basic.component.html                  |   42 
 src/app/routes/pro/list/projects/projects.component.less               |   16 
 src/app/routes/delon/cache/cache.component.html                        |   10 
 src/app/routes/dashboard/v1/v1.component.html                          |  150 +
 src/app/routes/delon/guard/guard.component.spec.ts                     |   17 
 src/app/routes/delon/qr/qr.component.ts                                |   17 
 src/app/routes/extras/helpcenter/helpcenter.component.html             |   94 
 src/app/routes/pro/form/step-form/step3.component.html                 |   34 
 src/app/routes/delon/simple-table/simple-table.component.html          |   52 
 src/app/routes/extras/extras.module.ts                                 |   24 
 src/app/routes/widgets/widgets-routing.module.ts                       |   12 
 src/app/routes/exception/403.component.ts                              |   12 
 src/app/routes/pro/list/projects/projects.component.html               |   61 
 src/app/routes/delon/form/form.component.html                          |    5 
 src/app/routes/extras/poi/poi.component.ts                             |   51 
 src/app/routes/delon/acl/acl.component.spec.ts                         |   16 
 src/app/routes/pro/form/step-form/step3.component.ts                   |   10 
 src/app/routes/dashboard/monitor/monitor.component.less                |   58 
 src/app/routes/extras/poi/edit/edit.component.html                     |   87 
 src/app/routes/passport/register-result/register-result.component.html |    7 
 src/app/routes/style/colors/colors.component.html                      |  105 
 src/app/routes/callback/callback.component.ts                          |   35 
 src/app/routes/dashboard/workplace/workplace.component.ts              |  114 
 src/app/routes/delon/print/print.component.ts                          |   79 
 src/app/routes/pro/form/step-form/step-form.component.less             |   26 
 src/app/routes/exception/500.component.ts                              |   12 
 src/app/routes/pro/profile/basic/basic.component.ts                    |   45 
 src/app/routes/delon/zip/zip.component.html                            |   38 
 src/app/routes/pro/form/basic-form/basic-form.component.ts             |   41 
 src/app/routes/pro/form/step-form/step1.component.ts                   |   61 
 src/app/routes/pro/form/step-form/transfer.service.ts                  |   53 
 src/app/routes/pro/result/fail/fail.component.html                     |   21 
 src/app/routes/extras/helpcenter/helpcenter.component.spec.ts          |   16 
 src/app/routes/delon/print/print.component.html                        |   61 
 src/app/routes/pro/form/step-form/step1.component.html                 |   59 
 src/app/routes/extras/settings/settings.component.html                 |  204 +
 src/app/routes/pro/list/list/list.component.ts                         |   43 
 src/app/routes/extras/helpcenter/helpcenter.component.ts               |   22 
 src/app/routes/extras/extras-routing.module.ts                         |   18 
 src/app/routes/style/colors/colors.component.spec.ts                   |   18 
 src/app/routes/pro/profile/advanced/advanced.component.less            |   19 
 src/app/routes/delon/guard/auth.component.ts                           |    9 
 src/assets/tmp/i18n/zh-CN.json                                         |    4 
 src/app/routes/pro/profile/advanced/advanced.component.ts              |   40 
 src/app/routes/pro/result/success/success.component.html               |   53 
 src/app/routes/widgets/widgets.module.ts                               |   13 
 src/app/routes/delon/guard/guard.component.ts                          |   23 
 src/app/routes/delon/delon.module.ts                                   |   48 
 src/app/routes/style/gridmasonry/gridmasonry.component.ts              |    7 
 src/app/routes/pro/list/applications/applications.component.ts         |   76 
 src/app/routes/exception/404.component.ts                              |   12 
 src/app/routes/delon/acl/acl.component.ts                              |   41 
 src/app/routes/style/typography/typography.component.ts                |   10 
 src/app/routes/pro/list/projects/projects.component.ts                 |   61 
 src/app/routes/delon/zip/zip.component.ts                              |   71 
 src/app/routes/dashboard/v1/v1.component.spec.ts                       |   16 
 src/app/routes/style/style-routing.module.ts                           |   18 
 src/app/routes/pro/form/step-form/step2.component.ts                   |   42 
 src/app/routes/pro/list/table-list/table-list.component.ts             |  154 +
 src/app/routes/data-v/relation/relation.component.ts                   |  169 +
 src/app/routes/routes.module.ts                                        |   30 
 src/app/routes/passport/login/login.component.less                     |   42 
 src/app/routes/pro/result/fail/fail.component.ts                       |    7 
 src/app/routes/pro/list/card-list/card-list.component.html             |   48 
 src/app/routes/style/colors/colors.component.less                      |   13 
 src/app/routes/delon/form/form.component.ts                            |   32 
 src/app/routes/passport/lock/lock.component.ts                         |   35 
 src/app/routes/dashboard/analysis/analysis.component.less              |  135 
 src/app/routes/pro/list/list/list.component.html                       |   16 
 src/app/routes/delon/simple-table/simple-table.component.ts            |   74 
 src/app/routes/pro/profile/advanced/advanced.component.html            |  144 +
 src/app/routes/pro/list/articles/articles.component.html               |   91 
 src/app/routes/routes-routing.module.ts                                |   80 
 src/app/routes/extras/poi/poi.component.html                           |   37 
 src/app/routes/passport/login/login.component.html                     |   70 
 src/app/routes/style/gridmasonry/gridmasonry.component.spec.ts         |   16 
 src/app/routes/widgets/widgets/widgets.component.spec.ts               |   16 
 src/app/routes/passport/lock/lock.component.html                       |   29 
 src/app/routes/style/gridmasonry/gridmasonry.component.html            |  247 +
 src/app/routes/delon/guard/can-leave.provide.ts                        |   38 
 src/app/routes/pro/list/applications/applications.component.html       |   92 
 src/app/routes/pro/pro.module.ts                                       |   48 
 src/app/routes/widgets/widgets/widgets.component.ts                    |   63 
 src/app/routes/pro/list/table-list/table-list.component.html           |  108 
 src/app/routes/pro/form/step-form/step-form.component.ts               |   16 
 src/app/routes/delon/guard/guard.component.html                        |   33 
 src/app/routes/dashboard/v1/v1.component.ts                            |   62 
 src/app/routes/pro/list/applications/applications.component.less       |   51 
 src/assets/tmp/app-data.json                                           |    4 
 src/app/routes/dashboard/analysis/analysis.component.ts                |   88 
 src/app/routes/delon/delon-routing.module.ts                           |   61 
 src/app/routes/extras/poi/edit/edit.component.ts                       |   39 
 src/app/routes/delon/util/util.component.html                          |   54 
 src/app/routes/delon/downfile/downfile.component.html                  |    6 
 src/app/routes/dashboard/workplace/workplace.component.less            |  240 +
 src/app/routes/pro/form/step-form/step2.component.html                 |   51 
 src/app/routes/pro/result/success/success.component.ts                 |   10 
 src/app/routes/style/color.service.ts                                  |   31 
 src/app/routes/data-v/relation/relation.component.less                 |    0 
 /dev/null                                                              |   34 
 src/app/routes/dashboard/workplace/workplace.component.html            |  111 
 src/app/routes/passport/register-result/register-result.component.ts   |   10 
 src/app/routes/delon/qr/qr.component.html                              |   76 
 src/app/routes/passport/register/register.component.less               |   42 
 src/app/routes/pro/list/articles/articles.component.ts                 |   86 
 143 files changed, 8,165 insertions(+), 63 deletions(-)

diff --git a/.angulardoc.json b/.angulardoc.json
deleted file mode 100644
index 196a55c..0000000
--- a/.angulardoc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "repoId": "3487b7a8-09dc-4dc4-9640-d5a366812785",
-  "lastSync": 0
-}
\ No newline at end of file
diff --git a/src/app/layout/default/header/header.component.html b/src/app/layout/default/header/header.component.html
index 72ca2b9..510865d 100644
--- a/src/app/layout/default/header/header.component.html
+++ b/src/app/layout/default/header/header.component.html
@@ -1,7 +1,7 @@
 <div class="logo">
   <a [routerLink]="['/']">
-    <img class="expanded" src="./assets/tmp/img/logo_100x40.png" alt="{{settings.app.name}}" style="max-height:40px;" />
-    <img class="collapsed" src="./assets/tmp/img/logo_30x30.png" alt="{{settings.app.name}}" style="max-height:30px;" />
+    <img class="expanded" src="./assets/logo-full.svg" alt="{{settings.app.name}}" style="max-height:40px;" />
+    <img class="collapsed" src="./assets/logo.svg" alt="{{settings.app.name}}" style="max-height:30px;" />
   </a>
 </div>
 <div class="top-nav-wrap">
@@ -13,38 +13,38 @@
       </div>
     </li>
     <!-- Github Page -->
-    <!-- <li>
+    <li>
       <a class="item" href="//github.com/cipchk/ng-alain" target="_blank">
         <i class="anticon anticon-github"></i>
       </a>
-    </li> -->
+    </li>
     <!-- Lock Page -->
-    <!-- <li class="hidden-xs">
+    <li class="hidden-xs">
       <div class="item" [routerLink]="['/lock']">
         <i class="anticon anticon-lock"></i>
       </div>
-    </li> -->
+    </li>
     <!-- Search Button -->
-    <!-- <li class="header-search__btn" (click)="searchToggleChange()">
+    <li class="header-search__btn" (click)="searchToggleChange()">
       <div class="item">
         <i class="anticon anticon-search"></i>
       </div>
-    </li> -->
+    </li>
   </ul>
-  <!-- <header-search class="header-search" [toggleChange]="searchToggleStatus"></header-search> -->
+  <header-search class="header-search" [toggleChange]="searchToggleStatus"></header-search>
   <ul class="top-nav">
     <!-- Notify -->
-    <!-- <li>
+    <li>
       <header-notify></header-notify>
-    </li> -->
+    </li>
     <!-- Task -->
-    <!-- <li class="hidden-xs">
+    <li class="hidden-xs">
       <header-task></header-task>
-    </li> -->
+    </li>
     <!-- App Icons -->
-    <!-- <li class="hidden-xs">
+    <li class="hidden-xs">
       <header-icon></header-icon>
-    </li> -->
+    </li>
     <!-- Settings -->
     <li class="hidden-xs">
       <nz-dropdown nzTrigger="click" nzPlacement="bottomRight">
diff --git a/src/app/routes/callback/callback.component.ts b/src/app/routes/callback/callback.component.ts
new file mode 100644
index 0000000..33392ad
--- /dev/null
+++ b/src/app/routes/callback/callback.component.ts
@@ -0,0 +1,35 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { SocialService } from '@delon/auth';
+
+@Component({
+  selector: 'app-callback',
+  template: ``,
+  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/dashboard/analysis/analysis.component.html b/src/app/routes/dashboard/analysis/analysis.component.html
new file mode 100644
index 0000000..2b95509
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.html
@@ -0,0 +1,226 @@
+<page-header></page-header>
+<div nz-row [nzGutter]="24" class="pt-lg">
+  <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+    <g2-card [title]="'������������'" total="�� 126,560" contentHeight="44px" [action]="action1" [footer]="footer1">
+      <ng-template #action1>
+        <nz-tooltip [nzTitle]="'������������'">
+          <i nz-tooltip class="anticon anticon-info-circle-o"></i>
+        </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 mb0">���������������
+          <span class="ml-sm">���12,423</span>
+        </p>
+      </ng-template>
+    </g2-card>
+  </div>
+  <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+    <g2-card [title]="'���������'" total="8,848" contentHeight="46px" [action]="action2" [footer]="footer2">
+      <ng-template #action2>
+        <nz-tooltip [nzTitle]="'������������'">
+          <i nz-tooltip class="anticon anticon-info-circle-o"></i>
+        </nz-tooltip>
+      </ng-template>
+      <g2-mini-area color="#975FE4" height="46" [data]="data.visitData"></g2-mini-area>
+      <ng-template #footer2>
+        <p class="text-truncate mb0">������������
+          <span class="ml-sm">1,234</span>
+        </p>
+      </ng-template>
+    </g2-card>
+  </div>
+  <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+    <g2-card [title]="'������������'" total="6,560" contentHeight="46px" [action]="action3" [footer]="footer3">
+      <ng-template #action3>
+        <nz-tooltip [nzTitle]="'������������'">
+          <i nz-tooltip class="anticon anticon-info-circle-o"></i>
+        </nz-tooltip>
+      </ng-template>
+      <g2-mini-bar height="46" [data]="data.visitData"></g2-mini-bar>
+      <ng-template #footer3>
+        <p class="text-truncate mb0">���������
+          <span class="ml-sm">60%</span>
+        </p>
+      </ng-template>
+    </g2-card>
+  </div>
+  <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="6">
+    <g2-card [title]="'������������������'" total="78%" contentHeight="46px" [action]="action4" [footer]="footer4">
+      <ng-template #action4>
+        <nz-tooltip [nzTitle]="'������������'">
+          <i nz-tooltip class="anticon anticon-info-circle-o"></i>
+        </nz-tooltip>
+      </ng-template>
+      <g2-mini-progress height="46" percent="78" strokeWidth="8" target="80" color="#13C2C2"></g2-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>
+    </g2-card>
+  </div>
+</div>
+<nz-card [nzLoading]="loading" [nzBordered]="false" class="ant-card__body-nopadding sales-card">
+  <nz-tabset [nzTabBarExtraContent]="extraTemplate">
+    <nz-tab nzTitle="���������">
+      <div nz-row>
+        <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="16">
+          <div class="bar">
+            <g2-bar height="295" [title]="'���������������'" [data]="data.salesData"></g2-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 nzTitle="���������">
+      <div nz-row>
+        <div nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="16">
+          <div class="bar">
+            <g2-bar height="295" [title]="'���������������'" [data]="data.salesData"></g2-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 #extraTemplate>
+      <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-range-picker [(ngModel)]="date_range" style="display:inline-block; width: 256px;"></nz-range-picker>
+      </div>
+    </ng-template>
+  </nz-tabset>
+</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="������������������" [nzExtra]="extraOp">
+      <ng-template #extraOp>
+        <nz-dropdown>
+          <i class="anticon anticon-ellipsis" nz-dropdown></i>
+          <ul nz-menu>
+            <li nz-menu-item>���������</li>
+            <li nz-menu-item>���������</li>
+          </ul>
+        </nz-dropdown>
+      </ng-template>
+      <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]="'������������'">
+                <i nz-tooltip class="anticon anticon-info-circle-o ml-sm"></i>
+              </nz-tooltip>
+            </ng-template>
+          </number-info>
+          <g2-mini-area [line]="true" height="45" [data]="data.visitData2"></g2-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>
+          <g2-mini-area [line]="true" height="45" [data]="data.visitData2"></g2-mini-area>
+        </div>
+      </div>
+      <simple-table [data]="data.searchData" [columns]="searchColumn" size="small" ps="5" [toTopInChange]="false">
+        <ng-template st-row="range" let-i>
+          <trend [flag]="i.status === 1 ? 'down' : 'up'">
+            <span>{{i.range}}%</span>
+          </trend>
+        </ng-template>
+      </simple-table>
+    </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}" [nzExtra]="extra"
+      class="sales-card" style="min-height: 482px;">
+      <ng-template #extra>
+        <div class="sales-card-extra">
+          <nz-dropdown>
+            <i class="anticon anticon-icon-group" nz-dropdown nzType="ellipsis"></i>
+            <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()">
+              <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>
+      <h4 class="margin:8px 0 32px 0;">���������</h4>
+      <g2-pie [hasLegend]="true" subTitle="���������" [height]="248" [lineWidth]="4" [total]="salesTotal" [data]="salesPieData" [valueFormat]="handlePieValueFormat">
+      </g2-pie>
+    </nz-card>
+  </div>
+</div>
+<nz-card [nzLoading]="loading" [nzBordered]="false" [nzBodyStyle]="{'padding': '0 0 32px'}" class="offline-card mt-lg">
+  <nz-tabset [(nzSelectedIndex)]="_activeTab" (nzSelectChange)="_tabChange($event)">
+    <nz-tab *ngFor="let tab of data.offlineData; let i = index;" [nzTitle]="nzTabHeading">
+      <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;">
+            <g2-pie [animate]="false" [color]="i !== _activeTab && '#BDE4FF'" [inner]="0.55" [tooltip]="false" [padding]="[0, 0, 0, 0]"
+              [percent]="tab.cvr * 100" [height]="64">
+            </g2-pie>
+          </div>
+        </div>
+      </ng-template>
+      <div class="px-lg">
+        <g2-timeline [data]="tab.chart" [titleMap]="{ y1: '���������', y2: '������������' }"></g2-timeline>
+      </div>
+    </nz-tab>
+  </nz-tabset>
+</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..8487fe6
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.less
@@ -0,0 +1,135 @@
+@import 'node_modules/@delon/theme/styles/default';
+: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: 0 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: 0 0 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..fa81d14
--- /dev/null
+++ b/src/app/routes/dashboard/analysis/analysis.component.ts
@@ -0,0 +1,88 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { SimpleTableColumn } from '@delon/abc';
+import { getTimeDistance, yuan } from '@delon/util';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-dashboard-analysis',
+  templateUrl: './analysis.component.html',
+  styleUrls: ['./analysis.component.less'],
+})
+export class DashboardAnalysisComponent implements OnInit {
+  data: any = {
+    salesData: [],
+    offlineData: [],
+  };
+  loading = true;
+  date_range: Date[] = [];
+  rankingListData: any[] = Array(7)
+    .fill({})
+    .map((item, i) => {
+      return {
+        title: `��������� ${i} ������`,
+        total: 323234,
+      };
+    });
+  searchColumn: SimpleTableColumn[] = [
+    { title: '������', index: 'index' },
+    {
+      title: '���������������',
+      index: 'keyword',
+      click: (item: any) => this.msg.success(item.keyword),
+    },
+    {
+      type: 'number',
+      title: '���������',
+      index: 'count',
+      sorter: (a, b) => a.count - b.count,
+    },
+    {
+      type: 'number',
+      title: '���������',
+      index: 'range',
+      render: 'range',
+      sorter: (a, b) => a.range - b.range,
+    },
+  ];
+
+  constructor(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.http.get('/chart').subscribe((res: any) => {
+      res.offlineData.forEach((item: any) => {
+        item.chart = Object.assign([], res.offlineChartData);
+      });
+      this.data = res;
+      this.loading = false;
+      this.changeSaleType();
+    });
+  }
+
+  setDate(type: any) {
+    this.date_range = getTimeDistance(type);
+  }
+
+  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..f3acdf5
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.html
@@ -0,0 +1,78 @@
+<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>
+        <g2-mini-area [animate]="false" [line]="true" [borderWidth]="2" [height]="84" [yAxis]="activeYAxis" [data]="activeData"></g2-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">
+      <g2-gauge [title]="'���������'" [height]="180" [percent]="87" [format]="couponFormat"></g2-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">
+          <g2-pie [animate]="false" [percent]="28" subTitle="������������" total="28%" [height]="128" [lineWidth]="2"></g2-pie>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <g2-pie [animate]="false" color="#5DDECF" [percent]="22" subTitle="������" total="22%" [height]="128" [lineWidth]="2"></g2-pie>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <g2-pie [animate]="false" color="#2FC25B" [percent]="32" subTitle="������" total="32%" [height]="128" [lineWidth]="2"></g2-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'}">
+      <g2-tag-cloud [data]="tags" [height]="165"></g2-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'}">
+      <g2-water-wave [title]="'������������������'" [percent]="34" [height]="165"></g2-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..3da2ad8
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.less
@@ -0,0 +1,58 @@
+@import 'node_modules/@delon/theme/styles/default';
+: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;
+    g2-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..ef25f13
--- /dev/null
+++ b/src/app/routes/dashboard/monitor/monitor.component.ts
@@ -0,0 +1,99 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { zip } from 'rxjs';
+import { getTimeDistance, yuan } from '@delon/util';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-dashboard-monitor',
+  templateUrl: './monitor.component.html',
+  styleUrls: ['./monitor.component.less'],
+})
+export class DashboardMonitorComponent implements OnInit, OnDestroy {
+  data: any = {};
+  tags = [];
+  loading = true;
+  q: any = {
+    start: null,
+    end: null,
+  };
+
+  constructor(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    zip(this.http.get('/chart'), this.http.get('/chart/tags')).subscribe(
+      ([res, tags]: [any, any]) => {
+        this.data = res;
+        tags.list[
+          Math.floor(Math.random() * tags.list.length) + 1
+        ].value = 1000;
+        this.tags = tags.list;
+        this.loading = false;
+      },
+    );
+
+    // 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: `${i.toString().padStart(2, '0')}: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..69c7e2b
--- /dev/null
+++ b/src/app/routes/dashboard/v1/v1.component.html
@@ -0,0 +1,150 @@
+<div class="content__title">
+  <h1>
+    Dashboard
+    <small>Welcome !</small>
+  </h1>
+</div>
+<quick-menu>
+  <nz-list [nzBordered]="false" [nzSplit]="false">
+    <nz-list-item>
+      <a routerLink="/">Home</a>
+    </nz-list-item>
+    <nz-list-item>
+      <a routerLink="/widgets">Widgets</a>
+    </nz-list-item>
+    <nz-list-item>
+      <a routerLink="/style/typography">typography</a>
+    </nz-list-item>
+    <nz-list-item>
+      <a routerLink="/style/gridmasonry">gridmasonry</a>
+    </nz-list-item>
+    <nz-list-item>
+      <a routerLink="/pro/result/success">success result</a>
+    </nz-list-item>
+  </nz-list>
+</quick-menu>
+<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 mb0">Website Traffics</p>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></g2-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 mb0">Website Impressions</p>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></g2-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 mb0">Total Sales</p>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></g2-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-magenta rounded-md">
+      <div nz-col nzSpan="12" class="p-md text-white">
+        <div class="h2 mt0">456</div>
+        <p class="text-nowrap mb0">Support Tickets</p>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="webSite"></g2-mini-bar>
+      </div>
+    </div>
+  </div>
+</div>
+<div nz-row nzGutter="16">
+  <div nz-col nzXs="24" nzMd="12">
+    <nz-card [nzBordered]="false" [nzTitle]="title">
+      <ng-template #title>
+        Sales Statistics
+        <small class="text-sm font-weight-normal">Business Expectations & Retail Sales Statistics</small>
+      </ng-template>
+      <g2-bar height="275" [data]="salesData"></g2-bar>
+    </nz-card>
+  </div>
+  <div nz-col nzXs="24" nzMd="12">
+    <nz-card [nzTitle]="title" [nzBordered]="false">
+      <ng-template #title>
+        Growth Rate
+        <small class="text-sm font-weight-normal">Business Expectations & Retail Sales Statistics</small>
+      </ng-template>
+      <g2-timeline [data]="offlineChartData" [height]="239" [padding]="[0, 0, 0, 0]" [titleMap]="{ y1: '���������', y2: '������������' }"></g2-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]="title" [nzBordered]="false" class="ant-card__body-nopadding">
+      <ng-template #title>
+        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/tmp/img/' + item.avatar + '.png'"></nz-avatar>
+        </div>
+        <div nz-col [nzSpan]="20">
+          <strong>{{item.name}}</strong>
+          <p class="mb0">{{item.content}}</p>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col nzXs="24" nzMd="12">
+    <nz-card nzTitle="Todo lists" [nzBordered]="false" class="ant-card__body-nopadding">
+      <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/tmp/img/' + item.avatar + '.png'"></nz-avatar>
+        </div>
+        <div nz-col [nzSpan]="18">
+          <strong>{{item.name}}</strong>
+          <p [class.text-deleted]="item.completed" class="mb0">{{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..7854384
--- /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..ccf0158
--- /dev/null
+++ b/src/app/routes/dashboard/v1/v1.component.ts
@@ -0,0 +1,62 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-dashboard-v1',
+  templateUrl: './v1.component.html',
+})
+export class DashboardV1Component implements OnInit {
+  constructor(private http: _HttpClient, public msg: NzMessageService) {}
+
+  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.`,
+    },
+  ];
+
+  webSite: any[] = [];
+  salesData: any[] = [];
+  offlineChartData: any[] = [];
+
+  ngOnInit() {
+    this.http.get('/chart').subscribe((res: any) => {
+      this.webSite = res.visitData.slice(0, 10);
+      this.salesData = res.salesData;
+      this.offlineChartData = res.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..5b5e68b
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.html
@@ -0,0 +1,111 @@
+<page-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 nzSrc="https://gw.alipayobjects.com/zos/rmsportal/lctvVCLfRpYCkYxAsiVQ.png"></nz-avatar>
+      </div>
+      <div class="desc">
+        <div class="desc-title">���������������������������������</div>
+        <div>��������� | ���������������������������������������������������������������</div>
+      </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>
+</page-header>
+<div nz-row [nzGutter]="24">
+  <div nz-col nzXs="24" nzSm="24" nzMd="16">
+    <nz-card nzTitle="������������������" [nzBordered]="false" [nzLoading]="loading" class="ant-card__body-nopadding 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 [nzBordered]="false" class="ant-card__body-nopadding 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" class="ant-card__body-nopadding mb-lg active-card">
+      <nz-list nzSize="large" class="activities">
+        <nz-list-item *ngFor="let item of 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" class="ant-card__body-nopadding 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">
+      <g2-radar [data]="radarData" [height]="343" [hasLegend]="true"></g2-radar>
+    </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..d8dfe1f
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.less
@@ -0,0 +1,240 @@
+@import 'node_modules/@delon/theme/styles/default';
+: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;
+    white-space: nowrap;
+    & > div {
+      padding: 0 32px;
+      position: relative;
+      display: inline-block;
+      & > 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 0.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: @text-color;
+      display: inline-block;
+      font-size: @font-size-base;
+      margin-bottom: 13px;
+      width: 25%;
+      &:hover {
+        color: @primary-color;
+      }
+    }
+  }
+
+  @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;
+    }
+    .project-list {
+      .project-grid {
+        width: 50%;
+      }
+    }
+  }
+
+  @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..2e366e0
--- /dev/null
+++ b/src/app/routes/dashboard/workplace/workplace.component.ts
@@ -0,0 +1,114 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { zip } from 'rxjs';
+import { NzMessageService } from 'ng-zorro-antd';
+import { getTimeDistance, yuan } from '@delon/util';
+import { _HttpClient } from '@delon/theme';
+import { JWTTokenModel } from '@delon/auth';
+
+@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(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.http.get('user-context').subscribe(
+      res => {
+          console.log(res);
+      }
+    );
+    zip(
+      this.http.get('/chart'),
+      this.http.get('/api/notice'),
+      this.http.get('/api/activities'),
+    ).subscribe(([chart, notice, activities]: [any, any, any]) => {
+      this.radarData = chart.radarData;
+      this.notice = notice;
+      this.activities = activities.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.loading = false;
+    });
+  }
+
+  ngOnDestroy(): void {}
+}
diff --git a/src/app/routes/data-v/data-v-routing.module.ts b/src/app/routes/data-v/data-v-routing.module.ts
new file mode 100644
index 0000000..71efc39
--- /dev/null
+++ b/src/app/routes/data-v/data-v-routing.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { RelationComponent } from './relation/relation.component';
+
+const routes: Routes = [{ path: 'relation', component: RelationComponent }];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class DataVRoutingModule {}
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..532fa85
--- /dev/null
+++ b/src/app/routes/data-v/data-v.module.ts
@@ -0,0 +1,11 @@
+import { NgModule } from '@angular/core';
+import { SharedModule } from '@shared/shared.module';
+
+import { DataVRoutingModule } from './data-v-routing.module';
+import { RelationComponent } from './relation/relation.component';
+
+@NgModule({
+  imports: [SharedModule, DataVRoutingModule],
+  declarations: [RelationComponent],
+})
+export class DataVModule {}
diff --git a/src/app/routes/home-page/home-page/home-page.component.less b/src/app/routes/data-v/relation/relation.component.html
similarity index 100%
copy from src/app/routes/home-page/home-page/home-page.component.less
copy to src/app/routes/data-v/relation/relation.component.html
diff --git a/src/app/routes/home-page/home-page/home-page.component.less b/src/app/routes/data-v/relation/relation.component.less
similarity index 100%
rename from src/app/routes/home-page/home-page/home-page.component.less
rename to 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..a0fa4a7
--- /dev/null
+++ b/src/app/routes/data-v/relation/relation.component.ts
@@ -0,0 +1,169 @@
+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: 0.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/delon/acl/acl.component.html b/src/app/routes/delon/acl/acl.component.html
new file mode 100644
index 0000000..c8964f1
--- /dev/null
+++ b/src/app/routes/delon/acl/acl.component.html
@@ -0,0 +1,43 @@
+<div class="content__title">
+  <h1>
+    ACL ������������
+    <small>������������������������������ACLService���������������������������������������������������������������������������������������������������ACLService���Route Guard���������������������</small>
+  </h1>
+</div>
+<page-header [title]="'asdfasdf'"></page-header>
+<nz-card nzTitle="������">
+  klsjdf
+</nz-card>
+<div nz-row [nzGutter]="8">
+  <div nz-col [nzSpan]="24">
+    <nz-card nzTitle="������������">
+      ACL���������������{{ aclSrv.data | json }}
+      <button nz-button [acl]="'role-a'">role-a</button>
+      <button nz-button [acl]="'role-b'" class="ml-sm">role-b</button>
+    </nz-card>
+  </div>
+</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/delon/acl/acl.component.spec.ts b/src/app/routes/delon/acl/acl.component.spec.ts
new file mode 100644
index 0000000..9a4e9d3
--- /dev/null
+++ b/src/app/routes/delon/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/delon/acl/acl.component.ts b/src/app/routes/delon/acl/acl.component.ts
new file mode 100644
index 0000000..9b0b471
--- /dev/null
+++ b/src/app/routes/delon/acl/acl.component.ts
@@ -0,0 +1,41 @@
+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(public aclSrv: ACLService, private menuSrv: MenuService) {}
+
+  private reMenu() {
+    this.menuSrv.resume();
+  }
+
+  toggleFull() {
+    this.full = !this.full;
+    this.aclSrv.setFull(this.full);
+    this.reMenu();
+  }
+
+  toggleRoleA() {
+    this.full = false;
+    this.roleA = this.roleA === 'role-a' ? '' : 'role-a';
+    this.aclSrv.setFull(this.full);
+    this.aclSrv.setRole([this.roleA]);
+    this.reMenu();
+  }
+
+  toggleRoleB() {
+    this.full = false;
+    this.roleB = this.roleB === 'role-b' ? '' : 'role-b';
+    this.aclSrv.setFull(this.full);
+    this.aclSrv.setRole([this.roleB]);
+    this.reMenu();
+  }
+}
diff --git a/src/app/routes/delon/cache/cache.component.html b/src/app/routes/delon/cache/cache.component.html
new file mode 100644
index 0000000..911ae01
--- /dev/null
+++ b/src/app/routes/delon/cache/cache.component.html
@@ -0,0 +1,10 @@
+<div class="content__title">
+  <h1>
+    Cache ������,
+    <a href="http://ng-alain.com/components/cache" target="_blank">Document</a>
+  </h1>
+</div>
+<nz-card nzTitle="Service">
+  <button nz-button (click)="set()">������</button>
+  <button nz-button (click)="get()" class="ml-sm">������</button>
+</nz-card>
diff --git a/src/app/routes/delon/cache/cache.component.ts b/src/app/routes/delon/cache/cache.component.ts
new file mode 100644
index 0000000..be31179
--- /dev/null
+++ b/src/app/routes/delon/cache/cache.component.ts
@@ -0,0 +1,24 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { CacheService } from '@delon/cache';
+
+@Component({
+  selector: 'app-cache',
+  templateUrl: './cache.component.html',
+  styles: [],
+})
+export class CacheComponent implements OnInit {
+  KEY = 'user';
+
+  constructor(public cache: CacheService, public msg: NzMessageService) {}
+
+  ngOnInit() {}
+
+  set() {
+    this.cache.set(this.KEY, +new Date());
+  }
+
+  get() {
+    this.msg.success(this.cache.getNone(this.KEY));
+  }
+}
diff --git a/src/app/routes/delon/delon-routing.module.ts b/src/app/routes/delon/delon-routing.module.ts
new file mode 100644
index 0000000..3bd0ddc
--- /dev/null
+++ b/src/app/routes/delon/delon-routing.module.ts
@@ -0,0 +1,61 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { ACLGuard } from '@delon/acl';
+
+import { SimpleTableComponent } from './simple-table/simple-table.component';
+import { UtilComponent } from './util/util.component';
+import { PrintComponent } from './print/print.component';
+import { ACLComponent } from './acl/acl.component';
+import { GuardComponent } from './guard/guard.component';
+import { GuardLeaveComponent } from './guard/leave.component';
+import { GuardAuthComponent } from './guard/auth.component';
+import { GuardAdminComponent } from './guard/admin.component';
+import { CanLeaveProvide } from './guard/can-leave.provide';
+import { CacheComponent } from './cache/cache.component';
+import { DownFileComponent } from './downfile/downfile.component';
+import { XlsxComponent } from './xlsx/xlsx.component';
+import { ZipComponent } from './zip/zip.component';
+import { DelonFormComponent } from './form/form.component';
+import { QRComponent } from './qr/qr.component';
+
+const routes: Routes = [
+  { path: 'simple-table', component: SimpleTableComponent },
+  { path: 'util', component: UtilComponent },
+  { path: 'print', component: PrintComponent },
+  { path: 'acl', component: ACLComponent },
+  {
+    path: 'guard',
+    component: GuardComponent,
+    children: [
+      {
+        path: 'leave',
+        component: GuardLeaveComponent,
+        canDeactivate: [CanLeaveProvide],
+      },
+      {
+        path: 'auth',
+        component: GuardAuthComponent,
+        canActivate: [ACLGuard],
+        data: { guard: 'user1' },
+      },
+      {
+        path: 'admin',
+        component: GuardAdminComponent,
+        canActivate: [ACLGuard],
+        data: { guard: 'admin' },
+      },
+    ],
+  },
+  { path: 'cache', component: CacheComponent },
+  { path: 'qr', component: QRComponent },
+  { path: 'downfile', component: DownFileComponent },
+  { path: 'xlsx', component: XlsxComponent },
+  { path: 'zip', component: ZipComponent },
+  { path: 'form', component: DelonFormComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class DelonRoutingModule {}
diff --git a/src/app/routes/delon/delon.module.ts b/src/app/routes/delon/delon.module.ts
new file mode 100644
index 0000000..a143429
--- /dev/null
+++ b/src/app/routes/delon/delon.module.ts
@@ -0,0 +1,48 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { SharedModule } from '@shared/shared.module';
+
+import { DelonRoutingModule } from './delon-routing.module';
+
+import { SimpleTableComponent } from './simple-table/simple-table.component';
+import { UtilComponent } from './util/util.component';
+import { PrintComponent } from './print/print.component';
+import { ACLComponent } from './acl/acl.component';
+import { CanLeaveProvide } from './guard/can-leave.provide';
+import { GuardComponent } from './guard/guard.component';
+import { GuardLeaveComponent } from './guard/leave.component';
+import { GuardAdminComponent } from './guard/admin.component';
+import { GuardAuthComponent } from './guard/auth.component';
+import { CacheComponent } from './cache/cache.component';
+import { DownFileComponent } from './downfile/downfile.component';
+import { XlsxComponent } from './xlsx/xlsx.component';
+import { ZipComponent } from './zip/zip.component';
+import { DelonFormComponent } from './form/form.component';
+import { QRComponent } from './qr/qr.component';
+
+const COMPONENT = [
+  SimpleTableComponent,
+  UtilComponent,
+  PrintComponent,
+  ACLComponent,
+  GuardComponent,
+  GuardLeaveComponent,
+  GuardAdminComponent,
+  GuardAuthComponent,
+  CacheComponent,
+  DownFileComponent,
+  XlsxComponent,
+  ZipComponent,
+  DelonFormComponent,
+  QRComponent,
+];
+
+const COMPONENT_NOROUNT = [];
+
+@NgModule({
+  imports: [CommonModule, SharedModule, DelonRoutingModule],
+  providers: [CanLeaveProvide],
+  declarations: [...COMPONENT, ...COMPONENT_NOROUNT],
+  entryComponents: COMPONENT_NOROUNT,
+})
+export class DelonModule {}
diff --git a/src/app/routes/delon/downfile/downfile.component.html b/src/app/routes/delon/downfile/downfile.component.html
new file mode 100644
index 0000000..35f4f69
--- /dev/null
+++ b/src/app/routes/delon/downfile/downfile.component.html
@@ -0,0 +1,6 @@
+<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/tmp/demo{{i}}" file-name="demo������">{{i}}</button>
+</nz-card>
diff --git a/src/app/routes/delon/downfile/downfile.component.spec.ts b/src/app/routes/delon/downfile/downfile.component.spec.ts
new file mode 100644
index 0000000..5e1bf7e
--- /dev/null
+++ b/src/app/routes/delon/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/delon/downfile/downfile.component.ts b/src/app/routes/delon/downfile/downfile.component.ts
new file mode 100644
index 0000000..5a0b795
--- /dev/null
+++ b/src/app/routes/delon/downfile/downfile.component.ts
@@ -0,0 +1,14 @@
+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/delon/form/form.component.html b/src/app/routes/delon/form/form.component.html
new file mode 100644
index 0000000..0025e21
--- /dev/null
+++ b/src/app/routes/delon/form/form.component.html
@@ -0,0 +1,5 @@
+<page-header [title]="'Page Name'"></page-header>
+<nz-card>
+  <sf mode="search" [schema]="searchSchema" [formData]="params" (formSubmit)="st.reset($event)" (formReset)="st.reset(params)"></sf>
+  <simple-table #st [data]="url" [columns]="columns" [extraParams]="params"></simple-table>
+</nz-card>
diff --git a/src/app/routes/delon/form/form.component.ts b/src/app/routes/delon/form/form.component.ts
new file mode 100644
index 0000000..4773622
--- /dev/null
+++ b/src/app/routes/delon/form/form.component.ts
@@ -0,0 +1,32 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+import { SimpleTableColumn, SimpleTableComponent } from '@delon/abc';
+import { SFSchema } from '@delon/form';
+
+@Component({
+  selector: 'app-delon-form',
+  templateUrl: './form.component.html',
+})
+export class DelonFormComponent implements OnInit {
+  params: any = {};
+  url = `/user`;
+  @ViewChild('st') st: SimpleTableComponent;
+  searchSchema: SFSchema = {
+    properties: {
+      no: {
+        type: 'string',
+        title: '������',
+      },
+    },
+  };
+  columns: SimpleTableColumn[] = [
+    { title: '������', index: 'no' },
+    { title: '������������', type: 'number', index: 'callNo' },
+    { title: '������', type: 'img', width: '50px', index: 'avatar' },
+    { title: '������', type: 'date', index: 'updatedAt' },
+  ];
+
+  constructor(private http: _HttpClient) {}
+
+  ngOnInit() {}
+}
diff --git a/src/app/routes/delon/guard/admin.component.ts b/src/app/routes/delon/guard/admin.component.ts
new file mode 100644
index 0000000..3a0aae6
--- /dev/null
+++ b/src/app/routes/delon/guard/admin.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-guard-admin',
+  template: `
+    <p>������������admin������</p>
+  `,
+})
+export class GuardAdminComponent {}
diff --git a/src/app/routes/delon/guard/auth.component.ts b/src/app/routes/delon/guard/auth.component.ts
new file mode 100644
index 0000000..fcb335e
--- /dev/null
+++ b/src/app/routes/delon/guard/auth.component.ts
@@ -0,0 +1,9 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-guard-auth',
+  template: `
+    <p>������������user1������</p>
+  `,
+})
+export class GuardAuthComponent {}
diff --git a/src/app/routes/delon/guard/can-leave.provide.ts b/src/app/routes/delon/guard/can-leave.provide.ts
new file mode 100644
index 0000000..1d50dac
--- /dev/null
+++ b/src/app/routes/delon/guard/can-leave.provide.ts
@@ -0,0 +1,38 @@
+import { Injectable } from '@angular/core';
+import {
+  CanDeactivate,
+  ActivatedRouteSnapshot,
+  RouterStateSnapshot,
+} from '@angular/router';
+import { GuardComponent } from './guard.component';
+import { Observable } from 'rxjs';
+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({
+        nzTitle: '���������������������',
+        nzContent: '���������������������������������������������������������������������',
+        nzOkText: '������',
+        nzCancelText: '������',
+        nzOnOk: () => {
+          observer.next(true);
+          observer.complete();
+        },
+        nzOnCancel: () => {
+          observer.next(false);
+          observer.complete();
+        },
+      });
+    });
+  }
+}
diff --git a/src/app/routes/delon/guard/guard.component.html b/src/app/routes/delon/guard/guard.component.html
new file mode 100644
index 0000000..892c463
--- /dev/null
+++ b/src/app/routes/delon/guard/guard.component.html
@@ -0,0 +1,33 @@
+<div class="content__title">
+  <h1>
+    ������������
+  </h1>
+</div>
+<nz-button-group>
+  <button nz-button [routerLink]="['/delon/guard/leave']">
+    <span>���������������</span>
+  </button>
+</nz-button-group>
+<nz-button-group class="ml-sm">
+  <button nz-button (click)="setRole(true)">
+    <span>���������������</span>
+  </button>
+  <button nz-button (click)="setRole('user1')">
+    <span>������������1</span>
+  </button>
+  <button nz-button (click)="setRole('user2')">
+    <span>������������2</span>
+  </button>
+</nz-button-group>
+<nz-button-group class="ml-sm">
+  <button nz-button [routerLink]="['/delon/guard/auth']">
+    <span>������user1</span>
+  </button>
+  <button nz-button [routerLink]="['/delon/guard/admin']">
+    <span>���������������</span>
+  </button>
+</nz-button-group>
+<p class="mb-lg">
+  ������ACL���������{{ aclSrv.data | json }}
+</p>
+<router-outlet></router-outlet>
diff --git a/src/app/routes/delon/guard/guard.component.spec.ts b/src/app/routes/delon/guard/guard.component.spec.ts
new file mode 100644
index 0000000..cb8ee27
--- /dev/null
+++ b/src/app/routes/delon/guard/guard.component.spec.ts
@@ -0,0 +1,17 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '@testing/common.spec';
+
+import { GuardComponent } from './guard.component';
+
+describe('Comoponent: Guard', () => {
+  setUpTestBed(<TestModuleMetadata>{
+    declarations: [GuardComponent],
+    providers: [],
+  });
+
+  it('should create an instance', () => {
+    const fixture = TestBed.createComponent(GuardComponent);
+    const comp = fixture.debugElement.componentInstance;
+    expect(comp).toBeTruthy();
+  });
+});
diff --git a/src/app/routes/delon/guard/guard.component.ts b/src/app/routes/delon/guard/guard.component.ts
new file mode 100644
index 0000000..be2efd4
--- /dev/null
+++ b/src/app/routes/delon/guard/guard.component.ts
@@ -0,0 +1,23 @@
+import { MenuService } from '@delon/theme';
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { ACLService } from '@delon/acl';
+
+@Component({
+  selector: 'app-guard',
+  templateUrl: './guard.component.html',
+})
+export class GuardComponent {
+  constructor(
+    public aclSrv: ACLService,
+    private menuSrv: MenuService,
+    private router: Router,
+  ) {}
+
+  setRole(value: string | boolean) {
+    this.aclSrv.setFull(typeof value === 'boolean' ? value : false);
+    this.aclSrv.set({ role: [value as string] });
+    this.menuSrv.resume();
+    this.router.navigate(['/delon/guard']);
+  }
+}
diff --git a/src/app/routes/delon/guard/leave.component.ts b/src/app/routes/delon/guard/leave.component.ts
new file mode 100644
index 0000000..37bdba9
--- /dev/null
+++ b/src/app/routes/delon/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/delon/print/print.component.html b/src/app/routes/delon/print/print.component.html
new file mode 100644
index 0000000..5a17ff1
--- /dev/null
+++ b/src/app/routes/delon/print/print.component.html
@@ -0,0 +1,61 @@
+<div class="content__title">
+  <h1>Lodop������
+    <small>������������������
+      <a href="http://ng-alain.com/components/lodop" target="_blank">ng-alain.com</a>
+    </small>
+  </h1>
+</div>
+<nz-card>
+  <nz-alert *ngIf="error" [nzType]="'warning'" [nzMessage]="message">
+    <ng-template #message>
+      ������������
+      <a href="http://c-lodop.com/download.html" target="_blank">Lodop������</a>���
+    </ng-template>
+  </nz-alert>
+  <form *ngIf="!error" nz-form>
+    <nz-form-item nz-row>
+      <nz-form-label nz-col [nzSm]="6">���������������</nz-form-label>
+      <nz-form-control nz-col [nzSm]="18">
+        <nz-input-group>
+          <div nz-col [nzSpan]="16">
+            <input nz-input nzPlaceHolder="https://localhost:8443/CLodopfuncs.js" [(ngModel)]="cog.url" name="url">
+          </div>
+          <div nz-col [nzSpan]="8">
+            <button nz-button (click)="reload(null)">���������������������</button>
+          </div>
+        </nz-input-group>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item nz-row>
+      <nz-form-label nz-col [nzSm]="6">���������</nz-form-label>
+      <nz-form-control nz-col [nzSm]="18">
+        <nz-select style="width:90%;" nzPlaceHolder="������������������" nzShowSearch nzAllowClear [(ngModel)]="cog.printer" name="printer" (ngModelChange)="changePinter($event)">
+          <nz-option *ngFor="let name of pinters" [nzLabel]="name" [nzValue]="name">
+          </nz-option>
+        </nz-select>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item nz-row>
+      <nz-form-label nz-col [nzSm]="6">������������</nz-form-label>
+      <nz-form-control nz-col [nzSm]="18">
+        <nz-select style="width:90%;" nzPlaceHolder="���������������������" nzShowSearch nzAllowClear [(ngModel)]="cog.paper" name="paper">
+          <nz-option *ngFor="let name of papers" [nzLabel]="name" [nzValue]="name">
+          </nz-option>
+        </nz-select>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item nz-row>
+      <nz-form-label nz-col [nzSm]="6">������������</nz-form-label>
+      <nz-form-control nz-col [nzSm]="18">
+        <textarea nz-input [(ngModel)]="cog.html" name="html" nzAutosize></textarea>
+        <div nz-form-extra>������HTML������������������������������������</div>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item nz-row>
+      <nz-form-control nz-col [nzSm]="18" [nzOffset]="6">
+        <button nz-button (click)="print(true)" [nzLoading]="printing">������������</button>
+        <button nz-button (click)="print()" [nzLoading]="printing">������������</button>
+      </nz-form-control>
+    </nz-form-item>
+  </form>
+</nz-card>
diff --git a/src/app/routes/delon/print/print.component.ts b/src/app/routes/delon/print/print.component.ts
new file mode 100644
index 0000000..98ef0d6
--- /dev/null
+++ b/src/app/routes/delon/print/print.component.ts
@@ -0,0 +1,79 @@
+import { Component } from '@angular/core';
+import { NzMessageService, NzNotificationService } from 'ng-zorro-antd';
+import { Lodop, LodopService } from '@delon/abc';
+
+@Component({
+  selector: 'app-print',
+  templateUrl: './print.component.html',
+})
+export class PrintComponent {
+  cog: any = {
+    url: 'https://localhost:8443/CLodopfuncs.js',
+    printer: '',
+    paper: '',
+    html: `
+      <h1>Title</h1>
+      <p>���~���@#���%������&*������������sdilfjnvn</p>
+      <p>���~���@#���%������&*������������sdilfjnvn</p>
+      <p>���~���@#���%������&*������������sdilfjnvn</p>
+      <p>���~���@#���%������&*������������sdilfjnvn</p>
+      <p>���~���@#���%������&*������������sdilfjnvn</p>
+    `,
+  };
+  error = false;
+  lodop: Lodop = null;
+  pinters: any[] = [];
+  papers: string[] = [];
+  constructor(
+    public lodopSrv: LodopService,
+    private msg: NzMessageService,
+    private notify: NzNotificationService,
+  ) {
+    this.lodopSrv.lodop.subscribe(({ lodop, ok }) => {
+      if (!ok) {
+        this.error = true;
+        return;
+      }
+      this.error = false;
+      this.msg.success(`���������������������`);
+      this.lodop = lodop;
+      this.pinters = this.lodopSrv.printer;
+    });
+  }
+
+  reload(options: any = { url: 'https://localhost:8443/CLodopfuncs.js' }) {
+    this.pinters = [];
+    this.papers = [];
+    this.cog.printer = '';
+    this.cog.paper = '';
+
+    this.lodopSrv.cog = Object.assign({}, this.cog, options);
+    this.error = false;
+    if (options === null) this.lodopSrv.reset();
+  }
+
+  changePinter(name: string) {
+    this.papers = this.lodop.GET_PAGESIZES_LIST(name, '\n').split('\n');
+  }
+
+  printing = false;
+  print(isPrivew = false) {
+    const LODOP = this.lodop;
+    LODOP.PRINT_INITA(10, 20, 810, 610, '������C-Lodop���������������������');
+    LODOP.SET_PRINTER_INDEXA(this.cog.printer);
+    LODOP.SET_PRINT_PAGESIZE(0, 0, 0, this.cog.paper);
+    LODOP.ADD_PRINT_TEXT(
+      1,
+      1,
+      300,
+      200,
+      '������������������������������������������������������',
+    );
+    LODOP.ADD_PRINT_TEXT(20, 10, '90%', '95%', this.cog.html);
+    LODOP.SET_PRINT_STYLEA(0, 'ItemType', 4);
+    LODOP.NewPageA();
+    LODOP.ADD_PRINT_HTM(20, 10, '90%', '95%', this.cog.html);
+    if (isPrivew) LODOP.PREVIEW();
+    else LODOP.PRINT();
+  }
+}
diff --git a/src/app/routes/delon/qr/qr.component.html b/src/app/routes/delon/qr/qr.component.html
new file mode 100644
index 0000000..4fd22d9
--- /dev/null
+++ b/src/app/routes/delon/qr/qr.component.html
@@ -0,0 +1,76 @@
+<div class="content__title">
+  <h1>���������
+    <a href="//ng-alain.com/components/qr" target="_blank">Document</a>
+  </h1>
+</div>
+<nz-card>
+  <nz-row [nzGutter]="24">
+    <nz-col [nzSpan]="8" class="text-center">
+      <qr [value]="value" [background]="background" [backgroundAlpha]="backgroundAlpha" [foreground]="foreground" [foregroundAlpha]="foregroundAlpha"
+        [level]="level" [mime]="mime" [padding]="padding" [size]="size" style="border:1px solid #999"></qr>
+    </nz-col>
+    <nz-col [nzSpan]="16">
+      <form nz-form>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">������</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-input-group>
+              <div nz-col nzSpan="12">
+                <input nz-input type="color" [(ngModel)]="background" [ngModelOptions]="{standalone: true}">
+              </div>
+              <div nz-col nzSpan="12">
+                <nz-input-number [(ngModel)]="backgroundAlpha" [nzMin]="0" [nzMax]="1" [nzStep]="0.1" [ngModelOptions]="{standalone: true}"></nz-input-number>
+              </div>
+            </nz-input-group>
+          </nz-form-control>
+        </nz-form-item>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">������</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-input-group>
+              <div nz-col nzSpan="12">
+                <input nz-input type="color" [(ngModel)]="foreground" [ngModelOptions]="{standalone: true}">
+              </div>
+              <div nz-col nzSpan="12">
+                <nz-input-number [(ngModel)]="foregroundAlpha" [nzMin]="0" [nzMax]="1" [nzStep]="0.1" [ngModelOptions]="{standalone: true}"></nz-input-number>
+              </div>
+            </nz-input-group>
+          </nz-form-control>
+        </nz-form-item>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">������</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-select [(ngModel)]="level" [ngModelOptions]="{standalone: true}">
+              <nz-option nzValue="L" nzLabel="L"></nz-option>
+              <nz-option nzValue="M" nzLabel="M"></nz-option>
+              <nz-option nzValue="Q" nzLabel="Q"></nz-option>
+              <nz-option nzValue="H" nzLabel="H"></nz-option>
+            </nz-select>
+          </nz-form-control>
+        </nz-form-item>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">Mime</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-select [(ngModel)]="mime" [ngModelOptions]="{standalone: true}">
+              <nz-option nzValue="image/png" nzLabel="image/png"></nz-option>
+              <nz-option nzValue="image/jpeg" nzLabel="image/jpeg"></nz-option>
+              <nz-option nzValue="image/gif" nzLabel="image/gif"></nz-option>
+            </nz-select>
+          </nz-form-control>
+        </nz-form-item>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">���������</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-input-number [(ngModel)]="padding" [ngModelOptions]="{standalone: true}" [nzMin]="0" [nzMax]="100"></nz-input-number>px
+          </nz-form-control>
+        </nz-form-item>
+        <nz-form-item>
+          <nz-form-label [nzSpan]="8">������</nz-form-label>
+          <nz-form-control [nzSpan]="16">
+            <nz-input-number [(ngModel)]="size" [ngModelOptions]="{standalone: true}" [nzMin]="100" [nzMax]="1000" [nzStep]="padding"></nz-input-number>px
+          </nz-form-control>
+        </nz-form-item>
+      </form>
+    </nz-col>
+  </nz-row>
+</nz-card>
diff --git a/src/app/routes/delon/qr/qr.component.ts b/src/app/routes/delon/qr/qr.component.ts
new file mode 100644
index 0000000..a75a274
--- /dev/null
+++ b/src/app/routes/delon/qr/qr.component.ts
@@ -0,0 +1,17 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-qr',
+  templateUrl: './qr.component.html',
+})
+export class QRComponent {
+  value = 'https://ng-alain.com/';
+  background = 'white';
+  backgroundAlpha = 1.0;
+  foreground = 'black';
+  foregroundAlpha = 1.0;
+  level = 'L';
+  mime = 'image/png';
+  padding = 10;
+  size = 220;
+}
diff --git a/src/app/routes/delon/simple-table/simple-table.component.html b/src/app/routes/delon/simple-table/simple-table.component.html
new file mode 100644
index 0000000..dea8663
--- /dev/null
+++ b/src/app/routes/delon/simple-table/simple-table.component.html
@@ -0,0 +1,52 @@
+<div class="content__title">
+  <h1>
+    Fullscreen Table
+    <small>������
+      <a href="//ng-alain.com/components/simple-table" target="_blank">simple-table</a>���
+      <a href="//ng-alain.com/components/full-content" target="_blank">full-content</a> ��������������� nz-table ���������������������������������������������������������������������������������������������������������������</small>
+  </h1>
+</div>
+<full-content (fullscreenChange)="fullChange($event)">
+  <nz-card>
+    <div nz-row class="mb-md">
+      <div nz-col nzSpan="12">
+        <form nz-form [nzLayout]="'inline'">
+          <nz-form-item>
+            <nz-form-label nzFor="userid">User ID</nz-form-label>
+            <nz-form-control>
+              <input nz-input [(ngModel)]="args.userid" name="userid" id="userid">
+            </nz-form-control>
+          </nz-form-item>
+          <nz-form-item>
+            <nz-form-control>
+              <button nz-button [nzType]="'primary'" (click)="st.load()" [nzLoading]="http.loading">Search</button>
+              <button nz-button (click)="st.load({_allow_anonymous: true})" [disabled]="http.loading">Clear</button>
+            </nz-form-control>
+          </nz-form-item>
+        </form>
+      </div>
+      <div nz-col nzSpan="12">
+        <div class="text-right">
+          <nz-dropdown>
+            <button nz-button nz-dropdown>
+              <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>
+          <button nz-button [nzType]="'default'" full-toggle class="ml-sm">Full</button>
+        </div>
+      </div>
+    </div>
+    <simple-table #st [data]="url" [extraParams]="args" [resReName]="{list: 'results' }" [total]="total" [ps]="ps" [columns]="columns"
+      [scroll]="scroll">
+      <ng-template st-row="events" let-item let-index="index">
+        <g2-mini-bar height="15" theme="mini" color="#999" borderWidth="3" [padding]="[0, 0, 0, 0]" [data]="events"></g2-mini-bar>
+      </ng-template>
+    </simple-table>
+  </nz-card>
+</full-content>
diff --git a/src/app/routes/delon/simple-table/simple-table.component.ts b/src/app/routes/delon/simple-table/simple-table.component.ts
new file mode 100644
index 0000000..99b5aea
--- /dev/null
+++ b/src/app/routes/delon/simple-table/simple-table.component.ts
@@ -0,0 +1,74 @@
+import { Component, OnInit, OnDestroy } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { map } from 'rxjs/operators';
+import {
+  SimpleTableChange,
+  SimpleTableColumn,
+  SimpleTableButton,
+} from '@delon/abc';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-simple-table',
+  templateUrl: './simple-table.component.html',
+})
+export class SimpleTableComponent implements OnInit {
+  ps = 20;
+  total = 200; // mock total
+  args: any = { _allow_anonymous: true };
+  url = `https://api.randomuser.me/?results=20`;
+  events: any[] = [];
+  scroll = { y: '230px' };
+  columns: SimpleTableColumn[] = [
+    { title: 'id', index: 'id.value', type: 'checkbox' },
+    { title: 'Avatar', index: 'picture.thumbnail', type: 'img', width: '80px' },
+    {
+      title: 'Name',
+      index: 'name.first',
+      width: '150px',
+      format: (item: any) => `${item.name.first} ${item.name.last}`,
+      type: 'link',
+      click: (item: any) => this.message.info(`${item.name.first}`),
+    },
+    { title: 'Email', index: 'email' },
+    {
+      title: 'Gender',
+      index: 'gender',
+      type: 'yn',
+      ynTruth: 'female',
+      ynYes: '���',
+      ynNo: '���',
+      width: '120px',
+    },
+    { title: 'Events', render: 'events', width: '90px' },
+    { title: 'Registered', index: 'registered', type: 'date', width: '150px' },
+    {
+      title: 'Actions',
+      width: '120px',
+      buttons: <SimpleTableButton[]>[
+        {
+          text: 'Edit',
+          click: (item: any) => this.message.info(`edit [${item.id.value}]`),
+          if: (item: any) => item.gender === 'female',
+        },
+        {
+          text: 'Delete',
+          type: 'del',
+          click: (item: any) => this.message.info(`deleted [${item.id.value}]`),
+        },
+      ],
+    },
+  ];
+
+  constructor(public http: _HttpClient, private message: NzMessageService) {}
+
+  ngOnInit(): void {
+    this.http
+      .get('/chart/visit')
+      .subscribe((res: any[]) => (this.events = res.slice(0, 8)));
+  }
+
+  fullChange(val: boolean) {
+    this.scroll = val ? { y: '350px' } : { y: '230px' };
+  }
+}
diff --git a/src/app/routes/delon/util/util.component.html b/src/app/routes/delon/util/util.component.html
new file mode 100644
index 0000000..704437b
--- /dev/null
+++ b/src/app/routes/delon/util/util.component.html
@@ -0,0 +1,54 @@
+<div class="content__title">
+  <h1>
+    ���������
+    <small>@delon/util ���������������</small>
+  </h1>
+</div>
+<nz-row [nzGutter]="16">
+  <nz-col [nzSpan]="12">
+    <nz-card nzTitle="������������">
+      <nz-card nzType="inner" nzTitle="format">
+        <form nz-form>
+          <nz-form-item>
+            <nz-form-label [nzSm]="8">String</nz-form-label>
+            <nz-form-control [nzSm]="16">
+              <input nz-input [(ngModel)]="format_str" [ngModelOptions]="{standalone: true}">
+            </nz-form-control>
+          </nz-form-item>
+          <nz-form-item>
+            <nz-form-label [nzSm]="8">Object</nz-form-label>
+            <nz-form-control [nzSm]="16">
+              <input nz-input [(ngModel)]="format_obj" [ngModelOptions]="{standalone: true}">
+            </nz-form-control>
+          </nz-form-item>
+          <nz-form-item>
+            <nz-form-control [nzSpan]="16" [nzOffset]="8">
+              <button (click)="onFormat()" nz-button>Run</button>
+            </nz-form-control>
+          </nz-form-item>
+          <nz-form-item>
+            <nz-form-label [nzSm]="8">Result</nz-form-label>
+            <nz-form-control [nzSm]="16">
+              {{format_res}}
+            </nz-form-control>
+          </nz-form-item>
+        </form>
+      </nz-card>
+      <nz-card nzType="inner" nzTitle="yuan">
+        <nz-row [nzGutter]="16">
+          <nz-col [nzSpan]="12">
+            <input type="number" nz-input [(ngModel)]="yuan_str" (ngModelChange)="onYuan($event)">
+          </nz-col>
+          <nz-col [nzSpan]="12">
+            <div [innerHTML]="yuan_res"></div>
+          </nz-col>
+        </nz-row>
+      </nz-card>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzSpan]="12">
+    <nz-card nzTitle="���������">
+      <button nz-button (click)="onCopy()">Copy</button>
+    </nz-card>
+  </nz-col>
+</nz-row>
diff --git a/src/app/routes/delon/util/util.component.ts b/src/app/routes/delon/util/util.component.ts
new file mode 100644
index 0000000..6dff141
--- /dev/null
+++ b/src/app/routes/delon/util/util.component.ts
@@ -0,0 +1,47 @@
+import { Component } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { copy, format, yuan } from '@delon/util';
+
+@Component({
+  selector: 'app-util',
+  templateUrl: './util.component.html',
+})
+export class UtilComponent {
+  constructor(public messageSrv: NzMessageService) {}
+
+  // region: string
+
+  format_str = 'this is ${name}';
+  format_res = '';
+  format_obj = JSON.stringify({ name: 'asdf' });
+  onFormat() {
+    let obj = null;
+    try {
+      obj = JSON.parse(this.format_obj);
+    } catch {
+      this.messageSrv.error(`������������ JSON.parse ������`);
+      return;
+    }
+    this.format_res = format(this.format_str, obj, true);
+  }
+
+  // yuan
+  yuan_str: any;
+  yuan_res: string;
+  onYuan(value: string) {
+    this.yuan_res = yuan(value);
+  }
+
+  // endregion
+
+  // region: other
+
+  content = `time ${+new Date()}
+
+    ���������@#���%������&*`;
+  onCopy() {
+    copy(`time ${+new Date()}`).then(() => this.messageSrv.success(`success`));
+  }
+
+  // endregion
+}
diff --git a/src/app/routes/delon/xlsx/xlsx.component.html b/src/app/routes/delon/xlsx/xlsx.component.html
new file mode 100644
index 0000000..4b07860
--- /dev/null
+++ b/src/app/routes/delon/xlsx/xlsx.component.html
@@ -0,0 +1,14 @@
+<div class="content__title">
+  <h1>Import & Export excel file,
+    <a href="//ng-alain.com/components/xlsx" target="_blank">Document</a>
+  </h1>
+</div>
+<nz-card nzTitle="Import">
+  <button nz-button (click)="url()">Via Url</button>
+  <input type="file" (change)="change($event)" multiple="false" class="ml-sm" />
+  <p class="mt-sm">result: {{data | json}}</p>
+</nz-card>
+<nz-card nzTitle="Export">
+  <button nz-button (click)="download()">Export</button>
+  <simple-table [data]="users" [ps]="3" [columns]="columns" class="mt-sm"></simple-table>
+</nz-card>
diff --git a/src/app/routes/delon/xlsx/xlsx.component.ts b/src/app/routes/delon/xlsx/xlsx.component.ts
new file mode 100644
index 0000000..c67a0bf
--- /dev/null
+++ b/src/app/routes/delon/xlsx/xlsx.component.ts
@@ -0,0 +1,50 @@
+import { Component, OnInit } from '@angular/core';
+import { XlsxService, SimpleTableColumn } from '@delon/abc';
+
+@Component({
+  selector: 'app-xlsx',
+  templateUrl: './xlsx.component.html',
+})
+export class XlsxComponent {
+  constructor(private xlsx: XlsxService) {}
+  data: any;
+  url() {
+    this.xlsx.import(`./assets/tmp/demo.xlsx`).then(res => (this.data = res));
+  }
+
+  change(e: Event) {
+    const file = (e.target as HTMLInputElement).files[0];
+    this.xlsx.import(file).then(res => (this.data = res));
+  }
+
+  users: any[] = Array(100)
+    .fill({})
+    .map((item: any, idx: number) => {
+      return {
+        id: idx + 1,
+        name: `name ${idx + 1}`,
+        age: Math.ceil(Math.random() * 10) + 20,
+      };
+    });
+
+  columns: SimpleTableColumn[] = [
+    { title: '������', index: 'id', type: 'checkbox' },
+    { title: '������', index: 'name' },
+    { title: '������', index: 'age' },
+  ];
+
+  download() {
+    const data = [this.columns.map(i => i.title)];
+    this.users.forEach(i =>
+      data.push(this.columns.map(c => i[c.index as string])),
+    );
+    this.xlsx.export({
+      sheets: [
+        {
+          data: data,
+          name: 'sheet name',
+        },
+      ],
+    });
+  }
+}
diff --git a/src/app/routes/delon/zip/zip.component.html b/src/app/routes/delon/zip/zip.component.html
new file mode 100644
index 0000000..f2cf5b5
--- /dev/null
+++ b/src/app/routes/delon/zip/zip.component.html
@@ -0,0 +1,38 @@
+<div class="content__title">
+  <h1>Read & Write zip file,
+    <a href="//ng-alain.com/components/zip" target="_blank">Document</a>
+  </h1>
+</div>
+<nz-card nzTitle="������">
+  <button nz-button (click)="url()">Via Url</button>
+  <input type="file" (change)="change($event)" multiple="false" class="ml-sm" />
+  <ol>
+    <li *ngFor="let i of list">{{i | json}}</li>
+  </ol>
+</nz-card>
+<nz-card nzTitle="������" *ngIf="instance">
+  <button nz-button (click)="data.push({})" [nzType]="'primary'">new</button>
+  <button nz-button (click)="download()" class="ml-sm">download</button>
+  <nz-table [nzData]="data" [nzFrontPagination]="false" [nzShowPagination]="false" class="mt-sm">
+    <thead>
+      <tr>
+        <th>
+          <span>path</span>
+        </th>
+        <th>
+          <span>url</span>
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr *ngFor="let i of data; let index = index">
+        <td>
+          <input nz-input [(ngModel)]="i.path" name="path{{index}}">
+        </td>
+        <td>
+          <input nz-input [(ngModel)]="i.url" name="url{{index}}">
+        </td>
+      </tr>
+    </tbody>
+  </nz-table>
+</nz-card>
diff --git a/src/app/routes/delon/zip/zip.component.ts b/src/app/routes/delon/zip/zip.component.ts
new file mode 100644
index 0000000..ddbd814
--- /dev/null
+++ b/src/app/routes/delon/zip/zip.component.ts
@@ -0,0 +1,71 @@
+import { Component, OnInit } from '@angular/core';
+import { ZipService } from '@delon/abc';
+import * as JSZip from 'jszip';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'app-zip',
+  templateUrl: './zip.component.html',
+})
+export class ZipComponent {
+  constructor(private zip: ZipService, private msg: NzMessageService) {
+    this.zip.create().then(ret => (this.instance = ret));
+  }
+
+  // region: read
+
+  list: any;
+  private format(data: any) {
+    const files = data.files;
+    this.list = Object.keys(files).map(key => {
+      return {
+        name: key,
+        dir: files[key].dir,
+        date: files[key].date,
+      };
+    });
+  }
+
+  url() {
+    this.zip.read(`./assets/tmp/demo.zip`).then(res => this.format(res));
+  }
+
+  change(e: Event) {
+    const file = (e.target as HTMLInputElement).files[0];
+    this.zip.read(file).then(res => this.format(res));
+  }
+
+  // endregion
+
+  // region: write
+
+  instance: JSZip = null;
+  data: { path: string; url: string }[] = [
+    { path: 'demo.docx', url: 'http://ng-alain.com/assets/demo.docx' },
+    {
+      path: '���������������.zip',
+      url: 'https://wximg.gtimg.com/shake_tv/mina/standard_logo.zip',
+    },
+  ];
+
+  download() {
+    const promises: Promise<any>[] = [];
+    this.data.forEach(item => {
+      promises.push(this.zip.pushUrl(this.instance, item.path, item.url));
+    });
+    Promise.all(promises).then(
+      () => {
+        this.zip.save(this.instance).then(() => {
+          this.msg.success('download success');
+          this.data = [];
+        });
+      },
+      (error: any) => {
+        console.warn(error);
+        this.msg.error(JSON.stringify(error));
+      },
+    );
+  }
+
+  // endregion
+}
diff --git a/src/app/routes/exception/403.component.ts b/src/app/routes/exception/403.component.ts
new file mode 100644
index 0000000..8355d3b
--- /dev/null
+++ b/src/app/routes/exception/403.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { NzModalService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'exception-403',
+  template: `<exception type="403" style="min-height: 500px; height: 80%;"></exception>`,
+})
+export class Exception403Component {
+  constructor(modalSrv: NzModalService) {
+    modalSrv.closeAll();
+  }
+}
diff --git a/src/app/routes/exception/404.component.ts b/src/app/routes/exception/404.component.ts
new file mode 100644
index 0000000..50f8baf
--- /dev/null
+++ b/src/app/routes/exception/404.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { NzModalService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'exception-404',
+  template: `<exception type="404" style="min-height: 500px; height: 80%;"></exception>`,
+})
+export class Exception404Component {
+  constructor(modalSrv: NzModalService) {
+    modalSrv.closeAll();
+  }
+}
diff --git a/src/app/routes/exception/500.component.ts b/src/app/routes/exception/500.component.ts
new file mode 100644
index 0000000..4614dbb
--- /dev/null
+++ b/src/app/routes/exception/500.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { NzModalService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'exception-500',
+  template: `<exception type="500" style="min-height: 500px; height: 80%;"></exception>`,
+})
+export class Exception500Component {
+  constructor(modalSrv: NzModalService) {
+    modalSrv.closeAll();
+  }
+}
diff --git a/src/app/routes/extras/extras-routing.module.ts b/src/app/routes/extras/extras-routing.module.ts
new file mode 100644
index 0000000..b9416f8
--- /dev/null
+++ b/src/app/routes/extras/extras-routing.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { HelpCenterComponent } from './helpcenter/helpcenter.component';
+import { ExtrasSettingsComponent } from './settings/settings.component';
+import { ExtrasPoiComponent } from './poi/poi.component';
+
+const routes: Routes = [
+  { path: 'helpcenter', component: HelpCenterComponent },
+  { path: 'settings', component: ExtrasSettingsComponent },
+  { path: 'poi', component: ExtrasPoiComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class ExtrasRoutingModule {}
diff --git a/src/app/routes/extras/extras.module.ts b/src/app/routes/extras/extras.module.ts
new file mode 100644
index 0000000..294c4a0
--- /dev/null
+++ b/src/app/routes/extras/extras.module.ts
@@ -0,0 +1,24 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { ExtrasRoutingModule } from './extras-routing.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 COMPONENTS_NOROUNT = [ExtrasPoiEditComponent];
+
+@NgModule({
+  imports: [SharedModule, ExtrasRoutingModule],
+  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..5d7a10d
--- /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>
+  <div>������������������������������������</div>
+</div>
+<div class="text-center">
+  <nz-input-group nzCompact nzSize="large">
+    <input [(ngModel)]="q" placeholder="���������������������������������������������������������������" style="width: 50%;" nz-input>
+    <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'" (click)="search()" nzSize="large">
+      <span>������</span>
+    </button>
+  </nz-input-group>
+  <div class="py-sm text-grey-dark">
+    ���������������
+    <a class="ml-sm" (click)="quick('���������������������')">���������������������</a>
+    <a class="ml-sm" (click)="quick('���������������')">���������������</a>
+    <a class="ml-sm" (click)="quick('������������')">������������</a>
+    <a class="ml-sm" (click)="quick('������������������')">������������������</a>
+    <a class="ml-sm" (click)="quick('������������������')">������������������</a>
+    <a class="ml-sm" (click)="quick('������������')">������������</a>
+  </div>
+</div>
+<nz-row [nzGutter]="16" class="py-lg">
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('������������')" class="d-block text-center text-primary">
+        <i class="anticon anticon-rocket display-1 mb-md"></i>
+        <h2 class="mb0">������������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('���������CDN')" class="d-block text-center text-red">
+        <i class="anticon anticon-hdd display-1 mb-md"></i>
+        <h2 class="mb0">���������CDN</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('������������')" class="d-block text-center text-orange">
+        <i class="anticon anticon-user display-1 mb-md"></i>
+        <h2 class="mb0">������������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('���������')" class="d-block text-center text-purple">
+        <i class="anticon anticon-database display-1 mb-md"></i>
+        <h2 class="mb0">���������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('���������������')" class="d-block text-center text-cyan">
+        <i class="anticon anticon-api display-1 mb-md"></i>
+        <h2 class="mb0">���������������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('������')" class="d-block text-center text-teal">
+        <i class="anticon anticon-global display-1 mb-md"></i>
+        <h2 class="mb0">������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('������������')" class="d-block text-center text-pink">
+        <i class="anticon anticon-appstore-o display-1 mb-md"></i>
+        <h2 class="mb0">������������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+  <nz-col [nzXs]="12" [nzMd]="8">
+    <nz-card>
+      <a (click)="msg.info('���������������')" class="d-block text-center text-success">
+        <i class="anticon anticon-tool display-1 mb-md"></i>
+        <h2 class="mb0">���������������</h2>
+      </a>
+    </nz-card>
+  </nz-col>
+</nz-row>
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..c87127f
--- /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..6db10a7
--- /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..f67a40e
--- /dev/null
+++ b/src/app/routes/extras/poi/edit/edit.component.html
@@ -0,0 +1,87 @@
+<div class="modal-header">
+  <div class="modal-title">{{i.id > 0 ? '������' : '������'}}-���������������HTML���������������������</div>
+</div>
+<form #f="ngForm" (ngSubmit)="save()" nz-form>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">���������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      {{i.user_id}}
+      <a (click)="msgSrv.info('find')">������������</a>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.name" name="name" maxlength="30" required />
+      <p nz-form-explain>���������������������������������������������������������������������������������������������������������</p>
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.branch_name" name="branch_name" maxlength="20" required />
+      <p nz-form-explain>������������������������������������������������������������������������������������������</p>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">���������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.geo" name="geo" maxlength="50" required />
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.address" name="address" maxlength="50" required />
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.lat" name="lat" required />
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.lng" name="lng" required />
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.tel" name="tel" maxlength="30" required />
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control 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>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">���������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.recommend" name="recommend" maxlength="200" placeholder="200���������" />
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.special" name="special" maxlength="50" placeholder="50���������" />
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.introduction" name="introduction" maxlength="300" placeholder="300���������" />
+    </nz-form-control>
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <input nz-input [(ngModel)]="i.open_time" name="open_time" maxlength="30" placeholder="30���������" />
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="mb-sm">
+    <nz-form-label nzSpan="4">������������</nz-form-label>
+    <nz-form-control nzSpan="8">
+      <nz-input-number [(ngModel)]="i.avg_price" name="avg_price" [nzMin]="0" [nzStep]="10"></nz-input-number>
+    </nz-form-control>
+  </nz-form-item>
+  <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..dbf6863
--- /dev/null
+++ b/src/app/routes/extras/poi/edit/edit.component.ts
@@ -0,0 +1,39 @@
+import { NzMessageService, NzModalRef } from 'ng-zorro-antd';
+import { HttpClient } from '@angular/common/http';
+import { Component, OnInit } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-extras-poi-edit',
+  templateUrl: './edit.component.html',
+})
+export class ExtrasPoiEditComponent implements OnInit {
+  i: any;
+  cat: string[] = ['������', '������,������', '������,������,���������'];
+
+  constructor(
+    private modal: NzModalRef,
+    public msgSrv: NzMessageService,
+    public http: _HttpClient,
+  ) {}
+
+  ngOnInit() {
+    if (this.i.id > 0) {
+      this.http
+        .get('./assets/tmp/pois.json')
+        .subscribe((res: any) => (this.i = res.data[0]));
+    }
+  }
+
+  save() {
+    this.http.get('./assets/tmp/pois.json').subscribe(() => {
+      this.msgSrv.success('���������������������������������������������');
+      this.modal.close(true);
+      this.close();
+    });
+  }
+
+  close() {
+    this.modal.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..dbe7296
--- /dev/null
+++ b/src/app/routes/extras/poi/poi.component.html
@@ -0,0 +1,37 @@
+<div class="content__title">
+  <h1>������
+    <small>������
+      <code>.simple-table</code> ������������������������������������������</small>
+  </h1>
+  <button nz-button (click)="add()" [nzType]="'primary'">������</button>
+</div>
+<form nz-form [nzLayout]="'inline'" class="search-form">
+  <nz-form-item>
+    <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>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <input nz-input [(ngModel)]="s.user_id" name="user_id" nzPlaceHolder="������������">
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <input nz-input [(ngModel)]="s.q" name="q" nzPlaceHolder="���������������������">
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <button nz-button (click)="st.reset(s)">������</button>
+    </nz-form-control>
+  </nz-form-item>
+</form>
+<simple-table #st class="simple-table" [columns]="columns" [data]="url" [extraParams]="s"></simple-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..614424c
--- /dev/null
+++ b/src/app/routes/extras/poi/poi.component.ts
@@ -0,0 +1,51 @@
+import { Component, ViewChild } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { ModalHelper } from '@delon/theme';
+import { SimpleTableComponent, SimpleTableColumn } from '@delon/abc';
+import { ExtrasPoiEditComponent } from './edit/edit.component';
+
+@Component({
+  selector: 'app-extras-poi',
+  templateUrl: './poi.component.html',
+})
+export class ExtrasPoiComponent {
+  @ViewChild('st') st: SimpleTableComponent;
+  s: any = {
+    pi: 1,
+    ps: 10,
+    s: '',
+  };
+  url = '/pois';
+  columns: SimpleTableColumn[] = [
+    { title: '������', index: 'id', width: '100px' },
+    { title: '������������', index: 'name' },
+    { title: '���������', index: 'branch_name' },
+    { title: '������', index: 'status_str', width: '100px' },
+    {
+      title: '������',
+      width: '180px',
+      buttons: [
+        {
+          text: '������',
+          type: 'modal',
+          component: ExtrasPoiEditComponent,
+          paramName: 'i',
+          click: () => this.msg.info('���������������������������������'),
+        },
+        { text: '������', click: () => this.msg.info('click photo') },
+        { text: '������SKU', click: () => this.msg.info('click sku') },
+      ],
+    },
+  ];
+
+  constructor(public msg: NzMessageService, private modal: ModalHelper) {}
+
+  add() {
+    this.modal
+      .static(ExtrasPoiEditComponent, { i: { id: 0 } })
+      .subscribe(() => {
+        this.st.load();
+        this.msg.info('���������������������������������');
+      });
+  }
+}
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..484896d
--- /dev/null
+++ b/src/app/routes/extras/settings/settings.component.html
@@ -0,0 +1,204 @@
+<nz-row [nzGutter]="24" class="py-lg">
+  <nz-col [nzSpan]="6">
+    <nz-card nzTitle="Personal settings" class="ant-card__body-nopadding">
+      <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" class="ant-card__body-nopadding">
+      <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>
+  </nz-col>
+  <nz-col [nzSpan]="18">
+    <nz-card nzTitle="Public profile" *ngIf="active===1">
+      <nz-row [nzGutter]="64">
+        <nz-col [nzSpan]="16">
+          <form nz-form [formGroup]="profileForm" (ngSubmit)="profileSave($event, profileForm.value)" [nzLayout]="'vertical'">
+            <nz-form-item>
+              <nz-form-label nzFor="name" nzRequired>name</nz-form-label>
+              <nz-form-control>
+                <input nz-input formControlName="name" id="name">
+                <div *ngIf="name.invalid && (name.dirty || name.touched)">
+                  <nz-form-explain *ngIf="name.errors.required">required</nz-form-explain>
+                  <nz-form-explain *ngIf="name.errors.pattern">must match pattern [-_a-zA-Z0-9]</nz-form-explain>
+                </div>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzFor="email">email</nz-form-label>
+              <nz-form-control>
+                <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>
+                <nz-form-explain>You can manage verified email addresses in your
+                  <a (click)="active=3">email settings</a>.</nz-form-explain>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzFor="bio">Bio</nz-form-label>
+              <nz-form-control>
+                <textarea nz-input formControlName="bio" id="bio" placeholder="Tell us a little bit about yourself"></textarea>
+                <nz-form-explain>You can
+                  <strong>@mention</strong> other users and organizations to link to them.</nz-form-explain>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzFor="url">URL</nz-form-label>
+              <nz-form-control>
+                <input nz-input formControlName="url" id="url">
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzFor="company">Company</nz-form-label>
+              <nz-form-control>
+                <input nz-input formControlName="company" id="company">
+                <nz-form-explain>You can
+                  <strong>@mention</strong> your company's GitHub organization to link it.</nz-form-explain>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item class="border-top-1 mt-md pt-md">
+              <nz-form-label nzFor="location">Location</nz-form-label>
+              <nz-form-control>
+                <input nz-input formControlName="location" id="location">
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-control>
+                <button nz-button [nzType]="'primary'" [disabled]="profileForm.invalid">Update profile</button>
+              </nz-form-control>
+            </nz-form-item>
+          </form>
+        </nz-col>
+        <nz-col [nzSpan]="8">
+          <h4>Profile picture</h4>
+          <img src="./assets/tmp/img/avatar.jpg" style="width: 100%;">
+          <nz-upload nzAction="https://jsonplaceholder.typicode.com/posts/" class="d-block mt-md text-center">
+            <button nz-button>Upload new picture</button>
+          </nz-upload>
+        </nz-col>
+      </nz-row>
+    </nz-card>
+    <nz-card nzTitle="Change password" *ngIf="active===2">
+      <nz-row [nzGutter]="64">
+        <nz-col [nzSpan]="16">
+          <form nz-form [nzLayout]="'vertical'">
+            <nz-form-item>
+              <nz-form-label nzFor="old_password" nzRequired>Old password</nz-form-label>
+              <nz-form-control>
+                <input nz-input [(ngModel)]="pwd.old_password" name="old_password" id="old_password" type="password" required>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzFor="new_password" nzRequired>New password</nz-form-label>
+              <nz-form-control>
+                <input nz-input [(ngModel)]="pwd.new_password" name="new_password" id="new_password" type="password" required>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-label nzRequired nzFor="confirm_new_password">Confirm new password</nz-form-label>
+              <nz-form-control>
+                <input nz-input [(ngModel)]="pwd.confirm_new_password" name="confirm_new_password" id="confirm_new_password" type="password"
+                  required>
+              </nz-form-control>
+            </nz-form-item>
+            <nz-form-item>
+              <nz-form-control>
+                <button nz-button (click)="pwdSave()" [nzType]="'primary'">Update profile</button>
+                <a class="pl-sm" [routerLink]="['/forget']">I forgot my password</a>
+              </nz-form-control>
+            </nz-form-item>
+          </form>
+        </nz-col>
+      </nz-row>
+      <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')">
+        <span>Change username</span>
+      </button>
+    </nz-card>
+    <nz-card nzTitle="Email" *ngIf="active===3">
+      <nz-row class="border-1 p-md rounded-sm" [nzType]="'flex'" [nzJustify]="'center'" [nzAlign]="'middle'">
+        <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>
+        </nz-col>
+        <nz-col [nzSpan]="12" class="text-right">
+          <i class="anticon anticon-delete text-lg"></i>
+        </nz-col>
+      </nz-row>
+      <h4 class="pt-md mb-sm">Add email address</h4>
+      <input nz-input style="width: 200px;" class="mr-sm">
+      <button nz-button (click)="msg.info('add')">Add</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 [(ngModel)]="primary_email" class="mr-sm">
+        <nz-option [nzLabel]="'cipchk@qq.com'" [nzValue]="'cipchk@qq.com'"></nz-option>
+      </nz-select>
+      <button nz-button (click)="msg.info('save')">Save</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>
+      <nz-list nzBordered>
+        <nz-list-item class="d-block">
+          <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">Automatically watch</label>
+        </nz-list-item>
+        <nz-list-item class="d-block">
+          <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">Email</label>
+          <label nz-checkbox [ngModel]="true">Web</label>
+        </nz-list-item>
+        <nz-list-item class="d-block">
+          <h4>Watching</h4>
+          <p class="py-sm">Notifications for all repositories or conversations you���re watching.</p>
+          <label nz-checkbox [ngModel]="true">Email</label>
+          <label nz-checkbox [ngModel]="true">Web</label>
+        </nz-list-item>
+      </nz-list>
+    </nz-card>
+    <nz-card class="ant-card__body-nopadding" *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.info('Register a new application')" [nzType]="'primary'">
+          Register a new application
+        </button>
+      </div>
+    </nz-card>
+    <nz-card nzTitle="Personal access tokens" [nzExtra]="extra" *ngIf="active===6">
+      <ng-template #extra>
+        <button nz-button (click)="msg.info('Generate new token')" [nzSize]="'small'">Generate new token</button>
+        <button nz-button (click)="msg.info('Revoke all')" [nzSize]="'small'" [nzType]="'danger'" class="ml-sm">Revoke all</button>
+      </ng-template>
+      <p>Tokens you have generated that can be used to access the GitHub API.</p>
+      <nz-list nzBordered class="mt-sm">
+        <nz-list-item>
+          <nz-col [nzSpan]="12">
+            <strong>octotree</strong> ��� repo
+          </nz-col>
+          <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>
+          </nz-col>
+        </nz-list-item>
+      </nz-list>
+    </nz-card>
+  </nz-col>
+</nz-row>
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..7bb9ac1
--- /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..487d0e9
--- /dev/null
+++ b/src/app/routes/extras/settings/settings.component.ts
@@ -0,0 +1,64 @@
+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/home-page/home-page-routing.module.ts b/src/app/routes/home-page/home-page-routing.module.ts
deleted file mode 100644
index 5b20053..0000000
--- a/src/app/routes/home-page/home-page-routing.module.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { NgModule } from '@angular/core';
-import { HomePageComponent } from './home-page/home-page.component';
-import { Routes, RouterModule } from '@angular/router';
-
-const routes: Routes = [{ path: '', component: HomePageComponent }];
-
-@NgModule({
-  imports: [RouterModule.forChild(routes)],
-  exports: [RouterModule],
-})
-export class HomePageRoutingModule { }
diff --git a/src/app/routes/home-page/home-page.module.ts b/src/app/routes/home-page/home-page.module.ts
deleted file mode 100644
index 9af96bc..0000000
--- a/src/app/routes/home-page/home-page.module.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-import { SharedModule } from '@shared/shared.module';
-import { HomePageRoutingModule } from './home-page-routing.module';
-import { HomePageComponent } from './home-page/home-page.component';
-
-@NgModule({
-  imports: [
-    SharedModule, HomePageRoutingModule
-  ],
-  declarations: [HomePageComponent]
-})
-export class HomePageModule { }
diff --git a/src/app/routes/home-page/home-page/home-page.component.html b/src/app/routes/home-page/home-page/home-page.component.html
deleted file mode 100644
index 3a45c9b..0000000
--- a/src/app/routes/home-page/home-page/home-page.component.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<div class="content__title">
-  <h1>������������</h1>
-</div>
-<div nz-row [nzGutter]="24" class="pt-lg">
-  <div nz-col nzXs="24" nzSm="12" nzMd="12" nzLg="8">
-    <g2-card [title]="'AQI������'" total="126,560" contentHeight="44px" [action]="action1" [footer]="footer1">
-      <ng-template #action1>
-        <nz-tooltip [nzTitle]="'������'">
-            <i class="anticon anticon-sync"></i>
-        </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 mb0">���������������
-          <span class="ml-sm">���12,423</span>
-        </p>
-      </ng-template>
-    </g2-card>
-  </div>
-</div>
diff --git a/src/app/routes/home-page/home-page/home-page.component.ts b/src/app/routes/home-page/home-page/home-page.component.ts
deleted file mode 100644
index a269aea..0000000
--- a/src/app/routes/home-page/home-page/home-page.component.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-
-@Component({
-  selector: 'app-home-page',
-  templateUrl: './home-page.component.html',
-  styleUrls: ['./home-page.component.less']
-})
-export class HomePageComponent implements OnInit {
-
-  constructor() { }
-
-  ngOnInit() {
-  }
-
-}
diff --git a/src/app/routes/passport/lock/lock.component.html b/src/app/routes/passport/lock/lock.component.html
new file mode 100644
index 0000000..ced40d1
--- /dev/null
+++ b/src/app/routes/passport/lock/lock.component.html
@@ -0,0 +1,29 @@
+<div class="wrapper">
+  <div class="abs-center width-lg">
+    <div class="py-lg text-center">
+      <nz-avatar [nzSrc]="settings.user.avatar" nzIcon="anticon anticon-user" nzSize="large"></nz-avatar>
+    </div>
+    <nz-card [nzBordered]="false">
+      <p class="mb-sm">������������������������������</p>
+      <form nz-form [formGroup]="f" (ngSubmit)="submit()" role="form">
+        <nz-form-item>
+          <nz-form-control>
+            <nz-input-group nzSize="large" nzSuffixIcon="anticon anticon-lock">
+              <input type="password" nz-input formControlName="password">
+            </nz-input-group>
+            <nz-form-explain *ngIf="f.get('password').dirty && f.get('password').errors">This field is required</nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+        <nz-row nzType="flex" nzAlign="middle">
+          <nz-col [nzOffset]="12" [nzSpan]="12" style="text-align:right;">
+            <button nz-button nzSize="large" [disabled]="!f.valid" nzType="primary">������</button>
+          </nz-col>
+        </nz-row>
+      </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/passport/lock/lock.component.spec.ts b/src/app/routes/passport/lock/lock.component.spec.ts
new file mode 100644
index 0000000..a4daab7
--- /dev/null
+++ b/src/app/routes/passport/lock/lock.component.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '@testing/common.spec';
+
+import { UserLockComponent } from './lock.component';
+
+describe('Pages: lock', () => {
+  setUpTestBed(<TestModuleMetadata>{
+    declarations: [UserLockComponent],
+  });
+
+  it('should create an instance', () => {
+    const fixture = TestBed.createComponent(UserLockComponent);
+    const comp = fixture.debugElement.componentInstance;
+    expect(comp).toBeTruthy();
+  });
+});
diff --git a/src/app/routes/passport/lock/lock.component.ts b/src/app/routes/passport/lock/lock.component.ts
new file mode 100644
index 0000000..1da2f35
--- /dev/null
+++ b/src/app/routes/passport/lock/lock.component.ts
@@ -0,0 +1,35 @@
+import { Router } from '@angular/router';
+import { Component } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { SettingsService } from '@delon/theme';
+
+@Component({
+  selector: 'passport-lock',
+  templateUrl: './lock.component.html',
+})
+export class UserLockComponent {
+  f: FormGroup;
+
+  constructor(
+    public settings: SettingsService,
+    fb: FormBuilder,
+    private router: Router,
+  ) {
+    this.f = fb.group({
+      password: [null, Validators.required],
+    });
+  }
+
+  submit() {
+    // tslint:disable-next-line:forin
+    for (const i in this.f.controls) {
+      this.f.controls[i].markAsDirty();
+      this.f.controls[i].updateValueAndValidity();
+    }
+    if (this.f.valid) {
+      console.log('Valid!');
+      console.log(this.f.value);
+      this.router.navigate(['dashboard']);
+    }
+  }
+}
diff --git a/src/app/routes/passport/login/login.component.html b/src/app/routes/passport/login/login.component.html
new file mode 100644
index 0000000..a2d3319
--- /dev/null
+++ b/src/app/routes/passport/login/login.component.html
@@ -0,0 +1,70 @@
+<form nz-form [formGroup]="form" (ngSubmit)="submit()" role="form">
+  <nz-tabset [nzAnimated]="false" class="tabs" (nzSelectChange)="switch($event)">
+    <nz-tab nzTitle="������������������">
+      <nz-alert *ngIf="error" [nzType]="'error'" [nzMessage]="error" [nzShowIcon]="true" class="mb-lg"></nz-alert>
+      <nz-form-item>
+        <nz-form-control>
+          <nz-input-group nzSize="large" nzPrefixIcon="anticon anticon-user">
+            <input nz-input formControlName="userName" placeholder="admin">
+          </nz-input-group>
+          <nz-form-explain *ngIf="userName.dirty && userName.errors">������������������������������������������</nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+      <nz-form-item>
+        <nz-form-control>
+          <nz-input-group nzSize="large" nzPrefixIcon="anticon anticon-lock">
+            <input nz-input type="password" formControlName="password" placeholder="888888">
+          </nz-input-group>
+          <nz-form-explain *ngIf="password.dirty && password.errors">
+            ������������������
+          </nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+    </nz-tab>
+    <nz-tab nzTitle="���������������">
+      <nz-form-item>
+        <nz-form-control>
+          <nz-input-group nzSize="large" nzPrefixIcon="anticon anticon-user">
+            <input nz-input formControlName="mobile" placeholder="���������">
+          </nz-input-group>
+          <nz-form-explain *ngIf="mobile.dirty && mobile.errors">������������������������������������������</nz-form-explain>
+        </nz-form-control>
+      </nz-form-item>
+      <nz-form-item>
+        <nz-form-control>
+          <nz-row [nzGutter]="8">
+            <nz-col [nzSpan]="16">
+              <nz-input-group nzSize="large" nzPrefixIcon="anticon anticon-mail">
+                <input nz-input formControlName="captcha" placeholder="���������">
+              </nz-input-group>
+              <nz-form-explain *ngIf="mobile.dirty && mobile.errors">
+                ���������������������
+              </nz-form-explain>
+            </nz-col>
+            <nz-col [nzSpan]="8">
+              <button nz-button nzSize="large" (click)="getCaptcha()" [disabled]="count" class="ant-btn__block">{{ count ? count + 's' : '���������������' }}</button>
+            </nz-col>
+          </nz-row>
+        </nz-form-control>
+      </nz-form-item>
+    </nz-tab>
+  </nz-tabset>
+  <nz-form-item>
+    <nz-col [nzSpan]="12">
+      <label nz-checkbox formControlName="remember">������������</label>
+    </nz-col>
+    <nz-col [nzSpan]="12" class="text-right">
+      <a class="forgot" (click)="msg.error('���������������')">���������������</a>
+    </nz-col>
+  </nz-form-item>
+  <nz-form-item>
+    <button nz-button type="submit" nzType="primary" nzSize="large" [nzLoading]="loading" class="ant-btn__block">������</button>
+  </nz-form-item>
+</form>
+<div class="other">
+  ������������������
+  <i title="in fact Auth0 via window" (click)="open('auth0', 'window')" class="anticon anticon-alipay-circle icon"></i>
+  <i title="in fact Github via redirect" (click)="open('taobao')" class="anticon anticon-taobao-circle icon"></i>
+  <i title="���������������" (click)="open('weibo', 'window')" class="anticon anticon-weibo-circle icon"></i>
+  <a class="register" routerLink="/passport/register">������������</a>
+</div>
diff --git a/src/app/routes/passport/login/login.component.less b/src/app/routes/passport/login/login.component.less
new file mode 100644
index 0000000..3d9450c
--- /dev/null
+++ b/src/app/routes/passport/login/login.component.less
@@ -0,0 +1,42 @@
+@import 'node_modules/@delon/theme/styles/default';
+:host {
+  display: block;
+  width: 368px;
+  margin: 0 auto;
+  ::ng-deep {
+    .ant-tabs .ant-tabs-bar {
+      border-bottom: 0;
+      margin-bottom: 24px;
+      text-align: center;
+    }
+    .ant-tabs-tab {
+      font-size: 16px;
+      line-height: 24px;
+    }
+    .ant-input-affix-wrapper .ant-input:not(:first-child) {
+      padding-left: 34px;
+    }
+    .icon {
+      font-size: 24px;
+      color: rgba(0, 0, 0, 0.2);
+      margin-left: 16px;
+      vertical-align: middle;
+      cursor: pointer;
+      transition: color 0.3s;
+      &:hover {
+        color: @primary-color;
+      }
+    }
+    .other {
+      text-align: left;
+      margin-top: 24px;
+      line-height: 22px;
+      nz-tooltip {
+        vertical-align: middle;
+      }
+      .register {
+        float: right;
+      }
+    }
+  }
+}
diff --git a/src/app/routes/passport/login/login.component.ts b/src/app/routes/passport/login/login.component.ts
new file mode 100644
index 0000000..f856d42
--- /dev/null
+++ b/src/app/routes/passport/login/login.component.ts
@@ -0,0 +1,181 @@
+import { SettingsService } from '@delon/theme';
+import { Component, OnDestroy, Inject, Optional } from '@angular/core';
+import { Router } from '@angular/router';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { NzMessageService, NzModalService } from 'ng-zorro-antd';
+import {
+  SocialService,
+  SocialOpenType,
+  TokenService,
+  DA_SERVICE_TOKEN,
+} from '@delon/auth';
+import { ReuseTabService } from '@delon/abc';
+import { environment } from '@env/environment';
+import { StartupService } from '@core/startup/startup.service';
+
+@Component({
+  selector: 'passport-login',
+  templateUrl: './login.component.html',
+  styleUrls: ['./login.component.less'],
+  providers: [SocialService],
+})
+export class UserLoginComponent implements OnDestroy {
+  form: FormGroup;
+  error = '';
+  type = 0;
+  loading = false;
+
+  constructor(
+    fb: FormBuilder,
+    private router: Router,
+    public msg: NzMessageService,
+    private modalSrv: NzModalService,
+    private settingsService: SettingsService,
+    private socialService: SocialService,
+    @Optional()
+    @Inject(ReuseTabService)
+    private reuseTabService: ReuseTabService,
+    @Inject(DA_SERVICE_TOKEN) private tokenService: TokenService,
+    private startupSrv: StartupService,
+  ) {
+    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],
+    });
+    modalSrv.closeAll();
+  }
+
+  // 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.userName.updateValueAndValidity();
+      this.password.markAsDirty();
+      this.password.updateValueAndValidity();
+      if (this.userName.invalid || this.password.invalid) return;
+    } else {
+      this.mobile.markAsDirty();
+      this.mobile.updateValueAndValidity();
+      this.captcha.markAsDirty();
+      this.captcha.updateValueAndValidity();
+      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.reuseTabService.clear();
+      // ������Token������
+      this.tokenService.set({
+        token: '123456789',
+        name: this.userName.value,
+        email: `cipchk@qq.com`,
+        id: 10000,
+        time: +new Date(),
+      });
+      // ������������ StartupService ��������������������� User ���������������������
+      // this.startupSrv.load().then(() => this.router.navigate(['/']));
+      // ������������������
+      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/passport/register-result/register-result.component.html b/src/app/routes/passport/register-result/register-result.component.html
new file mode 100644
index 0000000..4e6eade
--- /dev/null
+++ b/src/app/routes/passport/register-result/register-result.component.html
@@ -0,0 +1,7 @@
+<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 nzSize="large" [nzType]="'primary'">������������</button>
+  <button routerLink="/" nz-button nzSize="large">������������</button>
+</result>
diff --git a/src/app/routes/passport/register-result/register-result.component.ts b/src/app/routes/passport/register-result/register-result.component.ts
new file mode 100644
index 0000000..3228896
--- /dev/null
+++ b/src/app/routes/passport/register-result/register-result.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'passport-register-result',
+  templateUrl: './register-result.component.html'
+})
+export class UserRegisterResultComponent {
+  constructor(public msg: NzMessageService) {}
+}
diff --git a/src/app/routes/passport/register/register.component.html b/src/app/routes/passport/register/register.component.html
new file mode 100644
index 0000000..5d31b5c
--- /dev/null
+++ b/src/app/routes/passport/register/register.component.html
@@ -0,0 +1,85 @@
+<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>
+  <nz-form-item>
+    <nz-form-control>
+      <nz-input-group nzSize="large" nzAddonBeforeIcon="anticon anticon-user">
+        <input nz-input formControlName="mail" placeholder="������">
+      </nz-input-group>
+      <ng-container *ngIf="mail.dirty && mail.errors">
+        <nz-form-explain *ngIf="mail.errors?.required">������������������������</nz-form-explain>
+        <nz-form-explain *ngIf="mail.errors?.email">���������������������������</nz-form-explain>
+      </ng-container>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <nz-popover [nzPlacement]="'right'" [nzTrigger]="'focus'" [(nzVisible)]="visible" nzOverlayClassName="register-password-cdk"
+        [nzOverlayStyle]="{'width.px': 240}">
+        <nz-input-group nzSize="large" nz-popover nzAddonBeforeIcon="anticon anticon-lock">
+          <input nz-input type="password" formControlName="password" placeholder="������6���������������������������">
+        </nz-input-group>
+        <nz-form-explain *ngIf="password.dirty && password.errors">������������������</nz-form-explain>
+        <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 [nzPercent]="progress" [nzStatus]="passwordProgressMap[status]" [nzStrokeWidth]="6" [nzShowInfo]="false"></nz-progress>
+            </div>
+            <p class="mt-sm">��������������� 6 ������������������������������������������������������</p>
+          </div>
+        </ng-template>
+      </nz-popover>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <nz-input-group nzSize="large" nzAddonBeforeIcon="anticon anticon-lock">
+        <input nz-input type="password" formControlName="confirm" placeholder="������������">
+      </nz-input-group>
+      <ng-container *ngIf="confirm.dirty && confirm.errors">
+        <nz-form-explain *ngIf="confirm.errors?.required">������������������</nz-form-explain>
+        <nz-form-explain *ngIf="confirm.errors?.equar">���������������������������������</nz-form-explain>
+      </ng-container>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <nz-input-group nzSize="large" [nzAddOnBefore]="addOnBeforeTemplate">
+        <ng-template #addOnBeforeTemplate>
+          <nz-select formControlName="mobilePrefix" style="width: 100px;">
+            <nz-option [nzLabel]="'+86'" [nzValue]="'+86'"></nz-option>
+            <nz-option [nzLabel]="'+87'" [nzValue]="'+87'"></nz-option>
+          </nz-select>
+        </ng-template>
+        <input formControlName="mobile" nz-input>
+      </nz-input-group>
+      <nz-form-explain *ngIf="mobile.dirty && mobile.errors">���������������������</nz-form-explain>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control>
+      <nz-row [nzGutter]="8">
+        <nz-col [nzSpan]="16">
+          <nz-input-group nzSize="large" nzAddonBeforeIcon="anticon anticon-mail">
+            <input nz-input formControlName="captcha" placeholder="���������">
+          </nz-input-group>
+          <nz-form-explain *ngIf="captcha.dirty && captcha.errors">���������������������</nz-form-explain>
+        </nz-col>
+        <nz-col [nzSpan]="8">
+          <button nz-button nzSize="large" (click)="getCaptcha()" [disabled]="count" class="ant-btn__block">{{ count ? count + 's' : '���������������' }}</button>
+        </nz-col>
+      </nz-row>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <button nz-button nzType="primary" nzSize="large" type="submit" [nzLoading]="loading" class="submit">
+      <span>������</span>
+    </button>
+    <a class="login" routerLink="/passport/login">������������������������</a>
+  </nz-form-item>
+</form>
diff --git a/src/app/routes/passport/register/register.component.less b/src/app/routes/passport/register/register.component.less
new file mode 100644
index 0000000..507b597
--- /dev/null
+++ b/src/app/routes/passport/register/register.component.less
@@ -0,0 +1,42 @@
+@import 'node_modules/@delon/theme/styles/default';
+:host {
+  display: block;
+  width: 368px;
+  margin: 0 auto;
+  ::ng-deep {
+    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 0.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/passport/register/register.component.ts b/src/app/routes/passport/register/register.component.ts
new file mode 100644
index 0000000..3745053
--- /dev/null
+++ b/src/app/routes/passport/register/register.component.ts
@@ -0,0 +1,133 @@
+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: 'passport-register',
+  templateUrl: './register.component.html',
+  styleUrls: ['./register.component.less'],
+})
+export class UserRegisterComponent 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),
+          UserRegisterComponent.checkPassword.bind(this),
+        ],
+      ],
+      confirm: [
+        null,
+        [
+          Validators.required,
+          Validators.minLength(6),
+          UserRegisterComponent.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();
+      this.form.controls[i].updateValueAndValidity();
+    }
+    if (this.form.invalid) return;
+    // mock http
+    this.loading = true;
+    setTimeout(() => {
+      this.loading = false;
+      this.router.navigate(['/passport/register-result']);
+    }, 1000);
+  }
+
+  ngOnDestroy(): void {
+    if (this.interval$) clearInterval(this.interval$);
+  }
+}
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..37b5748
--- /dev/null
+++ b/src/app/routes/pro/form/advanced-form/advanced-form.component.html
@@ -0,0 +1,218 @@
+<page-header [title]="'������������'">
+  ������������������������������������������������������������������������������������������������������������������������������������������
+</page-header>
+<form nz-form [formGroup]="form" (ngSubmit)="_submitForm()" [nzLayout]="'vertical'">
+  <nz-card [nzBordered]="false" nzTitle="������������">
+    <nz-row nzGutter="16">
+      <nz-col nzLg="6" nzMd="12" nzSm="24">
+        <nz-form-item>
+          <nz-form-label nzFor="name">���������</nz-form-label>
+          <nz-form-control>
+            <input nz-input formControlName="name" id="name" placeholder="���������������������">
+            <nz-form-explain *ngIf="(name.dirty || name.touched) && name.errors?.required">
+              ���������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:6, offset:2}" [nzLg]="{span:8}" [nzMd]="{span:12}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <nz-input-group nzAddOnBefore="http://" nzAddOnAfter=".com">
+              <input nz-input formControlName="url" placeholder="���������">
+            </nz-input-group>
+            <nz-form-explain *ngIf="(url.dirty || url.touched) && url.errors?.required">
+              ���������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:8, offset:2}" [nzLg]="{span:10}" [nzMd]="{span:24}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>���������������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="owner" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value"></nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(owner.dirty || owner.touched) && owner.errors?.required">
+              ������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+    </nz-row>
+    <nz-row nzGutter="16">
+      <nz-col nzLg="6" nzMd="12" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>���������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="approver" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+              </nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(approver.dirty || approver.touched) && approver.errors?.required">
+              ������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:6, offset:2}" [nzLg]="{span:8}" [nzMd]="{span:12}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <nz-range-picker formControlName="date_range" [nzStyle]="{width: '100%'}"></nz-range-picker>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:8, offset:2}" [nzLg]="{span:10}" [nzMd]="{span:24}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="type" [nzShowSearch]="true" [nzPlaceHolder]="'���������������������'">
+              <nz-option [nzLabel]="'������'" [nzValue]="'private'"></nz-option>
+              <nz-option [nzLabel]="'������'" [nzValue]="'public'"></nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(type.dirty || type.touched) && type.errors?.required">
+              ���������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+    </nz-row>
+  </nz-card>
+  <nz-card [nzBordered]="false" nzTitle="������������">
+    <nz-row nzGutter="16">
+      <nz-col nzLg="6" nzMd="12" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>���������</nz-form-label>
+          <nz-form-control>
+            <input nz-input formControlName="name2" placeholder="������������������">
+            <nz-form-explain *ngIf="(name2.dirty || name2.touched) && name2.errors?.required">
+              ������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:6, offset:2}" [nzLg]="{span:8}" [nzMd]="{span:12}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <textarea nz-input formControlName="summary" [nzAutosize]="true" placeholder="���������������������"></textarea>
+            <nz-form-explain *ngIf="(summary.dirty || summary.touched) && summary.errors?.required">
+              ���������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:8, offset:2}" [nzLg]="{span:10}" [nzMd]="{span:24}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>���������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="owner2" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value">
+              </nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(owner2.dirty || owner2.touched) && owner2.errors?.required">
+              ������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+    </nz-row>
+    <nz-row nzGutter="16">
+      <nz-col nzLg="6" nzMd="12" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>���������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="approver2" [nzPlaceHolder]="'������������������'" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of users" [nzLabel]="i.label" [nzValue]="i.value"></nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(approver2.dirty || approver2.touched) && approver2.errors?.required">
+              ������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:6, offset:2}" [nzLg]="{span:8}" [nzMd]="{span:12}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <nz-time-picker formControlName="time"></nz-time-picker>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzXl]="{span:8, offset:2}" [nzLg]="{span:10}" [nzMd]="{span:24}" nzSm="24">
+        <nz-form-item>
+          <nz-form-label>������������</nz-form-label>
+          <nz-form-control>
+            <nz-select formControlName="type2" [nzShowSearch]="true" [nzPlaceHolder]="'���������������������'">
+              <nz-option [nzLabel]="'������'" [nzValue]="'private'"></nz-option>
+              <nz-option [nzLabel]="'������'" [nzValue]="'public'"></nz-option>
+            </nz-select>
+            <nz-form-explain *ngIf="(type2.dirty || type2.touched) && type2.errors?.required">
+              ���������������������
+            </nz-form-explain>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+    </nz-row>
+  </nz-card>
+  <nz-card [nzBordered]="false" nzTitle="������������">
+    <nz-table formArrayName="items" [nzData]="items.value" [nzShowPagination]="false">
+      <thead>
+        <tr>
+          <th>������������</th>
+          <th>������</th>
+          <th>������������</th>
+          <th>������</th>
+        </tr>
+      </thead>
+      <tbody>
+        <tr *ngFor="let item of items.controls; let i = index" [formGroupName]="i">
+          <td>
+            <span *ngIf="editIndex!==i">{{items.value[i].name}}</span>
+            <span *ngIf="editIndex===i" nz-form-control>
+              <input nz-input formControlName="name" placeholder="���������������������">
+            </span>
+          </td>
+          <td>
+            <span *ngIf="editIndex!==i">{{items.value[i].workId}}</span>
+            <span *ngIf="editIndex===i" nz-form-control>
+              <input nz-input formControlName="workId" placeholder="���������������">
+            </span>
+          </td>
+          <td>
+            <span *ngIf="editIndex!==i">{{items.value[i].department}}</span>
+            <span *ngIf="editIndex===i" nz-form-control>
+              <input nz-input formControlName="department" placeholder="���������������������">
+            </span>
+          </td>
+          <td>
+            <span *ngIf="editIndex!==i">
+              <a (click)="edit(i)">������</a>
+              <nz-divider nzType="vertical"></nz-divider>
+              <nz-popconfirm (nzOnConfirm)="del(i)" [nzTitle]="'������������������������'">
+                <a nz-popconfirm>������</a>
+              </nz-popconfirm>
+            </span>
+            <span *ngIf="editIndex===i">
+              <a (click)="save(i)">������</a>
+              <nz-divider nzType="vertical"></nz-divider>
+              <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'" (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 type="primary" nzType="primary">������</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..f8a6004
--- /dev/null
+++ b/src/app/routes/pro/form/advanced-form/advanced-form.component.ts
@@ -0,0 +1,156 @@
+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]],
+      date_range: [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() {
+    for (const i in this.form.controls) {
+      this.form.controls[i].markAsDirty();
+      this.form.controls[i].updateValueAndValidity();
+    }
+    if (this.form.invalid) return;
+  }
+}
diff --git a/src/app/routes/pro/form/basic-form/basic-form.component.html b/src/app/routes/pro/form/basic-form/basic-form.component.html
new file mode 100644
index 0000000..948a647
--- /dev/null
+++ b/src/app/routes/pro/form/basic-form/basic-form.component.html
@@ -0,0 +1,78 @@
+<page-header [title]="'������������'">
+  ������������������������������������������������������������������������������������������
+</page-header>
+<nz-card [nzBordered]="false">
+  <form nz-form [formGroup]="form" (ngSubmit)="submit()">
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzRequired nzFor="title">������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <input nz-input formControlName="title" id="title" placeholder="���������������������">
+        <nz-form-explain *ngIf="form.get('title').dirty && form.get('title').errors">���������������</nz-form-explain>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzRequired nzFor="date">������������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <nz-range-picker formControlName="date" [nzStyle]="{width: '100%'}"></nz-range-picker>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzRequired nzFor="goal">������������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <textarea nz-input formControlName="goal" id="goal" [nzAutosize]="{minRows: 4}" placeholder="������������������������������������"></textarea>
+        <nz-form-explain *ngIf="form.get('goal').dirty && form.get('goal').errors">���������������������</nz-form-explain>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzRequired nzFor="standard">������������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <textarea nz-input formControlName="standard" id="standard" [nzAutosize]="{minRows: 4}" placeholder="���������������������"></textarea>
+        <nz-form-explain *ngIf="form.get('standard').dirty && form.get('standard').errors">���������������������</nz-form-explain>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzFor="client">
+        ������
+        <em>
+          <nz-tooltip nzTitle="���������������������">
+            <i nz-tooltip class="anticon anticon-info-circle-o"></i>
+          </nz-tooltip>
+        </em>
+      </nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <input nz-input formControlName="client" id="client" placeholder="������������������������������������������������ @���������������">
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzFor="invites">���������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <input nz-input formControlName="invites" id="invites" placeholder="��������� @��������������������������������� 5 ���">
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzFor="weight">������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <nz-input-number formControlName="weight" id="weight" placeholder="���������"></nz-input-number>
+        <em>%</em>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-label nzXs="24" nzSm="7" nzFor="public">������������</nz-form-label>
+      <nz-form-control nzXs="24" nzSm="12" nzMd="10">
+        <nz-radio-group formControlName="public">
+          <label nz-radio [nzValue]="1">������</label>
+          <label nz-radio [nzValue]="2">������������</label>
+          <label nz-radio [nzValue]="3">���������</label>
+        </nz-radio-group>
+        <input *ngIf="form.value.public === 2" nz-input formControlName="publicUsers" placeholder="���������">
+        <nz-form-explain>���������������������������������</nz-form-explain>
+      </nz-form-control>
+    </nz-form-item>
+    <nz-form-item>
+      <nz-form-control [nzXs]="{ span: 24, offset: 0 }" [nzSm]="{ span: 10, offset: 7 }">
+        <button nz-button nzType="primary" type="submit" [nzLoading]="submitting">������</button>
+        <button nz-button class="ml-sm">������</button>
+      </nz-form-control>
+    </nz-form-item>
+  </form>
+</nz-card>
diff --git a/src/app/routes/pro/form/basic-form/basic-form.component.ts b/src/app/routes/pro/form/basic-form/basic-form.component.ts
new file mode 100644
index 0000000..53f5ea2
--- /dev/null
+++ b/src/app/routes/pro/form/basic-form/basic-form.component.ts
@@ -0,0 +1,41 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'app-basic-form',
+  templateUrl: './basic-form.component.html',
+})
+export class BasicFormComponent implements OnInit {
+  form: FormGroup;
+  submitting = false;
+
+  constructor(private fb: FormBuilder, private msg: NzMessageService) {}
+
+  ngOnInit(): void {
+    this.form = this.fb.group({
+      title: [null, [Validators.required]],
+      date: [null, [Validators.required]],
+      goal: [null, [Validators.required]],
+      standard: [null, [Validators.required]],
+      client: [null, []],
+      invites: [null, []],
+      weight: [null, []],
+      public: [1, [Validators.min(1), Validators.max(3)]],
+      publicUsers: [null, []],
+    });
+  }
+
+  submit() {
+    for (const i in this.form.controls) {
+      this.form.controls[i].markAsDirty();
+      this.form.controls[i].updateValueAndValidity();
+    }
+    if (this.form.invalid) return;
+    this.submitting = true;
+    setTimeout(() => {
+      this.submitting = false;
+      this.msg.success(`������������`);
+    }, 1000);
+  }
+}
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..af177e2
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.html
@@ -0,0 +1,13 @@
+<page-header [title]="'������������'">
+  ������������������������������������������������������������������������������������������
+</page-header>
+<nz-card [nzBordered]="false">
+  <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>
+</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..858481b
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.less
@@ -0,0 +1,26 @@
+: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..b5a72f5
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step-form.component.ts
@@ -0,0 +1,16 @@
+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.html b/src/app/routes/pro/form/step-form/step1.component.html
new file mode 100644
index 0000000..578d10b
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step1.component.html
@@ -0,0 +1,59 @@
+<form nz-form [formGroup]="form" (ngSubmit)="_submitForm()">
+  <nz-form-item>
+    <nz-form-label nzSpan="5" nzRequired>������������</nz-form-label>
+    <nz-form-control [nzSpan]="19">
+      <nz-select formControlName="pay_account">
+        <nz-option [nzLabel]="item.pay_account" [nzValue]="item.pay_account"></nz-option>
+      </nz-select>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5" nzRequired nzFor="receiver_account">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-input-group nzCompact>
+        <nz-select formControlName="receiver_type" style="width: 100px;">
+          <nz-option [nzLabel]="'���������'" [nzValue]="'alipay'"></nz-option>
+          <nz-option [nzLabel]="'������������'" [nzValue]="'bank'"></nz-option>
+        </nz-select>
+        <input formControlName="receiver_account" id="receiver_account" nz-input style="width: calc(100% - 100px);">
+      </nz-input-group>
+      <nz-form-explain *ngIf="(receiver_account.dirty || receiver_account.touched) && receiver_account.errors?.required">
+        ���������������������
+      </nz-form-explain>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5" nzRequired nzFor="receiver_name">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <input nz-input formControlName="receiver_name" id="receiver_name">
+      <ng-container *ngIf="receiver_name.dirty || receiver_name.touched">
+        <nz-form-explain *ngIf="receiver_name.errors?.required">���������������������</nz-form-explain>
+        <nz-form-explain *ngIf="receiver_name.errors?.minlength">������2���������������</nz-form-explain>
+      </ng-container>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5" nzRequired nzFor="amount">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <input nz-input formControlName="amount" id="amount" nzAddonAfter="���">
+      <ng-container *ngIf="amount.dirty || amount.touched">
+        <nz-form-explain *ngIf="amount.errors?.required">���������������������</nz-form-explain>
+        <nz-form-explain *ngIf="amount.errors?.pattern">������������������������</nz-form-explain>
+        <nz-form-explain *ngIf="amount.errors?.min">������������1���������</nz-form-explain>
+        <nz-form-explain *ngIf="amount.errors?.max">������������100���������</nz-form-explain>
+      </ng-container>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control nzSpan="19" nzOffset="5">
+      <button nz-button nzType="primary" [disabled]="form.invalid">���������</button>
+    </nz-form-control>
+  </nz-form-item>
+</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>
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..44a71f2
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step1.component.ts
@@ -0,0 +1,61 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { TransferService } from './transfer.service';
+
+@Component({
+  selector: 'app-step1',
+  templateUrl: './step1.component.html',
+})
+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.html b/src/app/routes/pro/form/step-form/step2.component.html
new file mode 100644
index 0000000..0cc972a
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step2.component.html
@@ -0,0 +1,51 @@
+<form nz-form [formGroup]="form" (ngSubmit)="_submitForm()">
+  <nz-alert class="pb-lg" [nzMessage]="'���������������������������������������������������������������������'" [nzShowIcon]="true" [nzCloseable]="true"></nz-alert>
+  <nz-form-item>
+    <nz-form-label nzSpan="5">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-form-text>{{item.pay_account}}</nz-form-text>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-form-text>{{item.receiver_type==='alipay' ? '���������' : '������'}}</nz-form-text>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-form-text>{{item.receiver_account}}</nz-form-text>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5">���������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-form-text>{{item.receiver_name}}</nz-form-text>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-label nzSpan="5">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <nz-form-text>
+        <strong class="text-lg">{{item.amount}}</strong>
+      </nz-form-text>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item class="border-top-1 mt-lg pt-lg">
+    <nz-form-label nzSpan="5" nzRequired nzFor="password">������������</nz-form-label>
+    <nz-form-control nzSpan="19">
+      <input nz-input formControlName="password" type="password" id="password">
+      <ng-container *ngIf="password.dirty || password.touched">
+        <nz-form-explain *ngIf="password.errors?.required">���������������</nz-form-explain>
+        <nz-form-explain *ngIf="password.errors?.minlength">������6������������</nz-form-explain>
+      </ng-container>
+    </nz-form-control>
+  </nz-form-item>
+  <nz-form-item>
+    <nz-form-control [nzSpan]="19" [nzOffset]="5">
+      <button nz-button [nzType]="'primary'" [nzLoading]="loading" [disabled]="form.invalid">������</button>
+      <button nz-button (click)="prev()">���������</button>
+    </nz-form-control>
+  </nz-form-item>
+</form>
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..9f63984
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step2.component.ts
@@ -0,0 +1,42 @@
+import { Component, OnInit } from '@angular/core';
+import { FormGroup, FormBuilder, Validators } from '@angular/forms';
+import { TransferService } from './transfer.service';
+
+@Component({
+  selector: 'app-step2',
+  templateUrl: './step2.component.html',
+})
+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.html b/src/app/routes/pro/form/step-form/step3.component.html
new file mode 100644
index 0000000..a511950
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step3.component.html
@@ -0,0 +1,34 @@
+<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()" [nzType]="'primary'">������������</button>
+    <button nz-button class="ml-sm">������������</button>
+  </div>
+</div>
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..27fc7df
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/step3.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { TransferService } from './transfer.service';
+
+@Component({
+  selector: 'app-step3',
+  templateUrl: './step3.component.html',
+})
+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..02f2c0e
--- /dev/null
+++ b/src/app/routes/pro/form/step-form/transfer.service.ts
@@ -0,0 +1,53 @@
+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/applications/applications.component.html b/src/app/routes/pro/list/applications/applications.component.html
new file mode 100644
index 0000000..b48f1fd
--- /dev/null
+++ b/src/app/routes/pro/list/applications/applications.component.html
@@ -0,0 +1,92 @@
+<nz-card [nzBordered]="false">
+  <form nz-form [nzLayout]="'inline'">
+    <standard-form-row [title]="'������������'" block style="padding-bottom: 11px;">
+      <nz-form-item>
+        <nz-form-control>
+          <tag-select>
+            <nz-tag *ngFor="let i of categories; let idx = index" nzMode="checkable" [nzChecked]="i.value" (nzCheckedChange)="changeCategory($event, idx)">
+              {{i.text}}
+            </nz-tag>
+          </tag-select>
+        </nz-form-control>
+      </nz-form-item>
+    </standard-form-row>
+    <standard-form-row [title]="'������������'" grid last>
+      <nz-row [nzGutter]="16">
+        <nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">������</nz-form-label>
+            <nz-form-control nzXs="24" nzSm="24" nzMd="12">
+              <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" 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>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+        <nz-col nzXs="24" nzSm="24" nzMd="12" nzLg="10" nzXl="8">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">���������</nz-form-label>
+            <nz-form-control nzXs="24" nzSm="24" nzMd="12">
+              <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" style="width: 200px;">
+                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+                <nz-option [nzLabel]="'������'" [nzValue]="'normal'"></nz-option>
+              </nz-select>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+      </nz-row>
+    </standard-form-row>
+  </form>
+</nz-card>
+<nz-list [nzLoading]="loading" [nzDataSource]="list" [nzRenderItem]="item" [nzGrid]="{ gutter: 24, xl: 6, lg: 8, md: 8, sm: 12, xs: 24 }">
+  <ng-template #item let-item>
+    <nz-list-item>
+      <nz-card nzHoverable [nzActions]="[op1,op2,op3,op4]">
+        <ng-template #op1>
+          <nz-tooltip [nzTitle]="'������'">
+            <i nz-tooltip class="anticon anticon-download"></i>
+          </nz-tooltip>
+        </ng-template>
+        <ng-template #op2>
+          <nz-tooltip [nzTitle]="'������'">
+            <i nz-tooltip class="anticon anticon-edit"></i>
+          </nz-tooltip>
+        </ng-template>
+        <ng-template #op3>
+          <nz-tooltip [nzTitle]="'������'">
+            <i nz-tooltip class="anticon anticon-share-alt"></i>
+          </nz-tooltip>
+        </ng-template>
+        <ng-template #op4>
+          <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>
+        </ng-template>
+        <nz-card-meta [nzTitle]="item.title" [nzAvatar]="nzAvatar">
+          <ng-template #nzAvatar>
+            <nz-avatar nzSize="small" [nzSrc]="item.avatar"></nz-avatar>
+          </ng-template>
+        </nz-card-meta>
+        <div class="card-info d-flex">
+          <div>
+            <p>������������</p>
+            <p>{{item.activeUser}}
+              <em class="wan">���</em>
+            </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/applications/applications.component.less b/src/app/routes/pro/list/applications/applications.component.less
new file mode 100644
index 0000000..4d4df68
--- /dev/null
+++ b/src/app/routes/pro/list/applications/applications.component.less
@@ -0,0 +1,51 @@
+@import 'node_modules/@delon/theme/styles/default';
+:host {
+  margin-bottom: -24px;
+  ::ng-deep {
+    .ant-card {
+      width: 100%;
+    }
+    .ant-card-meta-content {
+      margin-top: 0;
+    } // disabled white space
+    .ant-card-meta-avatar {
+      font-size: 0;
+    }
+    .ant-card-actions {
+      background: #f7f9fa;
+    }
+    .ant-list .ant-list-item-content-single {
+      max-width: 100%;
+    }
+    .card-info {
+      .clearfix();
+      margin-top: 16px;
+      margin-left: 40px;
+      & > div {
+        position: relative;
+        text-align: left;
+        float: left;
+        width: 50%;
+        p {
+          line-height: 32px;
+          font-size: 24px;
+          margin: 0;
+        }
+        p:first-child {
+          color: @text-color-secondary;
+          font-size: 12px;
+          line-height: 20px;
+          margin-bottom: 4px;
+        }
+      }
+    }
+    .wan {
+      position: relative;
+      top: -2px;
+      font-size: @font-size-base;
+      font-style: normal;
+      line-height: 20px;
+      margin-left: 2px;
+    }
+  }
+}
diff --git a/src/app/routes/pro/list/applications/applications.component.ts b/src/app/routes/pro/list/applications/applications.component.ts
new file mode 100644
index 0000000..404eeab
--- /dev/null
+++ b/src/app/routes/pro/list/applications/applications.component.ts
@@ -0,0 +1,76 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'pro-list-applications',
+  templateUrl: './applications.component.html',
+  styleUrls: ['./applications.component.less'],
+})
+export class ProListApplicationsComponent 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(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData() {
+    this.loading = true;
+    this.http.get('/api/list', { count: this.q.ps }).subscribe((res: any) => {
+      this.list = res.map(item => {
+        item.activeUser = this.formatWan(item.activeUser);
+        return item;
+      });
+      this.loading = false;
+    });
+  }
+
+  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}`;
+    }
+    return result;
+  }
+}
diff --git a/src/app/routes/pro/list/articles/articles.component.html b/src/app/routes/pro/list/articles/articles.component.html
new file mode 100644
index 0000000..216f744
--- /dev/null
+++ b/src/app/routes/pro/list/articles/articles.component.html
@@ -0,0 +1,91 @@
+<nz-card [nzBordered]="false">
+  <form nz-form [nzLayout]="'inline'">
+    <standard-form-row [title]="'������������'" block style="padding-bottom: 11px;">
+      <nz-form-item>
+        <nz-form-control>
+          <tag-select>
+            <nz-tag *ngFor="let i of categories; let idx = index" nzMode="checkable" [nzChecked]="i.value" (nzCheckedChange)="changeCategory($event, idx)">
+              {{i.text}}
+            </nz-tag>
+          </tag-select>
+        </nz-form-control>
+      </nz-form-item>
+    </standard-form-row>
+    <standard-form-row [title]="'owner'" grid>
+      <nz-form-item>
+        <nz-form-control>
+          <nz-select [(ngModel)]="q.owners" name="owners" [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>
+        </nz-form-control>
+      </nz-form-item>
+    </standard-form-row>
+    <standard-form-row [title]="'������������'" grid last>
+      <nz-row [nzGutter]="16">
+        <nz-col nzXl="8" nzLg="10" nzMd="12" nzSm="24" nzXs="24">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">������������</nz-form-label>
+            <nz-form-control>
+              <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" style="width: 200px;">
+                <nz-option [nzLabel]="'������'" [nzValue]="'lisa'"></nz-option>
+              </nz-select>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+        <nz-col nzXl="8" nzLg="10" nzMd="12" nzSm="24" nzXs="24">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">���������</nz-form-label>
+            <nz-form-control>
+              <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" style="width: 200px;">
+                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+              </nz-select>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+      </nz-row>
+    </standard-form-row>
+  </form>
+</nz-card>
+<nz-card [nzBordered]="false">
+  <nz-list nzItemLayout="vertical" [nzLoading]="loading" [nzDataSource]="list" [nzRenderItem]="item" [nzLoadMore]="loadMore">
+    <ng-template #item let-item>
+      <nz-list-item [nzContent]="nzContent" [nzExtra]="nzExtra" [nzActions]="[op1,op2,op3]">
+        <ng-template #op1>
+          <i class="anticon anticon-star-o mr-sm"></i>{{item.star}}</ng-template>
+        <ng-template #op2>
+          <i class="anticon anticon-like-o mr-sm"></i>{{item.like}}</ng-template>
+        <ng-template #op3>
+          <i class="anticon anticon-message mr-sm"></i>{{item.message}}</ng-template>
+        <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(true)" [nzLoading]="loading" [nzType]="'dashed'" style="min-width:200px;">������������</button>
+      </div>
+    </ng-template>
+  </nz-list>
+</nz-card>
diff --git a/src/app/routes/pro/list/articles/articles.component.ts b/src/app/routes/pro/list/articles/articles.component.ts
new file mode 100644
index 0000000..213dbf2
--- /dev/null
+++ b/src/app/routes/pro/list/articles/articles.component.ts
@@ -0,0 +1,86 @@
+import { Component, ViewEncapsulation, OnInit } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'pro-list-articles',
+  templateUrl: './articles.component.html',
+})
+export class ProListArticlesComponent 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
+
+  constructor(private http: _HttpClient) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData(more = false) {
+    this.loading = true;
+    this.http.get('/api/list', { count: this.q.ps }).subscribe((res: any) => {
+      this.list = more ? this.list.concat(res) : res;
+      this.loading = false;
+    });
+  }
+}
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..77302ce
--- /dev/null
+++ b/src/app/routes/pro/list/basic-list/basic-list.component.html
@@ -0,0 +1,91 @@
+<page-header></page-header>
+<nz-card [nzBordered]="false">
+  <div nz-row>
+    <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+      <span class="text-grey-dark">������������</span>
+      <span class="d-block display-2">8���������</span>
+      <em></em>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+      <span class="text-grey-dark">������������������������������</span>
+      <span class="d-block display-2">32������</span>
+      <em></em>
+    </div>
+    <div nz-col [nzXs]="24" [nzSm]="8" class="header-info">
+      <span class="text-grey-dark">���������������������</span>
+      <span class="d-block display-2">24���������</span>
+    </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" 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-group nzSuffixIcon="anticon anticon-search" style="width: 270px;">
+        <input type="text" nz-input placeholder="���������" [(ngModel)]="q.q" name="q">
+      </nz-input-group>
+    </div>
+  </div>
+  <button nz-button (click)="msg.success('add')" [nzType]="'dashed'" class="ant-btn__block mb-sm">
+    <i class="anticon anticon-plus"></i>
+    <span>������</span>
+  </button>
+  <nz-list [nzDataSource]="data" [nzLoading]="loading" [nzRenderItem]="item" [nzPagination]="pagination">
+    <ng-template #item let-item>
+      <nz-list-item [nzContent]="nzContent" [nzActions]="[edit, op]">
+        <ng-template #edit>
+          <a (click)="msg.success('���������' + item.title)">������</a>
+        </ng-template>
+        <ng-template #op>
+          <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>
+        </ng-template>
+        <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 [nzPercent]="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" (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..4a8ff3f
--- /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..ae20a91
--- /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 { _HttpClient } from '@delon/theme';
+
+@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(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData() {
+    this.loading = true;
+    this.http.get('/api/list', { count: 5 }).subscribe((res: any) => {
+      this.data = res;
+      this.loading = false;
+    });
+  }
+}
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..b3c60d6
--- /dev/null
+++ b/src/app/routes/pro/list/card-list/card-list.component.html
@@ -0,0 +1,48 @@
+<page-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>
+  ������������������������������������������ ant.design���������������������������������������������������������������������������������������������������������������
+  <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>
+</page-header>
+<nz-list [nzLoading]="loading" [nzDataSource]="list" [nzRenderItem]="item" [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" [nzActions]="[op1, op2]">
+        <ng-template #op1>
+          <a (click)="msg.success('������������' + item.id);">���������</a>
+        </ng-template>
+        <ng-template #op2>
+          <a (click)="msg.success('������������' + item.id);">���������</a>
+        </ng-template>
+        <nz-card-meta [nzAvatar]="nzAvatar" [nzTitle]="nzTitle" [nzDescription]="nzDescription">
+          <ng-template #nzAvatar>
+            <nz-avatar nzSize="large" [nzSrc]="item.avatar"></nz-avatar>
+          </ng-template>
+          <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..69ee8ad
--- /dev/null
+++ b/src/app/routes/pro/list/card-list/card-list.component.ts
@@ -0,0 +1,31 @@
+import { Component, OnInit, ViewEncapsulation } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+
+@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(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.loading = true;
+    this.http.get('/api/list', { count: 8 }).subscribe((res: any) => {
+      this.list = this.list.concat(res);
+      this.loading = false;
+    });
+  }
+}
diff --git a/src/app/routes/pro/list/list/list.component.html b/src/app/routes/pro/list/list/list.component.html
new file mode 100644
index 0000000..b4ea4ca
--- /dev/null
+++ b/src/app/routes/pro/list/list/list.component.html
@@ -0,0 +1,16 @@
+<page-header #ph [title]="'������������'">
+  <div class="text-center">
+    <nz-input-group nzSearch nzSize="large" [nzSuffix]="suffixButton" style="width: 520px;">
+      <input type="text" nz-input placeholder="���������">
+      <ng-template #suffixButton>
+        <button nz-button nzType="primary" nzSize="large" nzSearch>Search</button>
+      </ng-template>
+    </nz-input-group>
+  </div>
+  <ng-template #tab>
+    <nz-tabset [nzSelectedIndex]="pos">
+      <nz-tab *ngFor="let i of tabs" [nzTitle]="i.tab" (click)="to(i)"></nz-tab>
+    </nz-tabset>
+  </ng-template>
+</page-header>
+<router-outlet></router-outlet>
diff --git a/src/app/routes/pro/list/list/list.component.ts b/src/app/routes/pro/list/list/list.component.ts
new file mode 100644
index 0000000..1745cd0
--- /dev/null
+++ b/src/app/routes/pro/list/list/list.component.ts
@@ -0,0 +1,43 @@
+import { Component, ViewChild, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { PageHeaderComponent } from '@delon/abc';
+
+@Component({
+  // tslint:disable-next-line:component-selector
+  selector: 'pro-list-layout',
+  templateUrl: './list.component.html',
+})
+export class ProListLayoutComponent implements OnInit {
+  tabs: any[] = [
+    {
+      key: 'articles',
+      tab: '������',
+    },
+    {
+      key: 'applications',
+      tab: '������',
+    },
+    {
+      key: 'projects',
+      tab: '������',
+    },
+  ];
+
+  @ViewChild('ph') ph: PageHeaderComponent;
+
+  pos = 0;
+
+  constructor(private router: Router) {}
+
+  ngOnInit(): void {
+    const key = this.router.url.substr(this.router.url.lastIndexOf('/') + 1);
+    const idx = this.tabs.findIndex(w => w.key === key);
+    if (idx !== -1) this.pos = idx;
+  }
+
+  to(item: any) {
+    this.router
+      .navigateByUrl(`/pro/list/${item.key}`)
+      .then(() => this.ph.refresh());
+  }
+}
diff --git a/src/app/routes/pro/list/projects/projects.component.html b/src/app/routes/pro/list/projects/projects.component.html
new file mode 100644
index 0000000..179fefd
--- /dev/null
+++ b/src/app/routes/pro/list/projects/projects.component.html
@@ -0,0 +1,61 @@
+<nz-card [nzBordered]="false">
+  <form nz-form [nzLayout]="'inline'">
+    <standard-form-row [title]="'������������'" block style="padding-bottom: 11px;">
+      <nz-form-item>
+        <nz-form-control>
+          <tag-select>
+            <nz-tag *ngFor="let i of categories; let idx = index" nzMode="checkable" [nzChecked]="i.value" (nzCheckedChange)="changeCategory($event, idx)">
+              {{i.text}}
+            </nz-tag>
+          </tag-select>
+        </nz-form-control>
+      </nz-form-item>
+    </standard-form-row>
+    <standard-form-row [title]="'������������'" grid last>
+      <nz-row [nzGutter]="16">
+        <nz-col nzXl="8" nzLg="10" nzMd="12" nzSm="24" nzXs="24">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">������������</nz-form-label>
+            <nz-form-control>
+              <nz-select [(ngModel)]="q.user" name="user" [nzPlaceHolder]="'������'" [nzShowSearch]="true" style="width: 200px;">
+                <nz-option [nzLabel]="'������'" [nzValue]="'lisa'"></nz-option>
+              </nz-select>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+        <nz-col nzXl="8" nzLg="10" nzMd="12" nzSm="24" nzXs="24">
+          <nz-form-item>
+            <nz-form-label nzFor="rate">���������</nz-form-label>
+            <nz-form-control>
+              <nz-select [(ngModel)]="q.rate" name="rate" [nzPlaceHolder]="'������'" [nzShowSearch]="true" style="width: 200px;">
+                <nz-option [nzLabel]="'������'" [nzValue]="'good'"></nz-option>
+              </nz-select>
+            </nz-form-control>
+          </nz-form-item>
+        </nz-col>
+      </nz-row>
+    </standard-form-row>
+  </form>
+</nz-card>
+<nz-list [nzLoading]="loading" [nzRenderItem]="item" [nzDataSource]="list" [nzGrid]="{gutter: 24, lg: 6, md: 8, sm: 12, xs: 24 }">
+  <ng-template #item let-item>
+    <nz-list-item>
+      <nz-card nzHoverable [nzCover]="cover">
+        <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 | _date:'fn'}}</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/projects/projects.component.less b/src/app/routes/pro/list/projects/projects.component.less
new file mode 100644
index 0000000..79249fb
--- /dev/null
+++ b/src/app/routes/pro/list/projects/projects.component.less
@@ -0,0 +1,16 @@
+:host ::ng-deep {
+  .ant-card-meta-title {
+    margin-bottom: 4px;
+  }
+  nz-list nz-card {
+    margin-bottom: 0 !important;
+  }
+  .card-item-content {
+    display: flex;
+    margin-top: 16px;
+    margin-bottom: -4px;
+    line-height: 20px;
+    height: 20px;
+    justify-content: space-between;
+  }
+}
diff --git a/src/app/routes/pro/list/projects/projects.component.ts b/src/app/routes/pro/list/projects/projects.component.ts
new file mode 100644
index 0000000..0d1a423
--- /dev/null
+++ b/src/app/routes/pro/list/projects/projects.component.ts
@@ -0,0 +1,61 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'pro-list-projects',
+  templateUrl: './projects.component.html',
+  styleUrls: ['./projects.component.less'],
+})
+export class ProListProjectsComponent 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(private http: _HttpClient, public msg: NzMessageService) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData() {
+    this.loading = true;
+    this.http.get('/api/list', { count: this.q.ps }).subscribe((res: any) => {
+      this.list = this.list.concat(res);
+      this.loading = false;
+    });
+  }
+}
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..02b9619
--- /dev/null
+++ b/src/app/routes/pro/list/table-list/table-list.component.html
@@ -0,0 +1,108 @@
+<page-header [title]="'������������'"></page-header>
+<nz-card [nzBordered]="false">
+  <form nz-form [nzLayout]="'inline'" (ngSubmit)="getData()" class="search__form">
+    <nz-row [nzGutter]="{ md: 8, lg: 24, xl: 48 }">
+      <nz-col nzMd="8" nzSm="24">
+        <nz-form-item>
+          <nz-form-label nzFor="no">������������</nz-form-label>
+          <nz-form-control>
+            <input nz-input [(ngModel)]="q.no" name="no" placeholder="���������" id="no">
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col nzMd="8" nzSm="24">
+        <nz-form-item>
+          <nz-form-label nzFor="status">������������</nz-form-label>
+          <nz-form-control>
+            <nz-select [(ngModel)]="q.status" name="status" id="status" [nzPlaceHolder]="'���������'" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+            </nz-select>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col nzMd="8" nzSm="24" *ngIf="expandForm">
+        <nz-form-item>
+          <nz-form-label nzFor="callNo">������������</nz-form-label>
+          <nz-form-control>
+            <input nz-input id="callNo">
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col nzMd="8" nzSm="24" *ngIf="expandForm">
+        <nz-form-item>
+          <nz-form-label nzFor="updatedAt">������������</nz-form-label>
+          <nz-form-control>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col nzMd="8" nzSm="24" *ngIf="expandForm">
+        <nz-form-item>
+          <nz-form-label nzFor="status2">������������</nz-form-label>
+          <nz-form-control>
+            <nz-select [nzPlaceHolder]="'���������'" nzId="status2" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+            </nz-select>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col nzMd="8" nzSm="24" *ngIf="expandForm">
+        <nz-form-item>
+          <nz-form-label nzFor="status3">������������</nz-form-label>
+          <nz-form-control>
+            <nz-select [nzPlaceHolder]="'���������'" nzId="status3" [nzShowSearch]="true">
+              <nz-option *ngFor="let i of status; let idx = index" [nzLabel]="i.text" [nzValue]="idx"></nz-option>
+            </nz-select>
+          </nz-form-control>
+        </nz-form-item>
+      </nz-col>
+      <nz-col [nzSpan]="expandForm ? 24 : 8" [class.text-right]="expandForm">
+        <button nz-button type="submit" [nzType]="'primary'" [nzLoading]="loading">������</button>
+        <button nz-button type="reset" (click)="getData()" class="mx-sm">������</button>
+        <a (click)="expandForm=!expandForm">
+          {{expandForm ? '������' : '������'}}
+          <i class="anticon" [class.anticon-down]="!expandForm" [class.anticon-up]="expandForm"></i>
+        </a>
+      </nz-col>
+    </nz-row>
+  </form>
+  <button nz-button (click)="add(modalContent)" [nzType]="'primary'">
+    <i class="anticon anticon-plus"></i>
+    <span>������</span>
+  </button>
+  <ng-container *ngIf="selectedRows.length > 0">
+    <button nz-button class="ml-sm">������������</button>
+    <nz-dropdown [nzPlacement]="'bottomLeft'">
+      <button nz-button nz-dropdown class="ml-sm">
+        ������������
+        <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 class="my-md">
+    <nz-alert [nzType]="'info'" [nzShowIcon]="true" [nzMessage]="message">
+      <ng-template #message>
+        ���������
+        <strong class="text-primary">{{selectedRows.length}}</strong> ���&nbsp;&nbsp; ������������������
+        <strong>{{totalCallNo}}</strong> ���
+        <a *ngIf="totalCallNo > 0" (click)="st.clearCheck()" class="ml-lg">������</a>
+      </ng-template>
+    </nz-alert>
+  </div>
+  <simple-table #st [columns]="columns" [data]="data" [loading]="loading" (checkboxChange)="checkboxChange($event)" (filterChange)="getData()">
+    <ng-template st-row="status" let-i>
+      <nz-badge [nzStatus]="i.statusType" [nzText]="i.statusText"></nz-badge>
+    </ng-template>
+  </simple-table>
+</nz-card>
+<ng-template #modalContent>
+  <nz-form-item>
+    <nz-form-label nzFor="no">������</nz-form-label>
+    <nz-form-control>
+      <input nz-input [(ngModel)]="description" name="description" placeholder="���������" id="no">
+    </nz-form-control>
+  </nz-form-item>
+</ng-template>
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..f420f8d
--- /dev/null
+++ b/src/app/routes/pro/list/table-list/table-list.component.ts
@@ -0,0 +1,154 @@
+import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core';
+import { NzMessageService, NzModalService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { tap, map } from 'rxjs/operators';
+import {
+  SimpleTableComponent,
+  SimpleTableColumn,
+  SimpleTableData,
+} from '@delon/abc';
+
+@Component({
+  selector: 'pro-table-list',
+  templateUrl: './table-list.component.html',
+})
+export class ProTableListComponent implements OnInit {
+  q: any = {
+    pi: 1,
+    ps: 10,
+    sorter: '',
+    status: null,
+    statusList: [],
+  };
+  data: any[] = [];
+  loading = false;
+  status = [
+    { index: 0, text: '������', value: false, type: 'default', checked: false },
+    {
+      index: 1,
+      text: '���������',
+      value: false,
+      type: 'processing',
+      checked: false,
+    },
+    { index: 2, text: '���������', value: false, type: 'success', checked: false },
+    { index: 3, text: '������', value: false, type: 'error', checked: false },
+  ];
+  @ViewChild('st') st: SimpleTableComponent;
+  columns: SimpleTableColumn[] = [
+    { title: '', index: 'key', type: 'checkbox' },
+    { title: '������������', index: 'no' },
+    { title: '������', index: 'description' },
+    {
+      title: '������������������',
+      index: 'callNo',
+      type: 'number',
+      format: (item: any) => `${item.callNo} ���`,
+      sorter: (a: any, b: any) => a.callNo - b.callNo,
+    },
+    {
+      title: '������',
+      index: 'status',
+      render: 'status',
+      filters: this.status,
+      filter: () => true,
+    },
+    {
+      title: '������������',
+      index: 'updatedAt',
+      type: 'date',
+      sorter: (a: any, b: any) => a.updatedAt - b.updatedAt,
+    },
+    {
+      title: '������',
+      buttons: [
+        {
+          text: '������',
+          click: (item: any) => this.msg.success(`������${item.no}`),
+        },
+        {
+          text: '������������',
+          click: (item: any) => this.msg.success(`������������${item.no}`),
+        },
+      ],
+    },
+  ];
+  selectedRows: SimpleTableData[] = [];
+  description = '';
+  totalCallNo = 0;
+  expandForm = false;
+
+  constructor(
+    private http: _HttpClient,
+    public msg: NzMessageService,
+    private modalSrv: NzModalService,
+  ) {}
+
+  ngOnInit() {
+    this.getData();
+  }
+
+  getData() {
+    this.loading = true;
+    this.q.statusList = this.status
+      .filter(w => w.checked)
+      .map(item => item.index);
+    if (this.q.status !== null && this.q.status > -1)
+      this.q.statusList.push(this.q.status);
+    this.http
+      .get('/rule', this.q)
+      .pipe(
+        map((list: any[]) =>
+          list.map(i => {
+            const statusItem = this.status[i.status];
+            i.statusText = statusItem.text;
+            i.statusType = statusItem.type;
+            return i;
+          }),
+        ),
+        tap(() => (this.loading = false)),
+      )
+      .subscribe(res => (this.data = res));
+  }
+
+  checkboxChange(list: SimpleTableData[]) {
+    this.selectedRows = list;
+    this.totalCallNo = this.selectedRows.reduce(
+      (total, cv) => total + cv.callNo,
+      0,
+    );
+  }
+
+  remove() {
+    this.http
+      .delete('/rule', { nos: this.selectedRows.map(i => i.no).join(',') })
+      .subscribe(() => {
+        this.getData();
+        this.st.clearCheck();
+      });
+  }
+
+  approval() {
+    this.msg.success(`��������� ${this.selectedRows.length} ���`);
+  }
+
+  add(tpl: TemplateRef<{}>) {
+    this.modalSrv.create({
+      nzTitle: '������������',
+      nzContent: tpl,
+      nzOnOk: () => {
+        this.loading = true;
+        this.http
+          .post('/rule', { description: this.description })
+          .subscribe(() => {
+            this.getData();
+          });
+      },
+    });
+  }
+
+  reset(ls: any[]) {
+    for (const item of ls) item.value = false;
+    this.getData();
+  }
+}
diff --git a/src/app/routes/pro/pro-routing.module.ts b/src/app/routes/pro/pro-routing.module.ts
new file mode 100644
index 0000000..a77d7bd
--- /dev/null
+++ b/src/app/routes/pro/pro-routing.module.ts
@@ -0,0 +1,65 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { StepFormComponent } from './form/step-form/step-form.component';
+import { AdvancedFormComponent } from './form/advanced-form/advanced-form.component';
+import { BasicFormComponent } from './form/basic-form/basic-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 { ProListArticlesComponent } from './list/articles/articles.component';
+import { ProListProjectsComponent } from './list/projects/projects.component';
+import { ProListApplicationsComponent } from './list/applications/applications.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 { ProListLayoutComponent } from './list/list/list.component';
+
+const routes: Routes = [
+  {
+    path: 'form',
+    children: [
+      { path: 'basic-form', component: BasicFormComponent },
+      { 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: '',
+        component: ProListLayoutComponent,
+        children: [
+          { path: 'articles', component: ProListArticlesComponent },
+          { path: 'projects', component: ProListProjectsComponent },
+          { path: 'applications', component: ProListApplicationsComponent },
+        ],
+      },
+    ],
+  },
+  {
+    path: 'profile',
+    children: [
+      { path: 'basic', component: ProProfileBaseComponent },
+      { path: 'advanced', component: ProProfileAdvancedComponent },
+    ],
+  },
+  {
+    path: 'result',
+    children: [
+      { path: 'success', component: ProResultSuccessComponent },
+      { path: 'fail', component: ProResultFailComponent },
+    ],
+  },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class ProRoutingModule {}
diff --git a/src/app/routes/pro/pro.module.ts b/src/app/routes/pro/pro.module.ts
new file mode 100644
index 0000000..e978bf4
--- /dev/null
+++ b/src/app/routes/pro/pro.module.ts
@@ -0,0 +1,48 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SharedModule } from '@shared/shared.module';
+import { ProRoutingModule } from './pro-routing.module';
+
+import { BasicFormComponent } from './form/basic-form/basic-form.component';
+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 { ProListLayoutComponent } from './list/list/list.component';
+import { ProListArticlesComponent } from './list/articles/articles.component';
+import { ProListProjectsComponent } from './list/projects/projects.component';
+import { ProListApplicationsComponent } from './list/applications/applications.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';
+
+const COMPONENTS_NOROUNT = [Step1Component, Step2Component, Step3Component];
+
+@NgModule({
+  imports: [SharedModule, ProRoutingModule],
+  declarations: [
+    BasicFormComponent,
+    StepFormComponent,
+    AdvancedFormComponent,
+    ProTableListComponent,
+    ProBasicListComponent,
+    ProCardListComponent,
+    ProListLayoutComponent,
+    ProListArticlesComponent,
+    ProListProjectsComponent,
+    ProListApplicationsComponent,
+    ProProfileBaseComponent,
+    ProProfileAdvancedComponent,
+    ProResultSuccessComponent,
+    ProResultFailComponent,
+    ...COMPONENTS_NOROUNT,
+  ],
+  entryComponents: COMPONENTS_NOROUNT,
+})
+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..d243e7b
--- /dev/null
+++ b/src/app/routes/pro/profile/advanced/advanced.component.html
@@ -0,0 +1,144 @@
+<page-header [title]="'���������234231029431'">
+  <ng-template #logo>
+    <img src="https://gw.alipayobjects.com/zos/rmsportal/nxkuOJlFJuAUhzlMTCEe.png">
+  </ng-template>
+  <ng-template #action>
+    <nz-button-group>
+      <button nz-button>������</button>
+      <button nz-button>������</button>
+    </nz-button-group>
+    <nz-dropdown class="mx-sm">
+      <button nz-button nz-dropdown>
+        <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'">���������</button>
+  </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>
+      <nz-tab nzTitle="������"></nz-tab>
+      <nz-tab nzTitle="������"></nz-tab>
+    </nz-tabset>
+  </ng-template>
+  <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>
+</page-header>
+<nz-card [nzBordered]="false" class="mb-lg" nzTitle="������������">
+  <nz-steps [nzCurrent]="1" nzProgressDot>
+    <nz-step [nzTitle]="'������������'" [nzDescription]="createDesc">
+      <ng-template #createDesc>
+        <div class="desc">
+          <div class="my-sm">���������
+            <i class="anticon anticon-dingding-o ml-sm"></i>
+          </div>
+          <div>2016-12-12 12:32</div>
+        </div>
+      </ng-template>
+    </nz-step>
+    <nz-step [nzTitle]="'������������'" [nzDescription]="checkedDesc">
+      <ng-template #checkedDesc>
+        <div class="desc">
+          <div class="my-sm">���������
+            <i class="anticon anticon-dingding-o ml-sm" style="color: #00a0e9;"></i>
+          </div>
+          <a (click)="msg.success('click')">���������</a>
+        </div>
+      </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>
+    <nz-tabset nzSize="large" (nzSelectChange)="change($event)">
+      <nz-tab nzTitle="���������������"></nz-tab>
+      <nz-tab nzTitle="���������������"></nz-tab>
+      <nz-tab nzTitle="���������������"></nz-tab>
+    </nz-tabset>
+  </nz-card-tab>
+  <simple-table [columns]="opColumns" [data]="list">
+    <ng-template st-row="status" let-i>
+      <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+      <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+    </ng-template>
+  </simple-table>
+</nz-card>
diff --git a/src/app/routes/pro/profile/advanced/advanced.component.less b/src/app/routes/pro/profile/advanced/advanced.component.less
new file mode 100644
index 0000000..a7cfd73
--- /dev/null
+++ b/src/app/routes/pro/profile/advanced/advanced.component.less
@@ -0,0 +1,19 @@
+@import 'node_modules/@delon/theme/styles/default';
+:host {
+  ::ng-deep {
+    @media screen and (max-width: @screen-sm) {
+      .desc {
+        left: 8px;
+      }
+    }
+    .desc {
+      font-size: @font-size-base;
+      position: relative;
+      left: 38px;
+      & > div {
+        margin-top: 8px;
+        margin-bottom: 4px;
+      }
+    }
+  }
+}
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..d8dcf10
--- /dev/null
+++ b/src/app/routes/pro/profile/advanced/advanced.component.ts
@@ -0,0 +1,40 @@
+import { Component, OnInit } from '@angular/core';
+import { NzMessageService, NzTabChangeEvent } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { SimpleTableColumn } from '@delon/abc';
+
+@Component({
+  selector: 'pro-profile-advanced',
+  templateUrl: './advanced.component.html',
+  styleUrls: ['./advanced.component.less'],
+})
+export class ProProfileAdvancedComponent implements OnInit {
+  list: any[] = [];
+
+  data = {
+    advancedOperation1: [],
+    advancedOperation2: [],
+    advancedOperation3: [],
+  };
+
+  opColumns: SimpleTableColumn[] = [
+    { title: '������������', index: 'type' },
+    { title: '���������', index: 'name' },
+    { title: '������������', index: 'status', render: 'status' },
+    { title: '������������', index: 'updatedAt', type: 'date' },
+    { title: '������', index: 'memo', default: '-' },
+  ];
+
+  constructor(public msg: NzMessageService, private http: _HttpClient) {}
+
+  ngOnInit() {
+    this.http.get('/profile/advanced').subscribe((res: any) => {
+      this.data = res;
+      this.change({ index: 0, tab: null });
+    });
+  }
+
+  change(args: NzTabChangeEvent) {
+    this.list = this.data[`advancedOperation${args.index + 1}`];
+  }
+}
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..4c47ebb
--- /dev/null
+++ b/src/app/routes/pro/profile/basic/basic.component.html
@@ -0,0 +1,42 @@
+<page-header [title]="'���������������'"></page-header>
+<nz-card [nzHoverable]="true" [nzBordered]="false">
+  <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>
+  <simple-table [data]="goods" [columns]="goodsColumns">
+    <ng-template #body>
+      <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>
+    </ng-template>
+  </simple-table>
+  <div class="text-lg my-md">������������</div>
+  <simple-table [data]="progress" [columns]="progressColumns">
+    <ng-template st-row="status" let-i>
+      <nz-badge *ngIf="i.status === 'success'" [nzStatus]="'success'" [nzText]="'������'"></nz-badge>
+      <nz-badge *ngIf="i.status !== 'success'" [nzStatus]="'processing'" [nzText]="'���������'"></nz-badge>
+    </ng-template>
+  </simple-table>
+</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..597778c
--- /dev/null
+++ b/src/app/routes/pro/profile/basic/basic.component.ts
@@ -0,0 +1,45 @@
+import { Component } from '@angular/core';
+import { NzMessageService } from 'ng-zorro-antd';
+import { _HttpClient } from '@delon/theme';
+import { SimpleTableColumn } from '@delon/abc';
+import { tap } from 'rxjs/operators';
+
+@Component({
+  selector: 'pro-profile-basic',
+  templateUrl: './basic.component.html',
+})
+export class ProProfileBaseComponent {
+  basicNum = 0;
+  amountNum = 0;
+  goods = this.http.get('/profile/goods').pipe(
+    tap((list: any[]) => {
+      list.forEach(item => {
+        this.basicNum += Number(item.num);
+        this.amountNum += Number(item.amount);
+      });
+    }),
+  );
+  goodsColumns: SimpleTableColumn[] = [
+    {
+      title: '������������',
+      index: 'id',
+      type: 'link',
+      click: (item: any) => this.msg.success(`show ${item.id}`),
+    },
+    { title: '������������', index: 'name' },
+    { title: '������������', index: 'barcode' },
+    { title: '������', index: 'price', type: 'currency' },
+    { title: '���������������', index: 'num', className: 'text-right' },
+    { title: '������', index: 'amount', type: 'currency' },
+  ];
+  progress = this.http.get('/profile/progress');
+  progressColumns: SimpleTableColumn[] = [
+    { title: '������', index: 'time' },
+    { title: '������������', index: 'rate' },
+    { title: '������', render: 'status' },
+    { title: '���������ID', index: 'operator' },
+    { title: '������', index: 'cost' },
+  ];
+
+  constructor(private http: _HttpClient, private msg: NzMessageService) {}
+}
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..d3a820b
--- /dev/null
+++ b/src/app/routes/pro/result/fail/fail.component.html
@@ -0,0 +1,21 @@
+<page-header></page-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">
+        <i class="anticon anticon-close-circle-o text-error pr-sm"></i>������������������������
+        <a class="ml-md">������������
+          <i class="anticon anticon-right pl-sm"></i>
+        </a>
+      </div>
+      <div>
+        <i class="anticon anticon-close-circle-o text-error pr-sm"></i>������������������������������������
+        <a class="ml-md">������������
+          <i class="anticon anticon-right pl-sm"></i>
+        </a>
+      </div>
+    </ng-template>
+    <button nz-button [nzType]="'primary'">������������</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..603cf37
--- /dev/null
+++ b/src/app/routes/pro/result/fail/fail.component.ts
@@ -0,0 +1,7 @@
+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..377a799
--- /dev/null
+++ b/src/app/routes/pro/result/success/success.component.html
@@ -0,0 +1,53 @@
+<page-header></page-header>
+<nz-card>
+  <result type="success" [title]="'������������'" description="��������������������������������������������������������������������������������������������������� Message ���������������������������������������������������������������������������������������������������x������������������������������������������������������������������������������������"
+    [extra]="resultExtra">
+    <ng-template #resultExtra>
+      <div nz-row [nzGutter]="16" class="mb-md">
+        <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="12" [nzLg]="12" [nzXl]="6">
+          <span class="text-grey-darker">������ ID���</span>
+          23421
+        </div>
+        <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="12" [nzLg]="12" [nzXl]="6">
+          <span class="text-grey-darker">������������</span>
+          ���������
+        </div>
+        <div nz-col [nzXs]="24" [nzSm]="24" [nzMd]="24" [nzLg]="24" [nzXl]="12">
+          <span class="text-grey-darker">���������������</span>
+          2016-12-12 ~ 2017-12-12
+        </div>
+      </div>
+      <nz-steps [nzCurrent]="1" nzProgressDot>
+        <nz-step [nzTitle]="'������������'" [nzDescription]="createDesc">
+          <ng-template #createDesc>
+            <div style="font-size: 14px; position: relative; left: 38px;">
+              <div style="margin-top: 8px; margin-bottom: 4px;">
+                ���������
+                <i class="anticon anticon-dingding-o ml-sm"></i>
+              </div>
+              <div style="margin-top: 8px; margin-bottom: 4px;">2016-12-12 12:32</div>
+            </div>
+          </ng-template>
+        </nz-step>
+        <nz-step [nzTitle]="'������������'" [nzDescription]="checkedDesc">
+          <ng-template #checkedDesc>
+            <div style="font-size: 14px; position: relative; left: 38px;">
+              <div style="margin-top: 8px; margin-bottom: 4px;">
+                ���������
+                <i class="anticon anticon-dingding-o ml-sm" style="color: #00a0e9;"></i>
+              </div>
+              <div style="margin-top: 8px; margin-bottom: 4px;">
+                <a (click)="msg.success('click')">���������</a>
+              </div>
+            </div>
+          </ng-template>
+        </nz-step>
+        <nz-step [nzTitle]="'������������'"></nz-step>
+        <nz-step [nzTitle]="'������'"></nz-step>
+      </nz-steps>
+    </ng-template>
+    <button nz-button [nzType]="'primary'">������������</button>
+    <button nz-button>������������</button>
+    <button nz-button>��� ���</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..06abce1
--- /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/routes-routing.module.ts b/src/app/routes/routes-routing.module.ts
index 84bc767..b271c92 100644
--- a/src/app/routes/routes-routing.module.ts
+++ b/src/app/routes/routes-routing.module.ts
@@ -3,20 +3,86 @@
 import { environment } from '@env/environment';
 // layout
 import { LayoutDefaultComponent } from '../layout/default/default.component';
-
+import { LayoutFullScreenComponent } from '../layout/fullscreen/fullscreen.component';
+import { LayoutPassportComponent } from '../layout/passport/passport.component';
+// dashboard pages
+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';
+// passport pages
+import { UserLoginComponent } from './passport/login/login.component';
+import { UserRegisterComponent } from './passport/register/register.component';
+import { UserRegisterResultComponent } from './passport/register-result/register-result.component';
+// single pages
+import { CallbackComponent } from './callback/callback.component';
+import { UserLockComponent } from './passport/lock/lock.component';
+import { Exception403Component } from './exception/403.component';
+import { Exception404Component } from './exception/404.component';
+import { Exception500Component } from './exception/500.component';
 
 const routes: Routes = [
   {
     path: '',
     component: LayoutDefaultComponent,
     children: [
-      { path: '', redirectTo: 'home-page', pathMatch: 'full' },
+      { path: '', redirectTo: 'dashboard/v1', pathMatch: 'full' },
+      { path: 'dashboard', redirectTo: 'dashboard/v1', pathMatch: 'full' },
+      { path: 'dashboard/v1', component: DashboardV1Component },
+      { path: 'dashboard/analysis', component: DashboardAnalysisComponent },
+      { path: 'dashboard/monitor', component: DashboardMonitorComponent },
+      { path: 'dashboard/workplace', component: DashboardWorkplaceComponent },
       {
-        path: 'home-page',
-        loadChildren: './home-page/home-page.module#HomePageModule',
-      }
-    ]
-  }
+        path: 'widgets',
+        loadChildren: './widgets/widgets.module#WidgetsModule',
+      },
+      { path: 'style', loadChildren: './style/style.module#StyleModule' },
+      { path: 'delon', loadChildren: './delon/delon.module#DelonModule' },
+      { 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' },
+    ],
+  },
+  // passport
+  {
+    path: 'passport',
+    component: LayoutPassportComponent,
+    children: [
+      {
+        path: 'login',
+        component: UserLoginComponent,
+        data: { title: '������', titleI18n: 'pro-login' },
+      },
+      {
+        path: 'register',
+        component: UserRegisterComponent,
+        data: { title: '������', titleI18n: 'pro-register' },
+      },
+      {
+        path: 'register-result',
+        component: UserRegisterResultComponent,
+        data: { title: '������������', titleI18n: 'pro-register-result' },
+      },
+    ],
+  },
+  // ���������������Layout
+  { path: 'callback/:type', component: CallbackComponent },
+  {
+    path: 'lock',
+    component: UserLockComponent,
+    data: { title: '������', titleI18n: 'lock' },
+  },
+  { path: '403', component: Exception403Component },
+  { path: '404', component: Exception404Component },
+  { path: '500', component: Exception500Component },
+  { path: '**', redirectTo: 'dashboard' },
 ];
 
 @NgModule({
diff --git a/src/app/routes/routes.module.ts b/src/app/routes/routes.module.ts
index 3c51835..5fe1b20 100644
--- a/src/app/routes/routes.module.ts
+++ b/src/app/routes/routes.module.ts
@@ -2,9 +2,37 @@
 
 import { SharedModule } from '@shared/shared.module';
 import { RouteRoutingModule } from './routes-routing.module';
+// dashboard pages
+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';
+// passport pages
+import { UserLoginComponent } from './passport/login/login.component';
+import { UserRegisterComponent } from './passport/register/register.component';
+import { UserRegisterResultComponent } from './passport/register-result/register-result.component';
+// single pages
+import { UserLockComponent } from './passport/lock/lock.component';
+import { CallbackComponent } from './callback/callback.component';
+import { Exception403Component } from './exception/403.component';
+import { Exception404Component } from './exception/404.component';
+import { Exception500Component } from './exception/500.component';
 
 const COMPONENTS = [
-
+  DashboardV1Component,
+  DashboardAnalysisComponent,
+  DashboardMonitorComponent,
+  DashboardWorkplaceComponent,
+  // passport pages
+  UserLoginComponent,
+  UserRegisterComponent,
+  UserRegisterResultComponent,
+  // single pages
+  UserLockComponent,
+  CallbackComponent,
+  Exception403Component,
+  Exception404Component,
+  Exception500Component
 ];
 const COMPONENTS_NOROUNT = [];
 
diff --git a/src/app/routes/style/color.service.ts b/src/app/routes/style/color.service.ts
new file mode 100644
index 0000000..25ef957
--- /dev/null
+++ b/src/app/routes/style/color.service.ts
@@ -0,0 +1,31 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class ColorService {
+  APP_COLORS = {
+    primary: '#1890ff',
+    success: '#52c41a',
+    error: '#f5222d',
+    warning: '#fadb14',
+    red: '#f5222d',
+    volcano: '#fa541c',
+    orange: '#fa8c16',
+    gold: '#faad14',
+    yellow: '#fadb14',
+    lime: '#a0d911',
+    green: '#52c41a',
+    cyan: '#13c2c2',
+    blue: '#1890ff',
+    geekblue: '#2f54eb',
+    purple: '#722ed1',
+    magenta: '#eb2f96',
+  };
+
+  get names() {
+    return Object.keys(this.APP_COLORS).filter((name, index) => index > 3);
+  }
+
+  get brands() {
+    return ['primary', 'success', 'error', 'warning'];
+  }
+}
diff --git a/src/app/routes/style/colors/colors.component.html b/src/app/routes/style/colors/colors.component.html
new file mode 100644
index 0000000..e0489d9
--- /dev/null
+++ b/src/app/routes/style/colors/colors.component.html
@@ -0,0 +1,105 @@
+<div class="content__title">
+  <h1>
+    Colors
+    <small>Color Palettes</small>
+  </h1>
+</div>
+<div nz-row [nzGutter]="16" class="list">
+  <div nz-col [nzMd]="24">
+    <nz-card nzTitle="Classic colors">
+      <div nz-row *ngFor="let c of c.brands">
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}}-light p-lg">
+            <p (click)="onCopy('bg-' + c + '-light')">.bg-{{c}}-light</p>
+            <p (click)="onCopy('text-' + c + '-light')">.text-{{c}}-light</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}} p-lg">
+            <p (click)="onCopy('bg-' + c)">.bg-{{c}}</p>
+            <p (click)="onCopy('text-' + c)">.text-{{c}}</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}}-dark p-lg">
+            <p (click)="onCopy('bg-' + c + '-dark')">.bg-{{c}}-dark</p>
+            <p (click)="onCopy('text-' + c + '-dark')">.text-{{c}}-dark</p>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+</div>
+<div nz-row [nzGutter]="16" class="list">
+  <div nz-col [nzMd]="24">
+    <nz-card nzTitle="Name colors">
+      <div nz-row *ngFor="let c of c.names">
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}}-light p-lg">
+            <p (click)="onCopy('bg-' + c + '-light')">.bg-{{c}}-light</p>
+            <p (click)="onCopy('text-' + c + '-light')">.text-{{c}}-light</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}} p-lg">
+            <p (click)="onCopy('bg-' + c)">.bg-{{c}}</p>
+            <p (click)="onCopy('text-' + c)">.text-{{c}}</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <div class="bg-{{c}}-dark p-lg">
+            <p (click)="onCopy('bg-' + c + '-dark')">.bg-{{c}}-dark</p>
+            <p (click)="onCopy('text-' + c + '-dark')">.text-{{c}}-dark</p>
+          </div>
+        </div>
+      </div>
+      <div nz-row>
+        <div nz-col [nzSpan]="5">
+          <div class="bg-grey-darker p-lg">
+            <p (click)="onCopy('bg-grey-darker')">.bg-grey-darker</p>
+            <p (click)="onCopy('text-grey-darker')">.text-grey-darker</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="5">
+          <div class="bg-grey-dark p-lg">
+            <p (click)="onCopy('bg-grey-dark')">.bg-grey-dark</p>
+            <p (click)="onCopy('text-grey-dark')">.text-grey-dark</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="4">
+          <div class="bg-grey p-lg">
+            <p (click)="onCopy('bg-grey')">.bg-grey</p>
+            <p (click)="onCopy('text-grey')">.text-grey</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="5">
+          <div class="bg-grey-light p-lg">
+            <p (click)="onCopy('bg-grey-light')">.bg-grey-light</p>
+            <p (click)="onCopy('text-grey-light')">.text-grey-light</p>
+          </div>
+        </div>
+        <div nz-col [nzSpan]="5">
+          <div class="bg-grey-lighter p-lg">
+            <p (click)="onCopy('bg-grey-lighter')">.bg-grey-lighter</p>
+            <p (click)="onCopy('text-grey-lighter')">.text-grey-lighter</p>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+</div>
+<div nz-row [nzGutter]="16" class="list">
+  <div nz-col [nzMd]="24">
+    <nz-card nzTitle="Full Colors">
+      <div nz-row>
+        <div nz-col [nzSpan]="4" *ngFor="let c of c.names">
+          <div *ngFor="let i of nums" class="bg-{{c}}-{{i}} p-lg">
+            <p (click)="onCopy('bg-' + c + '-' + i)">.bg-{{c}}-{{i}}</p>
+            <p (click)="onCopy('bg-' + c + '-' + i + '-h')">.bg-{{c}}-{{i}}-h</p>
+            <p (click)="onCopy('text-' + c + '-' + i)">.text-{{c}}-{{i}}</p>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+</div>
diff --git a/src/app/routes/style/colors/colors.component.less b/src/app/routes/style/colors/colors.component.less
new file mode 100644
index 0000000..7725678
--- /dev/null
+++ b/src/app/routes/style/colors/colors.component.less
@@ -0,0 +1,13 @@
+:host {
+  ::ng-deep {
+    .list {
+      p {
+        margin-bottom: 0;
+        cursor: pointer;
+        &:first-child {
+          margin-bottom: 4px;
+        }
+      }
+    }
+  }
+}
diff --git a/src/app/routes/style/colors/colors.component.spec.ts b/src/app/routes/style/colors/colors.component.spec.ts
new file mode 100644
index 0000000..cb1053a
--- /dev/null
+++ b/src/app/routes/style/colors/colors.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '@testing/common.spec';
+
+import { ColorsComponent } from './colors.component';
+import { ColorService } from '../color.service';
+
+describe('Component: Colors', () => {
+  setUpTestBed(<TestModuleMetadata>{
+    declarations: [ColorsComponent],
+    providers: [ColorService],
+  });
+
+  it('should create an instance', () => {
+    const fixture = TestBed.createComponent(ColorsComponent);
+    const comp = fixture.debugElement.componentInstance;
+    expect(comp).toBeTruthy();
+  });
+});
diff --git a/src/app/routes/style/colors/colors.component.ts b/src/app/routes/style/colors/colors.component.ts
new file mode 100644
index 0000000..d17d0ce
--- /dev/null
+++ b/src/app/routes/style/colors/colors.component.ts
@@ -0,0 +1,20 @@
+import { Component } from '@angular/core';
+import { ColorService } from '../color.service';
+import { copy } from '@delon/util';
+import { NzMessageService } from 'ng-zorro-antd';
+
+@Component({
+  selector: 'app-colors',
+  templateUrl: './colors.component.html',
+  styleUrls: ['./colors.component.less'],
+})
+export class ColorsComponent {
+  nums = Array(10)
+    .fill(1)
+    .map((v, i) => v + i);
+  constructor(public c: ColorService, private msg: NzMessageService) {}
+
+  onCopy(str: string) {
+    copy(str).then(() => this.msg.success(`Copied Success!`));
+  }
+}
diff --git a/src/app/routes/style/gridmasonry/gridmasonry.component.html b/src/app/routes/style/gridmasonry/gridmasonry.component.html
new file mode 100644
index 0000000..99cfe46
--- /dev/null
+++ b/src/app/routes/style/gridmasonry/gridmasonry.component.html
@@ -0,0 +1,247 @@
+<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/tmp/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/tmp/img/bg2.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/img/bg3.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/img/bg4.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/img/bg5.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/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/tmp/img/bg7.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/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/tmp/img/bg9.jpg" alt="" />
+  </div>
+  <div class="col-masonry">
+    <img src="assets/tmp/img/bg10.jpg" alt="" />
+  </div>
+</div>
diff --git a/src/app/routes/style/gridmasonry/gridmasonry.component.spec.ts b/src/app/routes/style/gridmasonry/gridmasonry.component.spec.ts
new file mode 100644
index 0000000..2671125
--- /dev/null
+++ b/src/app/routes/style/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/style/gridmasonry/gridmasonry.component.ts b/src/app/routes/style/gridmasonry/gridmasonry.component.ts
new file mode 100644
index 0000000..5f7ab57
--- /dev/null
+++ b/src/app/routes/style/gridmasonry/gridmasonry.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-gridmasonry',
+  templateUrl: './gridmasonry.component.html',
+})
+export class GridMasonryComponent {}
diff --git a/src/app/routes/style/style-routing.module.ts b/src/app/routes/style/style-routing.module.ts
new file mode 100644
index 0000000..27f3778
--- /dev/null
+++ b/src/app/routes/style/style-routing.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { GridMasonryComponent } from './gridmasonry/gridmasonry.component';
+import { TypographyComponent } from './typography/typography.component';
+import { ColorsComponent } from './colors/colors.component';
+
+const routes: Routes = [
+  { path: 'gridmasonry', component: GridMasonryComponent },
+  { path: 'typography', component: TypographyComponent },
+  { path: 'colors', component: ColorsComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class StyleRoutingModule {}
diff --git a/src/app/routes/style/style.module.ts b/src/app/routes/style/style.module.ts
new file mode 100644
index 0000000..4311eed
--- /dev/null
+++ b/src/app/routes/style/style.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { SharedModule } from '@shared/shared.module';
+
+import { StyleRoutingModule } from './style-routing.module';
+import { ColorService } from './color.service';
+
+import { GridMasonryComponent } from './gridmasonry/gridmasonry.component';
+import { TypographyComponent } from './typography/typography.component';
+import { ColorsComponent } from './colors/colors.component';
+
+@NgModule({
+  imports: [SharedModule, StyleRoutingModule],
+  declarations: [
+    GridMasonryComponent,
+    TypographyComponent,
+    ColorsComponent,
+  ],
+  providers: [ColorService],
+})
+export class StyleModule {}
diff --git a/src/app/routes/style/typography/typography.component.html b/src/app/routes/style/typography/typography.component.html
new file mode 100644
index 0000000..5a0f0fa
--- /dev/null
+++ b/src/app/routes/style/typography/typography.component.html
@@ -0,0 +1,130 @@
+<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">
+        class="h1"
+        <small>Sub-heading</small>
+      </h1>
+      <h2 class="h2">
+        class="h2"
+        <small>Sub-heading</small>
+      </h2>
+      <h3 class="h3">
+        class="h3"
+        <small>Sub-heading</small>
+      </h3>
+      <h4 class="h4">
+        class="h4"
+        <small>Sub-heading</small>
+      </h4>
+      <h5 class="h5">
+        class="h5"
+        <small>Sub-heading</small>
+      </h5>
+      <h6 class="h6">
+        class="h6"
+        <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">class="text-left text-sm"</p>
+      <p class="mt-sm text-center text-md">class="text-center text-md"</p>
+      <p class="text-right text-lg">class="text-right text-lg"</p>
+    </nz-card>
+  </div>
+  <div nz-col [nzMd]="8">
+    <nz-card nzTitle="Text Colors">
+      <p *ngFor="let color of c.names" class="pb-0 text-{{color}}">class="text-{{color}} bg-{{color}}"</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">[class="text-nowrap"].Ad eiusmod eu velit veniam laborum voluptate duis aliqua esse eiusmod.</p>
+      <h4 class="pt-sm">text-truncate</h4>
+      <p class="pt-sm text-truncate">[class="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">class="text-lowercase"</p>
+      <p class="pt-sm text-uppercase">class="text-uppercase"</p>
+      <p class="pt-sm text-capitalize">class="text-capitalize"</p>
+      <p class="pt-sm text-deleted">class="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">class="border border-primary"</div>
+      <div class="p-sm m-sm text-center width-sm d-inline-block border-top-1 border-success rounded-circle">class="border-top-1 border-success rounded-circle"</div>
+      <div class="p-sm m-sm text-center width-sm d-inline-block border-bottom-1 border-error">class="border-bottom-1 border-error"</div>
+      <div class="p-sm m-sm text-center width-md d-inline-block border-right-1 border-warning">class="border-right-1 border-warning"</div>
+    </nz-card>
+  </div>
+  <div nz-col [nzMd]="8">
+    <nz-card nzTitle="Padding & Margin">
+      <strong>������������</strong>
+      <p>
+        <code>[<������>p|m][<������>t|r|b|l|x|y]?0</code>
+      </p>
+      <p>eg: p0, pt0, mb0, mt0</p>
+      <strong>������</strong>
+      <p>
+        <code>[<������>p|m][<������>t|r|b|l|x|y]?-[<������>sm|md|lg]</code>
+      </p>
+      <p>eg: p-sm, pb-sm, mt-md, mr-md</p>
+    </nz-card>
+  </div>
+</div>
+<div nz-row [nzGutter]="16">
+  <div nz-col [nzMd]="8">
+    <nz-card nzTitle="Display">
+      <p class="display-1">class="display-1"</p>
+      <p class="display-2">class="display-2"</p>
+      <p class="display-3">class="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 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>
diff --git a/src/app/routes/style/typography/typography.component.spec.ts b/src/app/routes/style/typography/typography.component.spec.ts
new file mode 100644
index 0000000..b575b38
--- /dev/null
+++ b/src/app/routes/style/typography/typography.component.spec.ts
@@ -0,0 +1,18 @@
+import { TestBed, TestModuleMetadata } from '@angular/core/testing';
+import { setUpTestBed } from '@testing/common.spec';
+
+import { TypographyComponent } from './typography.component';
+import { ColorService } from '../color.service';
+
+describe('Component: Typography', () => {
+  setUpTestBed(<TestModuleMetadata>{
+    declarations: [TypographyComponent],
+    providers: [ColorService],
+  });
+
+  it('should create an instance', () => {
+    const fixture = TestBed.createComponent(TypographyComponent);
+    const comp = fixture.debugElement.componentInstance;
+    expect(comp).toBeTruthy();
+  });
+});
diff --git a/src/app/routes/style/typography/typography.component.ts b/src/app/routes/style/typography/typography.component.ts
new file mode 100644
index 0000000..b982092
--- /dev/null
+++ b/src/app/routes/style/typography/typography.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { ColorService } from '../color.service';
+
+@Component({
+  selector: 'app-typography',
+  templateUrl: './typography.component.html',
+})
+export class TypographyComponent {
+  constructor(public c: ColorService) {}
+}
diff --git a/src/app/routes/widgets/widgets-routing.module.ts b/src/app/routes/widgets/widgets-routing.module.ts
new file mode 100644
index 0000000..7368602
--- /dev/null
+++ b/src/app/routes/widgets/widgets-routing.module.ts
@@ -0,0 +1,12 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { WidgetsComponent } from './widgets/widgets.component';
+
+const routes: Routes = [{ path: '', component: WidgetsComponent }];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
+})
+export class WidgetsRoutingModule {}
diff --git a/src/app/routes/widgets/widgets.module.ts b/src/app/routes/widgets/widgets.module.ts
new file mode 100644
index 0000000..e77f2d8
--- /dev/null
+++ b/src/app/routes/widgets/widgets.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import { SharedModule } from '@shared/shared.module';
+
+import { WidgetsRoutingModule } from './widgets-routing.module';
+
+import { WidgetsComponent } from './widgets/widgets.component';
+
+@NgModule({
+  imports: [SharedModule, WidgetsRoutingModule],
+  declarations: [WidgetsComponent],
+})
+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..66c50f6
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.html
@@ -0,0 +1,797 @@
+<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="anticon anticon-pay-circle display-2"></i>
+      </div>
+      <h3 class="h3">99.999</h3>
+      <div class="text-grey">Games played last month</div>
+      <nz-progress [nzStatus]="'active'" [nzPercent]="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="anticon anticon-pie-chart display-2"></i>
+      </div>
+      <h3 class="h3">300</h3>
+      <div class="text-grey">Coffee cups per day</div>
+      <nz-progress [nzStatus]="'success'" [nzPercent]="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="anticon anticon-cloud display-2"></i>
+      </div>
+      <h3 class="h3">1000 Gb</h3>
+      <div class="text-grey">Average Monthly Uploads</div>
+      <nz-progress [nzStatus]="'exception'" [nzPercent]="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 class="ant-card__body-nopadding">
+      <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="anticon anticon-user display-2"></i>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">10k</h4>
+              <div class="text-grey">VISITORS</div>
+            </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="anticon anticon-sound display-2"></i>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">100%</h4>
+              <div class="text-grey">VOLUME</div>
+            </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="anticon anticon-fork display-2"></i>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">150</h4>
+              <div class="text-grey">FORKS</div>
+            </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="anticon anticon-message display-2"></i>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">10</h4>
+              <div class="text-grey">MESSAGES</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+    <nz-card class="ant-card__body-nopadding">
+      <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">
+              <g2-mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="smallData"></g2-mini-bar>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">10k</h4>
+              <div class="text-grey">VISITORS</div>
+            </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">
+              <g2-mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="smallData"></g2-mini-bar>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">100%</h4>
+              <div class="text-grey">VOLUME</div>
+            </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">
+              <g2-mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="smallData"></g2-mini-bar>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">150</h4>
+              <div class="text-grey">FORKS</div>
+            </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">
+              <g2-mini-bar height="35" color="#999" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="smallData"></g2-mini-bar>
+            </div>
+            <div nz-col [nzSpan]="12" class="py-md">
+              <h4 class="h4">10</h4>
+              <div class="text-grey">MESSAGES</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col [nzXs]="24" [nzSm]="8">
+    <nz-card class="ant-card__body-nopadding">
+      <div class="half-float half-float-md">
+        <img src="./assets/tmp/img/half-float-bg-1.jpg">
+        <div class="half-float-bottom rounded-circle bg-grey-lighter">
+          <img class="p-sm" src="./assets/tmp/img/1.png">
+        </div>
+      </div>
+      <div class="text-center">
+        <h3 class="h3">cipchk</h3>
+        <div class="text-grey">Lead director</div>
+        <div 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.</div>
+      </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 mb0">400</h3>
+            <div>Photos</div>
+          </div>
+          <div nz-col [nzSpan]="8" class="py-sm">
+            <h3 class="text-white mb0">2000</h3>
+            <div>Likes</div>
+          </div>
+          <div nz-col [nzSpan]="8" class="py-sm">
+            <h3 class="text-white mb0">500</h3>
+            <div>Following</div>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col [nzXs]="24" [nzSm]="8">
+    <nz-card class="ant-card__body-nopadding">
+      <div class="text-center bg-center py-lg text-white" style="background-image: url('./assets/tmp/img/bg9.jpg');">
+        <nz-avatar [nzSrc]="'./assets/tmp/img/1.png'"></nz-avatar>
+        <h3 class="text-white">cipchk</h3>
+        <div>
+          <i class="fa fa-github fa-fw"></i>
+          @cipchk
+        </div>
+      </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>
+        <div class="text-nowrap">Website Traffics</div>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="data"></g2-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>
+        <div class="text-nowrap">Website Impressions</div>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="data"></g2-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>
+        <div class="text-nowrap">Total Sales</div>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="data"></g2-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-magenta rounded-md">
+      <div nz-col nzSpan="12" class="p-md text-white">
+        <div class="h2 mt0">456</div>
+        <div class="text-nowrap">Support Tickets</div>
+      </div>
+      <div nz-col nzSpan="12">
+        <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="data"></g2-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="anticon anticon-user display-2"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-white py-md">
+        <h3 class="h3 mb0">10k</h3>
+        <div class="text-grey-dark">VISITORS</div>
+      </div>
+    </div>
+  </div>
+  <div nz-col nzXs="24" nzSm="12" nzMd="6" class="mb-md">
+    <div nz-row nzType="flex" nzAlign="middle" class="bg-magenta text-center rounded-md">
+      <div nz-col nzSpan="8" class="p-md text-white">
+        <i class="anticon anticon-sound display-2"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-white py-md">
+        <h3 class="h3 mb0">100%</h3>
+        <div class="text-grey-dark">VOLUME</div>
+      </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="anticon anticon-fork display-2"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-white py-md">
+        <h3 class="h3 mb0">150</h3>
+        <div class="text-grey-dark">FORKS</div>
+      </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="anticon anticon-message display-2"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-white py-md">
+        <h3 class="h3 mb0">10</h3>
+        <div class="text-grey-dark">NEW MESSAGES</div>
+      </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 display-1"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-green-light p-md">
+        <h2 class="h2 text-white mb0">150</h2>
+        <div class="text-lg text-uppercase">New connections</div>
+      </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 display-1"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-red-light p-md">
+        <h2 class="h2 text-white mb0">7000</h2>
+        <div class="text-lg text-uppercase">RATINGS RECEIVED</div>
+      </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 display-1"></i>
+      </div>
+      <div nz-col nzSpan="16" class="bg-warning-light p-md">
+        <h2 class="h2 text-white mb0">15</h2>
+        <div class="text-lg text-uppercase">ACHIEVEMENTS</div>
+      </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="anticon anticon-book display-1"></i>
+      </div>
+      <div nz-col nzSpan="14" class="py-md">
+        <h1 class="text-white mb0">120</h1>
+        <div>New Tasks!</div>
+      </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="anticon anticon-message display-1"></i>
+      </div>
+      <div nz-col nzSpan="14" class="py-md">
+        <h1 class="text-white mb0">36</h1>
+        <div>New Comments!</div>
+      </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="anticon anticon-shopping-cart display-1"></i>
+      </div>
+      <div nz-col nzSpan="14" class="py-md">
+        <h1 class="text-white mb0">110</h1>
+        <div>New Orders!</div>
+      </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="anticon anticon-customer-service display-1"></i>
+      </div>
+      <div nz-col nzSpan="14" class="py-md">
+        <h1 class="text-white mb0">19</h1>
+        <div>Support Tickets!</div>
+      </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="������" [nzExtra]="extra">
+      <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 mb0">������������������</h4>
+                  <div class="text-grey">Register Server</div>
+                </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 mb0">������������</h4>
+                  <div class="text-grey">Msg Broker</div>
+                </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 mb0">���������������������</h4>
+                  <div class="text-grey">DRM</div>
+                </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 mb0">���������������������</h4>
+                  <div class="text-grey">ZDC</div>
+                </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 mb0">������������������</h4>
+                  <div class="text-grey">Register Server</div>
+                </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 mb0">������������</h4>
+                  <div class="text-grey">Msg Broker</div>
+                </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>
+                  <div class="text-grey">DRM</div>
+                </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>
+                  <div class="text-grey">ZDC</div>
+                </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 mb0">���������������</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'">
+            <span>������</span>
+          </button>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col [nzXs]="24" [nzSm]="12" [nzMd]="8">
+    <nz-card nzTitle="������ 1" class="ant-card__body-nopadding" [nzExtra]="extra">
+      <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> ���
+        <div class="text-grey">������������������</div>
+      </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 class="ant-card__body-nopadding bg-green rounded-md">
+      <div class="p-md">
+        <div class="h5 pb-sm text-white">Received all time</div>
+        <g2-mini-area color="#fff" height="46" [data]="data"></g2-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 mb0">400</h3>
+            <div>Photos</div>
+          </div>
+          <div nz-col [nzSpan]="8" class="py-sm">
+            <h3 class="text-white mb0">2000</h3>
+            <div>Likes</div>
+          </div>
+          <div nz-col [nzSpan]="8" class="py-sm">
+            <h3 class="text-white mb0">500</h3>
+            <div>Following</div>
+          </div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col nzXs="24" nzSm="12" nzMd="8" class="mb-md">
+    <nz-card class="ant-card__body-nopadding bg-green rounded-md">
+      <div class="p-md">
+        <div class="h5 pb-sm text-white">Monthly incomes</div>
+        <g2-mini-area color="#fff" height="46" [data]="data"></g2-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">
+          <g2-mini-bar height="35" color="#fff" borderWidth="3" [padding]="[36, 30, 30, 30]" [data]="data"></g2-mini-bar>
+        </div>
+        <div nz-col [nzSpan]="8">
+          <div class="text-white">+150</div>
+          <div class="text-grey">From last month</div>
+        </div>
+      </div>
+      <div class="py-sm text-center bg-white text-grey">
+        <div nz-row>
+          <div nz-col [nzSpan]="12">
+            <div class="text-grey-dark">Gross income</div>
+            <h4 class="h4 mb0">12000</h4>
+          </div>
+          <div nz-col [nzSpan]="12">
+            <div class="text-grey-dark">Net income</div>
+            <h4 class="h4 mb0">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/tmp/img/bg1.jpg" alt="" />
+      </div>
+      <div nz-col nzSpan="8" class="text-white text-center">
+        <h2 class="h1 text-white mb0">11��</h2>
+        <div class="py-sm">Cold</div>
+        <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 mb0">ANT DESIGN</h3>
+        <div class="text-grey">A UI Design Language</div>
+        <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>
+        <div class="pt-md">
+          <a class="text-grey" href="//ng.ant.design" target="_blank">View Site...</a>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col nzXs="24" nzMd="12">
+    <nz-card [nzTitle]="nzTitle" class="ant-card__body-nopadding" [nzTitle]="nzTitle">
+      <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/tmp/img/' + item.avatar + '.png'"></nz-avatar>
+        </div>
+        <div nz-col [nzSpan]="20">
+          <strong>{{item.name}}</strong>
+          <div>{{item.content}}</div>
+        </div>
+      </div>
+    </nz-card>
+  </div>
+  <div nz-col nzXs="24" nzMd="12">
+    <nz-card nzTitle="Todo lists" class="ant-card__body-nopadding">
+      <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/tmp/img/' + item.avatar + '.png'"></nz-avatar>
+        </div>
+        <div nz-col [nzSpan]="18">
+          <strong>{{item.name}}</strong>
+          <div [class.text-deleted]="item.completed">{{item.content}}</div>
+        </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..8077540
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.less
@@ -0,0 +1,11 @@
+@import 'node_modules/@delon/theme/styles/default';
+:host ::ng-deep {
+  .ant-carousel {
+    .slick-dots {
+      bottom: -10px;
+      li.slick-active button {
+        background: @primary-color;
+      }
+    }
+  }
+}
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..54ebf23
--- /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..dd98087
--- /dev/null
+++ b/src/app/routes/widgets/widgets/widgets.component.ts
@@ -0,0 +1,63 @@
+import { NzMessageService } from 'ng-zorro-antd';
+import { Component } from '@angular/core';
+import { _HttpClient } from '@delon/theme';
+
+@Component({
+  selector: 'app-widgets',
+  templateUrl: './widgets.component.html',
+  styleUrls: ['./widgets.component.less'],
+})
+export class WidgetsComponent {
+  data = [];
+  smallData = [];
+
+  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, private http: _HttpClient) {
+    this.http.get('/chart/visit').subscribe((res: any[]) => {
+      this.data = res;
+      this.smallData = res.slice(0, 6);
+    });
+  }
+}
diff --git a/src/assets/tmp/app-data.json b/src/assets/tmp/app-data.json
index ed08616..1aa46f3 100644
--- a/src/assets/tmp/app-data.json
+++ b/src/assets/tmp/app-data.json
@@ -1,12 +1,12 @@
 {
   "app": {
-    "name": "������������������������",
+    "name": "Alain",
     "description": "Ng-zorro admin panel front-end framework"
   },
   "user": {
     "name": "Admin",
     "avatar": "./assets/tmp/img/avatar.jpg",
-    "email": "admin@qq.com"
+    "email": "cipchk@qq.com"
   },
   "menu": [
     {
diff --git a/src/assets/tmp/i18n/zh-CN.json b/src/assets/tmp/i18n/zh-CN.json
index 9b78ffe..a9558b4 100644
--- a/src/assets/tmp/i18n/zh-CN.json
+++ b/src/assets/tmp/i18n/zh-CN.json
@@ -64,7 +64,5 @@
   "pro-user": "������",
   "pro-login": "������",
   "pro-register": "������",
-  "pro-register-result": "������������",
-  "home-page":"������������",
-  "system_navigation":"������������"
+  "pro-register-result": "������������"
 }
diff --git a/src/assets/tmp/img/No1.png b/src/assets/tmp/img/No1.png
deleted file mode 100644
index 3247245..0000000
--- a/src/assets/tmp/img/No1.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/No2.png b/src/assets/tmp/img/No2.png
deleted file mode 100644
index e137d5e..0000000
--- a/src/assets/tmp/img/No2.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/No3.png b/src/assets/tmp/img/No3.png
deleted file mode 100644
index 04677e7..0000000
--- a/src/assets/tmp/img/No3.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/No4.png b/src/assets/tmp/img/No4.png
deleted file mode 100644
index efd5b94..0000000
--- a/src/assets/tmp/img/No4.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/No5.png b/src/assets/tmp/img/No5.png
deleted file mode 100644
index 4025d3e..0000000
--- a/src/assets/tmp/img/No5.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/logo.png b/src/assets/tmp/img/logo.png
deleted file mode 100644
index 4c3a71f..0000000
--- a/src/assets/tmp/img/logo.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/logo_100x40.png b/src/assets/tmp/img/logo_100x40.png
deleted file mode 100644
index a1e8606..0000000
--- a/src/assets/tmp/img/logo_100x40.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/logo_30x30.png b/src/assets/tmp/img/logo_30x30.png
deleted file mode 100644
index 547aadf..0000000
--- a/src/assets/tmp/img/logo_30x30.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/logo_44x44.png b/src/assets/tmp/img/logo_44x44.png
deleted file mode 100644
index d1db631..0000000
--- a/src/assets/tmp/img/logo_44x44.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/map_coordinates.png b/src/assets/tmp/img/map_coordinates.png
deleted file mode 100644
index 1c6a7e4..0000000
--- a/src/assets/tmp/img/map_coordinates.png
+++ /dev/null
Binary files differ
diff --git a/src/assets/tmp/img/zorro.svg b/src/assets/tmp/img/zorro.svg
deleted file mode 100644
index 059bf56..0000000
--- a/src/assets/tmp/img/zorro.svg
+++ /dev/null
@@ -1,34 +0,0 @@
-<?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/index.html b/src/index.html
index b3e7817..b1f13ae 100644
--- a/src/index.html
+++ b/src/index.html
@@ -3,7 +3,7 @@
 
 <head>
   <meta charset="utf-8">
-  <title>������������������������</title>
+  <title>ngAlain</title>
   <base href="/">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta http-equiv="x-ua-compatible" content="ie=edge">

--
Gitblit v1.8.0