fengxiang
2018-01-11 3405a42d4434bb77026c029ed20f2898ba665107
框架升级
26 files renamed
4 files deleted
23 files added
33 files modified
19197 ■■■■ changed files
.dockerignore 12 ●●●●● patch | view | raw | blame | history
.editorconfig 2 ●●● patch | view | raw | blame | history
.gitignore 2 ●●●●● patch | view | raw | blame | history
.npmignore 6 ●●●●● patch | view | raw | blame | history
.stylelintrc 30 ●●●●● patch | view | raw | blame | history
.travis.yml 27 ●●●●● patch | view | raw | blame | history
CHANGELOG.md 194 ●●●●● patch | view | raw | blame | history
CONTRIBUTING.md 200 ●●●●● patch | view | raw | blame | history
Dockerfile 27 ●●●●● patch | view | raw | blame | history
LICENSE 21 ●●●●● patch | view | raw | blame | history
README-zh_CN.md 107 ●●●●● patch | view | raw | blame | history
README.md 105 ●●●● patch | view | raw | blame | history
_mock/README.md 1 ●●●● patch | view | raw | blame | history
_mock/_api.ts 17 ●●●● patch | view | raw | blame | history
_mock/_chart.ts 37 ●●●●● patch | view | raw | blame | history
_mock/_profile.ts 26 ●●●● patch | view | raw | blame | history
_mock/_rule.ts 26 ●●●●● patch | view | raw | blame | history
_mock/index.ts 4 ●●●● patch | view | raw | blame | history
docker-compose.debug.yml 13 ●●●●● patch | view | raw | blame | history
docker-compose.yml 10 ●●●●● patch | view | raw | blame | history
e2e/app.e2e-spec.ts 2 ●●● patch | view | raw | blame | history
package-lock.json 13440 ●●●●● patch | view | raw | blame | history
package.json 34 ●●●●● patch | view | raw | blame | history
src/app/app.component.spec.ts 6 ●●●●● patch | view | raw | blame | history
src/app/app.module.ts 41 ●●●● patch | view | raw | blame | history
src/app/core/README.md 5 ●●●●● patch | view | raw | blame | history
src/app/core/core.module.ts 7 ●●●● patch | view | raw | blame | history
src/app/core/i18n/i18n.service.spec.ts 6 ●●●●● patch | view | raw | blame | history
src/app/core/i18n/i18n.service.ts 22 ●●●●● patch | view | raw | blame | history
src/app/core/net/default.interceptor.ts 6 ●●●●● patch | view | raw | blame | history
src/app/core/services/startup.service.ts 48 ●●●●● patch | view | raw | blame | history
src/app/core/startup/startup.service.ts 57 ●●●●● patch | view | raw | blame | history
src/app/delon.module.ts 208 ●●●●● patch | view | raw | blame | history
src/app/layout/default/default.component.html 5 ●●●● patch | view | raw | blame | history
src/app/layout/default/default.component.spec.ts 17 ●●●●● patch | view | raw | blame | history
src/app/layout/default/default.component.ts 6 ●●●● patch | view | raw | blame | history
src/app/layout/default/header/components/fullscreen.component.ts 2 ●●● patch | view | raw | blame | history
src/app/layout/default/header/components/icon.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/langs.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/notify.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/search.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/storage.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/task.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/theme.component.ts patch | view | raw | blame | history
src/app/layout/default/header/components/user.component.ts 3 ●●●● patch | view | raw | blame | history
src/app/layout/default/header/header.component.html 2 ●●● patch | view | raw | blame | history
src/app/layout/default/header/header.component.spec.ts 3 ●●●● patch | view | raw | blame | history
src/app/layout/default/header/header.component.ts patch | view | raw | blame | history
src/app/layout/default/header/index.md patch | view | raw | blame | history
src/app/layout/default/sidebar/sidebar.component.html patch | view | raw | blame | history
src/app/layout/default/sidebar/sidebar.component.spec.ts 2 ●●● patch | view | raw | blame | history
src/app/layout/default/sidebar/sidebar.component.ts patch | view | raw | blame | history
src/app/layout/fullscreen/fullscreen.component.ts 2 ●●● patch | view | raw | blame | history
src/app/layout/layout.component.spec.ts 17 ●●●●● patch | view | raw | blame | history
src/app/layout/layout.module.ts 40 ●●●● patch | view | raw | blame | history
src/app/layout/passport/passport.component.html patch | view | raw | blame | history
src/app/layout/passport/passport.component.less patch | view | raw | blame | history
src/app/layout/passport/passport.component.ts 8 ●●●● patch | view | raw | blame | history
src/app/routes/dashboard/analysis/analysis.component.ts 17 ●●●●● patch | view | raw | blame | history
src/app/routes/dashboard/monitor/monitor.component.ts 524 ●●●●● patch | view | raw | blame | history
src/app/routes/dashboard/v1/v1.component.ts 24 ●●●●● patch | view | raw | blame | history
src/app/routes/dashboard/workplace/workplace.component.less 2 ●●● patch | view | raw | blame | history
src/app/routes/dashboard/workplace/workplace.component.ts 20 ●●●●● patch | view | raw | blame | history
src/app/routes/routes-routing.module.ts 30 ●●●● patch | view | raw | blame | history
src/app/routes/routes.module.ts 24 ●●●●● patch | view | raw | blame | history
src/app/shared/README.md 30 ●●●●● patch | view | raw | blame | history
src/app/shared/shared.module.ts 195 ●●●● patch | view | raw | blame | history
src/assets/app-data.json 173 ●●●●● patch | view | raw | blame | history
src/assets/demo.docx patch | view | raw | blame | history
src/assets/demo.pdf patch | view | raw | blame | history
src/assets/demo.pptx patch | view | raw | blame | history
src/assets/demo.xlsx patch | view | raw | blame | history
src/assets/i18n/en.json 9 ●●●●● patch | view | raw | blame | history
src/assets/i18n/zh-CN.json 20 ●●●●● patch | view | raw | blame | history
src/assets/iconsfont.json 2310 ●●●●● patch | view | raw | blame | history
src/assets/users-installer-data.json 605 ●●●●● patch | view | raw | blame | history
src/environments/environment.chore.ts 4 ●●●● patch | view | raw | blame | history
src/environments/environment.hmr.ts 6 ●●●● patch | view | raw | blame | history
src/environments/environment.prod.ts 4 ●●●● patch | view | raw | blame | history
src/environments/environment.ts 3 ●●●● patch | view | raw | blame | history
src/test.ts 2 ●●● patch | view | raw | blame | history
src/testing/common.spec.ts 20 ●●●● patch | view | raw | blame | history
src/tsconfig.app.json 16 ●●●●● patch | view | raw | blame | history
src/tsconfig.spec.json 16 ●●●●● patch | view | raw | blame | history
tsconfig.json 8 ●●●●● patch | view | raw | blame | history
yarn.lock 279 ●●●● patch | view | raw | blame | history
.dockerignore
New file
@@ -0,0 +1,12 @@
node_modules
npm-debug.log
Dockerfile*
docker-compose*
.dockerignore
.git
.gitignore
README.md
LICENSE
.vscode
_screenshot
_documents
.editorconfig
@@ -4,7 +4,7 @@
[*]
charset = utf-8
indent_style = space
indent_size = 2
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
.gitignore
@@ -38,4 +38,6 @@
Thumbs.db
.angulardoc.json
yarn.lock
/_nginx/*
.github/*
.npmignore
New file
@@ -0,0 +1,6 @@
.github
_screenshot
node_modules
dist
tmp
.stylelintrc
New file
@@ -0,0 +1,30 @@
{
  "extends": "stylelint-config-standard",
  "rules": {
    "comment-empty-line-before": null,
    "declaration-empty-line-before": null,
    "function-comma-newline-after": null,
    "function-name-case": null,
    "function-parentheses-newline-inside": null,
    "function-max-empty-lines": null,
    "function-whitespace-after": null,
    "indentation": null,
    "number-leading-zero": null,
    "number-no-trailing-zeros": null,
    "rule-empty-line-before": null,
    "selector-combinator-space-after": null,
    "selector-list-comma-newline-after": null,
    "selector-pseudo-element-colon-notation": null,
    "unit-no-unknown": null,
    "value-list-max-empty-lines": null,
    "selector-type-no-unknown": null,
    "selector-pseudo-element-no-unknown": [
        true,
        {
            "ignorePseudoElements": [
                "ng-deep"
            ]
        }
    ]
  }
}
.travis.yml
New file
@@ -0,0 +1,27 @@
sudo: false
language: node_js
node_js:
  - "8.5.0"
addons:
  chrome: stable
git:
  depth: 1
before_install:
  - export CHROME_BIN=chromium-browser
  - export DISPLAY=:99.0
  - sh -e /etc/init.d/xvfb start
  - npm install -g npm@~5.3.0
install:
  - npm install
script:
  - npm run test
  - npm run test-coverage
after_success:
  - ./node_modules/.bin/codecov
CHANGELOG.md
New file
@@ -0,0 +1,194 @@
# update no more, please to [release](https://github.com/cipchk/ng-alain/releases) page.
-------------------
# 0.1.2-beta.10
+ ng-zorro-antd 0.6.x 由于[#504](https://github.com/NG-ZORRO/ng-zorro-antd/issues/504)的原因回滚至最低版本,本次只对 ng-zorro-antd 组件国际化产生影响。
# 0.1.2-beta.9
+ 新增 ng-zorro-antd 组件的国际化,见 [translator.service](./src/app/core/translator/translator.service.ts)
    + 当前 ng-zorro-antd 为 `rc` 版本,若遇到构建当中存在 `@angular/cdk` 问题,请手动安装。
> 下周末将发布正式版,这段时间将不会再新增任何功能。
# 0.1.2-beta.8
+ 增加快捷菜单,见 [menu.service.ts](./src/app/core/services/menu.service.ts)
+ 修复菜单小三角与菜单文本垂直问题
+ 移除 ng-zorro-antd 已知问题且修复的 bug 链接地址 `header.component.ts`。
# 0.1.2-beta.7
+ 增加Docker部署
    + 增加 `.dockerignore`、`docker-compose.yml`、`docker-compose.debug.yml`、`Dockerfile` 文件
    + 增加 `_nginx` 目录
# 0.1.2-beta.6
+ 增加全屏布局,见[用户关系图](https://cipchk.github.io/ng-alain/#/data-v/relation)
+ 侧边栏主菜单链接支持 `target` 属性
+ 基于Front-End-Checklist优化 `index.html`
# 0.1.2-beta.5
+ 新增 `[_src]` 指令,包括以下特性:
    + 支持微信、qq头像规则缩略图规则
    + 支持移除http&https协议http
    + 支持增加onerror事件
+ 样式相关:
    + 移除 `text-truncate` 的 `!important`。
    + 调整 `.simple-table` 的 `img` 边距由 `padding-left` 改变成 `margin-left` 更为合理。
+ 修复用户EMAIL无法缩短问题,closes [#35](https://github.com/cipchk/ng-alain/issues/35)
+ 修复注册、找回、屏幕页面密码框类型问题,closes [#34](https://github.com/cipchk/ng-alain/issues/34)
+ 调整 `sparkline.directive.ts` 目录。
+ 调整tsline规则:`curly: false`。
# 0.1.2-beta.4
+ 修复分页当前页hover文字颜色问题,closes [#31](https://github.com/cipchk/ng-alain/issues/31)
# 0.1.2-beta.3
+ 修复 `file-upload` 按钮由于 `span` 样式关系导致元素无法触发问题,closes [#27](https://github.com/cipchk/ng-alain/issues/27)
# 0.1.2-beta.2
+ 新增 `TitleService` 用于设置页面标题
# 0.1.2-beta.1
+ 为了更好支持 git-subtree 调整 `styles` 目录位置至 `src/styles/alain/`(以及 `themes.service.ts` 变更)
# 0.1.1-beta.2
+ 支持 `ng-zorro-antd` 部分组件换肤
+ 修复若干样式细节
# 0.1.1-beta.1
为了 ng-alain 更好的发展(主要是 alain 在其他框架中做准备),最后还是决定由 scss 转为 less,虽然 scss 更优雅这也是当初选择的原因:
+ scss 转 less 升级要点
    + `.angular-cli.json` 中 `styles`、`styleExt` 变更为 `.less`
    + `themes.service.ts` 修改为 `.less`
    + 对所有 `.scss` 文件后缀换成 `.less`
+ **注:** 根据团队反馈,去掉所有业务的 `.less` 文件,这是因为作为后台管理绝大多数页面中无须编写样式,去掉可以提升编译速度。
+ 新增 `down-file` 指令。
+ 升级 `ng-zorro-antd` 至最新版本,并移除已经修复BUG的部分样式代码。
# 0.1.0-beta.1
**0.1.0版本说明:**
由于 `nz-menu` 很难满足 ng-alain 的需求,这包括换肤、收缩等问题,因此重写菜单;并且不兼容 `0.0.x` 的版本(已将独立另一分支);主要改变:
+ `0.1.0` 影响到整个 `layout`(结构发生改变)、`styles` 文件夹,因此升级时最好移除并重新添加。
+ 原10套颜色主题,保留5个主要色,且每一色系包括:菜单栏黑、白两色系,新依然保持10个主题色。
+ 菜单默认 `14px` 字号。
+ 优化框架样式属性参数化,允许通过 `_alain-custom-variables.scss` 改变主题基本配置;主要是ng-alain,对于 `ng-zorro-antd` 组件(如:字号、间距等)并不支持,这一点我一直在尝试,但成本太高!
+ 顶部快捷菜单与搜索框由改成左中右布局
+ **实验性功能** 支持自定义 ng-zorro-antd 所有组件字号
+ closes [#6](https://github.com/cipchk/ng-alain/issues/6) [#12](https://github.com/cipchk/ng-alain/issues/12) [#13](https://github.com/cipchk/ng-alain/issues/13) [#14](https://github.com/cipchk/ng-alain/issues/14) [#23](https://github.com/cipchk/ng-alain/issues/23)
**其他**
+ 支持 `ng lint`
+ 从 `app.component.ts` 中移除非必选 `nz-root`
+ 样式:
    + 新增 `badge-dot` 小红点。
    + 新增 `nz-table` 单元格与文本垂直居中
    + 新增 `unwrap` 样式,使内容区域与header、aside 无缝
    + 优化 `width-*`、`modal-*`
+ 默认开启支持IE版本(可通过 `polyfills.ts` 自行关闭)
+ 新 Logo
+ 升级 `angular`、`angular-cli`、`ng-zorro-antd` 至最新版本
    + 之前有过一个版本回退,以及 `licenses` BUG问题都已经修复。
    + close [#15](https://github.com/cipchk/ng-alain/issues/15)
# 0.1.0-beta.1
+ 增加 `.simple-table`、`.search-form`、`.fixed-btns` 样式,效果见[门店页](https://cipchk.github.io/ng-alain/#/extras/poi)
+ 增加HTML模板驱动表单视觉反馈,默认未开启,可以在 `_alain-custom-variables.scss` 增加 `$form-state-visual-feedback-enabled: true;`
+ 增加门店页
+ 增加 `_HttpClient`、`ModalHelper` 类
    + `_HttpClient` 简化请求以及更好的与 `[nzLoading]` 属性相配合
    + `ModalHelper` 简化打开与回调处理
+ 增加Modal相关样式,更便于自定义组件,见[CSS组件补丁类](./_documents/component-patch.md)
# 0.0.1-beta.3
+ **注** 允许通过 `_alain-custom-variables.scss` 覆盖 `styles` 属性值,例如:将内容区域背景色为白色。见 [升级目录结构](./_documents/upgrade.md)。
+ 增加 `yn`、`keys` 管道,见 [pipe文档](./_documents/pipe.md)
+ 增加 `badge` 样式
+ 升级 `angular-cli@4.4.1`、`ng-zorro-antd@0.5.1`
# 0.0.1-beta.2
+ 增加 `tree`、`sortable`、`sweetalert` 示例
# 0.0.1-beta.1
+ 增加顶部左右结构布局(替换 `header-left-right.component` 模板可以体验),新增 `.top-nav-wrap` 样式
+ 增加自定义样式风格目录结构
+ 增加利用 `environments` 使开发、生产设置不同参数(例如:后端地址)
+ 修复 `TokenService` 循环依赖问题
+ 重写模态框示例
+ 重写 `StartupService` 解决状态码处理BUG
+ 更新 `@angular/cli` 至最新版本,当前版本可能会存在 `licenses` BUG,可增加 ` --extract-licenses=false` 解决,抑或不升级
+ 优化样式目录结构
# 0.0.1-beta
+ 增加 `core`、`shared` 别名,允许通过 `@shared/shared.module` 访问 `SharedModule`
+ 增加顶部菜单栏 `.full` 样式,方便去掉搜索框菜单右对齐。
+ 修复首次加载菜单无法选中问题
+ 优化源代码包体大小,去掉 `ueditor` 示例、清除无效图像资源
+ 优化首次加载速度方法,仪表盘去掉延迟加载
+ 优化 `core/services` 目录结构
# 0.0.1-alpha.7
+ 增加TOKEN拦截器示例
+ 修复菜单有时出现重复选择问题,closes #8
+ 升级 `angular-cli`、`ng-zorro-antd` 至最新版本
+ 由于新版 `angular-cli` 对commonjs都必须指定一个名称,因此重写 `preloader` ( 并在 `main.ts` 中导入它)。
# 0.0.1-alpha.6
+ 新增应用启动,基础、菜单、用户数据由远程获取。
+ 新增ACL
+ 修复测试用例
+ 关闭 #6 #7
# 0.0.1-alpha.5
+ 新增若干小部件
+ 新增 `algin`、`img` 相关CSS工具类
+ 新增10*10种颜色CSS工具类
+ 升级 `ng-zorro-antd` 至最新版本
# 0.0.1-alpha.4
+ 新增G2图表
+ 移除未发布 `nz-avatar` antd补丁样式
+ 升级 `ng-zorro-antd` 至最新版本
+ 修复 [#1](https://github.com/cipchk/ng-alain/issues/1)
# 0.0.1-alpha.3
+ 新增路由守卫DEMO
+ 新增设置快捷入口
+ 新增 `nz-carousel` 指示点颜色补丁
+ 新增若干小部件
# 0.0.1-alpha.2
+ 新增 `.list-group` CSS组件
+ 新增 `_date`、`_currenty` Pipe
+ 新增扩展页:帮助中心、个人设置
+ 新增 component-patch.md pipe.md 说明
+ 修复顶部搜索框的 `nzFocus`、`nzBlur` 问题。
+ 调整 `color.service`、`scroll.service` 至 services 目录。
CONTRIBUTING.md
New file
@@ -0,0 +1,200 @@
# Contributing to ng-alain
We would love for you to contribute to ng-alain and help make it even better than it is
today! As a contributor, here are the guidelines we would like you to follow:
 - [Issues and Bugs](#issue)
 - [Feature Requests](#feature)
 - [Submission Guidelines](#submit)
 - [Coding Rules](#rules)
 - [Commit Message Guidelines](#commit)
## <a name="issue"></a> Found a Bug?
If you find a bug in the source code, you can help us by
[submitting an issue](#submit-issue) to our [GitHub Repository][github]. Even better, you can
[submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Missing a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to our GitHub
Repository. If you would like to *implement* a new feature, please submit an issue with
a  for your work first, to be sure that we can use it.
Please consider what kind of change it is:
* For a **Major Feature**, first open an issue and outline your proposal so that it can be
discussed. This will also allow us to better coordinate our efforts, prevent duplication of work,
and help you to craft the change so that it is successfully accepted into the project.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a minimal reproduction scenario using http://plnkr.co. Having a live, reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:
- version of ng-alain used
- 3rd-party libraries and their versions
- and most importantly - a use-case that fails
A minimal reproduce scenario using http://plnkr.co/ allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem. If plunker is not a suitable way to demonstrate the problem (for example for issues related to our npm packaging), please create a standalone git repository demonstrating the problem.
We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. Interestingly, from our experience users often find coding problems themselves while preparing a minimal plunk. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.
Unfortunately we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that don't have enough info to be reproduced.
You can file new issues by filling out our [new issue form](https://github.com/cipchk/ng-alain/issues/new).
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
* Search [GitHub](https://github.com/cipchk/ng-alain/pulls) for an open or closed PR
  that relates to your submission. You don't want to duplicate effort.
* Make your changes in a new git branch:
     ```shell
     git checkout -b my-fix-branch master
     ```
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Run the full ng-alain test suite <!-- , as described in the [developer documentation][dev-doc] -->, and ensure that all tests pass.
* Commit your changes using a descriptive commit message that follows our
  [commit message conventions](#commit). Adherence to these conventions
  is necessary because release notes are automatically generated from these messages.
     ```shell
     git commit -a
     ```
  Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Push your branch to GitHub:
    ```shell
    git push origin my-fix-branch
    ```
* In GitHub, send a pull request to `ng-alain:master`.
* If we suggest changes then:
  * Make the required updates.
  * Re-run the ng-alain test suites to ensure tests are still passing.
  * Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
    ```shell
    git rebase master -i
    git push -f
    ```
That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
    ```shell
    git push origin --delete my-fix-branch
    ```
* Check out the master branch:
    ```shell
    git checkout master -f
    ```
* Delete the local branch:
    ```shell
    git branch -D my-fix-branch
    ```
* Update your master with the latest upstream version:
    ```shell
    git pull --ff upstream master
    ```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more specs (unit-tests).
* All public API methods **must be documented**.
## <a name="commit"></a> Commit Message Guidelines
We have very precise rules over how our git commit messages can be formatted.  This leads to **more
readable messages** that are easy to follow when looking through the **project history**.  But also,
we use the git commit messages to **generate the ng-alain change log**.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**.  The header has a special
format that includes a **type**, a **scope** and a **subject**:
```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
Footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.
Samples: (even more [samples](https://github.com/cipchk/ng-alain/commits/master))
```
docs(changelog): update change log to beta.5
```
```
fix(release): need to depend on latest rxjs and zone.js
The version in our package.json gets copied to the one we publish, and users need the latest of these.
```
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
* **docs**: Documentation only changes
* **feat**: A new feature
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* **test**: Adding missing tests or correcting existing tests
### Subject
The subject contains succinct description of the change:
* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end
### Body
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[github]: https://github.com/cipchk/ng-alain
[plunker]: http://plnkr.co/edit
Dockerfile
New file
@@ -0,0 +1,27 @@
# STEP 1: Build
FROM node:8-alpine as builder
LABEL authors="cipchk <cipchk@qq.com>"
COPY package.json package-lock.json ./
RUN npm set progress=false && npm config set depth 0 && npm cache clean --force
RUN npm i && mkdir /ng-alain && cp -R ./node_modules ./ng-alain
WORKDIR /ng-alain
COPY . .
RUN npm run build
# STEP 2: Setup
FROM nginx:1.13.5-alpine
COPY --from=builder /ng-alain/_nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /ng-alain/_nginx/ssl/* /etc/nginx/ssl/
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /ng-alain/dist /usr/share/nginx/html
CMD [ "nginx", "-g", "daemon off;"]
LICENSE
New file
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 卡色
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
README-zh_CN.md
New file
@@ -0,0 +1,107 @@
[![Build Status](https://travis-ci.org/cipchk/ng-alain.svg?branch=master)](https://travis-ci.org/cipchk/ng-alain)
[![Dependency Status](https://david-dm.org/cipchk/ng-alain/status.svg)](https://david-dm.org/cipchk/ng-alain)
[![NPM version](https://img.shields.io/npm/v/ng-alain.svg)](https://www.npmjs.com/package/ng-alain)
# ng-alain
一套基于 [Ng-zorro-antd](https://github.com/NG-ZORRO/ng-zorro-antd)【ANT DESIGN】 的企业后台模板。
[README in English](README.md)
[DEMO](https://cipchk.github.io/ng-alain/)
## 快速入门
确保 `node` 版本 >= 6.9.0 且 `npm` 版本 >= 3 以上。
`ng-alain` 本身并非组件库,只是一个单纯的企业后台模板,你可以**直接克隆**到你的本地,然后立即进入实际开发。
```bash
# clone a blank ng-alain repo, just only basic function
#   --depth 1 removes all but one .git commit history
git clone -b blank --depth 1 https://github.com/cipchk/ng-alain.git
# or full master branch
git clone --depth 1 https://github.com/cipchk/ng-alain.git
# change directory
cd ng-alain
# install npm package
npm install
# in china please use cnpm (https://github.com/cnpm/cnpm)
# cnpm install
# start the serve
npm start
# use HMR
npm run serve:hmr
```
> [vscode] 建议安装 [ng-zorro-vscode](https://marketplace.visualstudio.com/items?itemName=cipchk.ng-zorro-vscode) 插件,含 `nz-alain-*` 代码片断。
## Links
+ [文档](http://ng-alain.com)
+ [@delon](https://github.com/cipchk/delon)
+ [DEMO](https://cipchk.github.io/ng-alain/)
## Delon
[delong](https://github.com/cipchk/delon) 是基于 Ant Design 设计理念的企业级中后台前端业务型组件库。
[![Build Status](https://travis-ci.org/cipchk/delon.svg?branch=master)](https://travis-ci.org/cipchk/delon)
[![Dependency Status](https://david-dm.org/cipchk/delon/status.svg)](https://david-dm.org/cipchk/delon)
[![DevDependency Status](https://david-dm.org/cipchk/delon/dev-status.svg)](https://david-dm.org/cipchk/delon?type=dev)
[![npm](https://img.shields.io/npm/l/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme)
[![npm](https://img.shields.io/npm/dm/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme)
| package name | version | next version |
| ------------ |:-----:|:----------:|
| @delon/theme | [![NPM version](https://img.shields.io/npm/v/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme) | [![NPM version](https://img.shields.io/npm/v/@delon/theme/next.svg)](https://www.npmjs.com/package/@delon/theme) |
| @delon/abc | [![NPM version](https://img.shields.io/npm/v/@delon/abc.svg)](https://www.npmjs.com/package/@delon/abc) | [![NPM version](https://img.shields.io/npm/v/@delon/abc/next.svg)](https://www.npmjs.com/package/@delon/abc) |
| @delon/acl | [![NPM version](https://img.shields.io/npm/v/@delon/acl.svg)](https://www.npmjs.com/package/@delon/acl) | [![NPM version](https://img.shields.io/npm/v/@delon/acl/next.svg)](https://www.npmjs.com/package/@delon/acl) |
| @delon/auth | [![NPM version](https://img.shields.io/npm/v/@delon/auth.svg)](https://www.npmjs.com/package/@delon/auth) | [![NPM version](https://img.shields.io/npm/v/@delon/auth/next.svg)](https://www.npmjs.com/package/@delon/auth) |
| @delon/mock | [![NPM version](https://img.shields.io/npm/v/@delon/mock.svg)](https://www.npmjs.com/package/@delon/mock) | [![NPM version](https://img.shields.io/npm/v/@delon/mock/next.svg)](https://www.npmjs.com/package/@delon/mock) |
| @delon/cache | - | [![NPM version](https://img.shields.io/npm/v/@delon/cache/next.svg)](https://www.npmjs.com/package/@delon/cache) |
| @delon/cli | - | [![NPM version](https://img.shields.io/npm/v/@delon/cli/next.svg)](https://www.npmjs.com/package/@delon/cli) |
## Architecture
![Architecture](https://github.com/cipchk/delon/blob/master/_screenshot/architecture.png)
## 特性
+ 基于 `ng-zorro-antd`
+ 响应式
+ 国际化
+ ACL访问控制
+ 延迟加载及良好的启用画面
+ 良好的UI路由设计
+ 十种颜色版本
+ Less预编译
+ 良好的目录组织结构
+ 简单升级
+ 模块热替换
+ 支持[Docker](_documents/docker.md)部署
## 应用截图
![desktop](https://github.com/cipchk/delon/blob/master/_screenshot/desktop.png)
![ipad](https://github.com/cipchk/delon/blob/master/_screenshot/ipad.png)
![iphone](https://github.com/cipchk/delon/blob/master/_screenshot/iphone.png)
## Troubleshooting
Please follow this guidelines when reporting bugs and feature requests:
1. Use [GitHub Issues](https://github.com/cipchk/ng-alain/issues) board to report bugs and feature requests (not our email address)
2. Please **always** write steps to reproduce the error. That way we can focus on fixing the bug, not scratching our heads trying to reproduce it.
Thanks for understanding!
### License
The MIT License (see the [LICENSE](https://github.com/cipchk/ng-alain/blob/master/LICENSE) file for the full text)
README.md
@@ -1,27 +1,104 @@
# ScreenFrontend
[![Build Status](https://travis-ci.org/cipchk/ng-alain.svg?branch=master)](https://travis-ci.org/cipchk/ng-alain)
[![Dependency Status](https://david-dm.org/cipchk/ng-alain/status.svg)](https://david-dm.org/cipchk/ng-alain)
[![NPM version](https://img.shields.io/npm/v/ng-alain.svg)](https://www.npmjs.com/package/ng-alain)
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.0.
# ng-alain
## Development server
[Ng-zorro-antd](https://github.com/NG-ZORRO/ng-zorro-antd) admin panel front-end framework.
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
更多信息见[中文 README](README-zh_CN.md)
## Code scaffolding
[DEMO](https://cipchk.github.io/ng-alain/)
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Quick start
## Build
Make sure you have Node version >= 6.9.0 and NPM >= 3 or higher.
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
```bash
# clone a blank ng-alain repo, just only basic function
#   --depth 1 removes all but one .git commit history
git clone -b blank --depth 1 https://github.com/cipchk/ng-alain.git
# or full master branch
git clone --depth 1 https://github.com/cipchk/ng-alain.git
## Running unit tests
# change directory
cd ng-alain
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
# install npm package
npm install
# in china please use cnpm (https://github.com/cnpm/cnpm)
# cnpm install
## Running end-to-end tests
# start the serve
npm start
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
# use HMR
npm run serve:hmr
```
## Further help
> [vscode] recommended install [ng-zorro-vscode](https://marketplace.visualstudio.com/items?itemName=cipchk.ng-zorro-vscode) plugins, that includes `nz-alain-*` snippets.
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
## Links
+ [Document](http://ng-alain.com)
+ [@delon](https://github.com/cipchk/delon)
+ [DEMO](https://cipchk.github.io/ng-alain/)
## Delon
[delong](https://github.com/cipchk/delon) is a production-ready solution for admin business components packages, Built on the design principles developed by Ant Design.
[![Build Status](https://travis-ci.org/cipchk/delon.svg?branch=master)](https://travis-ci.org/cipchk/delon)
[![Dependency Status](https://david-dm.org/cipchk/delon/status.svg)](https://david-dm.org/cipchk/delon)
[![DevDependency Status](https://david-dm.org/cipchk/delon/dev-status.svg)](https://david-dm.org/cipchk/delon?type=dev)
[![npm](https://img.shields.io/npm/l/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme)
[![npm](https://img.shields.io/npm/dm/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme)
| package name | version | next version |
| ------------ |:-----:|:----------:|
| @delon/theme | [![NPM version](https://img.shields.io/npm/v/@delon/theme.svg)](https://www.npmjs.com/package/@delon/theme) | [![NPM version](https://img.shields.io/npm/v/@delon/theme/next.svg)](https://www.npmjs.com/package/@delon/theme) |
| @delon/abc | [![NPM version](https://img.shields.io/npm/v/@delon/abc.svg)](https://www.npmjs.com/package/@delon/abc) | [![NPM version](https://img.shields.io/npm/v/@delon/abc/next.svg)](https://www.npmjs.com/package/@delon/abc) |
| @delon/acl | [![NPM version](https://img.shields.io/npm/v/@delon/acl.svg)](https://www.npmjs.com/package/@delon/acl) | [![NPM version](https://img.shields.io/npm/v/@delon/acl/next.svg)](https://www.npmjs.com/package/@delon/acl) |
| @delon/auth | [![NPM version](https://img.shields.io/npm/v/@delon/auth.svg)](https://www.npmjs.com/package/@delon/auth) | [![NPM version](https://img.shields.io/npm/v/@delon/auth/next.svg)](https://www.npmjs.com/package/@delon/auth) |
| @delon/mock | [![NPM version](https://img.shields.io/npm/v/@delon/mock.svg)](https://www.npmjs.com/package/@delon/mock) | [![NPM version](https://img.shields.io/npm/v/@delon/mock/next.svg)](https://www.npmjs.com/package/@delon/mock) |
| @delon/cache | - | [![NPM version](https://img.shields.io/npm/v/@delon/cache/next.svg)](https://www.npmjs.com/package/@delon/cache) |
| @delon/cli | - | [![NPM version](https://img.shields.io/npm/v/@delon/cli/next.svg)](https://www.npmjs.com/package/@delon/cli) |
## Architecture
![Architecture](https://github.com/cipchk/delon/blob/master/_screenshot/architecture.png)
## Features
+ `ng-zorro-antd` based
+ Responsive Layout
+ I18n
+ ACL
+ Lazy load Assets
+ UI Router States
+ Multiple color options
+ Less preprocessor
+ Well organized & commented code
+ Simple upgrade
+ Hot Module Replacement
+ Support [Docker](_documents/docker.md) deploy
## App Shots
![desktop](https://github.com/cipchk/delon/blob/master/_screenshot/desktop.png)
![ipad](https://github.com/cipchk/delon/blob/master/_screenshot/ipad.png)
![iphone](https://github.com/cipchk/delon/blob/master/_screenshot/iphone.png)
## Troubleshooting
Please follow this guidelines when reporting bugs and feature requests:
1. Use [GitHub Issues](https://github.com/cipchk/ng-alain/issues) board to report bugs and feature requests (not our email address)
2. Please **always** write steps to reproduce the error. That way we can focus on fixing the bug, not scratching our heads trying to reproduce it.
Thanks for understanding!
### License
The MIT License (see the [LICENSE](https://github.com/cipchk/ng-alain/blob/master/LICENSE) file for the full text)
_mock/README.md
New file
@@ -0,0 +1 @@
[Document](http://ng-alain.com/docs/mock)
_mock/_api.ts
File was renamed from _mock/api.service.ts
@@ -1,3 +1,6 @@
import { MockRequest } from '@delon/mock';
// region: mock data
const titles = [
    'Alipay',
    'Angular',
@@ -48,7 +51,9 @@
    '仲尼'
];
export function getFakeList(count: number = 20): any[] {
// endregion
function getFakeList(count: number = 20): any[] {
    const list = [];
    for (let i = 0; i < count; i += 1) {
        list.push({
@@ -91,7 +96,7 @@
    return list;
}
export function getNotice(): any[] {
function getNotice(): any[] {
    return [
        {
          id: 'xxx1',
@@ -156,7 +161,7 @@
      ];
}
export function getActivities(): any[] {
function getActivities(): any[] {
    return  [
        {
          id: 'trend-1',
@@ -258,3 +263,9 @@
        },
      ];
}
export const APIS = {
    '/api/list': (req: MockRequest) => getFakeList(req.queryString.count),
    '/api/notice': () => getNotice(),
    '/api/activities': () => getActivities()
};
_mock/_chart.ts
File was renamed from _mock/chart.service.ts
@@ -1,8 +1,9 @@
// tslint:disable
import * as Mock from 'mockjs';
import * as moment from "moment";
// mock data
// region: mock data
const visitData = [];
const beginDay = new Date().getTime();
@@ -185,19 +186,23 @@
    });
});
export const getFakeChartData = {
    visitData,
    visitData2,
    salesData,
    searchData,
    offlineData,
    offlineChartData,
    salesTypeData,
    salesTypeDataOnline,
    salesTypeDataOffline,
    radarData
};
// endregion
export default {
    getFakeChartData
export const CHARTS = {
    '/chart': Object.assign({}, {
        visitData,
        visitData2,
        salesData,
        searchData,
        offlineData,
        offlineChartData,
        salesTypeData,
        salesTypeDataOnline,
        salesTypeDataOffline,
        radarData
    }),
    '/chart/visit': Object.assign([], visitData),
    '/chart/tags': Mock.mock({
        'list|100': [{ name: '@city', 'value|1-100': 150, 'type|0-2': 1 }]
    })
};
_mock/_profile.ts
File was renamed from _mock/profile.service.ts
@@ -141,24 +141,8 @@
    },
];
export function getProfileBasicData() {
    return {
        basicGoods: basicGoods,
        basicProgress: basicProgress
    };
}
export function getProfileAdvancedData() {
    return {
        advancedOperation1: advancedOperation1,
        advancedOperation2: advancedOperation2,
        advancedOperation3: advancedOperation3
    };
}
export function getProfileDefault() {
    return {
        getProfileBasicData: getProfileBasicData,
        getProfileAdvancedData: getProfileAdvancedData
    };
}
export const PROFILES = {
    'GET /profile/progress': basicProgress,
    'GET /profile/goods': basicGoods,
    'GET /profile/advanced': { advancedOperation1, advancedOperation2, advancedOperation3 }
};
_mock/_rule.ts
File was renamed from _mock/rule.service.ts
@@ -1,3 +1,6 @@
import { HttpRequest } from '@angular/common/http';
import { MockRequest } from '@delon/mock';
const list = [];
for (let i = 0; i < 46; i += 1) {
@@ -18,7 +21,7 @@
    });
}
export function getRule(params: any) {
function getRule(params: any) {
    let ret = [...list];
    if (params.sorter) {
        const s = params.sorter.split('_');
@@ -38,16 +41,15 @@
    return ret;
}
export function removeRule(no: string): boolean {
    const idx = list.findIndex(w => w.no === no);
    if (idx !== -1) {
        list.splice(idx, 1);
        return true;
    }
    return false;
function removeRule(nos: string): boolean {
    nos.split(',').forEach(no => {
        const idx = list.findIndex(w => w.no === no);
        if (idx !== -1) list.splice(idx, 1);
    });
    return true;
}
export function saveRule(description: string) {
function saveRule(description: string) {
    const i = Math.ceil(Math.random() * 10000);
    list.unshift({
      key: i,
@@ -64,3 +66,9 @@
      progress: Math.ceil(Math.random() * 100),
    });
}
export const RULES = {
    '/rule': (req: MockRequest) => getRule(req.queryString),
    'DELETE /rule': (req: MockRequest) => removeRule(req.queryString.nos),
    'POST /rule': (req: MockRequest) => saveRule(req.body.description)
};
_mock/index.ts
New file
@@ -0,0 +1,4 @@
export * from './_profile';
export * from './_rule';
export * from './_api';
export * from './_chart';
docker-compose.debug.yml
New file
@@ -0,0 +1,13 @@
version: '2.1'
services:
  ng-alain:
    image: ng-alain
    build: .
    environment:
      NODE_ENV: development
    ports:
      - 80:80
      - 9229:9229
    ## set your startup file here
    command: node --inspect app.js
docker-compose.yml
New file
@@ -0,0 +1,10 @@
version: '2.1'
services:
  ng-alain:
    image: ng-alain
    build: .
    environment:
      NODE_ENV: production
    ports:
      - 80:80
e2e/app.e2e-spec.ts
@@ -1,6 +1,6 @@
import { AppPage } from './app.po';
describe('screen-frontend App', () => {
describe('ng-alain App', () => {
  let page: AppPage;
  beforeEach(() => {
package-lock.json
File was deleted
package.json
@@ -1,6 +1,6 @@
{
  "name": "screen-frontend",
  "version": "1.0.0",
  "name": "ng-alain",
  "version": "0.6.0-rc.2",
  "description": "ng-zorro-antd admin panel front-end framework",
  "author": "cipchk",
  "homepage": "https://cipchk.github.io/ng-alain/",
@@ -24,8 +24,8 @@
    "lint:style": "stylelint \"{src}/**/*.less\" --syntax less",
    "lint-staged": "lint-staged",
    "e2e": "ng e2e",
    "test": "ng test -sr",
    "test-coverage": "ng test -sr -cc"
    "test": "ng test -sr -sm=false",
    "test-coverage": "ng test -sr -cc -sm=false"
  },
  "dependencies": {
    "@angular/animations": "^5.0.0",
@@ -37,30 +37,36 @@
    "@angular/platform-browser": "^5.0.0",
    "@angular/platform-browser-dynamic": "^5.0.0",
    "@angular/router": "^5.0.0",
    "@antv/data-set": "^0.7.0",
    "@antv/data-set": "^0.8.3",
    "@antv/g2": "^3.0.1",
    "@antv/g2-plugin-slider": "^2.0.0",
    "@delon/abc": "^0.3.0-rc.1",
    "@delon/acl": "^0.3.0-rc.1",
    "@delon/theme": "^0.3.0-rc.1",
    "@delon/auth": "^0.3.0-rc.1",
    "@delon/abc": "^0.6.0-rc.2",
    "@delon/acl": "^0.6.0-rc.2",
    "@delon/auth": "^0.6.0-rc.2",
    "@delon/theme": "^0.6.0-rc.2",
    "@delon/mock": "^0.6.0-rc.2",
    "@delon/cache": "^0.6.0-rc.2",
    "@ngx-translate/core": "^9.0.0",
    "@ngx-translate/http-loader": "^2.0.0",
    "angular-baidu-maps": "^1.0.1",
    "angular-qq-maps": "^1.0.1",
    "angular-tree-component": "^6.1.0",
    "angular-split": "^1.0.0-rc.0",
    "angular-tree-component": "^7.0.1",
    "core-js": "^2.5.1",
    "file-saver": "^1.3.3",
    "font-awesome": "^4.7.0",
    "moment": "^2.19.3",
    "ng-clipboard-antd": "^2.0.1",
    "ng-tree-antd": "^2.0.0",
    "ng-zorro-antd": "^0.6.5",
    "ng-zorro-antd-extra": "^1.1.3",
    "ng-zorro-antd-extra": "^1.1.6",
    "ng2-dnd": "^5.0.0",
    "ng2-file-upload": "^1.2.1",
    "ng2-img-cropper": "^0.9.0",
    "ngx-color-picker": "^5.0.0",
    "ngx-countdown": "^2.0.0",
    "ngx-tinymce": "^1.0.1",
    "ngx-ueditor": "^1.1.0",
    "rxjs": "^5.5.5",
    "screenfull": "^3.3.1",
    "simple-line-icons": "^2.4.1",
@@ -76,6 +82,7 @@
    "@angularclass/hmr-loader": "^3.0.4",
    "@types/jasmine": "~2.6.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/jszip": "^3.1.2",
    "@types/node": "~6.0.60",
    "codecov": "^3.0.0",
    "codelyzer": "~4.0.1",
@@ -97,7 +104,10 @@
    "ts-node": "~3.2.0",
    "tslint": "~5.7.0",
    "typescript": "~2.5.0",
    "webpack-bundle-analyzer": "^2.9.0"
    "webpack-bundle-analyzer": "^2.9.0",
    "mockjs": "^1.0.1-beta3",
    "@types/mockjs": "^1.0.0",
    "xlsx": "^0.11.16"
  },
  "lint-staged": {
    "src/**/*.ts": "lint:ts",
src/app/app.component.spec.ts
@@ -1,15 +1,13 @@
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { setUpTestBed } from '../testing/common.spec';
import { APP_BASE_HREF } from '@angular/common';
import { setUpTestBed } from '@testing/common.spec';
import { AppComponent } from './app.component';
import { APP_BASE_HREF } from '@angular/common';
import { ThemesService, TitleService } from '@delon/theme';
describe('Component: App', () => {
    setUpTestBed(<TestModuleMetadata>{
        declarations: [ AppComponent ],
        providers: [
            ThemesService, TitleService,
            { provide: APP_BASE_HREF, useValue: '/' }
        ]
    });
src/app/app.module.ts
@@ -1,27 +1,26 @@
import { DateService } from '@business/services/util/date.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, LOCALE_ID, APP_INITIALIZER, Injector } from '@angular/core';
import { HttpClient, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient, HTTP_INTERCEPTORS } from '@angular/common/http';
import { DelonModule } from './delon.module';
import { CoreModule } from './core/core.module';
import { SharedModule } from './shared/shared.module';
import { AppComponent } from './app.component';
import { RoutesModule } from './routes/routes.module';
import { LayoutModule } from './layout/layout.module';
import { StartupService } from './core/services/startup.service';
import { StartupService } from '@core/startup/startup.service';
import { DefaultInterceptor } from '@core/net/default.interceptor';
import { AlainAuthModule, SimpleInterceptor } from '@delon/auth';
// i18n
import { I18NService } from './core/i18n/i18n.service';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { SimpleInterceptor } from '@delon/auth';
// angular i18n
import { registerLocaleData } from '@angular/common';
import localeZhHans from '@angular/common/locales/zh-Hans';
registerLocaleData(localeZhHans);
// i18n
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { I18NService } from '@core/i18n/i18n.service';
// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient) {
@@ -39,14 +38,12 @@
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        SharedModule.forRoot(),
        HttpClientModule,
        DelonModule,
        CoreModule,
        SharedModule,
        LayoutModule,
        RoutesModule,
        // auth
        AlainAuthModule.forRoot({
            login_url: `/pro/user/login`
        }),
        // i18n
        TranslateModule.forRoot({
            loader: {
@@ -57,11 +54,11 @@
        })
    ],
    providers: [
        { provide: LOCALE_ID, useValue: 'zh-Hans' },
        { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true},
        { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true},
        { provide: LOCALE_ID, useValue: 'zh-Hans' },
        // TODO 暂时关闭登陆验证
        //{ provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true},
        { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true},
        { provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false },
        DateService,
        StartupService,
        {
            provide: APP_INITIALIZER,
src/app/core/README.md
New file
@@ -0,0 +1,5 @@
### CoreModule
**应** 仅只留 `providers` 属性。
**作用:**  一些通用服务,例如:用户消息、HTTP数据访问。
src/app/core/core.module.ts
@@ -1,16 +1,11 @@
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { throwIfAlreadyLoaded } from './module-import-guard';
import { AlainThemeModule } from '@delon/theme';
import { I18NService } from './i18n/i18n.service';
import { _HttpClient } from '@delon/theme/services/http/http.client';
@NgModule({
    imports: [
       AlainThemeModule.forRoot()
    ],
    providers: [
        I18NService, _HttpClient
        I18NService
    ]
})
export class CoreModule {
src/app/core/i18n/i18n.service.spec.ts
@@ -1,4 +1,3 @@
import { SharedModule } from '@shared/shared.module';
import { TestBed, async, inject } from '@angular/core/testing';
import { TranslateService, TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { HttpClient, HttpClientModule } from '@angular/common/http';
@@ -6,13 +5,16 @@
import { I18NService } from './i18n.service';
import { HttpLoaderFactory } from '../../app.module';
import { SettingsService } from '@delon/theme';
import { DelonModule } from '../../delon.module';
import { SharedModule } from '@shared/shared.module';
describe('Service: I18n', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                HttpClientModule,
                SharedModule.forRoot(),
                DelonModule,
                SharedModule,
                TranslateModule.forRoot({
                    loader: {
                        provide: TranslateLoader,
src/app/core/i18n/i18n.service.ts
@@ -8,24 +8,25 @@
@Injectable()
export class I18NService implements AlainI18NService {
    private _default = 'en';
    private _default = 'zh-CN';
    private _langs = [
        { code: 'zh-CN', text: '中文' },
        { code: 'en', text: 'English' }
    ];
    constructor(settings: SettingsService,
    constructor(
        settings: SettingsService,
        private nzLocalService: NzLocaleService,
        private translate: TranslateService,
        private injector: Injector) {
        private injector: Injector
    ) {
        this._default = settings.layout.lang || translate.getBrowserLang();
        const lans = this._langs.map(item => item.code);
        if (!lans.includes(this._default)) {
            this._default = lans[0];
        }
        translate.addLangs(lans);
        translate.setDefaultLang(this._default);
    }
    use(lang: string = null, firstLoad = true): Observable<any> {
@@ -35,13 +36,20 @@
        if (!firstLoad) this.injector.get(Router).navigate([ '/' ]);
        return this.translate.use(lang);
    }
    /** 获取语言列表 */
    getLangs() {
        return this._langs;
    }
    /** 翻译 */
    fanyi(key: string) {
        return this.translate.instant(key);
    }
    /** 默认语言 */
    get defaultLang() {
        return this._default;
    }
    /** 当前语言 */
    get currentLang() {
        return this.translate.currentLang || this.translate.getDefaultLang() || this._default;
    }
}
src/app/core/net/default.interceptor.ts
@@ -7,8 +7,7 @@
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { catchError } from 'rxjs/operators';
import { map, mergeMap } from 'rxjs/operators';
import { environment } from '../../../environments/environment';
import { environment } from '@env/environment';
/**
 * 默认HTTP拦截器,其注册细节见 `app.module.ts`
@@ -27,13 +26,12 @@
        // TIPS:原TOKEN信息已交由 `@delon/auth` 处理
        // Document: http://ng-alain.com/docs/auth
        // 统一加上服务端前缀
        let url = req.url;
        if (!url.startsWith('https://') && !url.startsWith('http://')) {
            url = environment.SERVER_URL + url;
        }
        const newReq = req.clone({
            url: url
        });
src/app/core/services/startup.service.ts
File was deleted
src/app/core/startup/startup.service.ts
New file
@@ -0,0 +1,57 @@
import { Injectable, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { zip } from 'rxjs/observable/zip';
import { TranslateService } from '@ngx-translate/core';
import { MenuService, SettingsService, TitleService } from '@delon/theme';
import { ACLService } from '@delon/acl';
import { I18NService } from '../i18n/i18n.service';
/**
 * 用于应用启动时
 * 一般用来获取应用所需要的基础数据等
 */
@Injectable()
export class StartupService {
    constructor(
        private menuService: MenuService,
        private translate: TranslateService,
        private i18n: I18NService,
        private settingService: SettingsService,
        private aclService: ACLService,
        private titleService: TitleService,
        private httpClient: HttpClient,
        private injector: Injector) { }
    load(): Promise<any> {
        // only works with promises
        // https://github.com/angular/angular/issues/15088
        return new Promise((resolve, reject) => {
            zip(
                this.httpClient.get(`assets/i18n/${this.i18n.defaultLang}.json`),
                this.httpClient.get('assets/app-data.json'),
            ).subscribe(([langData, appData]) => {
                // setting language data
                this.translate.setTranslation(this.i18n.defaultLang, langData);
                this.translate.setDefaultLang(this.i18n.defaultLang);
                // application data
                const res: any = appData;
                // 应用信息:包括站点名、描述、年份
                this.settingService.setApp(res.app);
                // 用户信息:包括姓名、头像、邮箱地址
                this.settingService.setUser(res.user);
                // ACL:设置权限为全量
                this.aclService.setFull(true);
                // 初始化菜单
                this.menuService.add(res.menu);
                // 设置页面标题的后缀
                this.titleService.suffix = res.app.name;
                resolve(res);
            }, (err: HttpErrorResponse) => {
                resolve(null);
            });
        });
    }
}
src/app/delon.module.ts
New file
@@ -0,0 +1,208 @@
/**
 * 进一步对基础模块的导入提炼
 * 有关模块注册指导原则请参考:https://github.com/cipchk/ng-alain/issues/180
 */
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { throwIfAlreadyLoaded } from '@core/module-import-guard';
// region: zorro modules
import {
    // LoggerModule,
    // NzLocaleModule,
    NzButtonModule,
    NzAlertModule,
    NzBadgeModule,
    // NzCalendarModule,
    NzCascaderModule,
    NzCheckboxModule,
    NzDatePickerModule,
    NzFormModule,
    NzInputModule,
    NzInputNumberModule,
    NzGridModule,
    NzMessageModule,
    NzModalModule,
    NzNotificationModule,
    NzPaginationModule,
    NzPopconfirmModule,
    NzPopoverModule,
    NzRadioModule,
    NzRateModule,
    NzSelectModule,
    NzSpinModule,
    NzSliderModule,
    NzSwitchModule,
    NzProgressModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzTimePickerModule,
    NzUtilModule,
    NzStepsModule,
    NzDropDownModule,
    NzMenuModule,
    NzBreadCrumbModule,
    NzLayoutModule,
    NzRootModule,
    NzCarouselModule,
    // NzCardModule,
    NzCollapseModule,
    NzTimelineModule,
    NzToolTipModule,
    // NzBackTopModule,
    // NzAffixModule,
    // NzAnchorModule,
    NzAvatarModule,
    // SERVICES
    NzNotificationService,
    NzMessageService
} from 'ng-zorro-antd';
export const ZORROMODULES = [
    // LoggerModule,
    // NzLocaleModule,
    NzButtonModule,
    NzAlertModule,
    NzBadgeModule,
    // NzCalendarModule,
    NzCascaderModule,
    NzCheckboxModule,
    NzDatePickerModule,
    NzFormModule,
    NzInputModule,
    NzInputNumberModule,
    NzGridModule,
    NzMessageModule,
    NzModalModule,
    NzNotificationModule,
    NzPaginationModule,
    NzPopconfirmModule,
    NzPopoverModule,
    NzRadioModule,
    NzRateModule,
    NzSelectModule,
    NzSpinModule,
    NzSliderModule,
    NzSwitchModule,
    NzProgressModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzTimePickerModule,
    NzUtilModule,
    NzStepsModule,
    NzDropDownModule,
    NzMenuModule,
    NzBreadCrumbModule,
    NzLayoutModule,
    NzRootModule,
    NzCarouselModule,
    // NzCardModule,
    NzCollapseModule,
    NzTimelineModule,
    NzToolTipModule,
    // NzBackTopModule,
    // NzAffixModule,
    // NzAnchorModule,
    NzAvatarModule
];
// endregion
// region: @delon/abc modules
import {
    AdSimpleTableModule,
    AdReuseTabModule,
    AdAvatarListModule,
    AdChartsModule,
    AdCountDownModule,
    AdDescListModule,
    AdEllipsisModule,
    AdErrorCollectModule,
    AdExceptionModule,
    AdFooterToolbarModule,
    AdGlobalFooterModule,
    AdNoticeIconModule,
    AdNumberInfoModule,
    AdProHeaderModule,
    AdResultModule,
    AdSidebarNavModule,
    AdStandardFormRowModule,
    AdTagSelectModule,
    AdTrendModule,
    AdDownFileModule,
    AdImageModule,
    AdUtilsModule,
    AdFullContentModule,
    AdXlsxModule,
    AdZipModule
} from '@delon/abc';
export const ABCMODULES = [
    AdSimpleTableModule,
    AdReuseTabModule,
    AdAvatarListModule,
    AdChartsModule,
    AdCountDownModule,
    AdDescListModule,
    AdEllipsisModule,
    AdErrorCollectModule,
    AdExceptionModule,
    AdFooterToolbarModule,
    AdGlobalFooterModule,
    AdNoticeIconModule,
    AdNumberInfoModule,
    AdProHeaderModule,
    AdResultModule,
    AdSidebarNavModule,
    AdStandardFormRowModule,
    AdTagSelectModule,
    AdTrendModule,
    AdDownFileModule,
    AdImageModule,
    AdUtilsModule,
    AdFullContentModule,
    AdXlsxModule,
    AdZipModule
];
// endregion
import { NgZorroAntdModule } from 'ng-zorro-antd';
import { NgZorroAntdExtraModule } from 'ng-zorro-antd-extra';
import { AlainThemeModule } from '@delon/theme';
import { AlainABCModule } from '@delon/abc';
import { AlainAuthModule } from '@delon/auth';
import { AlainACLModule } from '@delon/acl';
import { DelonCacheModule } from '@delon/cache';
// mock
import { DelonMockModule } from '@delon/mock';
import * as MOCKDATA from '../../_mock';
import { environment } from '@env/environment';
const MOCKMODULE = !environment.production || environment.chore === true ?
                    [ DelonMockModule.forRoot({ data: MOCKDATA }) ] : [];
@NgModule({
    imports: [
        NgZorroAntdModule.forRoot(),
        NgZorroAntdExtraModule.forRoot(),
        // theme
        AlainThemeModule.forRoot(),
        // abc
        AlainABCModule.forRoot(),
        // auth
        AlainAuthModule.forRoot({
            // ignores: [ `\\/login`, `assets\\/` ],
            login_url: `/passport/login`,
            allow_anonymous_key: `_allow_anonymous`
        }),
        // acl
        AlainACLModule.forRoot(),
        // cache
        DelonCacheModule.forRoot(),
        // mock
        ...MOCKMODULE
    ]
})
export class DelonModule {
  constructor( @Optional() @SkipSelf() parentModule: DelonModule) {
    throwIfAlreadyLoaded(parentModule, 'DelonModule');
  }
}
src/app/layout/default/default.component.html
File was renamed from src/app/layout/layout.component.html
@@ -2,5 +2,8 @@
    <div class="router-progress-bar" *ngIf="isFetching"></div>
    <app-header class="header"></app-header>
    <app-sidebar class="aside"></app-sidebar>
    <section class="content"><router-outlet></router-outlet></section>
    <section class="content">
        <reuse-tab></reuse-tab>
        <router-outlet></router-outlet>
    </section>
</div>
src/app/layout/default/default.component.spec.ts
New file
@@ -0,0 +1,17 @@
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { setUpTestBed } from '@testing/common.spec';
import { LayoutDefaultComponent } from './default.component';
describe('Layout', () => {
    setUpTestBed(<TestModuleMetadata>{
        declarations: [LayoutDefaultComponent]
    });
    it('should create an instance', () => {
        const fixture = TestBed.createComponent(LayoutDefaultComponent);
        const comp = fixture.debugElement.componentInstance;
        expect(comp).toBeTruthy();
    });
});
src/app/layout/default/default.component.ts
File was renamed from src/app/layout/layout.component.ts
@@ -4,10 +4,10 @@
import { ScrollService, MenuService, SettingsService } from '@delon/theme';
@Component({
    selector: 'app-layout',
    templateUrl: './layout.component.html'
    selector: 'layout-default',
    templateUrl: './default.component.html'
})
export class LayoutComponent {
export class LayoutDefaultComponent {
    isFetching = false;
    constructor(
src/app/layout/default/header/components/fullscreen.component.ts
File was renamed from src/app/layout/header/components/fullscreen.component.ts
@@ -5,7 +5,7 @@
    selector: 'header-fullscreen',
    template: `
    <i class="anticon anticon-{{status ? 'shrink' : 'arrows-alt'}}"></i>
    {{status ? 'fullscreen-exit' : 'fullscreen' | translate }}
    {{(status ? 'fullscreen-exit' : 'fullscreen') | translate }}
    `
})
export class HeaderFullScreenComponent {
src/app/layout/default/header/components/icon.component.ts
src/app/layout/default/header/components/langs.component.ts
src/app/layout/default/header/components/notify.component.ts
src/app/layout/default/header/components/search.component.ts
src/app/layout/default/header/components/storage.component.ts
src/app/layout/default/header/components/task.component.ts
src/app/layout/default/header/components/theme.component.ts
src/app/layout/default/header/components/user.component.ts
File was renamed from src/app/layout/header/components/user.component.ts
@@ -30,6 +30,7 @@
        this.tokenService.change().subscribe((res: any) => {
            this.settings.setUser(res);
        });
        // mock
        const token = this.tokenService.get() || {
            token: 'nothing',
            name: 'Admin',
@@ -41,6 +42,6 @@
    logout() {
        this.tokenService.clear();
        this.router.navigateByUrl('/pro/user/login');
        this.router.navigateByUrl(this.tokenService.login_url);
    }
}
src/app/layout/default/header/header.component.html
File was renamed from src/app/layout/header/header.component.html
@@ -20,7 +20,7 @@
        </li>
        <!-- Lock Page -->
        <li class="hidden-xs">
            <div class="item" [routerLink]="['/lock']">
            <div class="item" [routerLink]="['/pages/lock']">
                <i class="anticon anticon-lock"></i>
            </div>
        </li>
src/app/layout/default/header/header.component.spec.ts
File was renamed from src/app/layout/header/header.component.spec.ts
@@ -1,6 +1,5 @@
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { setUpTestBed } from 'testing/common.spec';
import { setUpTestBed } from '@testing/common.spec';
import { HeaderComponent } from './header.component';
src/app/layout/default/header/header.component.ts
src/app/layout/default/header/index.md
src/app/layout/default/sidebar/sidebar.component.html
src/app/layout/default/sidebar/sidebar.component.spec.ts
File was renamed from src/app/layout/sidebar/sidebar.component.spec.ts
@@ -1,5 +1,5 @@
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { setUpTestBed } from '../../../testing/common.spec';
import { setUpTestBed } from '@testing/common.spec';
import { SidebarComponent } from './sidebar.component';
src/app/layout/default/sidebar/sidebar.component.ts
src/app/layout/fullscreen/fullscreen.component.ts
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
@Component({
    selector: 'app-layout-fullscreen',
    selector: 'layout-fullscreen',
    templateUrl: './fullscreen.component.html'
})
export class LayoutFullScreenComponent {
src/app/layout/layout.component.spec.ts
File was deleted
src/app/layout/layout.module.ts
@@ -1,22 +1,22 @@
import { NgModule } from '@angular/core';
import { SharedModule } from '@shared/shared.module';
import { LayoutComponent } from './layout.component';
import { LayoutDefaultComponent } from './default/default.component';
import { LayoutFullScreenComponent } from './fullscreen/fullscreen.component';
import { HeaderComponent } from './header/header.component';
import { SidebarComponent } from './sidebar/sidebar.component';
import { HeaderSearchComponent } from './header/components/search.component';
import { HeaderThemeComponent } from './header/components/theme.component';
import { HeaderNotifyComponent } from './header/components/notify.component';
import { HeaderTaskComponent } from './header/components/task.component';
import { HeaderIconComponent } from './header/components/icon.component';
import { HeaderFullScreenComponent } from './header/components/fullscreen.component';
import { HeaderLangsComponent } from './header/components/langs.component';
import { HeaderStorageComponent } from './header/components/storage.component';
import { HeaderUserComponent } from './header/components/user.component';
import { HeaderComponent } from './default/header/header.component';
import { SidebarComponent } from './default/sidebar/sidebar.component';
import { HeaderSearchComponent } from './default/header/components/search.component';
import { HeaderThemeComponent } from './default/header/components/theme.component';
import { HeaderNotifyComponent } from './default/header/components/notify.component';
import { HeaderTaskComponent } from './default/header/components/task.component';
import { HeaderIconComponent } from './default/header/components/icon.component';
import { HeaderFullScreenComponent } from './default/header/components/fullscreen.component';
import { HeaderLangsComponent } from './default/header/components/langs.component';
import { HeaderStorageComponent } from './default/header/components/storage.component';
import { HeaderUserComponent } from './default/header/components/user.component';
const COMPONENTS = [
    LayoutComponent,
    LayoutDefaultComponent,
    LayoutFullScreenComponent,
    HeaderComponent,
    SidebarComponent
@@ -34,10 +34,10 @@
    HeaderUserComponent
];
// pro
import { ProUserLayoutComponent } from './pro/user/user.component';
const PRO = [
    ProUserLayoutComponent
// passport
import { LayoutPassportComponent } from './passport/passport.component';
const PASSPORT = [
    LayoutPassportComponent
];
@NgModule({
@@ -46,11 +46,11 @@
    declarations: [
        ...COMPONENTS,
        ...HEADERCOMPONENTS,
        ...PRO
        ...PASSPORT
    ],
    exports: [
        ...COMPONENTS,
        ...PRO
        ...PASSPORT
    ]
})
export class LayoutModule { }
src/app/layout/passport/passport.component.html
src/app/layout/passport/passport.component.less
src/app/layout/passport/passport.component.ts
File was renamed from src/app/layout/pro/user/user.component.ts
@@ -1,11 +1,11 @@
import { Component } from '@angular/core';
@Component({
    selector: 'pro-user-layout',
    templateUrl: './user.component.html',
    styleUrls: ['./user.component.less']
    selector: 'layout-passport',
    templateUrl: './passport.component.html',
    styleUrls: ['./passport.component.less']
})
export class ProUserLayoutComponent {
export class LayoutPassportComponent {
    links = [
        {
            title: '帮助',
src/app/routes/dashboard/analysis/analysis.component.ts
@@ -1,7 +1,8 @@
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { getTimeDistance, yuan } from '@delon/abc';
import { getFakeChartData } from '../../../../../_mock/chart.service';
import { _HttpClient } from '@delon/theme';
@Component({
    selector: 'app-dashboard-analysis',
@@ -9,6 +10,7 @@
    styleUrls: ['./analysis.component.less']
})
export class DashboardAnalysisComponent implements OnInit {
    data: any = {
        salesData: [],
        offlineData: []
@@ -25,17 +27,18 @@
        };
    });
    constructor(public msg: NzMessageService) {}
    constructor(private http: _HttpClient, public msg: NzMessageService,
    private http2: HttpClient) {}
    ngOnInit() {
        setTimeout(() => {
            this.data = Object.assign({}, getFakeChartData);
            this.data.offlineData.forEach((item: any) => {
                item.chart = Object.assign([], getFakeChartData.offlineChartData);
        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();
        }, 500);
        });
    }
    setDate(type: any) {
src/app/routes/dashboard/monitor/monitor.component.ts
@@ -1,7 +1,8 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { zip } from 'rxjs/observable/zip';
import { getTimeDistance, yuan, fixedZero } from '@delon/abc';
import { getFakeChartData } from '../../../../../_mock/chart.service';
import { _HttpClient } from '@delon/theme';
@Component({
    selector: 'app-dashboard-monitor',
@@ -9,525 +10,26 @@
    styleUrls: ['./monitor.component.less']
})
export class DashboardMonitorComponent implements OnInit, OnDestroy {
    data: any = {
    };
    data: any = { };
    tags = [];
    loading = true;
    q: any = {
        start: null,
        end: null
    };
    // from [http://jsfiddle.net/uTSqT/12/]
    tags = [
        {
            'name': '阿里地区',
            'value': 99,
            'type': 2
        },
        {
            'name': '宝鸡市',
            'value': 17,
            'type': 0
        },
        {
            'name': '阿里地区',
            'value': 92,
            'type': 1
        },
        {
            'name': '七台河市',
            'value': 83,
            'type': 2
        },
        {
            'name': '铜仁市',
            'value': 79,
            'type': 1
        },
        {
            'name': '海南藏族自治州',
            'value': 92,
            'type': 1
        },
        {
            'name': '铜仁市',
            'value': 78,
            'type': 0
        },
        {
            'name': '大同市',
            'value': 86,
            'type': 0
        },
        {
            'name': '九江市',
            'value': 18,
            'type': 0
        },
        {
            'name': '鹤壁市',
            'value': 13,
            'type': 0
        },
        {
            'name': '泸州市',
            'value': 17,
            'type': 1
        },
        {
            'name': '白银市',
            'value': 52,
            'type': 2
        },
        {
            'name': '南京市',
            'value': 82,
            'type': 0
        },
        {
            'name': '北海市',
            'value': 3,
            'type': 2
        },
        {
            'name': '清远市',
            'value': 62,
            'type': 1
        },
        {
            'name': '邵阳市',
            'value': 38,
            'type': 1
        },
        {
            'name': '日喀则地区',
            'value': 35,
            'type': 2
        },
        {
            'name': '连云港市',
            'value': 62,
            'type': 2
        },
        {
            'name': '果洛藏族自治州',
            'value': 51,
            'type': 1
        },
        {
            'name': '黄南藏族自治州',
            'value': 50,
            'type': 1
        },
        {
            'name': '安顺市',
            'value': 94,
            'type': 1
        },
        {
            'name': '海外',
            'value': 95,
            'type': 0
        },
        {
            'name': '临夏回族自治州',
            'value': 37,
            'type': 1
        },
        {
            'name': '固原市',
            'value': 44,
            'type': 2
        },
        {
            'name': '澎湖县',
            'value': 49,
            'type': 0
        },
        {
            'name': '天津市',
            'value': 95,
            'type': 0
        },
        {
            'name': '上海市',
            'value': 1050,
            'type': 1
        },
        {
            'name': '湖州市',
            'value': 19,
            'type': 2
        },
        {
            'name': '克孜勒苏柯尔克孜自治州',
            'value': 86,
            'type': 0
        },
        {
            'name': '天津市',
            'value': 97,
            'type': 1
        },
        {
            'name': '宜宾市',
            'value': 42,
            'type': 2
        },
        {
            'name': '张家界市',
            'value': 11,
            'type': 1
        },
        {
            'name': '乐山市',
            'value': 19,
            'type': 0
        },
        {
            'name': '保定市',
            'value': 17,
            'type': 2
        },
        {
            'name': '重庆市',
            'value': 16,
            'type': 1
        },
        {
            'name': '海外',
            'value': 96,
            'type': 1
        },
        {
            'name': '韶关市',
            'value': 94,
            'type': 1
        },
        {
            'name': '嘉兴市',
            'value': 49,
            'type': 1
        },
        {
            'name': '来宾市',
            'value': 72,
            'type': 1
        },
        {
            'name': '晋城市',
            'value': 97,
            'type': 2
        },
        {
            'name': '日喀则地区',
            'value': 39,
            'type': 0
        },
        {
            'name': '哈尔滨市',
            'value': 92,
            'type': 1
        },
        {
            'name': '承德市',
            'value': 66,
            'type': 1
        },
        {
            'name': '临汾市',
            'value': 11,
            'type': 1
        },
        {
            'name': '防城港市',
            'value': 43,
            'type': 0
        },
        {
            'name': '日喀则地区',
            'value': 53,
            'type': 1
        },
        {
            'name': '铜陵市',
            'value': 9,
            'type': 1
        },
        {
            'name': '阳泉市',
            'value': 50,
            'type': 1
        },
        {
            'name': '金昌市',
            'value': 17,
            'type': 1
        },
        {
            'name': '防城港市',
            'value': 2,
            'type': 1
        },
        {
            'name': '铁岭市',
            'value': 93,
            'type': 0
        },
        {
            'name': '厦门市',
            'value': 3,
            'type': 1
        },
        {
            'name': '石嘴山市',
            'value': 21,
            'type': 1
        },
        {
            'name': '呼和浩特市',
            'value': 66,
            'type': 2
        },
        {
            'name': '内江市',
            'value': 45,
            'type': 1
        },
        {
            'name': '泉州市',
            'value': 36,
            'type': 2
        },
        {
            'name': '固原市',
            'value': 95,
            'type': 2
        },
        {
            'name': '巴音郭楞蒙古自治州',
            'value': 50,
            'type': 1
        },
        {
            'name': '湖州市',
            'value': 39,
            'type': 2
        },
        {
            'name': '澳门半岛',
            'value': 36,
            'type': 1
        },
        {
            'name': '玉树藏族自治州',
            'value': 18,
            'type': 1
        },
        {
            'name': '盐城市',
            'value': 86,
            'type': 1
        },
        {
            'name': '中卫市',
            'value': 33,
            'type': 1
        },
        {
            'name': '塔城地区',
            'value': 66,
            'type': 1
        },
        {
            'name': '常州市',
            'value': 41,
            'type': 0
        },
        {
            'name': '北京市',
            'value': 8,
            'type': 0
        },
        {
            'name': '伊春市',
            'value': 38,
            'type': 2
        },
        {
            'name': '信阳市',
            'value': 96,
            'type': 1
        },
        {
            'name': '曲靖市',
            'value': 52,
            'type': 1
        },
        {
            'name': '嘉义市',
            'value': 68,
            'type': 0
        },
        {
            'name': '抚顺市',
            'value': 20,
            'type': 2
        },
        {
            'name': '舟山市',
            'value': 50,
            'type': 2
        },
        {
            'name': '营口市',
            'value': 41,
            'type': 1
        },
        {
            'name': '屏东县',
            'value': 26,
            'type': 1
        },
        {
            'name': '重庆市',
            'value': 58,
            'type': 1
        },
        {
            'name': '齐齐哈尔市',
            'value': 80,
            'type': 1
        },
        {
            'name': '北海市',
            'value': 70,
            'type': 1
        },
        {
            'name': '双鸭山市',
            'value': 18,
            'type': 0
        },
        {
            'name': '白山市',
            'value': 64,
            'type': 1
        },
        {
            'name': '青岛市',
            'value': 99,
            'type': 0
        },
        {
            'name': '伊春市',
            'value': 95,
            'type': 0
        },
        {
            'name': '天津市',
            'value': 55,
            'type': 1
        },
        {
            'name': '上饶市',
            'value': 63,
            'type': 1
        },
        {
            'name': '南京市',
            'value': 32,
            'type': 2
        },
        {
            'name': '九江市',
            'value': 23,
            'type': 2
        },
        {
            'name': '固原市',
            'value': 30,
            'type': 0
        },
        {
            'name': '阜新市',
            'value': 43,
            'type': 2
        },
        {
            'name': '鹰潭市',
            'value': 86,
            'type': 1
        },
        {
            'name': '开封市',
            'value': 86,
            'type': 2
        },
        {
            'name': '铜陵市',
            'value': 13,
            'type': 1
        },
        {
            'name': '广安市',
            'value': 40,
            'type': 1
        },
        {
            'name': '吉林市',
            'value': 72,
            'type': 2
        },
        {
            'name': '吴忠市',
            'value': 9,
            'type': 2
        },
        {
            'name': '南平市',
            'value': 22,
            'type': 2
        },
        {
            'name': '秦皇岛市',
            'value': 81,
            'type': 1
        },
        {
            'name': '齐齐哈尔市',
            'value': 3,
            'type': 1
        },
        {
            'name': '张家口市',
            'value': 50,
            'type': 0
        },
        {
            'name': '河池市',
            'value': 74,
            'type': 2
        },
        {
            'name': '九龙',
            'value': 50,
            'type': 1
        },
        {
            'name': '佳木斯市',
            'value': 56,
            'type': 1
        }
    ];
    constructor(public msg: NzMessageService) {}
    constructor(private http: _HttpClient, public msg: NzMessageService) {}
    ngOnInit() {
        setTimeout(() => {
            this.data = getFakeChartData;
        zip(
            this.http.get('/chart'),
            this.http.get('/chart/tags')
        ).subscribe(([ res, tags ]) => {
            this.data = res;
            tags.list[Math.floor(Math.random() * tags.list.length) + 1].value = 1000;
            this.tags = tags.list;
            this.loading = false;
        }, 500);
        });
        // active chart
        this.genActiveData();
src/app/routes/dashboard/v1/v1.component.ts
@@ -1,16 +1,14 @@
import { NzMessageService } from 'ng-zorro-antd';
import { Component } from '@angular/core';
import { getFakeChartData } from '../../../../../_mock/chart.service';
import { Component, OnInit } from '@angular/core';
import { _HttpClient } from '@delon/theme';
@Component({
    selector: 'app-dashboard-v1',
    templateUrl: './v1.component.html'
})
export class DashboardV1Component {
export class DashboardV1Component implements OnInit {
    constructor(public msg: NzMessageService) {
        console.log(this.offlineChartData);
    }
    constructor(private http: _HttpClient, public msg: NzMessageService) { }
    todoData: any[] = [
        { completed: true, avatar: '1', name: '苏先生', content: `请告诉我,我应该说点什么好?` },
@@ -23,7 +21,15 @@
    quickMenu = false;
    webSite = [ ...getFakeChartData.visitData.slice(0, 10) ];
    salesData =  [...getFakeChartData.salesData];
    offlineChartData = Object.assign([], getFakeChartData.offlineChartData);
    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;
        });
    }
}
src/app/routes/dashboard/workplace/workplace.component.less
@@ -1,5 +1,5 @@
@import '~@delon/theme/styles/antd/themes/default.less';
@import '~@delon/abc/components/utils/utils.less';
@import '~@delon/abc/utils/utils.less';
:host ::ng-deep {
    .page-header {
src/app/routes/dashboard/workplace/workplace.component.ts
@@ -1,8 +1,8 @@
import { zip } from 'rxjs/observable/zip';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { NzMessageService } from 'ng-zorro-antd';
import { getTimeDistance, yuan, fixedZero } from '@delon/abc';
import { getNotice, getActivities } from '../../../../../_mock/api.service';
import { getFakeChartData } from '../../../../../_mock/chart.service';
import { _HttpClient } from '@delon/theme';
@Component({
    selector: 'app-dashboard-workplace',
@@ -76,21 +76,25 @@
      ];
    // endregion
    constructor(public msg: NzMessageService) {}
    constructor(private http: _HttpClient, public msg: NzMessageService) {}
    ngOnInit() {
        setTimeout(() => {
            this.notice = getNotice();
            this.activities = getActivities().map((item: any) => {
        zip(
            this.http.get('/chart'),
            this.http.get('/api/notice'),
            this.http.get('/api/activities')
        ).subscribe(([ chart, notice, activities ]) => {
            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.radarData = getFakeChartData.radarData;
            this.loading = false;
        }, 500);
        });
    }
    ngOnDestroy(): void {
src/app/routes/routes-routing.module.ts
File was renamed from src/app/routes/routes.ts
@@ -1,28 +1,40 @@
import { LayoutComponent } from '../layout/layout.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
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';
export const routes = [
const routes: Routes = [
    {
        path: '',
        component: LayoutComponent,
        component: LayoutDefaultComponent,
        children: [
            { path: '', redirectTo: 'dashboard/analysis', pathMatch: 'full' },
            { path: '', redirectTo: 'dashboard/v1', pathMatch: 'full' },
            { path: 'dashboard', redirectTo: 'dashboard/v1', pathMatch: 'full' },
            { path: 'dashboard/v1', component: DashboardV1Component, data: { translate: 'dashboard_v1' } },
            { path: 'dashboard/analysis', component: DashboardAnalysisComponent, data: { translate: 'dashboard_analysis' } },
            { path: 'dashboard/monitor', component: DashboardMonitorComponent, data: { translate: 'dashboard_monitor' } },
            { path: 'dashboard/workplace', component: DashboardWorkplaceComponent, data: { translate: 'dashboard_workplace' } },
            { path: 'users', loadChildren: './users/users.module#UsersModule' },
            { path: 'devices', loadChildren: './devices/devices.module#DevicesModule' },
            { path: 'sensors', loadChildren: './sensors/sensors.module#SensorsModule' },
            { path: 'systems', loadChildren: './systems/systems.module#SystemsModule' },
            { path: 'dashboard/v1', component: DashboardV1Component, data: { translate: 'dashboard_v1' } },
            { path: 'dashboard/analysis', component: DashboardAnalysisComponent, data: { translate: 'dashboard_analysis' } },
            { path: 'dashboard/monitor', component: DashboardMonitorComponent, data: { translate: 'dashboard_monitor' } },
            { path: 'dashboard/workplace', component: DashboardWorkplaceComponent, data: { translate: 'dashboard_workplace' } }
        ]
    },
    { path: '**', redirectTo: 'dashboard' }
];
@NgModule({
    imports: [RouterModule.forRoot(routes, { useHash: environment.useHash })],
    exports: [RouterModule]
  })
export class RouteRoutingModule { }
src/app/routes/routes.module.ts
@@ -1,16 +1,16 @@
import { DevicesModule } from './devices/devices.module';
import { DateService } from '@business/services/util/date.service';
import { _HttpClient } from '@delon/theme';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { SharedModule } from '@shared/shared.module';
import { environment } from '../../environments/environment';
import { routes } from './routes';
import { RouteRoutingModule } from './routes-routing.module';
import { environment } from '@env/environment';
// 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';
import { CoreModule } from '@core/core.module';
// region: zorro modules
// Statics
import 'rxjs/add/observable/throw';
@@ -22,22 +22,18 @@
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/filter';
@NgModule({
    imports: [
        SharedModule,
        RouterModule.forRoot(routes, { useHash: environment.useHash })
    ],
    imports: [ SharedModule, RouteRoutingModule ],
    declarations: [
        DashboardV1Component,
        DashboardAnalysisComponent,
        DashboardMonitorComponent,
        DashboardWorkplaceComponent
    ],
    exports: [
        RouterModule
        DashboardWorkplaceComponent,
    ],
    providers: [
        _HttpClient
        _HttpClient,
        DateService
    ]
})
src/app/shared/README.md
New file
@@ -0,0 +1,30 @@
# ShareModule
**应** 包含定义:
+ 应用通用自定义业务组件
**应** 导出所有包含的模块。
**不应** 有 `providers` 属性。
## 自定义全局组件或指令
每一个组件或指令应该有一个完整的说明文件,**建议**一个合理的目录结构应该是:
```
├── components
│   ├── comp1
│   │   ├── index.ts
│   │   ├── README.md
│   ├── comp2
│   │   ├── index.ts
│   │   ├── README.md
├── directives
│   ├── dire1
│   │   ├── index.ts
│   │   ├── README.md
│   ├── dire2
│   │   ├── index.ts
│   │   ├── README.md
```
src/app/shared/shared.module.ts
@@ -1,169 +1,23 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';
// delon
import { NgZorroAntdExtraModule } from 'ng-zorro-antd-extra';
import { AlainThemeModule } from '@delon/theme';
import { AlainABCModule } from '@delon/abc';
import { AlainACLModule } from '@delon/acl';
// third libs
import { CountdownModule } from 'ngx-countdown';
import { ZORROMODULES, ABCMODULES } from '../delon.module';
// i18n
import { TranslateModule } from '@ngx-translate/core';
import { I18NService } from '@core/i18n/i18n.service';
import {
    // LoggerModule,
    // NzLocaleModule,
    NzButtonModule,
    NzAlertModule,
    NzBadgeModule,
    // NzCalendarModule,
    NzCascaderModule,
    NzCheckboxModule,
    NzDatePickerModule,
    NzFormModule,
    NzInputModule,
    NzInputNumberModule,
    NzGridModule,
    NzMessageModule,
    NzModalModule,
    NzNotificationModule,
    NzPaginationModule,
    NzPopconfirmModule,
    NzPopoverModule,
    NzRadioModule,
    NzRateModule,
    NzSelectModule,
    NzSpinModule,
    NzSliderModule,
    NzSwitchModule,
    NzProgressModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzTimePickerModule,
    NzUtilModule,
    NzStepsModule,
    NzDropDownModule,
    NzMenuModule,
    NzBreadCrumbModule,
    NzLayoutModule,
    NzRootModule,
    NzCarouselModule,
    // NzCardModule,
    NzCollapseModule,
    NzTimelineModule,
    NzToolTipModule,
    // NzBackTopModule,
    // NzAffixModule,
    // NzAnchorModule,
    NzAvatarModule,
    // SERVICES
    NzNotificationService,
    NzMessageService
} from 'ng-zorro-antd';
const ZORROMODULES = [
    // LoggerModule,
    // NzLocaleModule,
    NzButtonModule,
    NzAlertModule,
    NzBadgeModule,
    // NzCalendarModule,
    NzCascaderModule,
    NzCheckboxModule,
    NzDatePickerModule,
    NzFormModule,
    NzInputModule,
    NzInputNumberModule,
    NzGridModule,
    NzMessageModule,
    NzModalModule,
    NzNotificationModule,
    NzPaginationModule,
    NzPopconfirmModule,
    NzPopoverModule,
    NzRadioModule,
    NzRateModule,
    NzSelectModule,
    NzSpinModule,
    NzSliderModule,
    NzSwitchModule,
    NzProgressModule,
    NzTableModule,
    NzTabsModule,
    NzTagModule,
    NzTimePickerModule,
    NzUtilModule,
    NzStepsModule,
    NzDropDownModule,
    NzMenuModule,
    NzBreadCrumbModule,
    NzLayoutModule,
    NzRootModule,
    NzCarouselModule,
    // NzCardModule,
    NzCollapseModule,
    NzTimelineModule,
    NzToolTipModule,
    // NzBackTopModule,
    // NzAffixModule,
    // NzAnchorModule,
    NzAvatarModule
];
// region: third libs
import { CountdownModule } from 'ngx-countdown';
const THIRDMODULES = [ CountdownModule ];
// endregion
// region: @delon/abc modules
import {
    AdAvatarListModule,
    AdChartsModule,
    AdCountDownModule,
    AdDescListModule,
    AdEllipsisModule,
    AdErrorCollectModule,
    AdExceptionModule,
    AdFooterToolbarModule,
    AdGlobalFooterModule,
    AdNoticeIconModule,
    AdNumberInfoModule,
    AdProHeaderModule,
    AdResultModule,
    AdSidebarNavModule,
    AdStandardFormRowModule,
    AdTagSelectModule,
    AdTrendModule,
    AdDownFileModule,
    AdImageModule,
    AdUtilsModule
} from '@delon/abc';
import { _HttpClient } from '@delon/theme/services/http/http.client';
import { CoreModule } from '@core/core.module';
const ABCMODULES = [
    AdAvatarListModule,
    AdChartsModule,
    AdCountDownModule,
    AdDescListModule,
    AdEllipsisModule,
    AdErrorCollectModule,
    AdExceptionModule,
    AdFooterToolbarModule,
    AdGlobalFooterModule,
    AdNoticeIconModule,
    AdNumberInfoModule,
    AdProHeaderModule,
    AdResultModule,
    AdSidebarNavModule,
    AdStandardFormRowModule,
    AdTagSelectModule,
    AdTrendModule,
    AdDownFileModule,
    AdImageModule,
    AdUtilsModule
];
// region: your componets & directives
const COMPONENTS = [];
const DIRECTIVES = [];
// endregion
@NgModule({
@@ -172,14 +26,18 @@
        FormsModule,
        RouterModule,
        ReactiveFormsModule,
        HttpClientModule,
        ...ZORROMODULES,
        NgZorroAntdExtraModule.forRoot(),
        NgZorroAntdExtraModule,
        AlainThemeModule.forChild(),
        ...ABCMODULES,
        AlainACLModule.forRoot(),
        AlainACLModule,
        // third libs
        CountdownModule
        ...THIRDMODULES
    ],
    declarations: [
        // your components
        ...COMPONENTS,
        ...DIRECTIVES
    ],
    exports: [
        CommonModule,
@@ -190,22 +48,13 @@
        NgZorroAntdExtraModule,
        AlainThemeModule,
        ...ABCMODULES,
        AlainACLModule,
        // i18n
        TranslateModule,
        // third libs
        CountdownModule
        ...THIRDMODULES,
        // your components
        ...COMPONENTS,
        ...DIRECTIVES
    ]
})
export class SharedModule {
    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [
                // ng-zorro-antd Services
                NzNotificationService,
                NzMessageService
            ]
        };
    }
}
export class SharedModule { }
src/assets/app-data.json
@@ -1,80 +1,101 @@
{
  "app": {
  "name": "监控平台",
  "description": "七星博士工业级监控平台"
},
  "user": {
  "name": "管理员",
  "avatar": "./assets/img/zorro.svg",
  "email": "23420800@qq.com"
},
  "menu": [{
  "text": "导航菜单",
  "translate": "main_navigation",
  "group": true,
  "children": [{
    "text": "首页",
    "translate": "home",
    "link": "/dashboard",
    "icon": "icon-cup"
  }, {
    "text": "用户管理",
    "translate": "user_management",
    "link": "/",
    "icon": "icon-user",
    "children": [{
      "text": "安装用户",
      "link": "/users/installer",
      "translate": "user_management_install"
    }, {
      "text": "报警用户",
      "link": "/users/alarm-user",
      "translate": "user_management_alarm-user"
    }]
  }, {
    "text": "设备管理",
    "translate": "device_management",
    "link": "/",
    "icon": "icon-grid",
    "children": [{
      "text": "基本信息",
      "link": "/devices/basic",
      "translate": "device_management_info"
    }, {
      "text": "型号配置",
      "link": "/devices/version",
      "translate": "device_management_version"
    }, {
      "text": "监测区管理",
      "link": "/devices/monitor-point",
      "translate": "device_management_point"
    }]
  }, {
    "text": "传感器管理",
    "translate": "sensor_management",
    "link": "/",
    "icon": "icon-note",
    "children": [{
      "text": "基本信息",
      "link": "/sensors/basic",
      "translate": "device_management_info"
    }]
  }, {
    "text": "系统管理",
    "translate": "system_management",
    "link": "/",
    "icon": "icon-note",
    "children": [
      {
      "text": "账户管理",
      "link": "/systems/account",
      "translate": "system_management_account"
      },
      {
        "text": "组织管理",
        "link": "/systems/organization"
    "app": {
        "name": "Alain",
        "description": "Ng-zorro admin panel front-end framework"
    },
    "user": {
        "name": "Admin",
        "avatar": "./assets/img/zorro.svg",
        "email": "cipchk@qq.com"
    },
    "menu": [{
            "text": "主导航",
            "translate": "main_navigation",
            "group": true,
            "children": [{
                "text": "仪表盘",
                "link": "/dashboard",
                "icon": "icon-speedometer",
                "children": [{
                    "text": "仪表盘V1",
                    "link": "/dashboard/v1",
                    "translate": "dashboard_v1"
                }, {
                    "text": "分析页",
                    "link": "/dashboard/analysis"
                }, {
                    "text": "Monitor",
                    "link": "/dashboard/monitor",
                    "translate": "dashboard_monitor"
                }, {
                    "text": "Workplace",
                    "link": "/dashboard/workplace",
                    "translate": "dashboard_workplace"
                }]
            }, {
                "text": "快捷菜单",
                "translate": "shortcut",
                "icon": "icon-rocket",
                "shortcut_root": true,
                "children": []
            }]
        }, {
            "text": "系统管理",
            "group": true,
            "children": [{
                "text": "用户管理",
                "link": "/users",
                "icon": "icon-user",
                "children": [{
                  "text": "安装用户",
                  "link": "/users/installer"
                }, {
                  "text": "报警用户",
                  "link": "/users/alarm-user"
                }]
              }, {
                "text": "设备管理",
                "link": "/devices",
                "icon": "icon-grid",
                "children": [{
                  "text": "基本信息",
                  "link": "/devices/basic"
                }, {
                  "text": "型号配置",
                  "link": "/devices/version"
                }, {
                  "text": "监测区管理",
                  "link": "/devices/monitor-point"
                }]
              }, {
                "text": "传感器管理",
                "link": "/sensors",
                "icon": "icon-note",
                "children": [{
                  "text": "基本信息",
                  "link": "/sensors/basic"
                }]
              }, {
                "text": "系统管理",
                "link": "/systems",
                "icon": "icon-note",
                "children": [
                  {
                  "text": "账户管理",
                  "link": "/systems/account"
                  },
                  {
                    "text": "组织管理",
                    "link": "/systems/organization"
                    }
                ]
              }
            ]
        }
    ]
  }]
}]
}
src/assets/demo.docx
Binary files differ
src/assets/demo.pdf
Binary files differ
src/assets/demo.pptx
Binary files differ
src/assets/demo.xlsx
Binary files differ
src/assets/i18n/en.json
@@ -1,8 +1,5 @@
{
    "home": "Home",
    "settings": "Settings",
    "profile": "Profile",
    "login": "Login",
@@ -41,19 +38,25 @@
    "typography": "Typography",
    "iconsfont": "Iconsfont",
    "colors": "Colors",
    "other": "Other",
    "split": "Split",
    "clipboard": "Clipboard",
    "forms": "Forms",
    "extended": "Extended",
    "standard": "Standard",
    "validation": "Validation",
    "upload": "Upload",
    "cropper": "Image Crop",
    "editor": "Editor",
    "charts": "Charts",
    "tables": "Tables",
    "fs-table": "Fullscreen Table",
    "maps": "Maps",
    "qq": "QQ",
    "baidu": "Baidu",
    "logics": "Logics",
    "guard": "Route Guard",
    "cache": "Cache",
    "acl": "ACL",
    "downfile": "Down File",
    "report": "Report",
src/assets/i18n/zh-CN.json
@@ -1,19 +1,5 @@
{
    "home": "主页",
    "user_management": "用户管理",
    "user_management_install": "安装用户",
    "user_management_alarm-user": "报警用户",
    "device_management": "设备管理",
    "device_management_info": "基本信息",
    "device_management_version": "型号配置",
    "device_management_point": "监测区管理",
    "sensor_management": "传感器管理",
    "sensor_management_info": "基本信息",
    "system_management":"系统管理",
    "system_management_account":"账户管理",
    "settings": "设置",
    "profile": "个人资料",
    "login": "登录",
@@ -52,19 +38,25 @@
    "typography": "字体排印",
    "iconsfont": "icon图标",
    "colors": "色彩",
    "other": "其它",
    "split": "拆分视图",
    "clipboard": "剪贴板",
    "forms": "表单",
    "standard": "标准",
    "extended": "扩展",
    "validation": "校验",
    "upload": "上传",
    "cropper": "图片裁剪",
    "editor": "编辑器",
    "charts": "图表",
    "tables": "表格",
    "fs-table": "全屏表格",
    "maps": "地图",
    "qq": "QQ",
    "baidu": "百度",
    "logics": "常用逻辑",
    "guard": "路由守卫",
    "cache": "字典缓存",
    "acl": "基于角色访问控制",
    "downfile": "下载文件",
    "report": "报表",
src/assets/iconsfont.json
New file
@@ -0,0 +1,2310 @@
[{
        "title": "antd: Directional Icons",
        "prefix": "anticon anticon-",
        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
        "list": [{
            "k": "step-backward"
        }, {
            "k": "step-forward"
        }, {
            "k": "fast-backward"
        }, {
            "k": "fast-forward"
        }, {
            "k": "shrink"
        }, {
            "k": "arrows-alt"
        }, {
            "k": "down"
        }, {
            "k": "up"
        }, {
            "k": "left"
        }, {
            "k": "right"
        }, {
            "k": "caret-up"
        }, {
            "k": "caret-down"
        }, {
            "k": "caret-left"
        }, {
            "k": "caret-right"
        }, {
            "k": "up-circle"
        }, {
            "k": "down-circle"
        }, {
            "k": "left-circle"
        }, {
            "k": "right-circle"
        }, {
            "k": "up-circle-o"
        }, {
            "k": "down-circle-o"
        }, {
            "k": "right-circle-o"
        }, {
            "k": "left-circle-o"
        }, {
            "k": "double-right"
        }, {
            "k": "double-left"
        }, {
            "k": "verticle-left"
        }, {
            "k": "verticle-right"
        }, {
            "k": "forward"
        }, {
            "k": "backward"
        }, {
            "k": "rollback"
        }, {
            "k": "enter"
        }, {
            "k": "retweet"
        }, {
            "k": "swap"
        }, {
            "k": "swap-left"
        }, {
            "k": "swap-right"
        }, {
            "k": "arrow-up"
        }, {
            "k": "arrow-down"
        }, {
            "k": "arrow-left"
        }, {
            "k": "arrow-right"
        }, {
            "k": "play-circle"
        }, {
            "k": "play-circle-o"
        }, {
            "k": "up-square"
        }, {
            "k": "down-square"
        }, {
            "k": "left-square"
        }, {
            "k": "right-square"
        }, {
            "k": "up-square-o"
        }, {
            "k": "down-square-o"
        }, {
            "k": "left-square-o"
        }, {
            "k": "right-square-o"
        }, {
            "k": "login"
        }, {
            "k": "logout"
        }, {
            "k": "menu-fold"
        }, {
            "k": "menu-unfold"
        }]
    },
    {
        "title": "antd: Suggested Icons",
        "prefix": "anticon anticon-",
        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
        "list": [{
            "k": "question"
        }, {
            "k": "question-circle-o"
        }, {
            "k": "question-circle"
        }, {
            "k": "plus"
        }, {
            "k": "plus-circle-o"
        }, {
            "k": "plus-circle"
        }, {
            "k": "pause"
        }, {
            "k": "pause-circle-o"
        }, {
            "k": "pause-circle"
        }, {
            "k": "minus"
        }, {
            "k": "minus-circle-o"
        }, {
            "k": "minus-circle"
        }, {
            "k": "plus-square"
        }, {
            "k": "plus-square-o"
        }, {
            "k": "minus-square"
        }, {
            "k": "minus-square-o"
        }, {
            "k": "info"
        }, {
            "k": "info-circle-o"
        }, {
            "k": "info-circle"
        }, {
            "k": "exclamation"
        }, {
            "k": "exclamation-circle-o"
        }, {
            "k": "exclamation-circle"
        }, {
            "k": "close"
        }, {
            "k": "close-circle"
        }, {
            "k": "close-circle-o"
        }, {
            "k": "close-square"
        }, {
            "k": "close-square-o"
        }, {
            "k": "check"
        }, {
            "k": "check-circle"
        }, {
            "k": "check-circle-o"
        }, {
            "k": "check-square"
        }, {
            "k": "check-square-o"
        }, {
            "k": "clock-circle-o"
        }, {
            "k": "clock-circle"
        }]
    },
    {
        "title": "antd: Application Icons",
        "prefix": "anticon anticon-",
        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
        "list": [{
            "k": "android"
        }, {
            "k": "android-o"
        }, {
            "k": "apple"
        }, {
            "k": "apple-o"
        }, {
            "k": "windows"
        }, {
            "k": "windows-o"
        }, {
            "k": "ie"
        }, {
            "k": "chrome"
        }, {
            "k": "github"
        }, {
            "k": "aliwangwang"
        }, {
            "k": "aliwangwang-o"
        }, {
            "k": "dingding"
        }, {
            "k": "dingding-o"
        }]
    },
    {
        "title": "antd: Application Icons",
        "prefix": "anticon anticon-",
        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
        "list": [{
            "k": "lock"
        }, {
            "k": "unlock"
        }, {
            "k": "area-chart"
        }, {
            "k": "pie-chart"
        }, {
            "k": "bar-chart"
        }, {
            "k": "dot-chart"
        }, {
            "k": "bars"
        }, {
            "k": "book"
        }, {
            "k": "calendar"
        }, {
            "k": "cloud"
        }, {
            "k": "cloud-download"
        }, {
            "k": "code"
        }, {
            "k": "code-o"
        }, {
            "k": "copy"
        }, {
            "k": "credit-card"
        }, {
            "k": "delete"
        }, {
            "k": "desktop"
        }, {
            "k": "download"
        }, {
            "k": "edit"
        }, {
            "k": "ellipsis"
        }, {
            "k": "file"
        }, {
            "k": "file-text"
        }, {
            "k": "file-unknown"
        }, {
            "k": "file-pdf"
        }, {
            "k": "file-excel"
        }, {
            "k": "file-jpg"
        }, {
            "k": "file-ppt"
        }, {
            "k": "file-add"
        }, {
            "k": "folder"
        }, {
            "k": "folder-open"
        }, {
            "k": "folder-add"
        }, {
            "k": "hdd"
        }, {
            "k": "frown"
        }, {
            "k": "frown-o"
        }, {
            "k": "meh"
        }, {
            "k": "meh-o"
        }, {
            "k": "smile"
        }, {
            "k": "smile-o"
        }, {
            "k": "inbox"
        }, {
            "k": "laptop"
        }, {
            "k": "appstore-o"
        }, {
            "k": "appstore"
        }, {
            "k": "line-chart"
        }, {
            "k": "link"
        }, {
            "k": "mail"
        }, {
            "k": "mobile"
        }, {
            "k": "notification"
        }, {
            "k": "paper-clip"
        }, {
            "k": "picture"
        }, {
            "k": "poweroff"
        }, {
            "k": "reload"
        }, {
            "k": "search"
        }, {
            "k": "setting"
        }, {
            "k": "share-alt"
        }, {
            "k": "shopping-cart"
        }, {
            "k": "tablet"
        }, {
            "k": "tag"
        }, {
            "k": "tag-o"
        }, {
            "k": "tags"
        }, {
            "k": "tags-o"
        }, {
            "k": "to-top"
        }, {
            "k": "upload"
        }, {
            "k": "user"
        }, {
            "k": "video-camera"
        }, {
            "k": "home"
        }, {
            "k": "loading"
        }, {
            "k": "loading-3-quarters"
        }, {
            "k": "cloud-upload-o"
        }, {
            "k": "cloud-download-o"
        }, {
            "k": "cloud-upload"
        }, {
            "k": "cloud-o"
        }, {
            "k": "star-o"
        }, {
            "k": "star"
        }, {
            "k": "heart-o"
        }, {
            "k": "heart"
        }, {
            "k": "environment"
        }, {
            "k": "environment-o"
        }, {
            "k": "eye"
        }, {
            "k": "eye-o"
        }, {
            "k": "camera"
        }, {
            "k": "camera-o"
        }, {
            "k": "save"
        }, {
            "k": "team"
        }, {
            "k": "solution"
        }, {
            "k": "phone"
        }, {
            "k": "filter"
        }, {
            "k": "exception"
        }, {
            "k": "export"
        }, {
            "k": "customer-service"
        }, {
            "k": "qrcode"
        }, {
            "k": "scan"
        }, {
            "k": "like"
        }, {
            "k": "like-o"
        }, {
            "k": "dislike"
        }, {
            "k": "dislike-o"
        }, {
            "k": "message"
        }, {
            "k": "pay-circle"
        }, {
            "k": "pay-circle-o"
        }, {
            "k": "calculator"
        }, {
            "k": "pushpin"
        }, {
            "k": "pushpin-o"
        }, {
            "k": "bulb"
        }, {
            "k": "select"
        }, {
            "k": "switcher"
        }, {
            "k": "rocket"
        }, {
            "k": "bell"
        }, {
            "k": "disconnect"
        }, {
            "k": "database"
        }, {
            "k": "compass"
        }, {
            "k": "barcode"
        }, {
            "k": "hourglass"
        }, {
            "k": "key"
        }, {
            "k": "flag"
        }, {
            "k": "layout"
        }, {
            "k": "printer"
        }, {
            "k": "sound"
        }, {
            "k": "usb"
        }, {
            "k": "skin"
        }, {
            "k": "tool"
        }, {
            "k": "sync"
        }, {
            "k": "wifi"
        }, {
            "k": "car"
        }, {
            "k": "schedule"
        }, {
            "k": "user-add"
        }, {
            "k": "user-delete"
        }, {
            "k": "usergroup-add"
        }, {
            "k": "usergroup-delete"
        }, {
            "k": "man"
        }, {
            "k": "woman"
        }, {
            "k": "shop"
        }, {
            "k": "gift"
        }, {
            "k": "idcard"
        }, {
            "k": "medicine-box"
        }, {
            "k": "red-envelope"
        }, {
            "k": "coffee"
        }, {
            "k": "copyright"
        }, {
            "k": "trademark"
        }, {
            "k": "safety"
        }, {
            "k": "wallet"
        }, {
            "k": "bank"
        }, {
            "k": "trophy"
        }, {
            "k": "contacts"
        }, {
            "k": "global"
        }, {
            "k": "shake"
        }, {
            "k": "api"
        }, {
            "k": "fork"
        }]
    },
    {
        "title": "antd: Brand and Logos",
        "prefix": "anticon anticon-",
        "tpl": "<i class=\"anticon anticon-{0}\"></i>",
        "list": [{
            "k": "android"
        }, {
            "k": "android-o"
        }, {
            "k": "apple"
        }, {
            "k": "apple-o"
        }, {
            "k": "windows"
        }, {
            "k": "windows-o"
        }, {
            "k": "ie"
        }, {
            "k": "chrome"
        }, {
            "k": "github"
        }, {
            "k": "aliwangwang"
        }, {
            "k": "aliwangwang-o"
        }, {
            "k": "dingding"
        }, {
            "k": "dingding-o"
        }]
    },
    {
        "title": "Simple Line icons",
        "prefix": "icon-",
        "tpl": "<i class=\"icon-{0}\"></i>",
        "list": [{
            "k": "user"
        }, {
            "k": "people"
        }, {
            "k": "user-female"
        }, {
            "k": "user-follow"
        }, {
            "k": "user-following"
        }, {
            "k": "user-unfollow"
        }, {
            "k": "login"
        }, {
            "k": "logout"
        }, {
            "k": "emotsmile"
        }, {
            "k": "phone"
        }, {
            "k": "call-end"
        }, {
            "k": "call-in"
        }, {
            "k": "call-out"
        }, {
            "k": "map"
        }, {
            "k": "location-pin"
        }, {
            "k": "direction"
        }, {
            "k": "directions"
        }, {
            "k": "compass"
        }, {
            "k": "layers"
        }, {
            "k": "menu"
        }, {
            "k": "list"
        }, {
            "k": "options-vertical"
        }, {
            "k": "options"
        }, {
            "k": "arrow-down"
        }, {
            "k": "arrow-left"
        }, {
            "k": "arrow-right"
        }, {
            "k": "arrow-up"
        }, {
            "k": "arrow-up-circle"
        }, {
            "k": "arrow-left-circle"
        }, {
            "k": "arrow-right-circle"
        }, {
            "k": "arrow-down-circle"
        }, {
            "k": "check"
        }, {
            "k": "clock"
        }, {
            "k": "plus"
        }, {
            "k": "close"
        }, {
            "k": "trophy"
        }, {
            "k": "screen-smartphone"
        }, {
            "k": "screen-desktop"
        }, {
            "k": "plane"
        }, {
            "k": "notebook"
        }, {
            "k": "mustache"
        }, {
            "k": "mouse"
        }, {
            "k": "magnet"
        }, {
            "k": "energy"
        }, {
            "k": "disc"
        }, {
            "k": "cursor"
        }, {
            "k": "cursor-move"
        }, {
            "k": "crop"
        }, {
            "k": "chemistry"
        }, {
            "k": "speedometer"
        }, {
            "k": "shield"
        }, {
            "k": "screen-tablet"
        }, {
            "k": "magic-wand"
        }, {
            "k": "hourglass"
        }, {
            "k": "graduation"
        }, {
            "k": "ghost"
        }, {
            "k": "game-controller"
        }, {
            "k": "fire"
        }, {
            "k": "eyeglass"
        }, {
            "k": "envelope-open"
        }, {
            "k": "envelope-letter"
        }, {
            "k": "bell"
        }, {
            "k": "badge"
        }, {
            "k": "anchor"
        }, {
            "k": "wallet"
        }, {
            "k": "vector"
        }, {
            "k": "speech"
        }, {
            "k": "puzzle"
        }, {
            "k": "printer"
        }, {
            "k": "present"
        }, {
            "k": "playlist"
        }, {
            "k": "pin"
        }, {
            "k": "picture"
        }, {
            "k": "handbag"
        }, {
            "k": "globe-alt"
        }, {
            "k": "globe"
        }, {
            "k": "folder-alt"
        }, {
            "k": "folder"
        }, {
            "k": "film"
        }, {
            "k": "feed"
        }, {
            "k": "drop"
        }, {
            "k": "drawar"
        }, {
            "k": "docs"
        }, {
            "k": "doc"
        }, {
            "k": "diamond"
        }, {
            "k": "cup"
        }, {
            "k": "calculator"
        }, {
            "k": "bubbles"
        }, {
            "k": "briefcase"
        }, {
            "k": "book-open"
        }, {
            "k": "basket-loaded"
        }, {
            "k": "basket"
        }, {
            "k": "bag"
        }, {
            "k": "action-undo"
        }, {
            "k": "action-redo"
        }, {
            "k": "wrench"
        }, {
            "k": "umbrella"
        }, {
            "k": "trash"
        }, {
            "k": "tag"
        }, {
            "k": "support"
        }, {
            "k": "frame"
        }, {
            "k": "size-fullscreen"
        }, {
            "k": "size-actual"
        }, {
            "k": "shuffle"
        }, {
            "k": "share-alt"
        }, {
            "k": "share"
        }, {
            "k": "rocket"
        }, {
            "k": "question"
        }, {
            "k": "pie-chart"
        }, {
            "k": "pencil"
        }, {
            "k": "note"
        }, {
            "k": "loop"
        }, {
            "k": "home"
        }, {
            "k": "grid"
        }, {
            "k": "graph"
        }, {
            "k": "microphone"
        }, {
            "k": "music-tone-alt"
        }, {
            "k": "music-tone"
        }, {
            "k": "earphones-alt"
        }, {
            "k": "earphones"
        }, {
            "k": "equalizer"
        }, {
            "k": "like"
        }, {
            "k": "dislike"
        }, {
            "k": "control-start"
        }, {
            "k": "control-rewind"
        }, {
            "k": "control-play"
        }, {
            "k": "control-pause"
        }, {
            "k": "control-forward"
        }, {
            "k": "control-end"
        }, {
            "k": "volume-1"
        }, {
            "k": "volume-2"
        }, {
            "k": "volume-off"
        }, {
            "k": "calendar"
        }, {
            "k": "bulb"
        }, {
            "k": "chart"
        }, {
            "k": "ban"
        }, {
            "k": "bubble"
        }, {
            "k": "camrecorder"
        }, {
            "k": "camera"
        }, {
            "k": "cloud-download"
        }, {
            "k": "cloud-upload"
        }, {
            "k": "envelope"
        }, {
            "k": "eye"
        }, {
            "k": "flag"
        }, {
            "k": "heart"
        }, {
            "k": "info"
        }, {
            "k": "key"
        }, {
            "k": "link"
        }, {
            "k": "lock"
        }, {
            "k": "lock-open"
        }, {
            "k": "magnifier"
        }, {
            "k": "magnifier-add"
        }, {
            "k": "magnifier-remove"
        }, {
            "k": "paper-clip"
        }, {
            "k": "paper-plane"
        }, {
            "k": "power"
        }, {
            "k": "refresh"
        }, {
            "k": "reload"
        }, {
            "k": "settings"
        }, {
            "k": "star"
        }, {
            "k": "symble-female"
        }, {
            "k": "symbol-male"
        }, {
            "k": "target"
        }, {
            "k": "credit-card"
        }, {
            "k": "paypal"
        }, {
            "k": "social-tumblr"
        }, {
            "k": "social-twitter"
        }, {
            "k": "social-facebook"
        }, {
            "k": "social-instagram"
        }, {
            "k": "social-linkedin"
        }, {
            "k": "social-pinterest"
        }, {
            "k": "social-github"
        }, {
            "k": "social-gplus"
        }, {
            "k": "social-reddit"
        }, {
            "k": "social-skype"
        }, {
            "k": "social-dribbble"
        }, {
            "k": "social-behance"
        }, {
            "k": "social-foursqare"
        }, {
            "k": "social-soundcloud"
        }, {
            "k": "social-spotify"
        }, {
            "k": "social-stumbleupon"
        }, {
            "k": "social-youtube"
        }, {
            "k": "social-dropbox"
        }]
    },
    {
        "title": "fa: Web Application Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "adjust"
        }, {
            "k": "anchor"
        }, {
            "k": "archive"
        }, {
            "k": "area-chart"
        }, {
            "k": "arrows"
        }, {
            "k": "arrows-h"
        }, {
            "k": "arrows-v"
        }, {
            "k": "asterisk"
        }, {
            "k": "at"
        }, {
            "k": "automobile",
            "a": true
        }, {
            "k": "ban"
        }, {
            "k": "bank",
            "a": true
        }, {
            "k": "bar-chart"
        }, {
            "k": "bar-chart-o",
            "a": true
        }, {
            "k": "barcode"
        }, {
            "k": "bars"
        }, {
            "k": "beer"
        }, {
            "k": "bell"
        }, {
            "k": "bell-o"
        }, {
            "k": "bell-slash"
        }, {
            "k": "bell-slash-o"
        }, {
            "k": "bicycle"
        }, {
            "k": "binoculars"
        }, {
            "k": "birthday-cake"
        }, {
            "k": "bolt"
        }, {
            "k": "bomb"
        }, {
            "k": "book"
        }, {
            "k": "bookmark"
        }, {
            "k": "bookmark-o"
        }, {
            "k": "briefcase"
        }, {
            "k": "bug"
        }, {
            "k": "building"
        }, {
            "k": "building-o"
        }, {
            "k": "bullhorn"
        }, {
            "k": "bullseye"
        }, {
            "k": "bus"
        }, {
            "k": "cab",
            "a": true
        }, {
            "k": "calculator"
        }, {
            "k": "calendar"
        }, {
            "k": "calendar-o"
        }, {
            "k": "camera"
        }, {
            "k": "camera-retro"
        }, {
            "k": "car"
        }, {
            "k": "caret-square-o-down"
        }, {
            "k": "caret-square-o-left"
        }, {
            "k": "caret-square-o-right"
        }, {
            "k": "caret-square-o-up"
        }, {
            "k": "cc"
        }, {
            "k": "certificate"
        }, {
            "k": "check"
        }, {
            "k": "check-circle"
        }, {
            "k": "check-circle-o"
        }, {
            "k": "check-square"
        }, {
            "k": "check-square-o"
        }, {
            "k": "child"
        }, {
            "k": "circle"
        }, {
            "k": "circle-o"
        }, {
            "k": "circle-o-notch"
        }, {
            "k": "circle-thin"
        }, {
            "k": "clock-o"
        }, {
            "k": "close",
            "a": true
        }, {
            "k": "cloud"
        }, {
            "k": "cloud-download"
        }, {
            "k": "cloud-upload"
        }, {
            "k": "code"
        }, {
            "k": "code-fork"
        }, {
            "k": "coffee"
        }, {
            "k": "cog"
        }, {
            "k": "cogs"
        }, {
            "k": "comment"
        }, {
            "k": "comment-o"
        }, {
            "k": "comments"
        }, {
            "k": "comments-o"
        }, {
            "k": "compass"
        }, {
            "k": "copyright"
        }, {
            "k": "credit-card"
        }, {
            "k": "crop"
        }, {
            "k": "crosshairs"
        }, {
            "k": "cube"
        }, {
            "k": "cubes"
        }, {
            "k": "cutlery"
        }, {
            "k": "dashboard",
            "a": true
        }, {
            "k": "database"
        }, {
            "k": "desktop"
        }, {
            "k": "dot-circle-o"
        }, {
            "k": "download"
        }, {
            "k": "edit",
            "a": true
        }, {
            "k": "ellipsis-h"
        }, {
            "k": "ellipsis-v"
        }, {
            "k": "envelope"
        }, {
            "k": "envelope-o"
        }, {
            "k": "envelope-square"
        }, {
            "k": "eraser"
        }, {
            "k": "exchange"
        }, {
            "k": "exclamation"
        }, {
            "k": "exclamation-circle"
        }, {
            "k": "exclamation-triangle"
        }, {
            "k": "external-link"
        }, {
            "k": "external-link-square"
        }, {
            "k": "eye"
        }, {
            "k": "eye-slash"
        }, {
            "k": "eyedropper"
        }, {
            "k": "fax"
        }, {
            "k": "female"
        }, {
            "k": "fighter-jet"
        }, {
            "k": "file-archive-o"
        }, {
            "k": "file-audio-o"
        }, {
            "k": "file-code-o"
        }, {
            "k": "file-excel-o"
        }, {
            "k": "file-image-o"
        }, {
            "k": "file-movie-o",
            "a": true
        }, {
            "k": "file-pdf-o"
        }, {
            "k": "file-photo-o",
            "a": true
        }, {
            "k": "file-picture-o",
            "a": true
        }, {
            "k": "file-powerpoint-o"
        }, {
            "k": "file-sound-o",
            "a": true
        }, {
            "k": "file-video-o"
        }, {
            "k": "file-word-o"
        }, {
            "k": "file-zip-o",
            "a": true
        }, {
            "k": "film"
        }, {
            "k": "filter"
        }, {
            "k": "fire"
        }, {
            "k": "fire-extinguisher"
        }, {
            "k": "flag"
        }, {
            "k": "flag-checkered"
        }, {
            "k": "flag-o"
        }, {
            "k": "flash",
            "a": true
        }, {
            "k": "flask"
        }, {
            "k": "folder"
        }, {
            "k": "folder-o"
        }, {
            "k": "folder-open"
        }, {
            "k": "folder-open-o"
        }, {
            "k": "frown-o"
        }, {
            "k": "futbol-o"
        }, {
            "k": "gamepad"
        }, {
            "k": "gavel"
        }, {
            "k": "gear",
            "a": true
        }, {
            "k": "gears",
            "a": true
        }, {
            "k": "gift"
        }, {
            "k": "glass"
        }, {
            "k": "globe"
        }, {
            "k": "graduation-cap"
        }, {
            "k": "group",
            "a": true
        }, {
            "k": "hdd-o"
        }, {
            "k": "headphones"
        }, {
            "k": "heart"
        }, {
            "k": "heart-o"
        }, {
            "k": "history"
        }, {
            "k": "home"
        }, {
            "k": "image",
            "a": true
        }, {
            "k": "inbox"
        }, {
            "k": "info"
        }, {
            "k": "info-circle"
        }, {
            "k": "institution",
            "a": true
        }, {
            "k": "key"
        }, {
            "k": "keyboard-o"
        }, {
            "k": "language"
        }, {
            "k": "laptop"
        }, {
            "k": "leaf"
        }, {
            "k": "legal",
            "a": true
        }, {
            "k": "lemon-o"
        }, {
            "k": "level-down"
        }, {
            "k": "level-up"
        }, {
            "k": "life-bouy",
            "a": true
        }, {
            "k": "life-buoy",
            "a": true
        }, {
            "k": "life-ring"
        }, {
            "k": "life-saver",
            "a": true
        }, {
            "k": "lightbulb-o"
        }, {
            "k": "line-chart"
        }, {
            "k": "location-arrow"
        }, {
            "k": "lock"
        }, {
            "k": "magic"
        }, {
            "k": "magnet"
        }, {
            "k": "mail-forward",
            "a": true
        }, {
            "k": "mail-reply",
            "a": true
        }, {
            "k": "mail-reply-all",
            "a": true
        }, {
            "k": "male"
        }, {
            "k": "map-marker"
        }, {
            "k": "meh-o"
        }, {
            "k": "microphone"
        }, {
            "k": "microphone-slash"
        }, {
            "k": "minus"
        }, {
            "k": "minus-circle"
        }, {
            "k": "minus-square"
        }, {
            "k": "minus-square-o"
        }, {
            "k": "mobile"
        }, {
            "k": "mobile-phone",
            "a": true
        }, {
            "k": "money"
        }, {
            "k": "moon-o"
        }, {
            "k": "mortar-board",
            "a": true
        }, {
            "k": "music"
        }, {
            "k": "navicon",
            "a": true
        }, {
            "k": "newspaper-o"
        }, {
            "k": "paint-brush"
        }, {
            "k": "paper-plane"
        }, {
            "k": "paper-plane-o"
        }, {
            "k": "paw"
        }, {
            "k": "pencil"
        }, {
            "k": "pencil-square"
        }, {
            "k": "pencil-square-o"
        }, {
            "k": "phone"
        }, {
            "k": "phone-square"
        }, {
            "k": "photo",
            "a": true
        }, {
            "k": "picture-o"
        }, {
            "k": "pie-chart"
        }, {
            "k": "plane"
        }, {
            "k": "plug"
        }, {
            "k": "plus"
        }, {
            "k": "plus-circle"
        }, {
            "k": "plus-square"
        }, {
            "k": "plus-square-o"
        }, {
            "k": "power-off"
        }, {
            "k": "print"
        }, {
            "k": "puzzle-piece"
        }, {
            "k": "qrcode"
        }, {
            "k": "question"
        }, {
            "k": "question-circle"
        }, {
            "k": "quote-left"
        }, {
            "k": "quote-right"
        }, {
            "k": "random"
        }, {
            "k": "recycle"
        }, {
            "k": "refresh"
        }, {
            "k": "remove",
            "a": true
        }, {
            "k": "reorder",
            "a": true
        }, {
            "k": "reply"
        }, {
            "k": "reply-all"
        }, {
            "k": "retweet"
        }, {
            "k": "road"
        }, {
            "k": "rocket"
        }, {
            "k": "rss"
        }, {
            "k": "rss-square"
        }, {
            "k": "search"
        }, {
            "k": "search-minus"
        }, {
            "k": "search-plus"
        }, {
            "k": "send",
            "a": true
        }, {
            "k": "send-o",
            "a": true
        }, {
            "k": "share"
        }, {
            "k": "share-alt"
        }, {
            "k": "share-alt-square"
        }, {
            "k": "share-square"
        }, {
            "k": "share-square-o"
        }, {
            "k": "shield"
        }, {
            "k": "shopping-cart"
        }, {
            "k": "sign-in"
        }, {
            "k": "sign-out"
        }, {
            "k": "signal"
        }, {
            "k": "sitemap"
        }, {
            "k": "sliders"
        }, {
            "k": "smile-o"
        }, {
            "k": "soccer-ball-o",
            "a": true
        }, {
            "k": "sort"
        }, {
            "k": "sort-alpha-asc"
        }, {
            "k": "sort-alpha-desc"
        }, {
            "k": "sort-amount-asc"
        }, {
            "k": "sort-amount-desc"
        }, {
            "k": "sort-asc"
        }, {
            "k": "sort-desc"
        }, {
            "k": "sort-down",
            "a": true
        }, {
            "k": "sort-numeric-asc"
        }, {
            "k": "sort-numeric-desc"
        }, {
            "k": "sort-up",
            "a": true
        }, {
            "k": "space-shuttle"
        }, {
            "k": "spinner"
        }, {
            "k": "spoon"
        }, {
            "k": "square"
        }, {
            "k": "square-o"
        }, {
            "k": "star"
        }, {
            "k": "star-half"
        }, {
            "k": "star-half-empty",
            "a": true
        }, {
            "k": "star-half-full",
            "a": true
        }, {
            "k": "star-half-o"
        }, {
            "k": "star-o"
        }, {
            "k": "suitcase"
        }, {
            "k": "sun-o"
        }, {
            "k": "support",
            "a": true
        }, {
            "k": "tablet"
        }, {
            "k": "tachometer"
        }, {
            "k": "tag"
        }, {
            "k": "tags"
        }, {
            "k": "tasks"
        }, {
            "k": "taxi"
        }, {
            "k": "terminal"
        }, {
            "k": "thumb-tack"
        }, {
            "k": "thumbs-down"
        }, {
            "k": "thumbs-o-down"
        }, {
            "k": "thumbs-o-up"
        }, {
            "k": "thumbs-up"
        }, {
            "k": "ticket"
        }, {
            "k": "times"
        }, {
            "k": "times-circle"
        }, {
            "k": "times-circle-o"
        }, {
            "k": "tint"
        }, {
            "k": "toggle-down",
            "a": true
        }, {
            "k": "toggle-left",
            "a": true
        }, {
            "k": "toggle-off"
        }, {
            "k": "toggle-on"
        }, {
            "k": "toggle-right",
            "a": true
        }, {
            "k": "toggle-up",
            "a": true
        }, {
            "k": "trash"
        }, {
            "k": "trash-o"
        }, {
            "k": "tree"
        }, {
            "k": "trophy"
        }, {
            "k": "truck"
        }, {
            "k": "tty"
        }, {
            "k": "umbrella"
        }, {
            "k": "university"
        }, {
            "k": "unlock"
        }, {
            "k": "unlock-alt"
        }, {
            "k": "unsorted",
            "a": true
        }, {
            "k": "upload"
        }, {
            "k": "user"
        }, {
            "k": "users"
        }, {
            "k": "video-camera"
        }, {
            "k": "volume-down"
        }, {
            "k": "volume-off"
        }, {
            "k": "volume-up"
        }, {
            "k": "warning",
            "a": true
        }, {
            "k": "wheelchair"
        }, {
            "k": "wifi"
        }, {
            "k": "wrench"
        }]
    },
    {
        "title": "fa: File Type Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "file"
        }, {
            "k": "file-archive-o"
        }, {
            "k": "file-audio-o"
        }, {
            "k": "file-code-o"
        }, {
            "k": "file-excel-o"
        }, {
            "k": "file-image-o"
        }, {
            "k": "file-movie-o",
            "a": true
        }, {
            "k": "file-o"
        }, {
            "k": "file-pdf-o"
        }, {
            "k": "file-photo-o",
            "a": true
        }, {
            "k": "file-picture-o",
            "a": true
        }, {
            "k": "file-powerpoint-o"
        }, {
            "k": "file-sound-o",
            "a": true
        }, {
            "k": "file-text"
        }, {
            "k": "file-text-o"
        }, {
            "k": "file-video-o"
        }, {
            "k": "file-word-o"
        }, {
            "k": "file-zip-o",
            "a": true
        }]
    },
    {
        "title": "fa: Spinner Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "tip": "These icons work great with the <code>fa-spin</code> class.",
        "list": [{
            "k": "circle-o-notch"
        }, {
            "k": "cog"
        }, {
            "k": "gear",
            "a": true
        }, {
            "k": "refresh"
        }, {
            "k": "spinner"
        }]
    },
    {
        "title": "fa: Form Control Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "check-square"
        }, {
            "k": "check-square-o"
        }, {
            "k": "circle"
        }, {
            "k": "circle-o"
        }, {
            "k": "dot-circle-o"
        }, {
            "k": "minus-square"
        }, {
            "k": "minus-square-o"
        }, {
            "k": "plus-square"
        }, {
            "k": "plus-square-o"
        }, {
            "k": "square"
        }, {
            "k": "square-o"
        }]
    },
    {
        "title": "fa: Payment Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "cc-amex"
        }, {
            "k": "cc-discover"
        }, {
            "k": "cc-mastercard"
        }, {
            "k": "cc-paypal"
        }, {
            "k": "cc-stripe"
        }, {
            "k": "cc-visa"
        }, {
            "k": "credit-card"
        }, {
            "k": "google-wallet"
        }, {
            "k": "paypal"
        }]
    },
    {
        "title": "fa: Chart Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "area-chart"
        }, {
            "k": "bar-chart"
        }, {
            "k": "bar-chart-o",
            "a": true
        }, {
            "k": "line-chart"
        }, {
            "k": "pie-chart"
        }]
    },
    {
        "title": "fa: Currency Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "bitcoin",
            "a": true
        }, {
            "k": "btc"
        }, {
            "k": "cny",
            "a": true
        }, {
            "k": "dollar",
            "a": true
        }, {
            "k": "eur"
        }, {
            "k": "euro",
            "a": true
        }, {
            "k": "gbp"
        }, {
            "k": "ils"
        }, {
            "k": "inr"
        }, {
            "k": "jpy"
        }, {
            "k": "krw"
        }, {
            "k": "money"
        }, {
            "k": "rmb",
            "a": true
        }, {
            "k": "rouble",
            "a": true
        }, {
            "k": "rub"
        }, {
            "k": "ruble",
            "a": true
        }, {
            "k": "rupee",
            "a": true
        }, {
            "k": "shekel",
            "a": true
        }, {
            "k": "sheqel",
            "a": true
        }, {
            "k": "try"
        }, {
            "k": "turkish-lira",
            "a": true
        }, {
            "k": "usd"
        }, {
            "k": "won",
            "a": true
        }, {
            "k": "yen",
            "a": true
        }]
    },
    {
        "title": "fa: Text Editor Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "align-center"
        }, {
            "k": "align-justify"
        }, {
            "k": "align-left"
        }, {
            "k": "align-right"
        }, {
            "k": "bold"
        }, {
            "k": "chain",
            "a": true
        }, {
            "k": "chain-broken"
        }, {
            "k": "clipboard"
        }, {
            "k": "columns"
        }, {
            "k": "copy",
            "a": true
        }, {
            "k": "cut",
            "a": true
        }, {
            "k": "dedent",
            "a": true
        }, {
            "k": "eraser"
        }, {
            "k": "file"
        }, {
            "k": "file-o"
        }, {
            "k": "file-text"
        }, {
            "k": "file-text-o"
        }, {
            "k": "files-o"
        }, {
            "k": "floppy-o"
        }, {
            "k": "font"
        }, {
            "k": "header"
        }, {
            "k": "indent"
        }, {
            "k": "italic"
        }, {
            "k": "link"
        }, {
            "k": "list"
        }, {
            "k": "list-alt"
        }, {
            "k": "list-ol"
        }, {
            "k": "list-ul"
        }, {
            "k": "outdent"
        }, {
            "k": "paperclip"
        }, {
            "k": "paragraph"
        }, {
            "k": "paste",
            "a": true
        }, {
            "k": "repeat"
        }, {
            "k": "rotate-left",
            "a": true
        }, {
            "k": "rotate-right",
            "a": true
        }, {
            "k": "save",
            "a": true
        }, {
            "k": "scissors"
        }, {
            "k": "strikethrough"
        }, {
            "k": "subscript"
        }, {
            "k": "superscript"
        }, {
            "k": "table"
        }, {
            "k": "text-height"
        }, {
            "k": "text-width"
        }, {
            "k": "th"
        }, {
            "k": "th-large"
        }, {
            "k": "th-list"
        }, {
            "k": "underline"
        }, {
            "k": "undo"
        }, {
            "k": "unlink",
            "a": true
        }]
    },
    {
        "title": "fa: Directional Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "angle-double-down"
        }, {
            "k": "angle-double-left"
        }, {
            "k": "angle-double-right"
        }, {
            "k": "angle-double-up"
        }, {
            "k": "angle-down"
        }, {
            "k": "angle-left"
        }, {
            "k": "angle-right"
        }, {
            "k": "angle-up"
        }, {
            "k": "arrow-circle-down"
        }, {
            "k": "arrow-circle-left"
        }, {
            "k": "arrow-circle-o-down"
        }, {
            "k": "arrow-circle-o-left"
        }, {
            "k": "arrow-circle-o-right"
        }, {
            "k": "arrow-circle-o-up"
        }, {
            "k": "arrow-circle-right"
        }, {
            "k": "arrow-circle-up"
        }, {
            "k": "arrow-down"
        }, {
            "k": "arrow-left"
        }, {
            "k": "arrow-right"
        }, {
            "k": "arrow-up"
        }, {
            "k": "arrows"
        }, {
            "k": "arrows-alt"
        }, {
            "k": "arrows-h"
        }, {
            "k": "arrows-v"
        }, {
            "k": "caret-down"
        }, {
            "k": "caret-left"
        }, {
            "k": "caret-right"
        }, {
            "k": "caret-square-o-down"
        }, {
            "k": "caret-square-o-left"
        }, {
            "k": "caret-square-o-right"
        }, {
            "k": "caret-square-o-up"
        }, {
            "k": "caret-up"
        }, {
            "k": "chevron-circle-down"
        }, {
            "k": "chevron-circle-left"
        }, {
            "k": "chevron-circle-right"
        }, {
            "k": "chevron-circle-up"
        }, {
            "k": "chevron-down"
        }, {
            "k": "chevron-left"
        }, {
            "k": "chevron-right"
        }, {
            "k": "chevron-up"
        }, {
            "k": "hand-o-down"
        }, {
            "k": "hand-o-left"
        }, {
            "k": "hand-o-right"
        }, {
            "k": "hand-o-up"
        }, {
            "k": "long-arrow-down"
        }, {
            "k": "long-arrow-left"
        }, {
            "k": "long-arrow-right"
        }, {
            "k": "long-arrow-up"
        }, {
            "k": "toggle-down",
            "a": true
        }, {
            "k": "toggle-left",
            "a": true
        }, {
            "k": "toggle-right",
            "a": true
        }, {
            "k": "toggle-up",
            "a": true
        }]
    },
    {
        "title": "fa: Video Player Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "arrows-alt"
        }, {
            "k": "backward"
        }, {
            "k": "compress"
        }, {
            "k": "eject"
        }, {
            "k": "expand"
        }, {
            "k": "fast-backward"
        }, {
            "k": "fast-forward"
        }, {
            "k": "forward"
        }, {
            "k": "pause"
        }, {
            "k": "play"
        }, {
            "k": "play-circle"
        }, {
            "k": "play-circle-o"
        }, {
            "k": "step-backward"
        }, {
            "k": "step-forward"
        }, {
            "k": "stop"
        }, {
            "k": "youtube-play"
        }]
    },
    {
        "title": "fa: Brand Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "adn"
        }, {
            "k": "android"
        }, {
            "k": "angellist"
        }, {
            "k": "apple"
        }, {
            "k": "behance"
        }, {
            "k": "behance-square"
        }, {
            "k": "bitbucket"
        }, {
            "k": "bitbucket-square"
        }, {
            "k": "bitcoin",
            "a": true
        }, {
            "k": "btc"
        }, {
            "k": "cc-amex"
        }, {
            "k": "cc-discover"
        }, {
            "k": "cc-mastercard"
        }, {
            "k": "cc-paypal"
        }, {
            "k": "cc-stripe"
        }, {
            "k": "cc-visa"
        }, {
            "k": "codepen"
        }, {
            "k": "css3"
        }, {
            "k": "delicious"
        }, {
            "k": "deviantart"
        }, {
            "k": "digg"
        }, {
            "k": "dribbble"
        }, {
            "k": "dropbox"
        }, {
            "k": "drupal"
        }, {
            "k": "empire"
        }, {
            "k": "facebook"
        }, {
            "k": "facebook-square"
        }, {
            "k": "flickr"
        }, {
            "k": "foursquare"
        }, {
            "k": "ge",
            "a": true
        }, {
            "k": "git"
        }, {
            "k": "git-square"
        }, {
            "k": "github"
        }, {
            "k": "github-alt"
        }, {
            "k": "github-square"
        }, {
            "k": "gittip"
        }, {
            "k": "google"
        }, {
            "k": "google-plus"
        }, {
            "k": "google-plus-square"
        }, {
            "k": "google-wallet"
        }, {
            "k": "hacker-news"
        }, {
            "k": "html5"
        }, {
            "k": "instagram"
        }, {
            "k": "ioxhost"
        }, {
            "k": "joomla"
        }, {
            "k": "jsfiddle"
        }, {
            "k": "lastfm"
        }, {
            "k": "lastfm-square"
        }, {
            "k": "linkedin"
        }, {
            "k": "linkedin-square"
        }, {
            "k": "linux"
        }, {
            "k": "maxcdn"
        }, {
            "k": "meanpath"
        }, {
            "k": "openid"
        }, {
            "k": "pagelines"
        }, {
            "k": "paypal"
        }, {
            "k": "pied-piper"
        }, {
            "k": "pied-piper-alt"
        }, {
            "k": "pinterest"
        }, {
            "k": "pinterest-square"
        }, {
            "k": "qq"
        }, {
            "k": "ra",
            "a": true
        }, {
            "k": "rebel"
        }, {
            "k": "reddit"
        }, {
            "k": "reddit-square"
        }, {
            "k": "renren"
        }, {
            "k": "share-alt"
        }, {
            "k": "share-alt-square"
        }, {
            "k": "skype"
        }, {
            "k": "slack"
        }, {
            "k": "slideshare"
        }, {
            "k": "soundcloud"
        }, {
            "k": "spotify"
        }, {
            "k": "stack-exchange"
        }, {
            "k": "stack-overflow"
        }, {
            "k": "steam"
        }, {
            "k": "steam-square"
        }, {
            "k": "stumbleupon"
        }, {
            "k": "stumbleupon-circle"
        }, {
            "k": "tencent-weibo"
        }, {
            "k": "trello"
        }, {
            "k": "tumblr"
        }, {
            "k": "tumblr-square"
        }, {
            "k": "twitch"
        }, {
            "k": "twitter"
        }, {
            "k": "twitter-square"
        }, {
            "k": "vimeo-square"
        }, {
            "k": "vine"
        }, {
            "k": "vk"
        }, {
            "k": "wechat",
            "a": true
        }, {
            "k": "weibo"
        }, {
            "k": "weixin"
        }, {
            "k": "windows"
        }, {
            "k": "wordpress"
        }, {
            "k": "xing"
        }, {
            "k": "xing-square"
        }, {
            "k": "yahoo"
        }, {
            "k": "yelp"
        }, {
            "k": "youtube"
        }, {
            "k": "youtube-play"
        }, {
            "k": "youtube-square"
        }]
    },
    {
        "title": "fa: Medical Icons",
        "prefix": "fa fa-",
        "tpl": "<i class=\"fa fa-{0}\"></i>",
        "list": [{
            "k": "ambulance"
        }, {
            "k": "h-square"
        }, {
            "k": "hospital-o"
        }, {
            "k": "medkit"
        }, {
            "k": "plus-square"
        }, {
            "k": "stethoscope"
        }, {
            "k": "user-md"
        }, {
            "k": "wheelchair"
        }]
    }
]
src/assets/users-installer-data.json
File was deleted
src/environments/environment.chore.ts
@@ -1,7 +1,7 @@
export const environment = {
    chore: true,
    SERVER_URL: `./`,
    production: true,
    hmr: false,
    useHash: false,
    SERVER_BASH_URL: 'http://47.96.171.62:8080/screen_api_v2'
    useHash: false
};
src/environments/environment.hmr.ts
@@ -1,7 +1,7 @@
export const environment = {
    chore: false,
    SERVER_URL: `./`,
    production: true,
    production: false,
    hmr: true,
    useHash: true,
    SERVER_BASH_URL: 'http://47.96.171.62:8080/screen_api_v2'
    useHash: true
};
src/environments/environment.prod.ts
@@ -1,7 +1,7 @@
export const environment = {
    chore: false,
    SERVER_URL: `./`,
    production: true,
    hmr: false,
    useHash: true,
    SERVER_BASH_URL: 'http://localhost:8080'
    useHash: true
};
src/environments/environment.ts
@@ -4,9 +4,10 @@
// The list of which env maps to which file can be found in `.angular-cli.json`.
export const environment = {
    chore: false,
    SERVER_URL: `./`,
    production: false,
    hmr: false,
    useHash: true,
    SERVER_BASH_URL: 'http://47.96.171.62:8080/screen_api_v2'
    SERVER_BASH_URL: `http://127.0.0.1:8001/`
};
src/test.ts
@@ -1,5 +1,4 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/long-stack-trace-zone';
import 'zone.js/dist/proxy.js';
import 'zone.js/dist/sync-test';
@@ -26,6 +25,7 @@
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// const context = require.context('./', true, /qq\.component\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
// Finally, start Karma to run the tests.
src/testing/common.spec.ts
@@ -2,15 +2,17 @@
import { TestBed, async, TestModuleMetadata } from '@angular/core/testing';
import { Type, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CoreModule } from '@core/core.module';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { HttpLoaderFactory } from 'app/app.module';
import { HttpClient } from '@angular/common/http';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { ALAIN_I18N_TOKEN, ColorsService, SettingsService, MenuService, ScrollService, _HttpClient, ALAIN_THEME_OPTIONS } from '@delon/theme';
import { I18NService } from '@core/i18n/i18n.service';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from '@core/core.module';
import { SharedModule } from '@shared/shared.module';
import { DelonModule } from '../app/delon.module';
import { AlainAuthModule } from '@delon/auth';
import { HttpLoaderFactory } from '../app/app.module';
const resetTestingModule = TestBed.resetTestingModule,
      preventAngularFromResetting = () => TestBed.resetTestingModule = () => TestBed;
@@ -29,7 +31,13 @@
        // region: imports
        if (!moduleDef.imports) moduleDef.imports = [];
        moduleDef.imports.push(RouterTestingModule);
        moduleDef.imports.push(SharedModule.forRoot());
        moduleDef.imports.push(HttpClientModule);
        moduleDef.imports.push(DelonModule);
        moduleDef.imports.push(SharedModule);
        // auth
        moduleDef.imports.push(AlainAuthModule.forRoot({
            login_url: `/passport/login`
        }));
        moduleDef.imports.push(TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
src/tsconfig.app.json
@@ -6,12 +6,16 @@
    "module": "es2015",
    "types": [],
    "paths": {
      "@shared": [ "app/shared" ],
      "@shared/*": [ "app/shared/*" ],
      "@core": [ "app/core/" ],
      "@core/*": [ "app/core/*" ],
      "@business": [ "app/business/" ],
      "@business/*": [ "app/business/*" ]
        "@shared": [ "app/shared" ],
        "@shared/*": [ "app/shared/*" ],
        "@core": [ "app/core/" ],
        "@core/*": [ "app/core/*" ],
        "@testing": [ "testing/" ],
        "@testing/*": [ "testing/*" ],
        "@env": [ "environments/" ],
        "@env/*": [ "environments/*" ],
        "@business": [ "app/business" ],
        "@business/*": [ "app/business/*" ]
    }
  },
  "exclude": [
src/tsconfig.spec.json
@@ -10,12 +10,16 @@
      "node"
    ],
    "paths": {
      "@shared": [ "app/shared" ],
      "@shared/*": [ "app/shared/*" ],
      "@core": [ "app/core/" ],
      "@core/*": [ "app/core/*" ],
      "@business": [ "app/business/" ],
      "@business/*": [ "app/business/*" ]
        "@shared": [ "app/shared" ],
        "@shared/*": [ "app/shared/*" ],
        "@core": [ "app/core/" ],
        "@core/*": [ "app/core/*" ],
        "@testing": [ "testing/" ],
        "@testing/*": [ "testing/*" ],
        "@env": [ "environments/" ],
        "@env/*": [ "environments/*" ],
        "@business": [ "app/business" ],
        "@business/*": [ "app/business/*" ]
    }
  },
  "files": [
tsconfig.json
@@ -7,8 +7,6 @@
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
@@ -23,7 +21,11 @@
        "@shared/*": [ "app/shared/*" ],
        "@core": [ "app/core/" ],
        "@core/*": [ "app/core/*" ],
        "@business": [ "app/business/" ],
        "@testing": [ "testing/" ],
        "@testing/*": [ "testing/*" ],
        "@env": [ "environments/" ],
        "@env/*": [ "environments/*" ],
        "@business": [ "app/business" ],
        "@business/*": [ "app/business/*" ]
    }
  }
yarn.lock
@@ -174,24 +174,25 @@
  version "2.1.3"
  resolved "http://registry.npm.taobao.org/@angularclass/hmr/download/@angularclass/hmr-2.1.3.tgz#34e658ed3da37f23b0a200e2da5a89be92bb209f"
"@antv/data-set@^0.7.0":
  version "0.7.0"
  resolved "http://registry.npm.taobao.org/@antv/data-set/download/@antv/data-set-0.7.0.tgz#0e1ab3c88abe83ad668600de4e18b1637c0621a3"
"@antv/data-set@^0.8.3":
  version "0.8.3"
  resolved "http://registry.npm.taobao.org/@antv/data-set/download/@antv/data-set-0.8.3.tgz#7f58207532a9de5d174b52676b876247b2acab02"
  dependencies:
    d3-array "^1.2.0"
    d3-composite-projections "^1.2.0"
    d3-dsv "^1.0.5"
    d3-geo "^1.6.4"
    d3-geo-projection "^2.1.2"
    d3-hierarchy "^1.1.5"
    d3-sankey "^0.7.1"
    d3-voronoi "^1.1.2"
    lodash "^4.17.4"
    point-at-length "^1.0.2"
    regression "^2.0.0"
    simple-statistics "^4.1.0"
    topojson-client "^3.0.0"
    wolfy87-eventemitter "^5.1.0"
    d3-array "~1.2.0"
    d3-composite-projections "~1.2.0"
    d3-dsv "~1.0.5"
    d3-geo "~1.6.4"
    d3-geo-projection "~2.1.2"
    d3-hexjson "^1.0.1"
    d3-hierarchy "~1.1.5"
    d3-sankey "~0.7.1"
    d3-voronoi "~1.1.2"
    lodash "~4.17.4"
    point-at-length "~1.0.2"
    regression "~2.0.0"
    simple-statistics "~4.1.0"
    topojson-client "~3.0.0"
    wolfy87-eventemitter "~5.1.0"
"@antv/g2-plugin-slider@^2.0.0":
  version "2.0.1"
@@ -218,21 +219,29 @@
    lodash "^4.17.4"
    wolfy87-eventemitter "^5.1.0"
"@delon/abc@^0.3.0-rc.1":
  version "0.3.2"
  resolved "http://registry.npm.taobao.org/@delon/abc/download/@delon/abc-0.3.2.tgz#b0de2df6f262ae283721c40ea3806137ac172dd0"
"@delon/abc@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/abc/download/@delon/abc-0.6.0-rc.2.tgz#29042b329147492d2900eff5266dce2f760118c9"
"@delon/acl@^0.3.0-rc.1":
  version "0.3.2"
  resolved "http://registry.npm.taobao.org/@delon/acl/download/@delon/acl-0.3.2.tgz#f9a507cbc2acb092d35c5ec51b402b4823bed466"
"@delon/acl@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/acl/download/@delon/acl-0.6.0-rc.2.tgz#3e62d7ea2b7b5faa03644354e9bc9c0e496baa8e"
"@delon/auth@^0.3.0-rc.1":
  version "0.3.2"
  resolved "http://registry.npm.taobao.org/@delon/auth/download/@delon/auth-0.3.2.tgz#59b0273a8a17ad3e893633c8bd83de15d913eb9a"
"@delon/auth@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/auth/download/@delon/auth-0.6.0-rc.2.tgz#2aab1245f114845b29f3d127846efa19d617ce5c"
"@delon/theme@^0.3.0-rc.1":
  version "0.3.2"
  resolved "http://registry.npm.taobao.org/@delon/theme/download/@delon/theme-0.3.2.tgz#7e7924c8c7524d937171b4ea08ff74f6be950be2"
"@delon/cache@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/cache/download/@delon/cache-0.6.0-rc.2.tgz#d65789d375c7939d398395e97adf66b9f87a2fa4"
"@delon/mock@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/mock/download/@delon/mock-0.6.0-rc.2.tgz#9e7b677c692241845425e82116755f3c0dfed439"
"@delon/theme@^0.6.0-rc.2":
  version "0.6.0-rc.2"
  resolved "http://registry.npm.taobao.org/@delon/theme/download/@delon/theme-0.6.0-rc.2.tgz#906f81ba8fe292aa86dea2cb97f7dffff37ffef3"
"@ngtools/json-schema@1.1.0", "@ngtools/json-schema@^1.1.0":
  version "1.1.0"
@@ -282,6 +291,20 @@
  resolved "http://registry.npm.taobao.org/@types/jasminewd2/download/@types/jasminewd2-2.0.3.tgz#0d2886b0cbdae4c0eeba55e30792f584bf040a95"
  dependencies:
    "@types/jasmine" "*"
"@types/jszip@^3.1.2":
  version "3.1.3"
  resolved "http://registry.npm.taobao.org/@types/jszip/download/@types/jszip-3.1.3.tgz#5567e9f0a31012341cedcc707175f2c28a430005"
  dependencies:
    "@types/node" "*"
"@types/mockjs@^1.0.0":
  version "1.0.0"
  resolved "http://registry.npm.taobao.org/@types/mockjs/download/@types/mockjs-1.0.0.tgz#a696e1f64c92e7bd6af6343bf8350d1b9d12b388"
"@types/node@*":
  version "9.3.0"
  resolved "http://registry.npm.taobao.org/@types/node/download/@types/node-9.3.0.tgz#3a129cda7c4e5df2409702626892cb4b96546dd5"
"@types/node@^6.0.46", "@types/node@~6.0.60":
  version "6.0.96"
@@ -334,6 +357,13 @@
acorn@^5.0.0, acorn@^5.1.1:
  version "5.3.0"
  resolved "http://registry.npm.taobao.org/acorn/download/acorn-5.3.0.tgz#7446d39459c54fb49a80e6ee6478149b940ec822"
adler-32@~1.1.0:
  version "1.1.0"
  resolved "http://registry.npm.taobao.org/adler-32/download/adler-32-1.1.0.tgz#03551a5c7f0edfbd4fc8fa12a6814978eab651c3"
  dependencies:
    exit-on-epipe "~1.0.1"
    printj "~1.1.0"
adm-zip@0.4.4:
  version "0.4.4"
@@ -398,9 +428,15 @@
  version "1.0.1"
  resolved "http://registry.npm.taobao.org/angular-qq-maps/download/angular-qq-maps-1.0.1.tgz#ba4f312f501bb208837081ed9dd7e595ba53c810"
angular-tree-component@^6.1.0:
  version "6.1.0"
  resolved "http://registry.npm.taobao.org/angular-tree-component/download/angular-tree-component-6.1.0.tgz#9d9a6b28a6881c2072cd6306b55229579e894071"
angular-split@^1.0.0-rc.0:
  version "1.0.0-rc.0"
  resolved "http://registry.npm.taobao.org/angular-split/download/angular-split-1.0.0-rc.0.tgz#d7ec2fcb2166ce0e63babe000e18126e6ee9a407"
  dependencies:
    tslib "^1.7.1"
angular-tree-component@^7.0.1:
  version "7.0.1"
  resolved "http://registry.npm.taobao.org/angular-tree-component/download/angular-tree-component-7.0.1.tgz#fc8d0e72d8c34b87131a3ba2bd32ad20945689ac"
  dependencies:
    lodash "4.17.4"
    mobx ">=3"
@@ -1104,6 +1140,13 @@
    align-text "^0.1.3"
    lazy-cache "^1.0.3"
cfb@~1.0.1:
  version "1.0.1"
  resolved "http://registry.npm.taobao.org/cfb/download/cfb-1.0.1.tgz#557bb24f67dae78803785a1595d365bc82c5fab4"
  dependencies:
    commander "^2.12.1"
    printj "~1.1.0"
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
  version "1.1.3"
  resolved "http://registry.npm.taobao.org/chalk/download/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -1286,6 +1329,14 @@
    source-map "^0.5.6"
    sprintf-js "^1.0.3"
codepage@~1.11.0:
  version "1.11.1"
  resolved "http://registry.npm.taobao.org/codepage/download/codepage-1.11.1.tgz#86472397ea5b2cdbb07b77016a512477a3cb8823"
  dependencies:
    commander "~2.11.0"
    exit-on-epipe "~1.0.1"
    voc "~1.0.0"
collapse-white-space@^1.0.2:
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/collapse-white-space/download/collapse-white-space-1.0.3.tgz#4b906f670e5a963a87b76b0e1689643341b6023c"
@@ -1342,9 +1393,13 @@
  dependencies:
    delayed-stream "~1.0.0"
commander@2, commander@2.12.x, commander@^2.11.0, commander@^2.9.0, commander@~2.12.1:
commander@*, commander@2, commander@2.12.x, commander@^2.11.0, commander@^2.12.1, commander@^2.9.0, commander@~2.12.1:
  version "2.12.2"
  resolved "http://registry.npm.taobao.org/commander/download/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
commander@~2.11.0:
  version "2.11.0"
  resolved "http://registry.npm.taobao.org/commander/download/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
common-tags@^1.3.1:
  version "1.7.0"
@@ -1518,6 +1573,13 @@
    js-yaml "^3.9.0"
    parse-json "^3.0.0"
    require-from-string "^2.0.1"
crc-32@~1.1.1:
  version "1.1.1"
  resolved "http://registry.npm.taobao.org/crc-32/download/crc-32-1.1.1.tgz#5d739d5e4c6e352ad8304d73223d483fe55adb8d"
  dependencies:
    exit-on-epipe "~1.0.1"
    printj "~1.1.0"
crc32-stream@^2.0.0:
  version "2.0.0"
@@ -1720,7 +1782,7 @@
  version "0.2.2"
  resolved "http://registry.npm.taobao.org/cyclist/download/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"
d3-array@1, d3-array@^1.2.0:
d3-array@1, d3-array@~1.2.0:
  version "1.2.1"
  resolved "http://registry.npm.taobao.org/d3-array/download/d3-array-1.2.1.tgz#d1ca33de2f6ac31efadb8e050a021d7e2396d5dc"
@@ -1732,14 +1794,14 @@
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/d3-color/download/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b"
d3-composite-projections@^1.2.0:
d3-composite-projections@~1.2.0:
  version "1.2.0"
  resolved "http://registry.npm.taobao.org/d3-composite-projections/download/d3-composite-projections-1.2.0.tgz#fa0e6f1442f17d04643843a3a883c7d94e0c27c0"
  dependencies:
    d3-geo "1.2.4"
    d3-path "^1.0.1"
d3-dsv@^1.0.5:
d3-dsv@~1.0.5:
  version "1.0.8"
  resolved "http://registry.npm.taobao.org/d3-dsv/download/d3-dsv-1.0.8.tgz#907e240d57b386618dc56468bacfe76bf19764ae"
  dependencies:
@@ -1751,13 +1813,13 @@
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/d3-ease/download/d3-ease-1.0.3.tgz#68bfbc349338a380c44d8acc4fbc3304aa2d8c0e"
d3-geo-projection@^2.1.2:
  version "2.3.2"
  resolved "http://registry.npm.taobao.org/d3-geo-projection/download/d3-geo-projection-2.3.2.tgz#72e559dc05d97fa9f218ccc9c537d329f4cfc474"
d3-geo-projection@~2.1.2:
  version "2.1.2"
  resolved "http://registry.npm.taobao.org/d3-geo-projection/download/d3-geo-projection-2.1.2.tgz#7df8e1e9d046d631c6509f7e531357d4adc24aa3"
  dependencies:
    commander "2"
    d3-array "1"
    d3-geo "^1.7.1"
    d3-geo "^1.1.0"
d3-geo@1.2.4:
  version "1.2.4"
@@ -1765,13 +1827,25 @@
  dependencies:
    d3-array "1"
d3-geo@^1.6.4, d3-geo@^1.7.1:
d3-geo@^1.1.0:
  version "1.9.1"
  resolved "http://registry.npm.taobao.org/d3-geo/download/d3-geo-1.9.1.tgz#157e3b0f917379d0f73bebfff3be537f49fa7356"
  dependencies:
    d3-array "1"
d3-hierarchy@^1.1.5:
d3-geo@~1.6.4:
  version "1.6.4"
  resolved "http://registry.npm.taobao.org/d3-geo/download/d3-geo-1.6.4.tgz#f20e1e461cb1845f5a8be55ab6f876542a7e3199"
  dependencies:
    d3-array "1"
d3-hexjson@^1.0.1:
  version "1.0.1"
  resolved "http://registry.npm.taobao.org/d3-hexjson/download/d3-hexjson-1.0.1.tgz#6a23111e8359f1e214f5d0afa379c02b2b67df0b"
  dependencies:
    d3-array "1"
d3-hierarchy@~1.1.5:
  version "1.1.5"
  resolved "http://registry.npm.taobao.org/d3-hierarchy/download/d3-hierarchy-1.1.5.tgz#a1c845c42f84a206bcf1c01c01098ea4ddaa7a26"
@@ -1785,7 +1859,7 @@
  version "1.0.5"
  resolved "http://registry.npm.taobao.org/d3-path/download/d3-path-1.0.5.tgz#241eb1849bd9e9e8021c0d0a799f8a0e8e441764"
d3-sankey@^0.7.1:
d3-sankey@~0.7.1:
  version "0.7.1"
  resolved "http://registry.npm.taobao.org/d3-sankey/download/d3-sankey-0.7.1.tgz#d229832268fc69a7fec84803e96c2256a614c521"
  dependencies:
@@ -1803,7 +1877,7 @@
  version "1.0.7"
  resolved "http://registry.npm.taobao.org/d3-timer/download/d3-timer-1.0.7.tgz#df9650ca587f6c96607ff4e60cc38229e8dd8531"
d3-voronoi@^1.1.2:
d3-voronoi@~1.1.2:
  version "1.1.2"
  resolved "http://registry.npm.taobao.org/d3-voronoi/download/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c"
@@ -2426,6 +2500,10 @@
  version "1.1.1"
  resolved "http://registry.npm.taobao.org/exit-hook/download/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
exit-on-epipe@~1.0.1:
  version "1.0.1"
  resolved "http://registry.npm.taobao.org/exit-on-epipe/download/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
exit@^0.1.2:
  version "0.1.2"
  resolved "http://registry.npm.taobao.org/exit/download/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -2736,6 +2814,12 @@
forwarded@~0.1.2:
  version "0.1.2"
  resolved "http://registry.npm.taobao.org/forwarded/download/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
frac@~1.1.0:
  version "1.1.0"
  resolved "http://registry.npm.taobao.org/frac/download/frac-1.1.0.tgz#dc437e9c6a646b60b127d82ac4902464445cc1e3"
  dependencies:
    voc "~1.0.0"
fresh@0.5.2:
  version "0.5.2"
@@ -4625,6 +4709,12 @@
  version "3.4.1"
  resolved "http://registry.npm.taobao.org/mobx/download/mobx-3.4.1.tgz#37abe5ee882d401828d9f26c6c1a2f47614bbbef"
mockjs@^1.0.1-beta3:
  version "1.0.1-beta3"
  resolved "http://registry.npm.taobao.org/mockjs/download/mockjs-1.0.1-beta3.tgz#d234f3c27256397564f2c955142e891909537209"
  dependencies:
    commander "*"
moment@^2.18.1, moment@^2.19.3:
  version "2.20.1"
  resolved "http://registry.npm.taobao.org/moment/download/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
@@ -4683,6 +4773,25 @@
  version "0.6.1"
  resolved "http://registry.npm.taobao.org/negotiator/download/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
ng-clipboard-antd@^2.0.1:
  version "2.0.1"
  resolved "http://registry.npm.taobao.org/ng-clipboard-antd/download/ng-clipboard-antd-2.0.1.tgz#2f200b8d22ecb6d5360408d6985df3f51abd7cf6"
  dependencies:
    "@angular/animations" "^5.0.0"
    "@angular/common" "^5.0.0"
    "@angular/compiler" "^5.0.0"
    "@angular/core" "^5.0.0"
    "@angular/forms" "^5.0.0"
    "@angular/http" "^5.0.0"
    "@angular/platform-browser" "^5.0.0"
    "@angular/platform-browser-dynamic" "^5.0.0"
    "@angular/router" "^5.0.0"
    core-js "^2.4.1"
    ng-zorro-antd "^0.6.7"
    ngx-highlight-js "^1.0.3"
    rxjs "^5.5.2"
    zone.js "^0.8.14"
ng-tree-antd@^2.0.0:
  version "2.1.0"
  resolved "http://registry.npm.taobao.org/ng-tree-antd/download/ng-tree-antd-2.1.0.tgz#4cbb93ad3c7a2bddc6c329d788e767777481dcbb"
@@ -4701,11 +4810,11 @@
    rxjs "^5.5.2"
    zone.js "^0.8.14"
ng-zorro-antd-extra@^1.1.3:
ng-zorro-antd-extra@^1.1.6:
  version "1.1.6"
  resolved "http://registry.npm.taobao.org/ng-zorro-antd-extra/download/ng-zorro-antd-extra-1.1.6.tgz#b69ba30603843ffd6ded09a46dd2038542251e40"
ng-zorro-antd@^0.6.5:
ng-zorro-antd@^0.6.5, ng-zorro-antd@^0.6.7:
  version "0.6.10"
  resolved "http://registry.npm.taobao.org/ng-zorro-antd/download/ng-zorro-antd-0.6.10.tgz#0cf5ec5cb94e10226a2b2becff67debf0c8ad860"
  dependencies:
@@ -4736,6 +4845,42 @@
ngx-highlight-js@^1.0.3:
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/ngx-highlight-js/download/ngx-highlight-js-1.0.3.tgz#b46ef9069d443baae7a43e5e4217d64fb8049003"
ngx-tinymce@^1.0.1:
  version "1.0.1"
  resolved "http://registry.npm.taobao.org/ngx-tinymce/download/ngx-tinymce-1.0.1.tgz#a5f04f71a6a393a8363690530c4d832fc39fc9f2"
  dependencies:
    "@angular/animations" "^5.0.0"
    "@angular/common" "^5.0.0"
    "@angular/compiler" "^5.0.0"
    "@angular/core" "^5.0.0"
    "@angular/forms" "^5.0.0"
    "@angular/http" "^5.0.0"
    "@angular/platform-browser" "^5.0.0"
    "@angular/platform-browser-dynamic" "^5.0.0"
    "@angular/router" "^5.0.0"
    core-js "^2.4.1"
    ngx-highlight-js "^1.0.3"
    rxjs "^5.5.2"
    zone.js "^0.8.14"
ngx-ueditor@^1.1.0:
  version "1.1.0"
  resolved "http://registry.npm.taobao.org/ngx-ueditor/download/ngx-ueditor-1.1.0.tgz#0766acc6a8e8205661131c97be49c1e991c97c6c"
  dependencies:
    "@angular/animations" "^5.0.0"
    "@angular/common" "^5.0.0"
    "@angular/compiler" "^5.0.0"
    "@angular/core" "^5.0.0"
    "@angular/forms" "^5.0.0"
    "@angular/http" "^5.0.0"
    "@angular/platform-browser" "^5.0.0"
    "@angular/platform-browser-dynamic" "^5.0.0"
    "@angular/router" "^5.0.0"
    core-js "^2.4.1"
    ngx-highlight-js "^1.0.3"
    rxjs "^5.5.2"
    zone.js "^0.8.14"
no-case@^2.2.0:
  version "2.3.2"
@@ -5301,9 +5446,9 @@
  dependencies:
    find-up "^2.1.0"
point-at-length@^1.0.2:
  version "1.1.0"
  resolved "http://registry.npm.taobao.org/point-at-length/download/point-at-length-1.1.0.tgz#0ad72ebd0980d7f5a1ab12296c055f9eb6b30e57"
point-at-length@~1.0.2:
  version "1.0.2"
  resolved "http://registry.npm.taobao.org/point-at-length/download/point-at-length-1.0.2.tgz#9176d8d6d7c8162f12b646f707db9f0ea728125e"
  dependencies:
    abs-svg-path "~0.1.1"
    isarray "~0.0.1"
@@ -5696,6 +5841,10 @@
    ansi-regex "^3.0.0"
    ansi-styles "^3.2.0"
printj@~1.1.0:
  version "1.1.0"
  resolved "http://registry.npm.taobao.org/printj/download/printj-1.1.0.tgz#85487b5e8f96763b0b4a253613bef9dd9b387e3c"
process-nextick-args@~1.0.6:
  version "1.0.7"
  resolved "http://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
@@ -6044,7 +6193,7 @@
  dependencies:
    jsesc "~0.5.0"
regression@^2.0.0:
regression@~2.0.0:
  version "2.0.1"
  resolved "http://registry.npm.taobao.org/regression/download/regression-2.0.1.tgz#8d29c3e8224a10850c35e337e85a8b2fac3b0c87"
@@ -6559,7 +6708,7 @@
  version "2.4.1"
  resolved "http://registry.npm.taobao.org/simple-line-icons/download/simple-line-icons-2.4.1.tgz#b75bc5a0d87e530928c2ccda5735274bb256f234"
simple-statistics@^4.1.0:
simple-statistics@~4.1.0:
  version "4.1.1"
  resolved "http://registry.npm.taobao.org/simple-statistics/download/simple-statistics-4.1.1.tgz#533c48d48336ba3d350d8135f20fa7138acb0c7d"
@@ -6763,6 +6912,12 @@
sprintf-js@~1.0.2:
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
ssf@~0.10.1:
  version "0.10.1"
  resolved "http://registry.npm.taobao.org/ssf/download/ssf-0.10.1.tgz#f23d82b63792ef56089089c1cd0c848e911cdba6"
  dependencies:
    frac "~1.1.0"
sshpk@^1.7.0:
  version "1.13.1"
@@ -7198,7 +7353,7 @@
  version "1.0.3"
  resolved "http://registry.npm.taobao.org/to-fast-properties/download/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
topojson-client@^3.0.0:
topojson-client@~3.0.0:
  version "3.0.0"
  resolved "http://registry.npm.taobao.org/topojson-client/download/topojson-client-3.0.0.tgz#1f99293a77ef42a448d032a81aa982b73f360d2f"
  dependencies:
@@ -7643,6 +7798,10 @@
  dependencies:
    indexof "0.0.1"
voc@~1.0.0:
  version "1.0.0"
  resolved "http://registry.npm.taobao.org/voc/download/voc-1.0.0.tgz#5465c0ce11d0881f7d8e36d8ca587043f33a25ae"
void-elements@^2.0.0:
  version "2.0.1"
  resolved "http://registry.npm.taobao.org/void-elements/download/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
@@ -7863,6 +8022,10 @@
  version "5.2.4"
  resolved "http://registry.npm.taobao.org/wolfy87-eventemitter/download/wolfy87-eventemitter-5.2.4.tgz#5021d2952d3611cbcd195149711d9b595cd11d48"
wolfy87-eventemitter@~5.1.0:
  version "5.1.0"
  resolved "http://registry.npm.taobao.org/wolfy87-eventemitter/download/wolfy87-eventemitter-5.1.0.tgz#35c1ac0dd1ac0c15e35d981508fc22084a13a011"
wordwrap@0.0.2:
  version "0.0.2"
  resolved "http://registry.npm.taobao.org/wordwrap/download/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
@@ -7933,6 +8096,18 @@
  version "0.1.0"
  resolved "http://registry.npm.taobao.org/x-is-string/download/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82"
xlsx@^0.11.16:
  version "0.11.17"
  resolved "http://registry.npm.taobao.org/xlsx/download/xlsx-0.11.17.tgz#507461fb9783ad0afe1cf751aeb59956e93232da"
  dependencies:
    adler-32 "~1.1.0"
    cfb "~1.0.1"
    codepage "~1.11.0"
    commander "~2.11.0"
    crc-32 "~1.1.1"
    exit-on-epipe "~1.0.1"
    ssf "~0.10.1"
xml-char-classes@^1.0.0:
  version "1.0.0"
  resolved "http://registry.npm.taobao.org/xml-char-classes/download/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d"