duanchangpeng 4 vuotta sitten
vanhempi
commit
a777fef5ec
100 muutettua tiedostoa jossa 28753 lisäystä ja 0 poistoa
  1. 5649 0
      hbuild/online/css/mui.css
  2. 4 0
      hbuild/online/css/mui.min.css
  3. BIN
      hbuild/online/fonts/mui.ttf
  4. 16 0
      hbuild/online/index.html
  5. 8390 0
      hbuild/online/js/mui.js
  6. 5 0
      hbuild/online/js/mui.min.js
  7. 170 0
      hbuild/online/manifest.json
  8. 21 0
      online/.gitignore
  9. 5 0
      online/babel.config.js
  10. 50 0
      online/package.json
  11. BIN
      online/public/favicon.ico
  12. 20 0
      online/public/index.html
  13. 47 0
      online/src/App.vue
  14. 150 0
      online/src/Global.js
  15. 145 0
      online/src/Mock/index.js
  16. 167 0
      online/src/api/getApiRes.js
  17. 110 0
      online/src/components/BaseCharts.js
  18. 63 0
      online/src/components/LineExample.js
  19. 93 0
      online/src/components/LineExample2.js
  20. 3833 0
      online/src/components/address3.json
  21. 32 0
      online/src/components/alert.vue
  22. 388 0
      online/src/components/appHeader.vue
  23. 106 0
      online/src/components/bottomTab.vue
  24. 139 0
      online/src/components/cityPicker.vue
  25. 396 0
      online/src/components/mapDrag.vue
  26. 581 0
      online/src/components/mapPage.vue
  27. 218 0
      online/src/components/statischart.vue
  28. 152 0
      online/src/components/statischart2.vue
  29. 134 0
      online/src/language/en-US.js
  30. 135 0
      online/src/language/ru-RU.js
  31. 135 0
      online/src/language/zh-CN.js
  32. 151 0
      online/src/main.js
  33. 81 0
      online/src/page/404.vue
  34. 782 0
      online/src/page/appoint.vue
  35. 257 0
      online/src/page/detector.vue
  36. 140 0
      online/src/page/detectorDetail.vue
  37. 176 0
      online/src/page/enterpriseDetail.vue
  38. 376 0
      online/src/page/enterprisemanage.vue
  39. 22 0
      online/src/page/index.vue
  40. 600 0
      online/src/page/lesson.vue
  41. 354 0
      online/src/page/listDetail.vue
  42. 666 0
      online/src/page/login.vue
  43. 407 0
      online/src/page/mainpage.vue
  44. 51 0
      online/src/page/map.vue
  45. 545 0
      online/src/page/mine.vue
  46. 47 0
      online/src/page/modal.vue
  47. 61 0
      online/src/page/notFound.vue
  48. 332 0
      online/src/page/plane.vue
  49. 265 0
      online/src/page/profile.vue
  50. 613 0
      online/src/page/record.vue
  51. 318 0
      online/src/page/runtime.vue
  52. 148 0
      online/src/page/setting.vue
  53. 50 0
      online/src/page/statis.vue
  54. 101 0
      online/src/page/test.vue
  55. 157 0
      online/src/page/userDetail.vue
  56. 212 0
      online/src/page/usermanage.vue
  57. 360 0
      online/src/page/white.vue
  58. 127 0
      online/src/router/index.js
  59. BIN
      online/src/static/images/404/man.png
  60. BIN
      online/src/static/images/appoint/tri.png
  61. BIN
      online/src/static/images/appoint/x.png
  62. BIN
      online/src/static/images/bottom/Calendar@2x.png
  63. BIN
      online/src/static/images/bottom/CalendarRed@2x.png
  64. BIN
      online/src/static/images/bottom/Newspaper@2x.png
  65. BIN
      online/src/static/images/bottom/NewspaperRed@2x.png
  66. BIN
      online/src/static/images/bottom/User@2x.png
  67. BIN
      online/src/static/images/bottom/UserRed@2x.png
  68. BIN
      online/src/static/images/comm/arrow-left.png
  69. BIN
      online/src/static/images/comm/b11.png
  70. BIN
      online/src/static/images/comm/b11_1.png
  71. BIN
      online/src/static/images/comm/b12.png
  72. BIN
      online/src/static/images/comm/b12_1.png
  73. BIN
      online/src/static/images/comm/b13.png
  74. BIN
      online/src/static/images/comm/b13_1.png
  75. BIN
      online/src/static/images/comm/b14.png
  76. BIN
      online/src/static/images/comm/b14_1.png
  77. BIN
      online/src/static/images/comm/cityPicker.png
  78. BIN
      online/src/static/images/comm/headerBg.png
  79. BIN
      online/src/static/images/comm/iconEquipmanage.png
  80. BIN
      online/src/static/images/comm/iconEquipmanage_a.png
  81. BIN
      online/src/static/images/comm/iconHome.png
  82. BIN
      online/src/static/images/comm/iconHome_a.png
  83. BIN
      online/src/static/images/comm/iconMap.png
  84. BIN
      online/src/static/images/comm/iconMap_a.png
  85. BIN
      online/src/static/images/comm/iconProfile.png
  86. BIN
      online/src/static/images/comm/iconProfile_a.png
  87. BIN
      online/src/static/images/comm/iconRecord.png
  88. BIN
      online/src/static/images/comm/iconRecord_a.png
  89. BIN
      online/src/static/images/comm/iconRuntime.png
  90. BIN
      online/src/static/images/comm/iconRuntime_a.png
  91. BIN
      online/src/static/images/comm/iconStatis.png
  92. BIN
      online/src/static/images/comm/iconStatis_a.png
  93. BIN
      online/src/static/images/comm/iconUser.png
  94. BIN
      online/src/static/images/comm/iconUser_a.png
  95. BIN
      online/src/static/images/comm/list.png
  96. BIN
      online/src/static/images/comm/right.png
  97. BIN
      online/src/static/images/comm/tab01.png
  98. BIN
      online/src/static/images/comm/tab01_b.png
  99. BIN
      online/src/static/images/comm/tab02.png
  100. BIN
      online/src/static/images/comm/tab02_b.png

+ 5649 - 0
hbuild/online/css/mui.css

@@ -0,0 +1,5649 @@
+/*!
+ * =====================================================
+ * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
+ * =====================================================
+ */
+
+/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
+html
+{
+    font-family: sans-serif;
+
+    -webkit-text-size-adjust: 100%;
+}
+
+body
+{
+    margin: 0;
+}
+
+body::after
+{
+    position: fixed;
+    top: -1000px;
+    left: -1000px;
+
+    content: '';
+    -webkit-animation: shadow-preload .1s;
+            animation: shadow-preload .1s;
+    -webkit-animation-delay: 3s;
+            animation-delay: 3s;
+}
+
+@-webkit-keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+@keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary
+{
+    display: block;
+}
+
+audio,
+canvas,
+progress,
+video
+{
+    display: inline-block;
+
+    vertical-align: baseline;
+}
+
+audio:not([controls])
+{
+    display: none;
+
+    height: 0;
+}
+
+[hidden],
+template
+{
+    display: none;
+}
+
+a
+{
+    background: transparent;
+}
+
+a:active,
+a:hover
+{
+    outline: 0;
+}
+
+abbr[title]
+{
+    border-bottom: 1px dotted;
+}
+
+b,
+strong
+{
+    font-weight: bold;
+}
+
+dfn
+{
+    font-style: italic;
+}
+
+h1
+{
+    font-size: 2em;
+
+    margin: .67em 0;
+}
+
+mark
+{
+    color: #000;
+    background: #ff0;
+}
+
+small
+{
+    font-size: 80%;
+}
+
+sub,
+sup
+{
+    font-size: 75%;
+    line-height: 0;
+
+    position: relative;
+
+    vertical-align: baseline;
+}
+
+sup
+{
+    top: -.5em;
+}
+
+sub
+{
+    bottom: -.25em;
+}
+
+img
+{
+    border: 0;
+}
+
+svg:not(:root)
+{
+    overflow: hidden;
+}
+
+figure
+{
+    margin: 1em 40px;
+}
+
+hr
+{
+    box-sizing: content-box;
+    height: 0;
+}
+
+pre
+{
+    overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp
+{
+    font-family: monospace, monospace;
+    font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea
+{
+    font: inherit;
+
+    margin: 0;
+
+    color: inherit;
+}
+
+button
+{
+    overflow: visible;
+}
+
+button,
+select
+{
+    text-transform: none;
+}
+
+button,
+html input[type='button'],
+input[type='reset'],
+input[type='submit']
+{
+    cursor: pointer;
+
+    -webkit-appearance: button;
+}
+
+button[disabled],
+html input[disabled]
+{
+    cursor: default;
+}
+
+input
+{
+    line-height: normal;
+}
+
+input[type='checkbox'],
+input[type='radio']
+{
+    box-sizing: border-box;
+    padding: 0;
+}
+
+input[type='number']::-webkit-inner-spin-button,
+input[type='number']::-webkit-outer-spin-button
+{
+    height: auto;
+}
+
+input[type='search']
+{
+    -webkit-box-sizing: content-box;
+            box-sizing: content-box;
+
+    -webkit-appearance: textfield;
+}
+
+input[type='search']::-webkit-search-cancel-button,
+input[type='search']::-webkit-search-decoration
+{
+    -webkit-appearance: none;
+}
+
+fieldset
+{
+    margin: 0 2px;
+    padding: .35em .625em .75em;
+
+    border: 1px solid #c0c0c0;
+}
+
+legend
+{
+    padding: 0;
+
+    border: 0;
+}
+
+textarea
+{
+    overflow: auto;
+}
+
+optgroup
+{
+    font-weight: bold;
+}
+
+table
+{
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+td,
+th
+{
+    padding: 0;
+}
+
+*
+{
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+
+    -webkit-user-select: none;
+
+    outline: none;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+
+body
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+    line-height: 21px;
+
+    color: #000;
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+a
+{
+    text-decoration: none;
+
+    color: #007aff;
+}
+a:active
+{
+    color: #0062cc;
+}
+
+.mui-content
+{
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+.mui-bar-nav ~ .mui-content
+{
+    padding-top: 44px;
+}
+.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 44px;
+}
+
+.mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 88px;
+}
+.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 88px;
+}
+
+.mui-bar-footer ~ .mui-content
+{
+    padding-bottom: 44px;
+}
+.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary ~ .mui-content
+{
+    padding-bottom: 88px;
+}
+.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 88px;
+}
+
+.mui-bar-tab ~ .mui-content
+{
+    padding-bottom: 50px;
+}
+.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer-secondary-tab ~ .mui-content
+{
+    padding-bottom: 94px;
+}
+.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 94px;
+}
+
+.mui-content-padded
+{
+    margin: 10px;
+}
+
+.mui-inline
+{
+    display: inline-block;
+
+    vertical-align: top;
+}
+
+.mui-block
+{
+    display: block !important;
+}
+
+.mui-visibility
+{
+    visibility: visible !important;
+}
+
+.mui-hidden
+{
+    display: none !important;
+}
+
+.mui-ellipsis
+{
+    overflow: hidden;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.mui-ellipsis-2
+{
+    display: -webkit-box;
+    overflow: hidden;
+
+    white-space: normal !important;
+    text-overflow: ellipsis;
+    word-wrap: break-word;
+
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+}
+
+.mui-table
+{
+    display: table;
+
+    width: 100%;
+
+    table-layout: fixed;
+}
+
+.mui-table-cell
+{
+    position: relative;
+
+    display: table-cell;
+}
+
+.mui-text-left
+{
+    text-align: left !important;
+}
+
+.mui-text-center
+{
+    text-align: center !important;
+}
+
+.mui-text-justify
+{
+    text-align: justify !important;
+}
+
+.mui-text-right
+{
+    text-align: right !important;
+}
+
+.mui-pull-left
+{
+    float: left;
+}
+
+.mui-pull-right
+{
+    float: right;
+}
+
+.mui-list-unstyled
+{
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline
+{
+    margin-left: -5px;
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline > li
+{
+    display: inline-block;
+
+    padding-right: 5px;
+    padding-left: 5px;
+}
+
+.mui-clearfix:before, .mui-clearfix:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-clearfix:after
+{
+    clear: both;
+}
+
+.mui-bg-primary
+{
+    background-color: #007aff;
+}
+
+.mui-bg-positive
+{
+    background-color: #4cd964;
+}
+
+.mui-bg-negative
+{
+    background-color: #dd524d;
+}
+
+.mui-error
+{
+    margin: 88px 35px;
+    padding: 10px;
+
+    border-radius: 6px;
+    background-color: #bbb;
+}
+
+.mui-subtitle
+{
+    font-size: 15px;
+}
+
+h1, h2, h3, h4, h5, h6
+{
+    line-height: 1;
+
+    margin-top: 5px;
+    margin-bottom: 5px;
+}
+
+h1, .mui-h1
+{
+    font-size: 36px;
+}
+
+h2, .mui-h2
+{
+    font-size: 30px;
+}
+
+h3, .mui-h3
+{
+    font-size: 24px;
+}
+
+h4, .mui-h4
+{
+    font-size: 18px;
+}
+
+h5, .mui-h5
+{
+    font-size: 14px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+h6, .mui-h6
+{
+    font-size: 12px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+p
+{
+    font-size: 14px;
+
+    margin-top: 0;
+    margin-bottom: 10px;
+
+    color: #8f8f94;
+}
+
+.mui-row:before, .mui-row:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-row:after
+{
+    clear: both;
+}
+
+.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12
+{
+    position: relative;
+
+    min-height: 1px;
+}
+
+.mui-row > [class*='mui-col-']
+{
+    float: left;
+}
+
+.mui-col-xs-12
+{
+    width: 100%;
+}
+
+.mui-col-xs-11
+{
+    width: 91.66666667%;
+}
+
+.mui-col-xs-10
+{
+    width: 83.33333333%;
+}
+
+.mui-col-xs-9
+{
+    width: 75%;
+}
+
+.mui-col-xs-8
+{
+    width: 66.66666667%;
+}
+
+.mui-col-xs-7
+{
+    width: 58.33333333%;
+}
+
+.mui-col-xs-6
+{
+    width: 50%;
+}
+
+.mui-col-xs-5
+{
+    width: 41.66666667%;
+}
+
+.mui-col-xs-4
+{
+    width: 33.33333333%;
+}
+
+.mui-col-xs-3
+{
+    width: 25%;
+}
+
+.mui-col-xs-2
+{
+    width: 16.66666667%;
+}
+
+.mui-col-xs-1
+{
+    width: 8.33333333%;
+}
+
+@media (min-width: 400px)
+{
+    .mui-col-sm-12
+    {
+        width: 100%;
+    }
+
+    .mui-col-sm-11
+    {
+        width: 91.66666667%;
+    }
+
+    .mui-col-sm-10
+    {
+        width: 83.33333333%;
+    }
+
+    .mui-col-sm-9
+    {
+        width: 75%;
+    }
+
+    .mui-col-sm-8
+    {
+        width: 66.66666667%;
+    }
+
+    .mui-col-sm-7
+    {
+        width: 58.33333333%;
+    }
+
+    .mui-col-sm-6
+    {
+        width: 50%;
+    }
+
+    .mui-col-sm-5
+    {
+        width: 41.66666667%;
+    }
+
+    .mui-col-sm-4
+    {
+        width: 33.33333333%;
+    }
+
+    .mui-col-sm-3
+    {
+        width: 25%;
+    }
+
+    .mui-col-sm-2
+    {
+        width: 16.66666667%;
+    }
+
+    .mui-col-sm-1
+    {
+        width: 8.33333333%;
+    }
+}
+.mui-scroll-wrapper
+{
+    position: absolute;
+    z-index: 2;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+
+.mui-scroll
+{
+    position: absolute;
+    z-index: 1;
+
+    width: 100%;
+}
+
+.mui-scrollbar
+{
+    position: absolute;
+    z-index: 9998;
+
+    overflow: hidden;
+
+    -webkit-transition: 500ms;
+            transition: 500ms;
+    transform: translateZ(0px);
+    pointer-events: none;
+
+    opacity: 0;
+}
+
+.mui-scrollbar-vertical
+{
+    top: 0;
+    right: 1px;
+    bottom: 2px;
+
+    width: 4px;
+}
+.mui-scrollbar-vertical .mui-scrollbar-indicator
+{
+    width: 100%;
+}
+
+.mui-scrollbar-horizontal
+{
+    right: 2px;
+    bottom: 0;
+    left: 2px;
+
+    height: 4px;
+}
+.mui-scrollbar-horizontal .mui-scrollbar-indicator
+{
+    height: 100%;
+}
+
+.mui-scrollbar-indicator
+{
+    position: absolute;
+
+    display: block;
+
+    box-sizing: border-box;
+
+    -webkit-transition: .01s cubic-bezier(.1, .57, .1, 1);
+            transition: .01s cubic-bezier(.1, .57, .1, 1);
+    transform: translate(0px, 0px) translateZ(0px);
+
+    border: 1px solid rgba(255, 255, 255, .80196);
+    border-radius: 2px;
+    background: rgba(0, 0, 0, .39804);
+}
+
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper
+{
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll
+{
+    position: absolute;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group
+{
+    position: static;
+    top: auto;
+    bottom: auto;
+    left: auto;
+
+    overflow: auto;
+
+    width: auto;
+}
+.mui-plus-pullrefresh .mui-slider-group
+{
+    overflow: visible;
+}
+.mui-plus-pullrefresh .mui-scroll
+{
+    position: static;
+
+    width: auto;
+}
+
+.mui-off-canvas-wrap .mui-bar
+{
+    position: absolute !important;
+
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-off-canvas-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms;
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left
+{
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right
+{
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+.mui-off-canvas-wrap.mui-active
+{
+    overflow: hidden;
+
+    height: 100%;
+}
+.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop
+{
+    position: absolute;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    transition: background 350ms cubic-bezier(.165, .84, .44, 1);
+
+    background: rgba(0, 0, 0, .4);
+    box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5);
+
+    -webkit-tap-highlight-color: transparent;
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(100%, 0px, 0px);
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(-100%, 0px, 0px);
+}
+
+.mui-off-canvas-left, .mui-off-canvas-right
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+    bottom: 0;
+
+    visibility: hidden;
+
+    box-sizing: content-box;
+    width: 70%;
+    min-height: 100%;
+
+    background: #333;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+
+.mui-off-canvas-left
+{
+    left: 0;
+}
+
+.mui-off-canvas-right
+{
+    right: 0;
+}
+
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable
+{
+    background-color: #333;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    width: 80%;
+
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+
+    opacity: .1;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left
+{
+    -webkit-transform-origin: -100%;
+            transform-origin: -100%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    -webkit-transform-origin: 200%;
+            transform-origin: 200%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap
+{
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right
+{
+    -webkit-transform: scale(1);
+            transform: scale(1);
+
+    opacity: 1;
+}
+
+.mui-loading .mui-spinner
+{
+    display: block;
+
+    margin: 0 auto;
+}
+
+.mui-spinner
+{
+    display: inline-block;
+
+    width: 24px;
+    height: 24px;
+
+    -webkit-transform-origin: 50%;
+            transform-origin: 50%;
+    -webkit-animation: spinner-spin 1s step-end infinite;
+            animation: spinner-spin 1s step-end infinite;
+}
+
+.mui-spinner:after
+{
+    display: block;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+    background-repeat: no-repeat;
+    background-position: 50%;
+    background-size: 100%;
+}
+
+.mui-spinner-white:after
+{
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+}
+
+@-webkit-keyframes spinner-spin
+{
+    0%
+    {
+        -webkit-transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        -webkit-transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        -webkit-transform: rotate(60deg);
+    }
+
+    25%
+    {
+        -webkit-transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        -webkit-transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        -webkit-transform: rotate(150deg);
+    }
+
+    50%
+    {
+        -webkit-transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        -webkit-transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        -webkit-transform: rotate(240deg);
+    }
+
+    75%
+    {
+        -webkit-transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        -webkit-transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        -webkit-transform: rotate(330deg);
+    }
+
+    100%
+    {
+        -webkit-transform: rotate(360deg);
+    }
+}
+@keyframes spinner-spin
+{
+    0%
+    {
+        transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        transform: rotate(60deg);
+    }
+
+    25%
+    {
+        transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        transform: rotate(150deg);
+    }
+
+    50%
+    {
+        transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        transform: rotate(240deg);
+    }
+
+    75%
+    {
+        transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        transform: rotate(330deg);
+    }
+
+    100%
+    {
+        transform: rotate(360deg);
+    }
+}
+input[type='button'],
+input[type='submit'],
+input[type='reset'],
+button,
+.mui-btn
+{
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1.42;
+
+    position: relative;
+
+    display: inline-block;
+
+    margin-bottom: 0;
+    padding: 6px 12px;
+
+    cursor: pointer;
+    -webkit-transition: all;
+            transition: all;
+    -webkit-transition-timing-function: linear;
+            transition-timing-function: linear;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    text-align: center;
+    vertical-align: top;
+    white-space: nowrap;
+
+    color: #333;
+    border: 1px solid #ccc;
+    border-radius: 3px;
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+    border-bottom-left-radius: 3px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+input[type='button']:enabled:active, input[type='button'].mui-active:enabled,
+input[type='submit']:enabled:active,
+input[type='submit'].mui-active:enabled,
+input[type='reset']:enabled:active,
+input[type='reset'].mui-active:enabled,
+button:enabled:active,
+button.mui-active:enabled,
+.mui-btn:enabled:active,
+.mui-btn.mui-active:enabled
+{
+    color: #fff;
+    background-color: #929292;
+}
+input[type='button']:disabled, input[type='button'].mui-disabled,
+input[type='submit']:disabled,
+input[type='submit'].mui-disabled,
+input[type='reset']:disabled,
+input[type='reset'].mui-disabled,
+button:disabled,
+button.mui-disabled,
+.mui-btn:disabled,
+.mui-btn.mui-disabled
+{
+    opacity: .6;
+}
+
+input[type='submit'],
+.mui-btn-primary,
+.mui-btn-blue
+{
+    color: #fff;
+    border: 1px solid #007aff;
+    background-color: #007aff;
+}
+input[type='submit']:enabled:active, input[type='submit'].mui-active:enabled,
+.mui-btn-primary:enabled:active,
+.mui-btn-primary.mui-active:enabled,
+.mui-btn-blue:enabled:active,
+.mui-btn-blue.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #0062cc;
+    background-color: #0062cc;
+}
+
+.mui-btn-positive,
+.mui-btn-success,
+.mui-btn-green
+{
+    color: #fff;
+    border: 1px solid #4cd964;
+    background-color: #4cd964;
+}
+.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled,
+.mui-btn-success:enabled:active,
+.mui-btn-success.mui-active:enabled,
+.mui-btn-green:enabled:active,
+.mui-btn-green.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #2ac845;
+    background-color: #2ac845;
+}
+
+.mui-btn-warning,
+.mui-btn-yellow
+{
+    color: #fff;
+    border: 1px solid #f0ad4e;
+    background-color: #f0ad4e;
+}
+.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled,
+.mui-btn-yellow:enabled:active,
+.mui-btn-yellow.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #ec971f;
+    background-color: #ec971f;
+}
+
+.mui-btn-negative,
+.mui-btn-danger,
+.mui-btn-red
+{
+    color: #fff;
+    border: 1px solid #dd524d;
+    background-color: #dd524d;
+}
+.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled,
+.mui-btn-danger:enabled:active,
+.mui-btn-danger.mui-active:enabled,
+.mui-btn-red:enabled:active,
+.mui-btn-red.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #cf2d28;
+    background-color: #cf2d28;
+}
+
+.mui-btn-royal,
+.mui-btn-purple
+{
+    color: #fff;
+    border: 1px solid #8a6de9;
+    background-color: #8a6de9;
+}
+.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled,
+.mui-btn-purple:enabled:active,
+.mui-btn-purple.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #6641e2;
+    background-color: #6641e2;
+}
+
+.mui-btn-grey
+{
+    color: #fff;
+    border: 1px solid #c7c7cc;
+    background-color: #c7c7cc;
+}
+.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #acacb4;
+    background-color: #acacb4;
+}
+
+.mui-btn-outlined
+{
+    background-color: transparent;
+}
+.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue
+{
+    color: #007aff;
+}
+.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green
+{
+    color: #4cd964;
+}
+.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow
+{
+    color: #f0ad4e;
+}
+.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red
+{
+    color: #dd524d;
+}
+.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple
+{
+    color: #8a6de9;
+}
+.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active
+{
+    color: #fff;
+}
+
+.mui-btn-link
+{
+    padding-top: 6px;
+    padding-bottom: 6px;
+
+    color: #007aff;
+    border: 0;
+    background-color: transparent;
+}
+.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled
+{
+    color: #0062cc;
+    background-color: transparent;
+}
+
+.mui-btn-block
+{
+    font-size: 18px;
+
+    display: block;
+
+    width: 100%;
+    margin-bottom: 10px;
+    padding: 15px 0;
+}
+
+.mui-btn .mui-badge
+{
+    font-size: 14px;
+
+    margin: -2px -4px -2px 4px;
+
+    background-color: rgba(0, 0, 0, .15);
+}
+
+.mui-btn .mui-badge-inverted,
+.mui-btn:enabled:active .mui-badge-inverted
+{
+    background-color: transparent;
+}
+
+.mui-btn-primary:enabled:active .mui-badge-inverted,
+.mui-btn-positive:enabled:active .mui-badge-inverted,
+.mui-btn-negative:enabled:active .mui-badge-inverted
+{
+    color: #fff;
+}
+
+.mui-btn-block .mui-badge
+{
+    position: absolute;
+    right: 0;
+
+    margin-right: 10px;
+}
+
+.mui-btn .mui-icon
+{
+    font-size: inherit;
+}
+
+.mui-btn.mui-icon
+{
+    font-size: 14px;
+    line-height: 1.42;
+}
+
+.mui-btn.mui-fab
+{
+    width: 56px;
+    height: 56px;
+    padding: 16px;
+
+    border-radius: 50%;
+    outline: none;
+}
+.mui-btn.mui-fab.mui-btn-mini
+{
+    width: 40px;
+    height: 40px;
+    padding: 8px;
+}
+.mui-btn.mui-fab .mui-icon
+{
+    font-size: 24px;
+    line-height: 24px;
+
+    width: 24px;
+    height: 24px;
+}
+
+.mui-btn .mui-spinner
+{
+    width: 14px;
+    height: 14px;
+
+    vertical-align: text-bottom;
+}
+
+.mui-btn-block .mui-spinner
+{
+    width: 22px;
+    height: 22px;
+}
+
+.mui-bar
+{
+    position: fixed;
+    z-index: 10;
+    right: 0;
+    left: 0;
+
+    height: 44px;
+    padding-right: 10px;
+    padding-left: 10px;
+
+    border-bottom: 0;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+            box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+
+    -webkit-backface-visibility: hidden;
+            backface-visibility: hidden;
+}
+
+.mui-bar .mui-title
+{
+    right: 40px;
+    left: 40px;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: auto;
+    margin: 0;
+
+    text-overflow: ellipsis;
+}
+.mui-bar .mui-backdrop
+{
+    background: none;
+}
+
+.mui-bar-header-secondary
+{
+    top: 44px;
+}
+
+.mui-bar-footer
+{
+    bottom: 0;
+}
+
+.mui-bar-footer-secondary
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary-tab
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer,
+.mui-bar-footer-secondary,
+.mui-bar-footer-secondary-tab
+{
+    border-top: 0;
+}
+
+.mui-bar-transparent
+{
+    top: 0;
+
+    background-color: rgba(247, 247, 247, 0);
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-bar-nav
+{
+    top: 0;
+
+    -webkit-box-shadow: 0 1px 6px #ccc;
+            box-shadow: 0 1px 6px #ccc;
+}
+.mui-bar-nav ~ .mui-content .mui-anchor
+{
+    display: block;
+    visibility: hidden;
+
+    height: 45px;
+    margin-top: -45px;
+}
+.mui-bar-nav.mui-bar .mui-icon
+{
+    margin-right: -10px;
+    margin-left: -10px;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+
+.mui-title
+{
+    font-size: 17px;
+    font-weight: 500;
+    line-height: 44px;
+
+    position: absolute;
+
+    display: block;
+
+    width: 100%;
+    margin: 0 -10px;
+    padding: 0;
+
+    text-align: center;
+    white-space: nowrap;
+
+    color: #000;
+}
+
+.mui-title a
+{
+    color: inherit;
+}
+
+.mui-bar-tab
+{
+    bottom: 0;
+
+    display: table;
+
+    width: 100%;
+    height: 50px;
+    padding: 0;
+
+    table-layout: fixed;
+
+    border-top: 0;
+    border-bottom: 0;
+
+    -webkit-touch-callout: none;
+}
+.mui-bar-tab .mui-tab-item
+{
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+    height: 50px;
+
+    text-align: center;
+    vertical-align: middle;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #929292;
+}
+.mui-bar-tab .mui-tab-item.mui-active
+{
+    color: #007aff;
+}
+.mui-bar-tab .mui-tab-item .mui-icon
+{
+    top: 3px;
+
+    width: 24px;
+    height: 24px;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label
+{
+    font-size: 11px;
+
+    display: block;
+    overflow: hidden;
+
+    text-overflow: ellipsis;
+}
+.mui-bar-tab .mui-tab-item .mui-icon:active
+{
+    background: none;
+}
+
+.mui-focusin > .mui-bar-nav,
+.mui-focusin > .mui-bar-header-secondary
+{
+    position: absolute;
+}
+
+.mui-focusin > .mui-bar ~ .mui-content
+{
+    padding-bottom: 0;
+}
+
+.mui-bar .mui-btn
+{
+    font-weight: 400;
+
+    position: relative;
+    z-index: 20;
+    top: 7px;
+
+    margin-top: 0;
+    padding: 6px 12px 7px;
+}
+.mui-bar .mui-btn.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-bar .mui-btn.mui-pull-left
+{
+    margin-right: 10px;
+}
+
+.mui-bar .mui-btn-link
+{
+    font-size: 16px;
+    line-height: 44px;
+
+    top: 0;
+
+    padding: 0;
+
+    color: #007aff;
+    border: 0;
+}
+.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active
+{
+    color: #0062cc;
+}
+
+.mui-bar .mui-btn-block
+{
+    font-size: 16px;
+
+    top: 6px;
+
+    margin-bottom: 0;
+    padding: 5px 0;
+}
+
+.mui-bar .mui-btn-nav.mui-pull-left
+{
+    margin-left: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav
+{
+    margin-right: -3px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right
+{
+    margin-right: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav
+{
+    margin-left: -3px;
+}
+.mui-bar .mui-btn-nav:active
+{
+    opacity: .3;
+}
+
+.mui-bar .mui-icon
+{
+    font-size: 24px;
+
+    position: relative;
+    z-index: 20;
+
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+.mui-bar .mui-icon:active
+{
+    opacity: .3;
+}
+.mui-bar .mui-btn .mui-icon
+{
+    top: 1px;
+
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon
+{
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon.mui-icon-caret
+{
+    top: 4px;
+
+    margin-left: -5px;
+}
+
+.mui-bar input[type='search']
+{
+    height: 29px;
+    margin: 6px 0;
+}
+
+.mui-bar .mui-input-row .mui-btn
+{
+    padding: 12px 10px;
+}
+
+.mui-bar .mui-search:before
+{
+    margin-top: -10px;
+}
+
+.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 12px;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 0;
+}
+
+.mui-bar .mui-segmented-control
+{
+    top: 7px;
+
+    width: auto;
+    margin: 0 auto;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-segmented-control
+{
+    top: 0;
+}
+
+.mui-badge
+{
+    font-size: 12px;
+    line-height: 1;
+
+    display: inline-block;
+
+    padding: 3px 6px;
+
+    color: #333;
+    border-radius: 100px;
+    background-color: rgba(0, 0, 0, .15);
+}
+.mui-badge.mui-badge-inverted
+{
+    padding: 0 5px 0 0;
+
+    color: #929292;
+    background-color: transparent;
+}
+
+.mui-badge-primary, .mui-badge-blue
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted
+{
+    color: #007aff;
+    background-color: transparent;
+}
+
+.mui-badge-success, .mui-badge-green
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted
+{
+    color: #4cd964;
+    background-color: transparent;
+}
+
+.mui-badge-warning, .mui-badge-yellow
+{
+    color: #fff;
+    background-color: #f0ad4e;
+}
+.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted
+{
+    color: #f0ad4e;
+    background-color: transparent;
+}
+
+.mui-badge-danger, .mui-badge-red
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted
+{
+    color: #dd524d;
+    background-color: transparent;
+}
+
+.mui-badge-royal, .mui-badge-purple
+{
+    color: #fff;
+    background-color: #8a6de9;
+}
+.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted
+{
+    color: #8a6de9;
+    background-color: transparent;
+}
+
+.mui-icon .mui-badge
+{
+    font-size: 10px;
+    line-height: 1.4;
+
+    position: absolute;
+    top: -2px;
+    left: 100%;
+
+    margin-left: -10px;
+    padding: 1px 5px;
+
+    color: white;
+    background: red;
+}
+
+.mui-card
+{
+    font-size: 14px;
+
+    position: relative;
+
+    overflow: hidden;
+
+    margin: 10px;
+
+    border-radius: 2px;
+    background-color: white;
+    background-clip: padding-box;
+    box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
+}
+
+.mui-content > .mui-card:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-card .mui-input-group:before, .mui-card .mui-input-group:after
+{
+    height: 0;
+}
+.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after
+{
+    height: 0;
+}
+
+.mui-card .mui-table-view
+{
+    margin-bottom: 0;
+
+    border-top: 0;
+    border-bottom: 0;
+    border-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child
+{
+    top: 0;
+
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child
+{
+    border-bottom-right-radius: 6px;
+    border-bottom-left-radius: 6px;
+}
+.mui-card .mui-table-view:before, .mui-card .mui-table-view:after
+{
+    height: 0;
+}
+
+.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+
+.mui-card-header,
+.mui-card-footer
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    min-height: 44px;
+    padding: 10px 15px;
+
+    -webkit-box-pack: justify;
+    -webkit-justify-content: space-between;
+            justify-content: space-between;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-card-header .mui-card-link,
+.mui-card-footer .mui-card-link
+{
+    line-height: 44px;
+
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+    margin-top: -10px;
+    margin-bottom: -10px;
+
+    -webkit-transition-duration: .3s;
+            transition-duration: .3s;
+    text-decoration: none;
+
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+            justify-content: flex-start;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+
+.mui-card-header:after,
+.mui-card-footer:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-card-header
+{
+    font-size: 17px;
+
+    border-radius: 2px 2px 0 0;
+}
+.mui-card-header:after
+{
+    top: auto;
+    bottom: 0;
+}
+.mui-card-header > img:first-child
+{
+    font-size: 0;
+    line-height: 0;
+
+    float: left;
+
+    width: 34px;
+    height: 34px;
+}
+
+.mui-card-footer
+{
+    color: #6d6d72;
+    border-radius: 0 0 2px 2px;
+}
+
+.mui-card-content
+{
+    font-size: 14px;
+
+    position: relative;
+}
+
+.mui-card-content-inner
+{
+    position: relative;
+
+    padding: 15px;
+}
+
+.mui-card-media
+{
+    vertical-align: bottom;
+
+    color: #fff;
+    background-position: center;
+    background-size: cover;
+}
+
+.mui-card-header.mui-card-media
+{
+    display: block;
+
+    padding: 10px;
+}
+.mui-card-header.mui-card-media .mui-media-body
+{
+    font-size: 14px;
+    font-weight: 500;
+    line-height: 17px;
+
+    margin-bottom: 0;
+    margin-left: 44px;
+
+    color: #333;
+}
+.mui-card-header.mui-card-media .mui-media-body p
+{
+    font-size: 13px;
+
+    margin-bottom: 0;
+}
+
+.mui-table-view
+{
+    position: relative;
+
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    list-style: none;
+
+    background-color: #fff;
+}
+.mui-table-view:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    top: -1px;
+}
+
+.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon
+{
+    font-size: 20px;
+
+    margin-top: -1px;
+    margin-right: 5px;
+    margin-left: -5px;
+}
+.mui-table-view-icon .mui-table-view-cell:after
+{
+    left: 40px;
+}
+
+.mui-table-view-chevron .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+
+.mui-table-view-radio .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after
+{
+    font-size: 30px;
+    font-weight: 600;
+
+    right: 9px;
+
+    content: '';
+
+    color: #007aff;
+}
+.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after
+{
+    content: '\e472';
+}
+
+.mui-table-view-inverted
+{
+    color: #fff;
+    background: #333;
+}
+.mui-table-view-inverted:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell.mui-active
+{
+    background-color: #242424;
+}
+.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #242424;
+}
+
+.mui-table-view-cell
+{
+    position: relative;
+
+    overflow: hidden;
+
+    padding: 11px 15px;
+
+    -webkit-touch-callout: none;
+}
+.mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox]
+{
+    top: 8px;
+}
+.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left
+{
+    padding-left: 58px;
+}
+.mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell > a:not(.mui-btn)
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    margin: -11px -15px;
+    padding: inherit;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: inherit;
+  /*&:active {
+      background-color: #eee;
+  }*/
+}
+.mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell p
+{
+    margin-bottom: 0;
+}
+
+.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 300ms ease;
+            transition:         transform 300ms ease;
+}
+.mui-table-view-cell.mui-active > .mui-slider-handle
+{
+    background-color: #eee;
+}
+.mui-table-view-cell > .mui-slider-handle
+{
+    position: relative;
+
+    background-color: #fff;
+}
+.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after
+{
+    right: 0;
+}
+.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+}
+.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right
+{
+    position: absolute;
+    top: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 100%;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn
+{
+    position: relative;
+    left: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    padding: 0 30px;
+
+    color: #fff;
+    border: 0;
+    border-radius: 0;
+
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+
+    width: 600%;
+    height: 100%;
+
+    content: '';
+
+    background: inherit;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon
+{
+    font-size: 30px;
+}
+.mui-table-view-cell > .mui-slider-right
+{
+    right: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(100%);
+            transform: translateX(100%);
+}
+.mui-table-view-cell > .mui-slider-left
+{
+    left: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(-100%);
+            transform: translateX(-100%);
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after
+{
+    right: 100%;
+
+    margin-right: -1px;
+}
+
+.mui-table-view-divider
+{
+    font-weight: 500;
+
+    position: relative;
+
+    margin-top: -1px;
+    margin-left: 0;
+    padding-top: 6px;
+    padding-bottom: 6px;
+    padding-left: 15px;
+
+    color: #999;
+    background-color: #fafafa;
+}
+.mui-table-view-divider:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-divider:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view .mui-media,
+.mui-table-view .mui-media-body
+{
+    overflow: hidden;
+}
+
+.mui-table-view .mui-media-large .mui-media-object
+{
+    line-height: 80px;
+
+    max-width: 80px;
+    height: 80px;
+}
+.mui-table-view .mui-media .mui-subtitle
+{
+    color: #000;
+}
+.mui-table-view .mui-media-object
+{
+    line-height: 42px;
+
+    max-width: 42px;
+    height: 42px;
+}
+.mui-table-view .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-media-object.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+    margin: -4px 0;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon
+{
+    font-size: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 55px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon:after
+{
+    height: 0 !important;
+}
+
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: block;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0 !important;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 70px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view-cell > .mui-btn,
+.mui-table-view-cell > .mui-badge,
+.mui-table-view-cell > .mui-switch,
+.mui-table-view-cell > a > .mui-btn,
+.mui-table-view-cell > a > .mui-badge,
+.mui-table-view-cell > a > .mui-switch
+{
+    position: absolute;
+    top: 50%;
+    right: 15px;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-table-view-cell .mui-navigate-right > .mui-btn,
+.mui-table-view-cell .mui-navigate-right > .mui-badge,
+.mui-table-view-cell .mui-navigate-right > .mui-switch,
+.mui-table-view-cell .mui-push-left > .mui-btn,
+.mui-table-view-cell .mui-push-left > .mui-badge,
+.mui-table-view-cell .mui-push-left > .mui-switch,
+.mui-table-view-cell .mui-push-right > .mui-btn,
+.mui-table-view-cell .mui-push-right > .mui-badge,
+.mui-table-view-cell .mui-push-right > .mui-switch,
+.mui-table-view-cell > a .mui-navigate-right > .mui-btn,
+.mui-table-view-cell > a .mui-navigate-right > .mui-badge,
+.mui-table-view-cell > a .mui-navigate-right > .mui-switch,
+.mui-table-view-cell > a .mui-push-left > .mui-btn,
+.mui-table-view-cell > a .mui-push-left > .mui-badge,
+.mui-table-view-cell > a .mui-push-left > .mui-switch,
+.mui-table-view-cell > a .mui-push-right > .mui-btn,
+.mui-table-view-cell > a .mui-push-right > .mui-badge,
+.mui-table-view-cell > a .mui-push-right > .mui-switch
+{
+    right: 35px;
+}
+
+.mui-content > .mui-table-view:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after
+{
+    content: '\e581';
+}
+.mui-table-view-cell.mui-collapse.mui-active
+{
+    margin-top: -1px;
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content
+{
+    display: block;
+}
+.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after
+{
+    content: '\e580';
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    margin-left: -31px;
+    padding-left: 47px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content
+{
+    position: relative;
+
+    display: none;
+    overflow: hidden;
+
+    margin: 11px -15px -11px;
+    padding: 8px 15px;
+
+    -webkit-transition: height .35s ease;
+         -o-transition: height .35s ease;
+            transition: height .35s ease;
+
+    background: white;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    width: auto;
+    height: auto;
+    margin: -8px -15px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    margin: -8px -16px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: none;
+
+    margin-top: 11px;
+    margin-right: -15px;
+    margin-bottom: -11px;
+    margin-left: -15px;
+
+    border: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron
+{
+    margin-right: -65px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell
+{
+    padding-left: 31px;
+
+    background-position: 31px 100%;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 30px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view.mui-grid-view
+{
+    font-size: 0;
+
+    display: block;
+
+    width: 100%;
+    padding: 0 10px 10px 0;
+
+    white-space: normal;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell
+{
+    font-size: 17px;
+
+    display: inline-block;
+
+    margin-right: -4px;
+    padding: 10px 0 0 14px;
+
+    text-align: center;
+    vertical-align: middle;
+
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object
+{
+    width: 100%;
+    max-width: 100%;
+    height: auto;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -10px 0 0 -14px;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body
+{
+    font-size: 15px;
+    line-height: 15px;
+
+    display: block;
+
+    width: 100%;
+    height: 15px;
+    margin-top: 8px;
+
+    text-overflow: ellipsis;
+
+    color: #333;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after
+{
+    height: 0;
+}
+
+.mui-grid-view.mui-grid-9
+{
+    margin: 0;
+    padding: 0;
+
+    border-top: 1px solid #eee;
+    border-left: 1px solid #eee;
+    background-color: #f2f2f2;
+}
+.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-grid-view.mui-grid-9:after
+{
+    clear: both;
+}
+.mui-grid-view.mui-grid-9:after
+{
+    position: static;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell
+{
+    margin: 0;
+    padding: 11px 15px;
+
+    vertical-align: top;
+
+    border-right: 1px solid #eee;
+    border-bottom: 1px solid #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: 0;
+    padding: 10px 0;
+}
+.mui-grid-view.mui-grid-9:before
+{
+    height: 0;
+}
+.mui-grid-view.mui-grid-9 .mui-media
+{
+    color: #797979;
+}
+.mui-grid-view.mui-grid-9 .mui-media .mui-icon
+{
+    font-size: 2.4em;
+
+    position: relative;
+}
+
+.mui-slider-cell
+{
+    position: relative;
+}
+.mui-slider-cell > .mui-slider-handle
+{
+    z-index: 1;
+}
+.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right
+{
+    position: absolute;
+    z-index: 0;
+    top: 0;
+    bottom: 0;
+}
+.mui-slider-cell > .mui-slider-left
+{
+    left: 0;
+}
+.mui-slider-cell > .mui-slider-right
+{
+    right: 0;
+}
+
+input,
+textarea,
+select
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+input:focus,
+textarea:focus,
+select:focus
+{
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+    -webkit-user-modify: read-write-plaintext-only;
+}
+
+select,
+textarea,
+input[type='text'],
+input[type='search'],
+input[type='password'],
+input[type='datetime'],
+input[type='datetime-local'],
+input[type='date'],
+input[type='month'],
+input[type='time'],
+input[type='week'],
+input[type='number'],
+input[type='email'],
+input[type='url'],
+input[type='tel'],
+input[type='color']
+{
+    line-height: 21px;
+
+    width: 100%;
+    height: 40px;
+    margin-bottom: 15px;
+    padding: 10px 15px;
+
+    -webkit-user-select: text;
+
+    border: 1px solid rgba(0, 0, 0, .2);
+    border-radius: 3px;
+    outline: none;
+    background-color: #fff;
+
+    -webkit-appearance: none;
+}
+
+input[type=number]::-webkit-inner-spin-button,
+input[type=number]::-webkit-outer-spin-button
+{
+    margin: 0;
+
+    -webkit-appearance: none;
+}
+
+input[type='search']
+{
+    font-size: 16px;
+
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+    height: 34px;
+
+    text-align: center;
+
+    border: 0;
+    border-radius: 6px;
+    background-color: rgba(0, 0, 0, .1);
+}
+
+input[type='search']:focus
+{
+    text-align: left;
+}
+
+textarea
+{
+    height: auto;
+
+    resize: none;
+}
+
+select
+{
+    font-size: 14px;
+
+    height: auto;
+    margin-top: 1px;
+
+    border: 0 !important;
+    background-color: #fff;
+}
+select:focus
+{
+    -webkit-user-modify: read-only;
+}
+
+.mui-input-group
+{
+    position: relative;
+
+    padding: 0;
+
+    border: 0;
+    background-color: #fff;
+}
+.mui-input-group:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-input-group:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-group input,
+.mui-input-group textarea
+{
+    margin-bottom: 0;
+
+    border: 0;
+    border-radius: 0;
+    background-color: transparent;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-input-group input[type='search']
+{
+    background: none;
+}
+
+.mui-input-group input:last-child
+{
+    background-image: none;
+}
+
+.mui-input-row
+{
+    clear: left;
+    overflow: hidden;
+}
+.mui-input-row select
+{
+    font-size: 17px;
+
+    height: 37px;
+    padding: 0;
+}
+
+.mui-input-row:last-child,
+.mui-input-row label + input, .mui-input-row .mui-btn + input
+{
+    background: none;
+}
+
+.mui-input-group .mui-input-row
+{
+    height: 40px;
+}
+.mui-input-group .mui-input-row:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-row label
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    line-height: 1.1;
+
+    float: left;
+
+    width: 35%;
+    padding: 11px 15px;
+}
+
+.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea
+{
+    float: right;
+
+    width: 65%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-input-row .mui-btn
+{
+    line-height: 1.1;
+
+    float: right;
+
+    width: 15%;
+    padding: 10px 15px;
+}
+
+.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea
+{
+    float: left;
+
+    width: 85%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-button-row
+{
+    position: relative;
+
+    padding-top: 5px;
+
+    text-align: center;
+}
+
+.mui-input-group .mui-button-row
+{
+    height: 45px;
+}
+
+.mui-input-row
+{
+    position: relative;
+}
+.mui-input-row.mui-input-range
+{
+    overflow: visible;
+
+    padding-right: 20px;
+}
+.mui-input-row .mui-inline
+{
+    padding: 8px 0;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye
+{
+    font-size: 20px;
+
+    position: absolute;
+    z-index: 1;
+    top: 10px;
+    right: 0;
+
+    width: 38px;
+    height: 38px;
+
+    text-align: center;
+
+    color: #999;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active
+{
+    color: #007aff;
+}
+.mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    font-size: 24px;
+
+    top: 8px;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech
+{
+    display: none;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech
+{
+    display: inline-block;
+}
+.mui-input-row .mui-icon-speech ~ .mui-placeholder
+{
+    right: 38px;
+}
+.mui-input-row.mui-search .mui-icon-clear
+{
+    top: 7px;
+}
+.mui-input-row.mui-search .mui-icon-speech
+{
+    top: 5px;
+}
+
+.mui-radio, .mui-checkbox
+{
+    position: relative;
+}
+.mui-radio label, .mui-checkbox label
+{
+    display: inline-block;
+    float: none;
+
+    width: 100%;
+    padding-right: 58px;
+}
+
+.mui-radio.mui-left input[type='radio'], .mui-checkbox.mui-left input[type='checkbox']
+{
+    left: 20px;
+}
+
+.mui-radio.mui-left label, .mui-checkbox.mui-left label
+{
+    padding-right: 15px;
+    padding-left: 58px;
+}
+
+.mui-radio input[type='radio'], .mui-checkbox input[type='checkbox']
+{
+    position: absolute;
+    top: 4px;
+    right: 20px;
+
+    display: inline-block;
+
+    width: 28px;
+    height: 26px;
+
+    border: 0;
+    outline: 0 !important;
+    background-color: transparent;
+
+    -webkit-appearance: none;
+}
+.mui-radio input[type='radio'][disabled]:before, .mui-checkbox input[type='checkbox'][disabled]:before
+{
+    opacity: .3;
+}
+.mui-radio input[type='radio']:before, .mui-checkbox input[type='checkbox']:before
+{
+    font-family: Muiicons;
+    font-size: 28px;
+    font-weight: normal;
+    line-height: 1;
+
+    text-decoration: none;
+
+    color: #aaa;
+    border-radius: 0;
+    background: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-radio input[type='radio']:checked:before, .mui-checkbox input[type='checkbox']:checked:before
+{
+    color: #007aff;
+}
+
+.mui-radio.mui-disabled label, .mui-radio label.mui-disabled, .mui-checkbox.mui-disabled label, .mui-checkbox label.mui-disabled
+{
+    opacity: .4;
+}
+
+.mui-radio input[type='radio']:before
+{
+    content: '\e411';
+}
+
+.mui-radio input[type='radio']:checked:before
+{
+    content: '\e441';
+}
+
+.mui-checkbox input[type='checkbox']:before
+{
+    content: '\e411';
+}
+
+.mui-checkbox input[type='checkbox']:checked:before
+{
+    content: '\e442';
+}
+
+.mui-select
+{
+    position: relative;
+}
+
+.mui-select:before
+{
+    font-family: Muiicons;
+
+    position: absolute;
+    top: 8px;
+    right: 21px;
+
+    content: '\e581';
+
+    color: rgba(170, 170, 170, .6);
+}
+
+.mui-input-row .mui-switch
+{
+    float: right;
+
+    margin-top: 5px;
+    margin-right: 20px;
+}
+
+.mui-input-range
+{
+  /*input[type="range"] {
+      -webkit-appearance: none;
+      background: #999;
+      height: 36px;
+      border-radius: 1px;
+      overflow: hidden;
+      margin-top: 2px;
+      margin-bottom: 2px;
+      outline:none;
+      position:relative;
+      width:100%;
+  }*/
+  /*input[type='range']::-webkit-slider-thumb {
+      -webkit-appearance: none!important;
+      opacity: 0.5;
+      height:28px;
+      width:28px;
+      border-radius: 50%;
+      background:#00b7fb;
+      position: relative;
+      pointer-events: none;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+      &:before{
+          position: absolute;
+          top: 13px;
+          left: -2000px;
+          width: 2000px;
+          height: 2px;
+          background: #00b7fb;
+          content:' ';
+      }
+  }*/
+}
+.mui-input-range input[type='range']
+{
+    position: relative;
+
+    width: 100%;
+    height: 2px;
+    margin: 17px 0;
+    padding: 0;
+
+    cursor: pointer;
+
+    border: 0;
+    border-radius: 3px;
+    outline: none;
+    background-color: #999;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range input[type='range']::-webkit-slider-thumb
+{
+    width: 28px;
+    height: 28px;
+
+    border-color: #0062cc;
+    border-radius: 50%;
+    background-color: #007aff;
+    background-clip: padding-box;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range label ~ input[type='range']
+{
+    width: 65%;
+}
+.mui-input-range .mui-tooltip
+{
+    font-size: 36px;
+    line-height: 64px;
+
+    position: absolute;
+    z-index: 1;
+    top: -70px;
+
+    width: 64px;
+    height: 64px;
+
+    text-align: center;
+
+    opacity: .8;
+    color: #333;
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    text-shadow: 0 1px 0 #f3f3f3;
+}
+
+.mui-search
+{
+    position: relative;
+}
+.mui-search input[type='search']
+{
+    padding-left: 30px;
+}
+.mui-search .mui-placeholder
+{
+    font-size: 16px;
+    line-height: 34px;
+
+    position: absolute;
+    z-index: 1;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: inline-block;
+
+    height: 34px;
+
+    text-align: center;
+
+    color: #999;
+    border: 0;
+    border-radius: 6px;
+    background: none;
+}
+.mui-search .mui-placeholder .mui-icon
+{
+    font-size: 20px;
+
+    color: #333;
+}
+.mui-search:before
+{
+    font-family: Muiicons;
+    font-size: 20px;
+    font-weight: normal;
+
+    position: absolute;
+    top: 50%;
+    right: 50%;
+
+    display: none;
+
+    margin-top: -18px;
+    margin-right: 31px;
+
+    content: '\e466';
+}
+.mui-search.mui-active:before
+{
+    font-size: 20px;
+
+    right: auto;
+    left: 5px;
+
+    display: block;
+
+    margin-right: 0;
+}
+.mui-search.mui-active input[type='search']
+{
+    text-align: left;
+}
+.mui-search.mui-active .mui-placeholder
+{
+    display: none;
+}
+
+.mui-segmented-control
+{
+    font-size: 15px;
+    font-weight: 400;
+
+    position: relative;
+
+    display: table;
+    overflow: hidden;
+
+    width: 100%;
+
+    table-layout: fixed;
+
+    border: 1px solid #007aff;
+    border-radius: 3px;
+    background-color: transparent;
+
+    -webkit-touch-callout: none;
+}
+.mui-segmented-control.mui-segmented-control-vertical
+{
+    border-collapse: collapse;
+
+    border-width: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-vertical .mui-control-item
+{
+    display: block;
+
+    border-bottom: 1px solid #c8c7cc;
+    border-left-width: 0;
+}
+.mui-segmented-control.mui-scroll-wrapper
+{
+    height: 38px;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-scroll
+{
+    width: auto;
+    height: 40px;
+
+    white-space: nowrap;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-control-item
+{
+    display: inline-block;
+
+    width: auto;
+    padding: 0 20px;
+
+    border: 0;
+}
+.mui-segmented-control .mui-control-item
+{
+    line-height: 38px;
+
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+
+    -webkit-transition: background-color .1s linear;
+            transition: background-color .1s linear;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    border-color: #007aff;
+    border-left: 1px solid #007aff;
+}
+.mui-segmented-control .mui-control-item:first-child
+{
+    border-left-width: 0;
+}
+.mui-segmented-control .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-segmented-control.mui-segmented-control-inverted
+{
+    width: 100%;
+
+    border: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item
+{
+    color: inherit;
+    border: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #007aff;
+    border-bottom: 2px solid #007aff;
+    background: none;
+}
+.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #007aff;
+}
+
+.mui-segmented-control-positive
+{
+    border: 1px solid #4cd964;
+}
+.mui-segmented-control-positive .mui-control-item
+{
+    color: #4cd964;
+    border-color: inherit;
+}
+.mui-segmented-control-positive .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #4cd964;
+    border-bottom: 2px solid #4cd964;
+    background: none;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #4cd964;
+}
+
+.mui-segmented-control-negative
+{
+    border: 1px solid #dd524d;
+}
+.mui-segmented-control-negative .mui-control-item
+{
+    color: #dd524d;
+    border-color: inherit;
+}
+.mui-segmented-control-negative .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #dd524d;
+    border-bottom: 2px solid #dd524d;
+    background: none;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #dd524d;
+}
+
+.mui-control-content
+{
+    position: relative;
+
+    display: none;
+}
+.mui-control-content.mui-active
+{
+    display: block;
+}
+
+.mui-popover
+{
+    position: absolute;
+    z-index: 999;
+
+    display: none;
+
+    width: 280px;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transition-property: opacity;
+            transition-property: opacity;
+    -webkit-transform: none;
+            transform: none;
+
+    opacity: 0;
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+            box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+}
+.mui-popover .mui-popover-arrow
+{
+    position: absolute;
+    z-index: 1000;
+    top: -25px;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 26px;
+    height: 26px;
+}
+.mui-popover .mui-popover-arrow:after
+{
+    position: absolute;
+    top: 19px;
+    left: 0;
+
+    width: 26px;
+    height: 26px;
+
+    content: ' ';
+    -webkit-transform: rotate(45deg);
+            transform: rotate(45deg);
+
+    border-radius: 3px;
+    background: #f7f7f7;
+}
+.mui-popover .mui-popover-arrow.mui-bottom
+{
+    top: 100%;
+    left: -26px;
+
+    margin-top: -1px;
+}
+.mui-popover .mui-popover-arrow.mui-bottom:after
+{
+    top: -19px;
+    left: 0;
+}
+.mui-popover.mui-popover-action
+{
+    bottom: 0;
+
+    width: 100%;
+
+    -webkit-transition: -webkit-transform .3s, opacity .3s;
+            transition:         transform .3s, opacity .3s;
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    border-radius: 0;
+    background: none;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+.mui-popover.mui-popover-action .mui-popover-arrow
+{
+    display: none;
+}
+.mui-popover.mui-popover-action.mui-popover-bottom
+{
+    position: fixed;
+}
+.mui-popover.mui-popover-action.mui-active
+{
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-popover.mui-popover-action .mui-table-view
+{
+    margin: 8px;
+
+    text-align: center;
+
+    color: #007aff;
+    border-radius: 4px;
+}
+.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-popover.mui-popover-action .mui-table-view small
+{
+    font-weight: 400;
+    line-height: 1.3;
+
+    display: block;
+}
+.mui-popover.mui-active
+{
+    display: block;
+
+    opacity: 1;
+}
+.mui-popover .mui-bar ~ .mui-table-view
+{
+    padding-top: 44px;
+}
+
+.mui-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop
+{
+    bottom: 50px;
+
+    background: none;
+}
+
+.mui-backdrop-action.mui-backdrop
+{
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop
+{
+    opacity: 0;
+}
+.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active
+{
+    -webkit-transition: all .4s ease;
+            transition: all .4s ease;
+
+    opacity: 1;
+}
+
+.mui-popover .mui-btn-block
+{
+    margin-bottom: 5px;
+}
+.mui-popover .mui-btn-block:last-child
+{
+    margin-bottom: 0;
+}
+
+.mui-popover .mui-bar
+{
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-bar-nav
+{
+    border-bottom: 1px solid rgba(0, 0, 0, .15);
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-scroll-wrapper
+{
+    margin: 7px 0;
+
+    border-radius: 7px;
+    background-clip: padding-box;
+}
+
+.mui-popover .mui-scroll .mui-table-view
+{
+    max-height: none;
+}
+
+.mui-popover .mui-table-view
+{
+    overflow: auto;
+
+    max-height: 300px;
+    margin-bottom: 0;
+
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    background-image: none;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after
+{
+    height: 0;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:first-child,
+.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn)
+{
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:last-child,
+.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn)
+{
+    border-bottom-right-radius: 12px;
+    border-bottom-left-radius: 12px;
+}
+
+.mui-popover.mui-bar-popover .mui-table-view
+{
+    width: 106px;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell
+{
+    padding: 11px 15px 11px 15px;
+
+    background-position: 0 100%;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -11px -15px -11px -15px;
+}
+
+.mui-popup-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+
+    opacity: 0;
+    background: rgba(0, 0, 0, .4);
+}
+.mui-popup-backdrop.mui-active
+{
+    opacity: 1;
+}
+
+.mui-popup
+{
+    position: fixed;
+    z-index: 10000;
+    top: 50%;
+    left: 50%;
+
+    display: none;
+    overflow: hidden;
+
+    width: 270px;
+
+    -webkit-transition-property: -webkit-transform,opacity;
+            transition-property:         transform,opacity;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1.185);
+            transform: translate3d(-50%, -50%, 0) scale(1.185);
+    text-align: center;
+
+    opacity: 0;
+    color: #000;
+    border-radius: 13px;
+}
+.mui-popup.mui-popup-in
+{
+    display: block;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 1;
+}
+.mui-popup.mui-popup-out
+{
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 0;
+}
+
+.mui-popup-inner
+{
+    position: relative;
+
+    padding: 15px;
+
+    border-radius: 13px 13px 0 0;
+    background: rgba(255, 255, 255, .95);
+}
+.mui-popup-inner:after
+{
+    position: absolute;
+    z-index: 15;
+    top: auto;
+    right: auto;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    width: 100%;
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+    -webkit-transform-origin: 50% 100%;
+            transform-origin: 50% 100%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+
+.mui-popup-title
+{
+    font-size: 18px;
+    font-weight: 500;
+
+    text-align: center;
+}
+
+.mui-popup-title + .mui-popup-text
+{
+    font-family: inherit;
+    font-size: 14px;
+
+    margin: 5px 0 0;
+}
+
+.mui-popup-buttons
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+            justify-content: center;
+}
+
+.mui-popup-button
+{
+    font-size: 17px;
+    line-height: 44px;
+
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    box-sizing: border-box;
+    width: 100%;
+    height: 44px;
+    padding: 0 5px;
+
+    cursor: pointer;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    background: rgba(255, 255, 255, .95);
+
+    -webkit-box-flex: 1;
+}
+.mui-popup-button:after
+{
+    position: absolute;
+    z-index: 15;
+    top: 0;
+    right: 0;
+    bottom: auto;
+    left: auto;
+
+    display: block;
+
+    width: 1px;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: scaleX(.5);
+            transform: scaleX(.5);
+    -webkit-transform-origin: 100% 50%;
+            transform-origin: 100% 50%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+.mui-popup-button:first-child
+{
+    border-radius: 0 0 0 13px;
+}
+.mui-popup-button:first-child:last-child
+{
+    border-radius: 0 0 13px 13px;
+}
+.mui-popup-button:last-child
+{
+    border-radius: 0 0 13px 0;
+}
+.mui-popup-button:last-child:after
+{
+    display: none;
+}
+.mui-popup-button.mui-popup-button-bold
+{
+    font-weight: 600;
+}
+
+.mui-popup-input input
+{
+    font-size: 14px;
+
+    width: 100%;
+    height: 26px;
+    margin: 15px 0 0;
+    padding: 0 5px;
+
+    border: 1px solid rgba(0, 0, 0, .3);
+    border-radius: 0;
+    background: #fff;
+}
+
+.mui-plus.mui-android .mui-popup-backdrop
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+}
+
+.mui-plus.mui-android .mui-popup
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+}
+
+/* === Progress Bar === */
+.mui-progressbar
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    width: 100%;
+    height: 2px;
+
+    -webkit-transform-origin: center top;
+            transform-origin: center top;
+    vertical-align: middle;
+
+    border-radius: 2px;
+    background: #b6b6b6;
+
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+.mui-progressbar span
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    -webkit-transition: 150ms;
+            transition: 150ms;
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+
+    background: #007aff;
+}
+.mui-progressbar.mui-progressbar-infinite:before
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+    -webkit-transform-origin: left center;
+            transform-origin: left center;
+    -webkit-animation: mui-progressbar-infinite 1s linear infinite;
+            animation: mui-progressbar-infinite 1s linear infinite;
+
+    background: #007aff;
+}
+
+body > .mui-progressbar
+{
+    position: absolute;
+    z-index: 10000;
+    top: 44px;
+    left: 0;
+
+    border-radius: 0;
+}
+
+.mui-progressbar-in
+{
+    -webkit-animation: mui-progressbar-in 300ms forwards;
+            animation: mui-progressbar-in 300ms forwards;
+}
+
+.mui-progressbar-out
+{
+    -webkit-animation: mui-progressbar-out 300ms forwards;
+            animation: mui-progressbar-out 300ms forwards;
+}
+
+@-webkit-keyframes mui-progressbar-in
+{
+    from
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@keyframes mui-progressbar-in
+{
+    from
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@-webkit-keyframes mui-progressbar-out
+{
+    from
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@keyframes mui-progressbar-out
+{
+    from
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@-webkit-keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        -webkit-transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        -webkit-transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+@keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+.mui-pagination
+{
+    display: inline-block;
+
+    margin: 0 auto;
+    padding-left: 0;
+
+    border-radius: 6px;
+}
+.mui-pagination > li
+{
+    display: inline;
+}
+.mui-pagination > li > a,
+.mui-pagination > li > span
+{
+    line-height: 1.428571429;
+
+    position: relative;
+
+    float: left;
+
+    margin-left: -1px;
+    padding: 6px 12px;
+
+    text-decoration: none;
+
+    color: #007aff;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+.mui-pagination > li:first-child > a,
+.mui-pagination > li:first-child > span
+{
+    margin-left: 0;
+
+    border-top-left-radius: 6px;
+    border-bottom-left-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:last-child > a,
+.mui-pagination > li:last-child > span
+{
+    border-top-right-radius: 6px;
+    border-bottom-right-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:active > a, .mui-pagination > li:active > a:active,
+.mui-pagination > li:active > span,
+.mui-pagination > li:active > span:active,
+.mui-pagination > li.mui-active > a,
+.mui-pagination > li.mui-active > a:active,
+.mui-pagination > li.mui-active > span,
+.mui-pagination > li.mui-active > span:active
+{
+    z-index: 2;
+
+    cursor: default;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pagination > li.mui-disabled > span,
+.mui-pagination > li.mui-disabled > span:active,
+.mui-pagination > li.mui-disabled > a,
+.mui-pagination > li.mui-disabled > a:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-pagination-lg > li > a,
+.mui-pagination-lg > li > span
+{
+    font-size: 18px;
+
+    padding: 10px 16px;
+}
+
+.mui-pagination-sm > li > a,
+.mui-pagination-sm > li > span
+{
+    font-size: 12px;
+
+    padding: 5px 10px;
+}
+
+.mui-pager
+{
+    padding-left: 0;
+
+    list-style: none;
+
+    text-align: center;
+}
+.mui-pager:before, .mui-pager:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-pager:after
+{
+    clear: both;
+}
+.mui-pager li
+{
+    display: inline;
+}
+.mui-pager li > a,
+.mui-pager li > span
+{
+    display: inline-block;
+
+    padding: 5px 14px;
+
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span
+{
+    cursor: default;
+    text-decoration: none;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pager .mui-next > a,
+.mui-pager .mui-next > span
+{
+    float: right;
+}
+.mui-pager .mui-previous > a,
+.mui-pager .mui-previous > span
+{
+    float: left;
+}
+.mui-pager .mui-disabled > a,
+.mui-pager .mui-disabled > a:active,
+.mui-pager .mui-disabled > span,
+.mui-pager .mui-disabled > span:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-modal
+{
+    position: fixed;
+    z-index: 999;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+    min-height: 100%;
+
+    -webkit-transition: -webkit-transform .25s, opacity 1ms .25s;
+            transition:         transform .25s, opacity 1ms .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    opacity: 0;
+    background-color: #fff;
+}
+.mui-modal.mui-active
+{
+    height: 100%;
+
+    -webkit-transition: -webkit-transform .25s;
+            transition:         transform .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    opacity: 1;
+}
+
+.mui-android .mui-modal .mui-bar
+{
+    position: static;
+}
+
+.mui-android .mui-modal .mui-bar-nav ~ .mui-content
+{
+    padding-top: 0;
+}
+
+.mui-slider
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    border-bottom: 0;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item
+{
+    border-top: 1px solid #c8c7cc;
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-slider .mui-slider-group
+{
+    font-size: 0;
+
+    position: relative;
+
+    -webkit-transition: all 0s linear;
+            transition: all 0s linear;
+    white-space: nowrap;
+}
+.mui-slider .mui-slider-group .mui-slider-item
+{
+    font-size: 14px;
+
+    position: relative;
+
+    display: inline-block;
+
+    width: 100%;
+    height: 100%;
+
+    vertical-align: top;
+    white-space: normal;
+}
+.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item)
+{
+    line-height: 0;
+
+    position: relative;
+
+    display: block;
+}
+.mui-slider .mui-slider-group .mui-slider-item img
+{
+    width: 100%;
+}
+.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after
+{
+    height: 0;
+}
+.mui-slider .mui-slider-group.mui-slider-loop
+{
+    -webkit-transform: translate(-100%, 0px);
+            transform: translate(-100%, 0px);
+}
+
+.mui-slider-title
+{
+    line-height: 30px;
+
+    position: absolute;
+    bottom: 0;
+    left: 0;
+
+    width: 100%;
+    height: 30px;
+    margin: 0;
+
+    text-align: left;
+    text-indent: 12px;
+
+    opacity: .8;
+    background-color: #000;
+}
+
+.mui-slider-indicator
+{
+    position: absolute;
+    bottom: 8px;
+
+    width: 100%;
+
+    text-align: center;
+
+    background: none;
+}
+.mui-slider-indicator.mui-segmented-control
+{
+    position: relative;
+    bottom: auto;
+}
+.mui-slider-indicator .mui-indicator
+{
+    display: inline-block;
+
+    width: 6px;
+    height: 6px;
+    margin: 1px 6px;
+
+    cursor: pointer;
+
+    border-radius: 50%;
+    background: #aaa;
+    -webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+            box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+}
+.mui-slider-indicator .mui-active.mui-indicator
+{
+    background: #fff;
+}
+.mui-slider-indicator .mui-icon
+{
+    font-size: 20px;
+    line-height: 30px;
+
+    width: 40px;
+    height: 30px;
+    margin: 3px;
+
+    text-align: center;
+
+    border: 1px solid #ddd;
+}
+.mui-slider-indicator .mui-number
+{
+    line-height: 32px;
+
+    display: inline-block;
+
+    width: 58px;
+}
+.mui-slider-indicator .mui-number span
+{
+    color: #ff5053;
+}
+
+.mui-slider-progress-bar
+{
+    z-index: 1;
+
+    height: 2px;
+
+    -webkit-transform: translateZ(0);
+            transform: translateZ(0);
+}
+
+.mui-switch
+{
+    position: relative;
+
+    display: block;
+
+    width: 74px;
+    height: 30px;
+
+    -webkit-transition-timing-function: ease-in-out;
+            transition-timing-function: ease-in-out;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    -webkit-transition-property: background-color, border;
+            transition-property: background-color, border;
+
+    border: 2px solid #ddd;
+    border-radius: 20px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-switch.mui-disabled
+{
+    opacity: .3;
+}
+.mui-switch .mui-switch-handle
+{
+    position: absolute;
+    z-index: 1;
+    top: -1px;
+    left: -1px;
+
+    width: 28px;
+    height: 28px;
+
+    -webkit-transition: .2s ease-in-out;
+            transition: .2s ease-in-out;
+    -webkit-transition-property: -webkit-transform, width,left;
+            transition-property:         transform, width,left;
+
+    border-radius: 16px;
+    background-color: #fff;
+    background-clip: padding-box;
+    -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+            box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+}
+.mui-switch:before
+{
+    font-size: 13px;
+
+    position: absolute;
+    top: 3px;
+    right: 11px;
+
+    content: 'Off';
+    text-transform: uppercase;
+
+    color: #999;
+}
+.mui-switch.mui-dragging
+{
+    border-color: #f7f7f7;
+    background-color: #f7f7f7;
+}
+.mui-switch.mui-dragging .mui-switch-handle
+{
+    width: 38px;
+}
+.mui-switch.mui-dragging.mui-active .mui-switch-handle
+{
+    left: -11px;
+
+    width: 38px;
+}
+.mui-switch.mui-active
+{
+    border-color: #4cd964;
+    background-color: #4cd964;
+}
+.mui-switch.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(43px, 0);
+            transform: translate(43px, 0);
+}
+.mui-switch.mui-active:before
+{
+    right: auto;
+    left: 15px;
+
+    content: 'On';
+
+    color: #fff;
+}
+.mui-switch input[type='checkbox']
+{
+    display: none;
+}
+
+.mui-switch-mini
+{
+    width: 47px;
+}
+.mui-switch-mini:before
+{
+    display: none;
+}
+.mui-switch-mini.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(16px, 0);
+            transform: translate(16px, 0);
+}
+
+.mui-switch-blue.mui-active
+{
+    border: 2px solid #007aff;
+    background-color: #007aff;
+}
+
+.mui-content.mui-fade
+{
+    left: 0;
+
+    opacity: 0;
+}
+.mui-content.mui-fade.mui-in
+{
+    opacity: 1;
+}
+.mui-content.mui-sliding
+{
+    z-index: 2;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-content.mui-sliding.mui-left
+{
+    z-index: 1;
+
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-content.mui-sliding.mui-right
+{
+    z-index: 3;
+
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+
+.mui-navigate-right:after,
+.mui-push-left:after,
+.mui-push-right:after
+{
+    font-family: Muiicons;
+    font-size: inherit;
+    line-height: 1;
+
+    position: absolute;
+    top: 50%;
+
+    display: inline-block;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+    text-decoration: none;
+
+    color: #bbb;
+
+    -webkit-font-smoothing: antialiased;
+}
+
+.mui-push-left:after
+{
+    left: 15px;
+
+    content: '\e582';
+}
+
+.mui-navigate-right:after,
+.mui-push-right:after
+{
+    right: 15px;
+
+    content: '\e583';
+}
+
+.mui-pull-top-pocket, .mui-pull-bottom-pocket
+{
+    position: absolute;
+    left: 0;
+
+    display: block;
+    visibility: hidden;
+    overflow: hidden;
+
+    width: 100%;
+    height: 50px;
+}
+
+.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket
+{
+    display: none;
+    visibility: visible;
+}
+
+.mui-pull-top-pocket
+{
+    top: 0;
+}
+
+.mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 44px;
+}
+
+.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket
+{
+    top: 88px;
+}
+
+.mui-pull-bottom-pocket
+{
+    position: relative;
+    bottom: 0;
+
+    height: 40px;
+}
+.mui-pull-bottom-pocket .mui-pull-loading
+{
+    visibility: hidden;
+}
+.mui-pull-bottom-pocket .mui-pull-loading.mui-in
+{
+    display: inline-block;
+}
+
+.mui-pull
+{
+    font-weight: bold;
+
+    position: absolute;
+    right: 0;
+    bottom: 10px;
+    left: 0;
+
+    text-align: center;
+
+    color: #777;
+}
+
+.mui-pull-loading
+{
+    margin-right: 10px;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    vertical-align: middle;
+}
+
+.mui-pull-loading.mui-reverse
+{
+    -webkit-transform: rotate(180deg) translateZ(0);
+            transform: rotate(180deg) translateZ(0);
+}
+
+.mui-pull-caption
+{
+    font-size: 15px;
+    line-height: 24px;
+
+    position: relative;
+
+    display: inline-block;
+    overflow: visible;
+
+    margin-top: 0;
+
+    vertical-align: middle;
+}
+.mui-pull-caption span
+{
+    display: none;
+}
+.mui-pull-caption span.mui-in
+{
+    display: inline;
+}
+
+.mui-toast-container
+{
+    line-height: 17px;
+
+    position: fixed;
+    z-index: 9999;
+    bottom: 50px;
+    left: 50%;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transform: translate(-50%, 0);
+            transform: translate(-50%, 0);
+
+    opacity: 0;
+}
+.mui-toast-container.mui-active
+{
+    opacity: .9;
+}
+
+.mui-toast-message
+{
+    font-size: 14px;
+
+    padding: 10px 25px;
+
+    text-align: center;
+
+    color: #fff;
+    border-radius: 6px;
+    background-color: #323232;
+}
+
+.mui-numbox
+{
+    position: relative;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: 120px;
+    height: 35px;
+    padding: 0 40px 0 40px;
+
+    vertical-align: top;
+    vertical-align: middle;
+
+    border: solid 1px #bbb;
+    border-radius: 3px;
+    background-color: #efeff4;
+}
+.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox]
+{
+    font-size: 18px;
+    font-weight: normal;
+    line-height: 100%;
+
+    position: absolute;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 40px;
+    height: 100%;
+    padding: 0;
+
+    color: #555;
+    border: none;
+    border-radius: 0;
+    background-color: #f9f9f9;
+}
+.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active
+{
+    background-color: #ccc;
+}
+.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled]
+{
+    color: #c0c0c0;
+}
+.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus
+{
+    right: 0;
+
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+}
+.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus
+{
+    left: 0;
+
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+}
+.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox
+{
+    display: inline-block;
+    overflow: hidden;
+
+    width: 100% !important;
+    height: 100%;
+    margin: 0;
+    padding: 0 3px !important;
+
+    text-align: center;
+    text-overflow: ellipsis;
+    word-break: normal;
+
+    border: none !important;
+    border-right: solid 1px #ccc !important;
+    border-left: solid 1px #ccc !important;
+    border-radius: 0 !important;
+}
+
+.mui-input-row .mui-numbox
+{
+    float: right;
+
+    margin: 2px 8px;
+}
+
+@font-face {
+    font-family: Muiicons;
+    font-weight: normal;
+    font-style: normal;
+
+    src: url('../fonts/mui.ttf') format('truetype');
+}
+.mui-icon
+{
+    font-family: Muiicons;
+    font-size: 24px;
+    font-weight: normal;
+    font-style: normal;
+    line-height: 1;
+
+    display: inline-block;
+
+    text-decoration: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-icon.mui-active
+{
+    color: #007aff;
+}
+.mui-icon.mui-right:before
+{
+    float: right;
+
+    padding-left: .2em;
+}
+
+.mui-icon-contact:before
+{
+    content: '\e100';
+}
+
+.mui-icon-person:before
+{
+    content: '\e101';
+}
+
+.mui-icon-personadd:before
+{
+    content: '\e102';
+}
+
+.mui-icon-contact-filled:before
+{
+    content: '\e130';
+}
+
+.mui-icon-person-filled:before
+{
+    content: '\e131';
+}
+
+.mui-icon-personadd-filled:before
+{
+    content: '\e132';
+}
+
+.mui-icon-phone:before
+{
+    content: '\e200';
+}
+
+.mui-icon-email:before
+{
+    content: '\e201';
+}
+
+.mui-icon-chatbubble:before
+{
+    content: '\e202';
+}
+
+.mui-icon-chatboxes:before
+{
+    content: '\e203';
+}
+
+.mui-icon-phone-filled:before
+{
+    content: '\e230';
+}
+
+.mui-icon-email-filled:before
+{
+    content: '\e231';
+}
+
+.mui-icon-chatbubble-filled:before
+{
+    content: '\e232';
+}
+
+.mui-icon-chatboxes-filled:before
+{
+    content: '\e233';
+}
+
+.mui-icon-weibo:before
+{
+    content: '\e260';
+}
+
+.mui-icon-weixin:before
+{
+    content: '\e261';
+}
+
+.mui-icon-pengyouquan:before
+{
+    content: '\e262';
+}
+
+.mui-icon-chat:before
+{
+    content: '\e263';
+}
+
+.mui-icon-qq:before
+{
+    content: '\e264';
+}
+
+.mui-icon-videocam:before
+{
+    content: '\e300';
+}
+
+.mui-icon-camera:before
+{
+    content: '\e301';
+}
+
+.mui-icon-mic:before
+{
+    content: '\e302';
+}
+
+.mui-icon-location:before
+{
+    content: '\e303';
+}
+
+.mui-icon-mic-filled:before, .mui-icon-speech:before
+{
+    content: '\e332';
+}
+
+.mui-icon-location-filled:before
+{
+    content: '\e333';
+}
+
+.mui-icon-micoff:before
+{
+    content: '\e360';
+}
+
+.mui-icon-image:before
+{
+    content: '\e363';
+}
+
+.mui-icon-map:before
+{
+    content: '\e364';
+}
+
+.mui-icon-compose:before
+{
+    content: '\e400';
+}
+
+.mui-icon-trash:before
+{
+    content: '\e401';
+}
+
+.mui-icon-upload:before
+{
+    content: '\e402';
+}
+
+.mui-icon-download:before
+{
+    content: '\e403';
+}
+
+.mui-icon-close:before
+{
+    content: '\e404';
+}
+
+.mui-icon-redo:before
+{
+    content: '\e405';
+}
+
+.mui-icon-undo:before
+{
+    content: '\e406';
+}
+
+.mui-icon-refresh:before
+{
+    content: '\e407';
+}
+
+.mui-icon-star:before
+{
+    content: '\e408';
+}
+
+.mui-icon-plus:before
+{
+    content: '\e409';
+}
+
+.mui-icon-minus:before
+{
+    content: '\e410';
+}
+
+.mui-icon-circle:before, .mui-icon-checkbox:before
+{
+    content: '\e411';
+}
+
+.mui-icon-close-filled:before, .mui-icon-clear:before
+{
+    content: '\e434';
+}
+
+.mui-icon-refresh-filled:before
+{
+    content: '\e437';
+}
+
+.mui-icon-star-filled:before
+{
+    content: '\e438';
+}
+
+.mui-icon-plus-filled:before
+{
+    content: '\e439';
+}
+
+.mui-icon-minus-filled:before
+{
+    content: '\e440';
+}
+
+.mui-icon-circle-filled:before
+{
+    content: '\e441';
+}
+
+.mui-icon-checkbox-filled:before
+{
+    content: '\e442';
+}
+
+.mui-icon-closeempty:before
+{
+    content: '\e460';
+}
+
+.mui-icon-refreshempty:before
+{
+    content: '\e461';
+}
+
+.mui-icon-reload:before
+{
+    content: '\e462';
+}
+
+.mui-icon-starhalf:before
+{
+    content: '\e463';
+}
+
+.mui-icon-spinner:before
+{
+    content: '\e464';
+}
+
+.mui-icon-spinner-cycle:before
+{
+    content: '\e465';
+}
+
+.mui-icon-search:before
+{
+    content: '\e466';
+}
+
+.mui-icon-plusempty:before
+{
+    content: '\e468';
+}
+
+.mui-icon-forward:before
+{
+    content: '\e470';
+}
+
+.mui-icon-back:before, .mui-icon-left-nav:before
+{
+    content: '\e471';
+}
+
+.mui-icon-checkmarkempty:before
+{
+    content: '\e472';
+}
+
+.mui-icon-home:before
+{
+    content: '\e500';
+}
+
+.mui-icon-navigate:before
+{
+    content: '\e501';
+}
+
+.mui-icon-gear:before
+{
+    content: '\e502';
+}
+
+.mui-icon-paperplane:before
+{
+    content: '\e503';
+}
+
+.mui-icon-info:before
+{
+    content: '\e504';
+}
+
+.mui-icon-help:before
+{
+    content: '\e505';
+}
+
+.mui-icon-locked:before
+{
+    content: '\e506';
+}
+
+.mui-icon-more:before
+{
+    content: '\e507';
+}
+
+.mui-icon-flag:before
+{
+    content: '\e508';
+}
+
+.mui-icon-home-filled:before
+{
+    content: '\e530';
+}
+
+.mui-icon-gear-filled:before
+{
+    content: '\e532';
+}
+
+.mui-icon-info-filled:before
+{
+    content: '\e534';
+}
+
+.mui-icon-help-filled:before
+{
+    content: '\e535';
+}
+
+.mui-icon-more-filled:before
+{
+    content: '\e537';
+}
+
+.mui-icon-settings:before
+{
+    content: '\e560';
+}
+
+.mui-icon-list:before
+{
+    content: '\e562';
+}
+
+.mui-icon-bars:before
+{
+    content: '\e563';
+}
+
+.mui-icon-loop:before
+{
+    content: '\e565';
+}
+
+.mui-icon-paperclip:before
+{
+    content: '\e567';
+}
+
+.mui-icon-eye:before
+{
+    content: '\e568';
+}
+
+.mui-icon-arrowup:before
+{
+    content: '\e580';
+}
+
+.mui-icon-arrowdown:before
+{
+    content: '\e581';
+}
+
+.mui-icon-arrowleft:before
+{
+    content: '\e582';
+}
+
+.mui-icon-arrowright:before
+{
+    content: '\e583';
+}
+
+.mui-icon-arrowthinup:before
+{
+    content: '\e584';
+}
+
+.mui-icon-arrowthindown:before
+{
+    content: '\e585';
+}
+
+.mui-icon-arrowthinleft:before
+{
+    content: '\e586';
+}
+
+.mui-icon-arrowthinright:before
+{
+    content: '\e587';
+}
+
+.mui-icon-pulldown:before
+{
+    content: '\e588';
+}
+
+.mui-fullscreen
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+.mui-fullscreen.mui-slider .mui-slider-group
+{
+    height: 100%;
+}
+.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    position: absolute;
+    top: 40px;
+    bottom: 0;
+
+    width: 100%;
+    height: auto;
+}
+.mui-fullscreen.mui-slider .mui-slider-item > a
+{
+    top: 50%;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a
+{
+    top: auto;
+
+    -webkit-transform: none;
+            transform: none;
+}
+
+.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen
+{
+    top: 44px;
+}
+
+.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    bottom: 50px;
+}
+
+.mui-android.mui-android-4-0 input:focus,
+.mui-android.mui-android-4-0 textarea:focus
+{
+    -webkit-user-modify: inherit;
+}
+
+.mui-android.mui-android-4-2 input,
+.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input,
+.mui-android.mui-android-4-3 textarea
+{
+    -webkit-user-select: text;
+}
+
+.mui-ios .mui-table-view-cell
+{
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+
+.mui-plus-visible, .mui-wechat-visible
+{
+    display: none !important;
+}
+
+.mui-plus-hidden, .mui-wechat-hidden
+{
+    display: block !important;
+}
+
+.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible
+{
+    display: block !important;
+}
+
+.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden
+{
+    display: none !important;
+}
+
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav
+{
+    height: 64px;
+    padding-top: 20px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content
+{
+    padding-top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 94px;
+}
+
+.mui-iframe-wrapper
+{
+    position: absolute;
+    right: 0;
+    left: 0;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-iframe-wrapper iframe
+{
+    width: 100%;
+    height: 100%;
+
+    border: 0;
+}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4 - 0
hbuild/online/css/mui.min.css


BIN
hbuild/online/fonts/mui.ttf


+ 16 - 0
hbuild/online/index.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+    <title></title>
+    <script src="js/mui.min.js"></script>
+    <link href="css/mui.min.css" rel="stylesheet"/>
+    <script type="text/javascript" charset="utf-8">
+      	mui.init();
+    </script>
+</head>
+<body>
+	
+</body>
+</html>

+ 8390 - 0
hbuild/online/js/mui.js

@@ -0,0 +1,8390 @@
+/*!
+ * =====================================================
+ * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
+ * =====================================================
+ */
+/**
+ * MUI核心JS
+ * @type _L4.$|Function
+ */
+var mui = (function(document, undefined) {
+	var readyRE = /complete|loaded|interactive/;
+	var idSelectorRE = /^#([\w-]+)$/;
+	var classSelectorRE = /^\.([\w-]+)$/;
+	var tagSelectorRE = /^[\w-]+$/;
+	var translateRE = /translate(?:3d)?\((.+?)\)/;
+	var translateMatrixRE = /matrix(3d)?\((.+?)\)/;
+
+	var $ = function(selector, context) {
+		context = context || document;
+		if (!selector)
+			return wrap();
+		if (typeof selector === 'object')
+			if ($.isArrayLike(selector)) {
+				return wrap($.slice.call(selector), null);
+			} else {
+				return wrap([selector], null);
+			}
+		if (typeof selector === 'function')
+			return $.ready(selector);
+		if (typeof selector === 'string') {
+			try {
+				selector = selector.trim();
+				if (idSelectorRE.test(selector)) {
+					var found = document.getElementById(RegExp.$1);
+					return wrap(found ? [found] : []);
+				}
+				return wrap($.qsa(selector, context), selector);
+			} catch (e) {}
+		}
+		return wrap();
+	};
+
+	var wrap = function(dom, selector) {
+		dom = dom || [];
+		Object.setPrototypeOf(dom, $.fn);
+		dom.selector = selector || '';
+		return dom;
+	};
+
+	$.uuid = 0;
+
+	$.data = {};
+	/**
+	 * extend(simple)
+	 * @param {type} target
+	 * @param {type} source
+	 * @param {type} deep
+	 * @returns {unresolved}
+	 */
+	$.extend = function() { //from jquery2
+		var options, name, src, copy, copyIsArray, clone,
+			target = arguments[0] || {},
+			i = 1,
+			length = arguments.length,
+			deep = false;
+
+		if (typeof target === "boolean") {
+			deep = target;
+
+			target = arguments[i] || {};
+			i++;
+		}
+
+		if (typeof target !== "object" && !$.isFunction(target)) {
+			target = {};
+		}
+
+		if (i === length) {
+			target = this;
+			i--;
+		}
+
+		for (; i < length; i++) {
+			if ((options = arguments[i]) != null) {
+				for (name in options) {
+					src = target[name];
+					copy = options[name];
+
+					if (target === copy) {
+						continue;
+					}
+
+					if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
+						if (copyIsArray) {
+							copyIsArray = false;
+							clone = src && $.isArray(src) ? src : [];
+
+						} else {
+							clone = src && $.isPlainObject(src) ? src : {};
+						}
+
+						target[name] = $.extend(deep, clone, copy);
+
+					} else if (copy !== undefined) {
+						target[name] = copy;
+					}
+				}
+			}
+		}
+
+		return target;
+	};
+	/**
+	 * mui noop(function)
+	 */
+	$.noop = function() {};
+	/**
+	 * mui slice(array)
+	 */
+	$.slice = [].slice;
+	/**
+	 * mui filter(array)
+	 */
+	$.filter = [].filter;
+
+	$.type = function(obj) {
+		return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object";
+	};
+	/**
+	 * mui isArray
+	 */
+	$.isArray = Array.isArray ||
+		function(object) {
+			return object instanceof Array;
+		};
+	/**
+	 * mui isArrayLike 
+	 * @param {Object} obj
+	 */
+	$.isArrayLike = function(obj) {
+		var length = !!obj && "length" in obj && obj.length;
+		var type = $.type(obj);
+		if (type === "function" || $.isWindow(obj)) {
+			return false;
+		}
+		return type === "array" || length === 0 ||
+			typeof length === "number" && length > 0 && (length - 1) in obj;
+	};
+	/**
+	 * mui isWindow(需考虑obj为undefined的情况)
+	 */
+	$.isWindow = function(obj) {
+		return obj != null && obj === obj.window;
+	};
+	/**
+	 * mui isObject
+	 */
+	$.isObject = function(obj) {
+		return $.type(obj) === "object";
+	};
+	/**
+	 * mui isPlainObject
+	 */
+	$.isPlainObject = function(obj) {
+		return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype;
+	};
+	/**
+	 * mui isEmptyObject
+	 * @param {Object} o
+	 */
+	$.isEmptyObject = function(o) {
+		for (var p in o) {
+			if (p !== undefined) {
+				return false;
+			}
+		}
+		return true;
+	};
+	/**
+	 * mui isFunction
+	 */
+	$.isFunction = function(value) {
+		return $.type(value) === "function";
+	};
+	/**
+	 * mui querySelectorAll
+	 * @param {type} selector
+	 * @param {type} context
+	 * @returns {Array}
+	 */
+	$.qsa = function(selector, context) {
+		context = context || document;
+		return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector));
+	};
+	/**
+	 * ready(DOMContentLoaded)
+	 * @param {type} callback
+	 * @returns {_L6.$}
+	 */
+	$.ready = function(callback) {
+		if (readyRE.test(document.readyState)) {
+			callback($);
+		} else {
+			document.addEventListener('DOMContentLoaded', function() {
+				callback($);
+			}, false);
+		}
+		return this;
+	};
+	/**
+	 * 将 fn 缓存一段时间后, 再被调用执行
+	 * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中;
+	 * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样;
+	 * 调用返回函数的 stop 停止最后一次的 buffer 效果
+	 * @param {Object} fn
+	 * @param {Object} ms
+	 * @param {Object} context
+	 */
+	$.buffer = function(fn, ms, context) {
+		var timer;
+		var lastStart = 0;
+		var lastEnd = 0;
+		var ms = ms || 150;
+
+		function run() {
+			if (timer) {
+				timer.cancel();
+				timer = 0;
+			}
+			lastStart = $.now();
+			fn.apply(context || this, arguments);
+			lastEnd = $.now();
+		}
+
+		return $.extend(function() {
+			if (
+				(!lastStart) || // 从未运行过
+				(lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒
+				(lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒
+			) {
+				run.apply(this, arguments);
+			} else {
+				if (timer) {
+					timer.cancel();
+				}
+				timer = $.later(run, ms, null, $.slice.call(arguments));
+			}
+		}, {
+			stop: function() {
+				if (timer) {
+					timer.cancel();
+					timer = 0;
+				}
+			}
+		});
+	};
+	/**
+	 * each
+	 * @param {type} elements
+	 * @param {type} callback
+	 * @returns {_L8.$}
+	 */
+	$.each = function(elements, callback, hasOwnProperty) {
+		if (!elements) {
+			return this;
+		}
+		if (typeof elements.length === 'number') {
+			[].every.call(elements, function(el, idx) {
+				return callback.call(el, idx, el) !== false;
+			});
+		} else {
+			for (var key in elements) {
+				if (hasOwnProperty) {
+					if (elements.hasOwnProperty(key)) {
+						if (callback.call(elements[key], key, elements[key]) === false) return elements;
+					}
+				} else {
+					if (callback.call(elements[key], key, elements[key]) === false) return elements;
+				}
+			}
+		}
+		return this;
+	};
+	$.focus = function(element) {
+		if ($.os.ios) {
+			setTimeout(function() {
+				element.focus();
+			}, 10);
+		} else {
+			element.focus();
+		}
+	};
+	/**
+	 * trigger event
+	 * @param {type} element
+	 * @param {type} eventType
+	 * @param {type} eventData
+	 * @returns {_L8.$}
+	 */
+	$.trigger = function(element, eventType, eventData) {
+		element.dispatchEvent(new CustomEvent(eventType, {
+			detail: eventData,
+			bubbles: true,
+			cancelable: true
+		}));
+		return this;
+	};
+	/**
+	 * getStyles
+	 * @param {type} element
+	 * @param {type} property
+	 * @returns {styles}
+	 */
+	$.getStyles = function(element, property) {
+		var styles = element.ownerDocument.defaultView.getComputedStyle(element, null);
+		if (property) {
+			return styles.getPropertyValue(property) || styles[property];
+		}
+		return styles;
+	};
+	/**
+	 * parseTranslate
+	 * @param {type} translateString
+	 * @param {type} position
+	 * @returns {Object}
+	 */
+	$.parseTranslate = function(translateString, position) {
+		var result = translateString.match(translateRE || '');
+		if (!result || !result[1]) {
+			result = ['', '0,0,0'];
+		}
+		result = result[1].split(",");
+		result = {
+			x: parseFloat(result[0]),
+			y: parseFloat(result[1]),
+			z: parseFloat(result[2])
+		};
+		if (position && result.hasOwnProperty(position)) {
+			return result[position];
+		}
+		return result;
+	};
+	/**
+	 * parseTranslateMatrix
+	 * @param {type} translateString
+	 * @param {type} position
+	 * @returns {Object}
+	 */
+	$.parseTranslateMatrix = function(translateString, position) {
+		var matrix = translateString.match(translateMatrixRE);
+		var is3D = matrix && matrix[1];
+		if (matrix) {
+			matrix = matrix[2].split(",");
+			if (is3D === "3d")
+				matrix = matrix.slice(12, 15);
+			else {
+				matrix.push(0);
+				matrix = matrix.slice(4, 7);
+			}
+		} else {
+			matrix = [0, 0, 0];
+		}
+		var result = {
+			x: parseFloat(matrix[0]),
+			y: parseFloat(matrix[1]),
+			z: parseFloat(matrix[2])
+		};
+		if (position && result.hasOwnProperty(position)) {
+			return result[position];
+		}
+		return result;
+	};
+	$.hooks = {};
+	$.addAction = function(type, hook) {
+		var hooks = $.hooks[type];
+		if (!hooks) {
+			hooks = [];
+		}
+		hook.index = hook.index || 1000;
+		hooks.push(hook);
+		hooks.sort(function(a, b) {
+			return a.index - b.index;
+		});
+		$.hooks[type] = hooks;
+		return $.hooks[type];
+	};
+	$.doAction = function(type, callback) {
+		if ($.isFunction(callback)) { //指定了callback
+			$.each($.hooks[type], callback);
+		} else { //未指定callback,直接执行
+			$.each($.hooks[type], function(index, hook) {
+				return !hook.handle();
+			});
+		}
+	};
+	/**
+	 * setTimeout封装
+	 * @param {Object} fn
+	 * @param {Object} when
+	 * @param {Object} context
+	 * @param {Object} data
+	 */
+	$.later = function(fn, when, context, data) {
+		when = when || 0;
+		var m = fn;
+		var d = data;
+		var f;
+		var r;
+
+		if (typeof fn === 'string') {
+			m = context[fn];
+		}
+
+		f = function() {
+			m.apply(context, $.isArray(d) ? d : [d]);
+		};
+
+		r = setTimeout(f, when);
+
+		return {
+			id: r,
+			cancel: function() {
+				clearTimeout(r);
+			}
+		};
+	};
+	$.now = Date.now || function() {
+		return +new Date();
+	};
+	var class2type = {};
+	$.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) {
+		class2type["[object " + name + "]"] = name.toLowerCase();
+	});
+	if (window.JSON) {
+		$.parseJSON = JSON.parse;
+	}
+	/**
+	 * $.fn
+	 */
+	$.fn = {
+		each: function(callback) {
+			[].every.call(this, function(el, idx) {
+				return callback.call(el, idx, el) !== false;
+			});
+			return this;
+		}
+	};
+
+	/**
+	 * 兼容 AMD 模块
+	 **/
+	if (typeof define === 'function' && define.amd) {
+		define('mui', [], function() {
+			return $;
+		});
+	}
+
+	return $;
+})(document);
+//window.mui = mui;
+//'$' in window || (window.$ = mui);
+/**
+ * $.os
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, window) {
+	function detect(ua) {
+		this.os = {};
+		var funcs = [
+
+			function() { //wechat
+				var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i);
+				if (wechat) { //wechat
+					this.os.wechat = {
+						version: wechat[2].replace(/_/g, '.')
+					};
+				}
+				return false;
+			},
+			function() { //android
+				var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
+				if (android) {
+					this.os.android = true;
+					this.os.version = android[2];
+
+					this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion));
+				}
+				return this.os.android === true;
+			},
+			function() { //ios
+				var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/);
+				if (iphone) { //iphone
+					this.os.ios = this.os.iphone = true;
+					this.os.version = iphone[2].replace(/_/g, '.');
+				} else {
+					var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
+					if (ipad) { //ipad
+						this.os.ios = this.os.ipad = true;
+						this.os.version = ipad[2].replace(/_/g, '.');
+					}
+				}
+				return this.os.ios === true;
+			}
+		];
+		[].every.call(funcs, function(func) {
+			return !func.call($);
+		});
+	}
+	detect.call($, navigator.userAgent);
+})(mui, window);
+/**
+ * $.os.plus
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, document) {
+	function detect(ua) {
+		this.os = this.os || {};
+		var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser?
+		if (plus) {
+			this.os.plus = true;
+			$(function() {
+				document.body.classList.add('mui-plus');
+			});
+			if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识
+				this.os.stream = true;
+				$(function() {
+					document.body.classList.add('mui-plus-stream');
+				});
+			}
+		}
+	}
+	detect.call($, navigator.userAgent);
+})(mui, document);
+/**
+ * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener)
+ * @param {Object} $
+ */
+(function($) {
+	if ('ontouchstart' in window) {
+		$.isTouchable = true;
+		$.EVENT_START = 'touchstart';
+		$.EVENT_MOVE = 'touchmove';
+		$.EVENT_END = 'touchend';
+	} else {
+		$.isTouchable = false;
+		$.EVENT_START = 'mousedown';
+		$.EVENT_MOVE = 'mousemove';
+		$.EVENT_END = 'mouseup';
+	}
+	$.EVENT_CANCEL = 'touchcancel';
+	$.EVENT_CLICK = 'click';
+
+	var _mid = 1;
+	var delegates = {};
+	//需要wrap的函数
+	var eventMethods = {
+		preventDefault: 'isDefaultPrevented',
+		stopImmediatePropagation: 'isImmediatePropagationStopped',
+		stopPropagation: 'isPropagationStopped'
+	};
+	//默认true返回函数
+	var returnTrue = function() {
+		return true
+	};
+	//默认false返回函数
+	var returnFalse = function() {
+		return false
+	};
+	//wrap浏览器事件
+	var compatible = function(event, target) {
+		if (!event.detail) {
+			event.detail = {
+				currentTarget: target
+			};
+		} else {
+			event.detail.currentTarget = target;
+		}
+		$.each(eventMethods, function(name, predicate) {
+			var sourceMethod = event[name];
+			event[name] = function() {
+				this[predicate] = returnTrue;
+				return sourceMethod && sourceMethod.apply(event, arguments)
+			}
+			event[predicate] = returnFalse;
+		}, true);
+		return event;
+	};
+	//简单的wrap对象_mid
+	var mid = function(obj) {
+		return obj && (obj._mid || (obj._mid = _mid++));
+	};
+	//事件委托对象绑定的事件回调列表
+	var delegateFns = {};
+	//返回事件委托的wrap事件回调
+	var delegateFn = function(element, event, selector, callback) {
+		return function(e) {
+			//same event
+			var callbackObjs = delegates[element._mid][event];
+			var handlerQueue = [];
+			var target = e.target;
+			var selectorAlls = {};
+			for (; target && target !== document; target = target.parentNode) {
+				if (target === element) {
+					break;
+				}
+				if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) {
+					break;
+				}
+				var matches = {};
+				$.each(callbackObjs, function(selector, callbacks) { //same selector
+					selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element));
+					if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) {
+						if (!matches[selector]) {
+							matches[selector] = callbacks;
+						}
+					}
+				}, true);
+				if (!$.isEmptyObject(matches)) {
+					handlerQueue.push({
+						element: target,
+						handlers: matches
+					});
+				}
+			}
+			selectorAlls = null;
+			e = compatible(e); //compatible event
+			$.each(handlerQueue, function(index, handler) {
+				target = handler.element;
+				var tagName = target.tagName;
+				if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) {
+					e.preventDefault();
+					e.detail && e.detail.gesture && e.detail.gesture.preventDefault();
+				}
+				$.each(handler.handlers, function(index, handler) {
+					$.each(handler, function(index, callback) {
+						if (callback.call(target, e) === false) {
+							e.preventDefault();
+							e.stopPropagation();
+						}
+					}, true);
+				}, true)
+				if (e.isPropagationStopped()) {
+					return false;
+				}
+			}, true);
+		};
+	};
+	var findDelegateFn = function(element, event) {
+		var delegateCallbacks = delegateFns[mid(element)];
+		var result = [];
+		if (delegateCallbacks) {
+			result = [];
+			if (event) {
+				var filterFn = function(fn) {
+					return fn.type === event;
+				}
+				return delegateCallbacks.filter(filterFn);
+			} else {
+				result = delegateCallbacks;
+			}
+		}
+		return result;
+	};
+	var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
+	/**
+	 * mui delegate events
+	 * @param {type} event
+	 * @param {type} selector
+	 * @param {type} callback
+	 * @returns {undefined}
+	 */
+	$.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持
+		return this.each(function() {
+			var element = this;
+			mid(element);
+			mid(callback);
+			var isAddEventListener = false;
+			var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {});
+			var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {}));
+			if ($.isEmptyObject(delegateCallbackObjs)) {
+				isAddEventListener = true;
+			}
+			var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []);
+			delegateCallbacks.push(callback);
+			if (isAddEventListener) {
+				var delegateFnArray = delegateFns[mid(element)];
+				if (!delegateFnArray) {
+					delegateFnArray = [];
+				}
+				var delegateCallback = delegateFn(element, event, selector, callback);
+				delegateFnArray.push(delegateCallback);
+				delegateCallback.i = delegateFnArray.length - 1;
+				delegateCallback.type = event;
+				delegateFns[mid(element)] = delegateFnArray;
+				element.addEventListener(event, delegateCallback);
+				if (event === 'tap') { //TODO 需要找个更好的解决方案
+					element.addEventListener('click', function(e) {
+						if (e.target) {
+							var tagName = e.target.tagName;
+							if (!preventDefaultException.test(tagName)) {
+								if (tagName === 'A') {
+									var href = e.target.href;
+									if (!(href && ~href.indexOf('tel:'))) {
+										e.preventDefault();
+									}
+								} else {
+									e.preventDefault();
+								}
+							}
+						}
+					});
+				}
+			}
+		});
+	};
+	$.fn.off = function(event, selector, callback) {
+		return this.each(function() {
+			var _mid = mid(this);
+			if (!event) { //mui(selector).off();
+				delegates[_mid] && delete delegates[_mid];
+			} else if (!selector) { //mui(selector).off(event);
+				delegates[_mid] && delete delegates[_mid][event];
+			} else if (!callback) { //mui(selector).off(event,selector);
+				delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector];
+			} else { //mui(selector).off(event,selector,callback);
+				var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector];
+				$.each(delegateCallbacks, function(index, delegateCallback) {
+					if (mid(delegateCallback) === mid(callback)) {
+						delegateCallbacks.splice(index, 1);
+						return false;
+					}
+				}, true);
+			}
+			if (delegates[_mid]) {
+				//如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调
+				if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) {
+					findDelegateFn(this, event).forEach(function(fn) {
+						this.removeEventListener(fn.type, fn);
+						delete delegateFns[_mid][fn.i];
+					}.bind(this));
+				}
+			} else {
+				//如果delegates[_mid]已不存在,删除所有
+				findDelegateFn(this).forEach(function(fn) {
+					this.removeEventListener(fn.type, fn);
+					delete delegateFns[_mid][fn.i];
+				}.bind(this));
+			}
+		});
+
+	};
+})(mui);
+/**
+ * mui target(action>popover>modal>tab>toggle)
+ */
+(function($, window, document) {
+	/**
+	 * targets
+	 */
+	$.targets = {};
+	/**
+	 * target handles
+	 */
+	$.targetHandles = [];
+	/**
+	 * register target
+	 * @param {type} target
+	 * @returns {$.targets}
+	 */
+	$.registerTarget = function(target) {
+
+		target.index = target.index || 1000;
+
+		$.targetHandles.push(target);
+
+		$.targetHandles.sort(function(a, b) {
+			return a.index - b.index;
+		});
+
+		return $.targetHandles;
+	};
+	window.addEventListener($.EVENT_START, function(event) {
+		var target = event.target;
+		var founds = {};
+		for (; target && target !== document; target = target.parentNode) {
+			var isFound = false;
+			$.each($.targetHandles, function(index, targetHandle) {
+				var name = targetHandle.name;
+				if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) {
+					$.targets[name] = targetHandle.handle(event, target);
+					if ($.targets[name]) {
+						founds[name] = true;
+						if (targetHandle.isContinue !== true) {
+							isFound = true;
+						}
+					}
+				} else {
+					if (!founds[name]) {
+						if (targetHandle.isReset !== false)
+							$.targets[name] = false;
+					}
+				}
+			});
+			if (isFound) {
+				break;
+			}
+		}
+	});
+	window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A)
+		var target = event.target;
+		var isFound = false;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.tagName === 'A') {
+				$.each($.targetHandles, function(index, targetHandle) {
+					var name = targetHandle.name;
+					if (targetHandle.hasOwnProperty('handle')) {
+						if (targetHandle.handle(event, target)) {
+							isFound = true;
+							event.preventDefault();
+							return false;
+						}
+					}
+				});
+				if (isFound) {
+					break;
+				}
+			}
+		}
+	});
+})(mui, window, document);
+/**
+ * fixed trim
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function(undefined) {
+	if (String.prototype.trim === undefined) { // fix for iOS 3.2
+		String.prototype.trim = function() {
+			return this.replace(/^\s+|\s+$/g, '');
+		};
+	}
+	Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
+		obj['__proto__'] = proto;
+		return obj;
+	};
+
+})();
+/**
+ * fixed CustomEvent
+ */
+(function() {
+	if (typeof window.CustomEvent === 'undefined') {
+		function CustomEvent(event, params) {
+			params = params || {
+				bubbles: false,
+				cancelable: false,
+				detail: undefined
+			};
+			var evt = document.createEvent('Events');
+			var bubbles = true;
+			for (var name in params) {
+				(name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]);
+			}
+			evt.initEvent(event, bubbles, true);
+			return evt;
+		};
+		CustomEvent.prototype = window.Event.prototype;
+		window.CustomEvent = CustomEvent;
+	}
+})();
+/*
+	A shim for non ES5 supporting browsers.
+	Adds function bind to Function prototype, so that you can do partial application.
+	Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees.
+*/
+
+Function.prototype.bind = Function.prototype.bind || function(to) {
+	// Make an array of our arguments, starting from second argument
+	var partial = Array.prototype.splice.call(arguments, 1),
+		// We'll need the original function.
+		fn = this;
+	var bound = function() {
+			// Join the already applied arguments to the now called ones (after converting to an array again).
+			var args = partial.concat(Array.prototype.splice.call(arguments, 0));
+			// If not being called as a constructor
+			if (!(this instanceof bound)) {
+				// return the result of the function called bound to target and partially applied.
+				return fn.apply(to, args);
+			}
+			// If being called as a constructor, apply the function bound to self.
+			fn.apply(this, args);
+		}
+		// Attach the prototype of the function to our newly created function.
+	bound.prototype = fn.prototype;
+	return bound;
+};
+/**
+ * mui fixed classList
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function(document) {
+    if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
+
+        Object.defineProperty(HTMLElement.prototype, 'classList', {
+            get: function() {
+                var self = this;
+                function update(fn) {
+                    return function(value) {
+                        var classes = self.className.split(/\s+/),
+                                index = classes.indexOf(value);
+
+                        fn(classes, index, value);
+                        self.className = classes.join(" ");
+                    };
+                }
+
+                var ret = {
+                    add: update(function(classes, index, value) {
+                        ~index || classes.push(value);
+                    }),
+                    remove: update(function(classes, index) {
+                        ~index && classes.splice(index, 1);
+                    }),
+                    toggle: update(function(classes, index, value) {
+                        ~index ? classes.splice(index, 1) : classes.push(value);
+                    }),
+                    contains: function(value) {
+                        return !!~self.className.split(/\s+/).indexOf(value);
+                    },
+                    item: function(i) {
+                        return self.className.split(/\s+/)[i] || null;
+                    }
+                };
+
+                Object.defineProperty(ret, 'length', {
+                    get: function() {
+                        return self.className.split(/\s+/).length;
+                    }
+                });
+
+                return ret;
+            }
+        });
+    }
+})(document);
+
+/**
+ * mui fixed requestAnimationFrame
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function(window) {
+	if (!window.requestAnimationFrame) {
+		var lastTime = 0;
+		window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) {
+			var currTime = new Date().getTime();
+			var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
+			var id = window.setTimeout(function() {
+				callback(currTime + timeToCall);
+			}, timeToCall);
+			lastTime = currTime + timeToCall;
+			return id;
+		};
+		window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) {
+			clearTimeout(id);
+		};
+	};
+}(window));
+/**
+ * fastclick(only for radio,checkbox)
+ */
+(function($, window, name) {
+	if (!$.os.android && !$.os.ios) { //目前仅识别android和ios
+		return;
+	}
+	if (window.FastClick) {
+		return;
+	}
+
+	var handle = function(event, target) {
+		if (target.tagName === 'LABEL') {
+			if (target.parentNode) {
+				target = target.parentNode.querySelector('input');
+			}
+		}
+		if (target && (target.type === 'radio' || target.type === 'checkbox')) {
+			if (!target.disabled) { //disabled
+				return target;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 40,
+		handle: handle,
+		target: false
+	});
+	var dispatchEvent = function(event) {
+		var targetElement = $.targets.click;
+		if (targetElement) {
+			var clickEvent, touch;
+			// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect
+			if (document.activeElement && document.activeElement !== targetElement) {
+				document.activeElement.blur();
+			}
+			touch = event.detail.gesture.changedTouches[0];
+			// Synthesise a click event, with an extra attribute so it can be tracked
+			clickEvent = document.createEvent('MouseEvents');
+			clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
+			clickEvent.forwardedTouchEvent = true;
+			targetElement.dispatchEvent(clickEvent);
+			event.detail && event.detail.gesture.preventDefault();
+		}
+	};
+	window.addEventListener('tap', dispatchEvent);
+	window.addEventListener('doubletap', dispatchEvent);
+	//捕获
+	window.addEventListener('click', function(event) {
+		if ($.targets.click) {
+			if (!event.forwardedTouchEvent) { //stop click
+				if (event.stopImmediatePropagation) {
+					event.stopImmediatePropagation();
+				} else {
+					// Part of the hack for browsers that don't support Event#stopImmediatePropagation
+					event.propagationStopped = true;
+				}
+				event.stopPropagation();
+				event.preventDefault();
+				return false;
+			}
+		}
+	}, true);
+
+})(mui, window, 'click');
+(function($, document) {
+	$(function() {
+		if (!$.os.ios) {
+			return;
+		}
+		var CLASS_FOCUSIN = 'mui-focusin';
+		var CLASS_BAR_TAB = 'mui-bar-tab';
+		var CLASS_BAR_FOOTER = 'mui-bar-footer';
+		var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary';
+		var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab';
+		// var content = document.querySelector('.' + CLASS_CONTENT);
+		// if (content) {
+		// 	document.body.insertBefore(content, document.body.firstElementChild);
+		// }
+		document.addEventListener('focusin', function(e) {
+			if ($.os.plus) { //在父webview里边不fix
+				if (window.plus) {
+					if (plus.webview.currentWebview().children().length > 0) {
+						return;
+					}
+				}
+			}
+			var target = e.target;
+			//TODO 需考虑所有键盘弹起的情况
+			if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) {
+				if (target.disabled || target.readOnly) {
+					return;
+				}
+				document.body.classList.add(CLASS_FOCUSIN);
+				var isFooter = false;
+				for (; target && target !== document; target = target.parentNode) {
+					var classList = target.classList;
+					if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) {
+						isFooter = true;
+						break;
+					}
+				}
+				if (isFooter) {
+					var scrollTop = document.body.scrollHeight;
+					var scrollLeft = document.body.scrollLeft;
+					setTimeout(function() {
+						window.scrollTo(scrollLeft, scrollTop);
+					}, 20);
+				}
+			}
+		});
+		document.addEventListener('focusout', function(e) {
+			var classList = document.body.classList;
+			if (classList.contains(CLASS_FOCUSIN)) {
+				classList.remove(CLASS_FOCUSIN);
+				setTimeout(function() {
+					window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
+				}, 20);
+			}
+		});
+	});
+})(mui, document);
+/**
+ * mui namespace(optimization)
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.namespace = 'mui';
+	$.classNamePrefix = $.namespace + '-';
+	$.classSelectorPrefix = '.' + $.classNamePrefix;
+	/**
+	 * 返回正确的className
+	 * @param {type} className
+	 * @returns {String}
+	 */
+	$.className = function(className) {
+		return $.classNamePrefix + className;
+	};
+	/**
+	 * 返回正确的classSelector
+	 * @param {type} classSelector
+	 * @returns {String}
+	 */
+	$.classSelector = function(classSelector) {
+		return classSelector.replace(/\./g, $.classSelectorPrefix);
+	};
+	/**
+         * 返回正确的eventName
+         * @param {type} event
+         * @param {type} module
+         * @returns {String}
+         */
+	$.eventName = function(event, module) {
+		return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : '');
+	};
+})(mui);
+
+/**
+ * mui gestures
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	$.gestures = {
+		session: {}
+	};
+	/**
+	 * Gesture preventDefault
+	 * @param {type} e
+	 * @returns {undefined}
+	 */
+	$.preventDefault = function(e) {
+		e.preventDefault();
+	};
+	/**
+	 * Gesture stopPropagation
+	 * @param {type} e
+	 * @returns {undefined}
+	 */
+	$.stopPropagation = function(e) {
+		e.stopPropagation();
+	};
+
+	/**
+	 * register gesture
+	 * @param {type} gesture
+	 * @returns {$.gestures}
+	 */
+	$.addGesture = function(gesture) {
+		return $.addAction('gestures', gesture);
+
+	};
+
+	var round = Math.round;
+	var abs = Math.abs;
+	var sqrt = Math.sqrt;
+	var atan = Math.atan;
+	var atan2 = Math.atan2;
+	/**
+	 * distance
+	 * @param {type} p1
+	 * @param {type} p2
+	 * @returns {Number}
+	 */
+	var getDistance = function(p1, p2, props) {
+		if(!props) {
+			props = ['x', 'y'];
+		}
+		var x = p2[props[0]] - p1[props[0]];
+		var y = p2[props[1]] - p1[props[1]];
+		return sqrt((x * x) + (y * y));
+	};
+	/**
+	 * scale
+	 * @param {Object} starts
+	 * @param {Object} moves
+	 */
+	var getScale = function(starts, moves) {
+		if(starts.length >= 2 && moves.length >= 2) {
+			var props = ['pageX', 'pageY'];
+			return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props);
+		}
+		return 1;
+	};
+	/**
+	 * angle
+	 * @param {type} p1
+	 * @param {type} p2
+	 * @returns {Number}
+	 */
+	var getAngle = function(p1, p2, props) {
+		if(!props) {
+			props = ['x', 'y'];
+		}
+		var x = p2[props[0]] - p1[props[0]];
+		var y = p2[props[1]] - p1[props[1]];
+		return atan2(y, x) * 180 / Math.PI;
+	};
+	/**
+	 * direction
+	 * @param {Object} x
+	 * @param {Object} y
+	 */
+	var getDirection = function(x, y) {
+		if(x === y) {
+			return '';
+		}
+		if(abs(x) >= abs(y)) {
+			return x > 0 ? 'left' : 'right';
+		}
+		return y > 0 ? 'up' : 'down';
+	};
+	/**
+	 * rotation
+	 * @param {Object} start
+	 * @param {Object} end
+	 */
+	var getRotation = function(start, end) {
+		var props = ['pageX', 'pageY'];
+		return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props);
+	};
+	/**
+	 * px per ms
+	 * @param {Object} deltaTime
+	 * @param {Object} x
+	 * @param {Object} y
+	 */
+	var getVelocity = function(deltaTime, x, y) {
+		return {
+			x: x / deltaTime || 0,
+			y: y / deltaTime || 0
+		};
+	};
+	/**
+	 * detect gestures
+	 * @param {type} event
+	 * @param {type} touch
+	 * @returns {undefined}
+	 */
+	var detect = function(event, touch) {
+		if($.gestures.stoped) {
+			return;
+		}
+		$.doAction('gestures', function(index, gesture) {
+			if(!$.gestures.stoped) {
+				if($.options.gestureConfig[gesture.name] !== false) {
+					gesture.handle(event, touch);
+				}
+			}
+		});
+	};
+	/**
+	 * 暂时无用
+	 * @param {Object} node
+	 * @param {Object} parent
+	 */
+	var hasParent = function(node, parent) {
+		while(node) {
+			if(node == parent) {
+				return true;
+			}
+			node = node.parentNode;
+		}
+		return false;
+	};
+
+	var uniqueArray = function(src, key, sort) {
+		var results = [];
+		var values = [];
+		var i = 0;
+
+		while(i < src.length) {
+			var val = key ? src[i][key] : src[i];
+			if(values.indexOf(val) < 0) {
+				results.push(src[i]);
+			}
+			values[i] = val;
+			i++;
+		}
+
+		if(sort) {
+			if(!key) {
+				results = results.sort();
+			} else {
+				results = results.sort(function sortUniqueArray(a, b) {
+					return a[key] > b[key];
+				});
+			}
+		}
+
+		return results;
+	};
+	var getMultiCenter = function(touches) {
+		var touchesLength = touches.length;
+		if(touchesLength === 1) {
+			return {
+				x: round(touches[0].pageX),
+				y: round(touches[0].pageY)
+			};
+		}
+
+		var x = 0;
+		var y = 0;
+		var i = 0;
+		while(i < touchesLength) {
+			x += touches[i].pageX;
+			y += touches[i].pageY;
+			i++;
+		}
+
+		return {
+			x: round(x / touchesLength),
+			y: round(y / touchesLength)
+		};
+	};
+	var multiTouch = function() {
+		return $.options.gestureConfig.pinch;
+	};
+	var copySimpleTouchData = function(touch) {
+		var touches = [];
+		var i = 0;
+		while(i < touch.touches.length) {
+			touches[i] = {
+				pageX: round(touch.touches[i].pageX),
+				pageY: round(touch.touches[i].pageY)
+			};
+			i++;
+		}
+		return {
+			timestamp: $.now(),
+			gesture: touch.gesture,
+			touches: touches,
+			center: getMultiCenter(touch.touches),
+			deltaX: touch.deltaX,
+			deltaY: touch.deltaY
+		};
+	};
+
+	var calDelta = function(touch) {
+		var session = $.gestures.session;
+		var center = touch.center;
+		var offset = session.offsetDelta || {};
+		var prevDelta = session.prevDelta || {};
+		var prevTouch = session.prevTouch || {};
+
+		if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) {
+			prevDelta = session.prevDelta = {
+				x: prevTouch.deltaX || 0,
+				y: prevTouch.deltaY || 0
+			};
+
+			offset = session.offsetDelta = {
+				x: center.x,
+				y: center.y
+			};
+		}
+		touch.deltaX = prevDelta.x + (center.x - offset.x);
+		touch.deltaY = prevDelta.y + (center.y - offset.y);
+	};
+	var calTouchData = function(touch) {
+		var session = $.gestures.session;
+		var touches = touch.touches;
+		var touchesLength = touches.length;
+
+		if(!session.firstTouch) {
+			session.firstTouch = copySimpleTouchData(touch);
+		}
+
+		if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) {
+			session.firstMultiTouch = copySimpleTouchData(touch);
+		} else if(touchesLength === 1) {
+			session.firstMultiTouch = false;
+		}
+
+		var firstTouch = session.firstTouch;
+		var firstMultiTouch = session.firstMultiTouch;
+		var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center;
+
+		var center = touch.center = getMultiCenter(touches);
+		touch.timestamp = $.now();
+		touch.deltaTime = touch.timestamp - firstTouch.timestamp;
+
+		touch.angle = getAngle(offsetCenter, center);
+		touch.distance = getDistance(offsetCenter, center);
+
+		calDelta(touch);
+
+		touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY);
+
+		touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1;
+		touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0;
+
+		calIntervalTouchData(touch);
+
+	};
+	var CAL_INTERVAL = 25;
+	var calIntervalTouchData = function(touch) {
+		var session = $.gestures.session;
+		var last = session.lastInterval || touch;
+		var deltaTime = touch.timestamp - last.timestamp;
+		var velocity;
+		var velocityX;
+		var velocityY;
+		var direction;
+
+		if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) {
+			var deltaX = last.deltaX - touch.deltaX;
+			var deltaY = last.deltaY - touch.deltaY;
+
+			var v = getVelocity(deltaTime, deltaX, deltaY);
+			velocityX = v.x;
+			velocityY = v.y;
+			velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
+			direction = getDirection(deltaX, deltaY) || last.direction;
+
+			session.lastInterval = touch;
+		} else {
+			velocity = last.velocity;
+			velocityX = last.velocityX;
+			velocityY = last.velocityY;
+			direction = last.direction;
+		}
+
+		touch.velocity = velocity;
+		touch.velocityX = velocityX;
+		touch.velocityY = velocityY;
+		touch.direction = direction;
+	};
+	var targetIds = {};
+	var convertTouches = function(touches) {
+		for(var i = 0; i < touches.length; i++) {
+			!touches['identifier'] && (touches['identifier'] = 0);
+		}
+		return touches;
+	};
+	var getTouches = function(event, touch) {
+		var allTouches = convertTouches($.slice.call(event.touches || [event]));
+
+		var type = event.type;
+
+		var targetTouches = [];
+		var changedTargetTouches = [];
+
+		//当touchstart或touchmove且touches长度为1,直接获得all和changed
+		if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) {
+			targetIds[allTouches[0].identifier] = true;
+			targetTouches = allTouches;
+			changedTargetTouches = allTouches;
+			touch.target = event.target;
+		} else {
+			var i = 0;
+			var targetTouches = [];
+			var changedTargetTouches = [];
+			var changedTouches = convertTouches($.slice.call(event.changedTouches || [event]));
+
+			touch.target = event.target;
+			var sessionTarget = $.gestures.session.target || event.target;
+			targetTouches = allTouches.filter(function(touch) {
+				return hasParent(touch.target, sessionTarget);
+			});
+
+			if(type === $.EVENT_START) {
+				i = 0;
+				while(i < targetTouches.length) {
+					targetIds[targetTouches[i].identifier] = true;
+					i++;
+				}
+			}
+
+			i = 0;
+			while(i < changedTouches.length) {
+				if(targetIds[changedTouches[i].identifier]) {
+					changedTargetTouches.push(changedTouches[i]);
+				}
+				if(type === $.EVENT_END || type === $.EVENT_CANCEL) {
+					delete targetIds[changedTouches[i].identifier];
+				}
+				i++;
+			}
+
+			if(!changedTargetTouches.length) {
+				return false;
+			}
+		}
+		targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true);
+		var touchesLength = targetTouches.length;
+		var changedTouchesLength = changedTargetTouches.length;
+		if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first
+			touch.isFirst = true;
+			$.gestures.touch = $.gestures.session = {
+				target: event.target
+			};
+		}
+		touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0));
+
+		touch.touches = targetTouches;
+		touch.changedTouches = changedTargetTouches;
+		return true;
+
+	};
+	var handleTouchEvent = function(event) {
+		var touch = {
+			gesture: event
+		};
+		var touches = getTouches(event, touch);
+		if(!touches) {
+			return;
+		}
+		calTouchData(touch);
+		detect(event, touch);
+		$.gestures.session.prevTouch = touch;
+		if(event.type === $.EVENT_END && !$.isTouchable) {
+			$.gestures.touch = $.gestures.session = {};
+		}
+	};
+	var supportsPassive = (function checkPassiveListener() {
+		var supportsPassive = false;
+		try {
+			var opts = Object.defineProperty({}, 'passive', {
+				get: function get() {
+					supportsPassive = true;
+				},
+			});
+			window.addEventListener('testPassiveListener', null, opts);
+		} catch(e) {
+			// No support
+		}
+		return supportsPassive;
+	}())
+	window.addEventListener($.EVENT_START, handleTouchEvent);
+	window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? {
+		passive: false,
+		capture: false
+	} : false);
+	window.addEventListener($.EVENT_END, handleTouchEvent);
+	window.addEventListener($.EVENT_CANCEL, handleTouchEvent);
+	//fixed hashchange(android)
+	window.addEventListener($.EVENT_CLICK, function(e) {
+		//TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等
+		if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) {
+			e.preventDefault();
+		}
+	}, true);
+
+	//增加原生滚动识别
+	$.isScrolling = false;
+	var scrollingTimeout = null;
+	window.addEventListener('scroll', function() {
+		$.isScrolling = true;
+		scrollingTimeout && clearTimeout(scrollingTimeout);
+		scrollingTimeout = setTimeout(function() {
+			$.isScrolling = false;
+		}, 250);
+	});
+})(mui, window);
+/**
+ * mui gesture flick[left|right|up|down]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var flickStartTime = 0;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		var now = $.now();
+		switch (event.type) {
+			case $.EVENT_MOVE:
+				if (now - flickStartTime > 300) {
+					flickStartTime = now;
+					session.flickStart = touch.center;
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				touch.flick = false;
+				if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) {
+					touch.flick = true;
+					touch.flickTime = now - flickStartTime;
+					touch.flickDistanceX = touch.center.x - session.flickStart.x;
+					touch.flickDistanceY = touch.center.y - session.flickStart.y;
+					$.trigger(session.target, name, touch);
+					$.trigger(session.target, name + touch.direction, touch);
+				}
+				break;
+		}
+
+	};
+	/**
+	 * mui gesture flick
+	 */
+	$.addGesture({
+		name: name,
+		index: 5,
+		handle: handle,
+		options: {
+			flickMaxTime: 200,
+			flickMinDistince: 10
+		}
+	});
+})(mui, 'flick');
+/**
+ * mui gesture swipe[left|right|up|down]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) {
+			var options = this.options;
+			touch.swipe = false;
+			//TODO 后续根据velocity计算
+			if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) {
+				touch.swipe = true;
+				$.trigger(session.target, name, touch);
+				$.trigger(session.target, name + touch.direction, touch);
+			}
+		}
+	};
+	/**
+	 * mui gesture swipe
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			swipeMaxTime: 300,
+			swipeMinDistince: 18
+		}
+	});
+})(mui, 'swipe');
+/**
+ * mui gesture drag[start|left|right|up|down|end]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		switch (event.type) {
+			case $.EVENT_START:
+				break;
+			case $.EVENT_MOVE:
+				if (!touch.direction || !session.target) {
+					return;
+				}
+				//修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套
+				if (session.lockDirection && session.startDirection) {
+					if (session.startDirection && session.startDirection !== touch.direction) {
+						if (session.startDirection === 'up' || session.startDirection === 'down') {
+							touch.direction = touch.deltaY < 0 ? 'up' : 'down';
+						} else {
+							touch.direction = touch.deltaX < 0 ? 'left' : 'right';
+						}
+					}
+				}
+
+				if (!session.drag) {
+					session.drag = true;
+					$.trigger(session.target, name + 'start', touch);
+				}
+				$.trigger(session.target, name, touch);
+				$.trigger(session.target, name + touch.direction, touch);
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if (session.drag && touch.isFinal) {
+					$.trigger(session.target, name + 'end', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture drag
+	 */
+	$.addGesture({
+		name: name,
+		index: 20,
+		handle: handle,
+		options: {
+			fingers: 1
+		}
+	});
+})(mui, 'drag');
+/**
+ * mui gesture tap and doubleTap
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var lastTarget;
+	var lastTapTime;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_END:
+				if (!touch.isFinal) {
+					return;
+				}
+				var target = session.target;
+				if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) {
+					return;
+				}
+				if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) {
+					if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target
+						if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) {
+							$.trigger(target, 'doubletap', touch);
+							lastTapTime = $.now();
+							lastTarget = target;
+							return;
+						}
+					}
+					$.trigger(target, name, touch);
+					lastTapTime = $.now();
+					lastTarget = target;
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture tap
+	 */
+	$.addGesture({
+		name: name,
+		index: 30,
+		handle: handle,
+		options: {
+			fingers: 1,
+			tapMaxInterval: 300,
+			tapMaxDistance: 5,
+			tapMaxTime: 250
+		}
+	});
+})(mui, 'tap');
+/**
+ * mui gesture longtap
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var timer;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_START:
+				clearTimeout(timer);
+				timer = setTimeout(function() {
+					$.trigger(session.target, name, touch);
+				}, options.holdTimeout);
+				break;
+			case $.EVENT_MOVE:
+				if (touch.distance > options.holdThreshold) {
+					clearTimeout(timer);
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				clearTimeout(timer);
+				break;
+		}
+	};
+	/**
+	 * mui gesture longtap
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			fingers: 1,
+			holdTimeout: 500,
+			holdThreshold: 2
+		}
+	});
+})(mui, 'longtap');
+/**
+ * mui gesture hold
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var timer;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_START:
+				if ($.options.gestureConfig.hold) {
+					timer && clearTimeout(timer);
+					timer = setTimeout(function() {
+						touch.hold = true;
+						$.trigger(session.target, name, touch);
+					}, options.holdTimeout);
+				}
+				break;
+			case $.EVENT_MOVE:
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if (timer) {
+					clearTimeout(timer) && (timer = null);
+					$.trigger(session.target, 'release', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture hold
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			fingers: 1,
+			holdTimeout: 0
+		}
+	});
+})(mui, 'hold');
+/**
+ * mui gesture pinch
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var options = this.options;
+		var session = $.gestures.session;
+		switch (event.type) {
+			case $.EVENT_START:
+				break;
+			case $.EVENT_MOVE:
+				if ($.options.gestureConfig.pinch) {
+					if (touch.touches.length < 2) {
+						return;
+					}
+					if (!session.pinch) { //start
+						session.pinch = true;
+						$.trigger(session.target, name + 'start', touch);
+					}
+					$.trigger(session.target, name, touch);
+					var scale = touch.scale;
+					var rotation = touch.rotation;
+					var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale;
+					var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。
+					if (scale > lastScale) { //out
+						lastScale = scale - scaleDiff;
+						$.trigger(session.target, name + 'out', touch);
+					} //in
+					else if (scale < lastScale) {
+						lastScale = scale + scaleDiff;
+						$.trigger(session.target, name + 'in', touch);
+					}
+					if (Math.abs(rotation) > options.minRotationAngle) {
+						$.trigger(session.target, 'rotate', touch);
+					}
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) {
+					session.pinch = false;
+					$.trigger(session.target, name + 'end', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture pinch
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			minRotationAngle: 0
+		}
+	});
+})(mui, 'pinch');
+/**
+ * mui.init
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.global = $.options = {
+		gestureConfig: {
+			tap: true,
+			doubletap: false,
+			longtap: false,
+			hold: false,
+			flick: true,
+			swipe: true,
+			drag: true,
+			pinch: false
+		}
+	};
+	/**
+	 *
+	 * @param {type} options
+	 * @returns {undefined}
+	 */
+	$.initGlobal = function(options) {
+		$.options = $.extend(true, $.global, options);
+		return this;
+	};
+	var inits = {};
+
+	/**
+	 * 单页配置 初始化
+	 * @param {object} options
+	 */
+	$.init = function(options) {
+		$.options = $.extend(true, $.global, options || {});
+		$.ready(function() {
+			$.doAction('inits', function(index, init) {
+				var isInit = !!(!inits[init.name] || init.repeat);
+				if (isInit) {
+					init.handle.call($);
+					inits[init.name] = true;
+				}
+			});
+		});
+		return this;
+	};
+
+	/**
+	 * 增加初始化执行流程
+	 * @param {function} init
+	 */
+	$.addInit = function(init) {
+		return $.addAction('inits', init);
+	};
+	/**
+	 * 处理html5版本subpages 
+	 */
+	$.addInit({
+		name: 'iframe',
+		index: 100,
+		handle: function() {
+			var options = $.options;
+			var subpages = options.subpages || [];
+			if (!$.os.plus && subpages.length) {
+				//暂时只处理单个subpage。后续可以考虑支持多个subpage
+				createIframe(subpages[0]);
+			}
+		}
+	});
+	var createIframe = function(options) {
+		var wrapper = document.createElement('div');
+		wrapper.className = 'mui-iframe-wrapper';
+		var styles = options.styles || {};
+		if (typeof styles.top !== 'string') {
+			styles.top = '0px';
+		}
+		if (typeof styles.bottom !== 'string') {
+			styles.bottom = '0px';
+		}
+		wrapper.style.top = styles.top;
+		wrapper.style.bottom = styles.bottom;
+		var iframe = document.createElement('iframe');
+		iframe.src = options.url;
+		iframe.id = options.id || options.url;
+		iframe.name = iframe.id;
+		wrapper.appendChild(iframe);
+		document.body.appendChild(wrapper);
+		//目前仅处理微信
+		$.os.wechat && handleScroll(wrapper, iframe);
+	};
+
+	function handleScroll(wrapper, iframe) {
+		var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src;
+		var scrollTop = (parseFloat(localStorage.getItem(key)) || 0);
+		if (scrollTop) {
+			(function(y) {
+				iframe.onload = function() {
+					window.scrollTo(0, y);
+				};
+			})(scrollTop);
+		}
+		setInterval(function() {
+			var _scrollTop = window.scrollY;
+			if (scrollTop !== _scrollTop) {
+				localStorage.setItem(key, _scrollTop + '');
+				scrollTop = _scrollTop;
+			}
+		}, 100);
+	};
+	$(function() {
+		var classList = document.body.classList;
+		var os = [];
+		if ($.os.ios) {
+			os.push({
+				os: 'ios',
+				version: $.os.version
+			});
+			classList.add('mui-ios');
+		} else if ($.os.android) {
+			os.push({
+				os: 'android',
+				version: $.os.version
+			});
+			classList.add('mui-android');
+		}
+		if ($.os.wechat) {
+			os.push({
+				os: 'wechat',
+				version: $.os.wechat.version
+			});
+			classList.add('mui-wechat');
+		}
+		if (os.length) {
+			$.each(os, function(index, osObj) {
+				var version = '';
+				var classArray = [];
+				if (osObj.version) {
+					$.each(osObj.version.split('.'), function(i, v) {
+						version = version + (version ? '-' : '') + v;
+						classList.add($.className(osObj.os + '-' + version));
+					});
+				}
+			});
+		}
+	});
+})(mui);
+/**
+ * mui.init 5+
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	var defaultOptions = {
+		swipeBack: false,
+		preloadPages: [], //5+ lazyLoad webview
+		preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出)
+		keyEventBind: {
+			backbutton: true,
+			menubutton: true
+		},
+		titleConfig: {
+			height: "44px",
+			backgroundColor: "#f7f7f7", //导航栏背景色
+			bottomBorderColor: "#cccccc", //底部边线颜色
+			title: { //标题配置
+				text: "", //标题文字
+				position: {
+					top: 0,
+					left: 0,
+					width: "100%",
+					height: "100%"
+				},
+				styles: {
+					color: "#000000",
+					align: "center",
+					family: "'Helvetica Neue',Helvetica,sans-serif",
+					size: "17px",
+					style: "normal",
+					weight: "normal",
+					fontSrc: ""
+				}
+			},
+			back: {
+				image: {
+					base64Data: '',
+					imgSrc: '',
+					sprite: {
+						top: '0px',
+						left: '0px',
+						width: '100%',
+						height: '100%'
+					},
+					position: {
+						top: "10px",
+						left: "10px",
+						width: "24px",
+						height: "24px"
+					}
+				}
+			}
+		}
+	};
+
+	//默认页面动画
+	var defaultShow = {
+		event:"titleUpdate",
+		autoShow: true,
+		duration: 300,
+		aniShow: 'slide-in-right',
+		extras:{}
+	};
+	//若执行了显示动画初始化操作,则要覆盖默认配置
+	if($.options.show) {
+		defaultShow = $.extend(true, defaultShow, $.options.show);
+	}
+
+	$.currentWebview = null;
+
+	$.extend(true, $.global, defaultOptions);
+	$.extend(true, $.options, defaultOptions);
+	/**
+	 * 等待动画配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.waitingOptions = function(options) {
+		return $.extend(true, {}, {
+			autoShow: true,
+			title: '',
+			modal: false
+		}, options);
+	};
+	/**
+	 * 窗口显示配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.showOptions = function(options) {
+		return $.extend(true, {}, defaultShow, options);
+	};
+	/**
+	 * 窗口默认配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.windowOptions = function(options) {
+		return $.extend({
+			scalable: false,
+			bounce: "" //vertical
+		}, options);
+	};
+	/**
+	 * plusReady
+	 * @param {type} callback
+	 * @returns {_L6.$}
+	 */
+	$.plusReady = function(callback) {
+		if(window.plus) {
+			setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)
+				callback();
+			}, 0);
+		} else {
+			document.addEventListener("plusready", function() {
+				callback();
+			}, false);
+		}
+		return this;
+	};
+	/**
+	 * 5+ event(5+没提供之前我自己实现)
+	 * @param {type} webview
+	 * @param {type} eventType
+	 * @param {type} data
+	 * @returns {undefined}
+	 */
+	$.fire = function(webview, eventType, data) {
+		if(webview) {
+			if(typeof data === 'undefined') {
+				data = '';
+			} else if(typeof data === 'boolean' || typeof data === 'number') {
+				webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")");
+				return;
+			} else if($.isPlainObject(data) || $.isArray(data)) {
+				data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c");
+			}
+			webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')");
+		}
+	};
+	/**
+	 * 5+ event(5+没提供之前我自己实现)
+	 * @param {type} eventType
+	 * @param {type} data
+	 * @returns {undefined}
+	 */
+	$.receive = function(eventType, data) {
+		if(eventType) {
+			try {
+				if(data && typeof data === 'string') {
+					data = JSON.parse(data);
+				}
+			} catch(e) {}
+			$.trigger(document, eventType, data);
+		}
+	};
+	var triggerPreload = function(webview) {
+		if(!webview.preloaded) { //保证仅触发一次
+			$.fire(webview, 'preload');
+			var list = webview.children();
+			for(var i = 0; i < list.length; i++) {
+				$.fire(list[i], 'preload');
+			}
+			webview.preloaded = true;
+		}
+	};
+	var trigger = function(webview, eventType, timeChecked) {
+		if(timeChecked) {
+			if(!webview[eventType + 'ed']) {
+				$.fire(webview, eventType);
+				var list = webview.children();
+				for(var i = 0; i < list.length; i++) {
+					$.fire(list[i], eventType);
+				}
+				webview[eventType + 'ed'] = true;
+			}
+		} else {
+			$.fire(webview, eventType);
+			var list = webview.children();
+			for(var i = 0; i < list.length; i++) {
+				$.fire(list[i], eventType);
+			}
+		}
+
+	};
+	/**
+	 * 打开新窗口
+	 * @param {string} url 要打开的页面地址
+	 * @param {string} id 指定页面ID
+	 * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}}
+	 */
+	$.openWindow = function(url, id, options) {
+		if(typeof url === 'object') {
+			options = url;
+			url = options.url;
+			id = options.id || url;
+		} else {
+			if(typeof id === 'object') {
+				options = id;
+				id = options.id || url;
+			} else {
+				id = id || url;
+			}
+		}
+		if(!$.os.plus) {
+			//TODO 先临时这么处理:手机上顶层跳,PC上parent跳
+			if($.os.ios || $.os.android) {
+				window.top.location.href = url;
+			} else {
+				window.parent.location.href = url;
+			}
+			return;
+		}
+		if(!window.plus) {
+			return;
+		}
+
+		options = options || {};
+		var params = options.params || {};
+		var webview = null,
+			webviewCache = null,
+			nShow, nWaiting;
+
+		if($.webviews[id]) {
+			webviewCache = $.webviews[id];
+			//webview真实存在,才能获取
+			if(plus.webview.getWebviewById(id)) {
+				webview = webviewCache.webview;
+			}
+		} else if(options.createNew !== true) {
+			webview = plus.webview.getWebviewById(id);
+		}
+
+		if(webview) { //已缓存
+			//每次show都需要传递动画参数;
+			//预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
+			nShow = webviewCache ? webviewCache.show : defaultShow;
+			nShow = options.show ? $.extend(nShow, options.show) : nShow;
+			nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
+				triggerPreload(webview);
+				trigger(webview, 'pagebeforeshow', false);
+			});
+			if(webviewCache) {
+				webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+			}
+			return webview;
+		} else { //新窗口
+			if(!url) {
+				throw new Error('webview[' + id + '] does not exist');
+			}
+
+			//显示waiting
+			var waitingConfig = $.waitingOptions(options.waiting);
+			if(waitingConfig.autoShow) {
+				nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
+			}
+
+			//创建页面
+			options = $.extend(options, {
+				id: id,
+				url: url
+			});
+
+			webview = $.createWindow(options);
+
+			//显示
+			nShow = $.showOptions(options.show);
+			if(nShow.autoShow) {
+				var showWebview = function() {
+					//关闭等待框
+					if(nWaiting) {
+						nWaiting.close();
+					}
+					//显示页面
+					webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
+					options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+				};
+				//titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
+				webview.addEventListener(nShow.event, showWebview, false);
+				//loaded事件发生后,触发预加载和pagebeforeshow事件
+				webview.addEventListener("loaded", function() {
+					triggerPreload(webview);
+					trigger(webview, 'pagebeforeshow', false);
+				}, false);
+			}
+		}
+		return webview;
+	};
+
+	$.openWindowWithTitle = function(options, titleConfig) {
+		options = options || {};
+		var url = options.url;
+		var id = options.id || url;
+
+		if(!$.os.plus) {
+			//TODO 先临时这么处理:手机上顶层跳,PC上parent跳
+			if($.os.ios || $.os.android) {
+				window.top.location.href = url;
+			} else {
+				window.parent.location.href = url;
+			}
+			return;
+		}
+		if(!window.plus) {
+			return;
+		}
+
+		var params = options.params || {};
+		var webview = null,
+			webviewCache = null,
+			nShow, nWaiting;
+
+		if($.webviews[id]) {
+			webviewCache = $.webviews[id];
+			//webview真实存在,才能获取
+			if(plus.webview.getWebviewById(id)) {
+				webview = webviewCache.webview;
+			}
+		} else if(options.createNew !== true) {
+			webview = plus.webview.getWebviewById(id);
+		}
+
+		if(webview) { //已缓存
+			//每次show都需要传递动画参数;
+			//预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
+			nShow = webviewCache ? webviewCache.show : defaultShow;
+			nShow = options.show ? $.extend(nShow, options.show) : nShow;
+			nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
+				triggerPreload(webview);
+				trigger(webview, 'pagebeforeshow', false);
+			});
+			if(webviewCache) {
+				webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+			}
+			return webview;
+		} else { //新窗口
+			if(!url) {
+				throw new Error('webview[' + id + '] does not exist');
+			}
+
+			//显示waiting
+			var waitingConfig = $.waitingOptions(options.waiting);
+			if(waitingConfig.autoShow) {
+				nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
+			}
+
+			//创建页面
+			options = $.extend(options, {
+				id: id,
+				url: url
+			});
+
+			webview = $.createWindow(options);
+
+			if(titleConfig) { //处理原生头
+				$.extend(true, $.options.titleConfig, titleConfig);
+				var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title";
+				var view = new plus.nativeObj.View(tid, {
+					top: 0,
+					height: $.options.titleConfig.height,
+					width: "100%",
+					dock: "top",
+					position: "dock"
+				});
+				view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色
+				var _b = parseInt($.options.titleConfig.height) - 1;
+				view.drawRect($.options.titleConfig.bottomBorderColor, {
+					top: _b + "px",
+					left: "0px"
+				}); //绘制底部边线
+
+				//绘制文字
+				if($.options.titleConfig.title.text){
+					var _title = $.options.titleConfig.title;
+					view.drawText(_title.text,_title.position , _title.styles);
+				}
+				
+				//返回图标绘制
+				var _back = $.options.titleConfig.back;
+				var backClick = null;
+				//优先字体
+
+				//其次是图片
+				var _backImage = _back.image;
+				if(_backImage.base64Data || _backImage.imgSrc) {
+					//TODO 此处需要处理百分比的情况
+					backClick = {
+						left:parseInt(_backImage.position.left),
+						right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width)
+					};
+					var bitmap = new plus.nativeObj.Bitmap(id + "_back");
+					if(_backImage.base64Data) { //优先base64编码字符串
+						bitmap.loadBase64Data(_backImage.base64Data);
+					} else { //其次加载图片文件
+						bitmap.load(_backImage.imgSrc);
+					}
+					view.drawBitmap(bitmap,_backImage.sprite , _backImage.position);
+				}
+
+				//处理点击事件
+				view.setTouchEventRect({
+					top: "0px",
+					left: "0px",
+					width: "100%",
+					height: "100%"
+				});
+				view.interceptTouchEvent(true);
+				view.addEventListener("click", function(e) {
+					var x = e.clientX;
+					
+					//返回按钮点击
+					if(backClick&& x > backClick.left && x < backClick.right){
+						if( _back.click && $.isFunction(_back.click)){
+							_back.click();
+						}else{
+							webview.evalJS("window.mui&&mui.back();");
+						}
+					}
+				}, false);
+				webview.append(view);
+
+			}
+
+			//显示
+			nShow = $.showOptions(options.show);
+			if(nShow.autoShow) {
+				//titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
+				webview.addEventListener(nShow.event, function () {
+					//关闭等待框
+					if(nWaiting) {
+						nWaiting.close();
+					}
+					//显示页面
+					webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
+				}, false);
+			}
+		}
+		return webview;
+	};
+
+	/**
+	 * 根据配置信息创建一个webview
+	 * @param {type} options
+	 * @param {type} isCreate
+	 * @returns {webview}
+	 */
+	$.createWindow = function(options, isCreate) {
+		if(!window.plus) {
+			return;
+		}
+		var id = options.id || options.url;
+		var webview;
+		if(options.preload) {
+			if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache
+				webview = $.webviews[id].webview;
+			} else { //新增预加载窗口
+				//判断是否携带createNew参数,默认为false
+				if(options.createNew !== true) {
+					webview = plus.webview.getWebviewById(id);
+				}
+
+				//之前没有,那就新创建	
+				if(!webview) {
+					webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({
+						preload: true
+					}, options.extras));
+					if(options.subpages) {
+						$.each(options.subpages, function(index, subpage) {
+							var subpageId = subpage.id || subpage.url;
+							if(subpageId) { //过滤空对象
+								var subWebview = plus.webview.getWebviewById(subpageId);
+								if(!subWebview) { //如果该webview不存在,则创建
+									subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({
+										preload: true
+									}, subpage.extras));
+								}
+								webview.append(subWebview);
+							}
+						});
+					}
+				}
+			}
+
+			//TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题;
+			$.webviews[id] = {
+				webview: webview, //目前仅preload的缓存webview
+				preload: true,
+				show: $.showOptions(options.show),
+				afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯
+			};
+			//索引该预加载窗口
+			var preloads = $.data.preloads;
+			var index = preloads.indexOf(id);
+			if(~index) { //删除已存在的(变相调整插入位置)
+				preloads.splice(index, 1);
+			}
+			preloads.push(id);
+			if(preloads.length > $.options.preloadLimit) {
+				//先进先出
+				var first = $.data.preloads.shift();
+				var webviewCache = $.webviews[first];
+				if(webviewCache && webviewCache.webview) {
+					//需要将自己打开的所有页面,全部close;
+					//关闭该预加载webview	
+					$.closeAll(webviewCache.webview);
+				}
+				//删除缓存
+				delete $.webviews[first];
+			}
+		} else {
+			if(isCreate !== false) { //直接创建非预加载窗口
+				webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras);
+				if(options.subpages) {
+					$.each(options.subpages, function(index, subpage) {
+						var subpageId = subpage.id || subpage.url;
+						var subWebview = plus.webview.getWebviewById(subpageId);
+						if(!subWebview) {
+							subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras);
+						}
+						webview.append(subWebview);
+					});
+				}
+			}
+		}
+		return webview;
+	};
+
+	/**
+	 * 预加载
+	 */
+	$.preload = function(options) {
+		//调用预加载函数,不管是否传递preload参数,强制变为true
+		if(!options.preload) {
+			options.preload = true;
+		}
+		return $.createWindow(options);
+	};
+
+	/**
+	 *关闭当前webview打开的所有webview;
+	 */
+	$.closeOpened = function(webview) {
+		var opened = webview.opened();
+		if(opened) {
+			for(var i = 0, len = opened.length; i < len; i++) {
+				var openedWebview = opened[i];
+				var open_open = openedWebview.opened();
+				if(open_open && open_open.length > 0) {
+					//关闭打开的webview
+					$.closeOpened(openedWebview);
+					//关闭自己
+					openedWebview.close("none");
+				} else {
+					//如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子;
+					if(openedWebview.parent() !== webview) {
+						openedWebview.close('none');
+					}
+				}
+			}
+		}
+	};
+	$.closeAll = function(webview, aniShow) {
+		$.closeOpened(webview);
+		if(aniShow) {
+			webview.close(aniShow);
+		} else {
+			webview.close();
+		}
+	};
+
+	/**
+	 * 批量创建webview
+	 * @param {type} options
+	 * @returns {undefined}
+	 */
+	$.createWindows = function(options) {
+		$.each(options, function(index, option) {
+			//初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建)
+			$.createWindow(option, false);
+		});
+	};
+	/**
+	 * 创建当前页面的子webview
+	 * @param {type} options
+	 * @returns {webview}
+	 */
+	$.appendWebview = function(options) {
+		if(!window.plus) {
+			return;
+		}
+		var id = options.id || options.url;
+		var webview;
+		if(!$.webviews[id]) { //保证执行一遍
+			//TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话;
+			if(!plus.webview.getWebviewById(id)) {
+				webview = plus.webview.create(options.url, id, options.styles, options.extras);
+			}
+			//之前的实现方案:子窗口loaded之后再append到父窗口中;
+			//问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败;
+			//     比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发;
+			//修改方式:不再监控loaded事件,直接append
+			//by chb@20150521
+			// webview.addEventListener('loaded', function() {
+			plus.webview.currentWebview().append(webview);
+			// });
+			$.webviews[id] = options;
+
+		}
+		return webview;
+	};
+
+	//全局webviews
+	$.webviews = {};
+	//预加载窗口索引
+	$.data.preloads = [];
+	//$.currentWebview
+	$.plusReady(function() {
+		$.currentWebview = plus.webview.currentWebview();
+	});
+	$.addInit({
+		name: '5+',
+		index: 100,
+		handle: function() {
+			var options = $.options;
+			var subpages = options.subpages || [];
+			if($.os.plus) {
+				$.plusReady(function() {
+					//TODO  这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法;
+					//或者:在openwindow方法中,监听实现;
+					$.each(subpages, function(index, subpage) {
+						$.appendWebview(subpage);
+					});
+					//判断是否首页
+					if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) {
+						//首页需要自己激活预加载;
+						//timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题;
+						setTimeout(function() {
+							triggerPreload(plus.webview.currentWebview());
+						}, 300);
+					}
+					//设置ios顶部状态栏颜色;
+					if($.os.ios && $.options.statusBarBackground) {
+						plus.navigator.setStatusBarBackground($.options.statusBarBackground);
+					}
+					if($.os.android && parseFloat($.os.version) < 4.4) {
+						//解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题;
+						if(plus.webview.currentWebview().parent() == null) {
+							document.addEventListener("resume", function() {
+								var body = document.body;
+								body.style.display = 'none';
+								setTimeout(function() {
+									body.style.display = '';
+								}, 10);
+							});
+						}
+					}
+				});
+			} else {
+				//已支持iframe嵌入
+				//				if (subpages.length > 0) {
+				//					var err = document.createElement('div');
+				//					err.className = 'mui-error';
+				//					//文字描述
+				//					var span = document.createElement('span');
+				//					span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考';
+				//					err.appendChild(span);
+				//					var a = document.createElement('a');
+				//					a.innerHTML = '"mui框架适用场景"';
+				//					a.href = 'http://ask.dcloud.net.cn/article/113';
+				//					err.appendChild(a);
+				//					document.body.appendChild(err);
+				//					console.log('在该浏览器下,不支持创建子页面');
+				//				}
+
+			}
+
+		}
+	});
+	window.addEventListener('preload', function() {
+		//处理预加载部分
+		var webviews = $.options.preloadPages || [];
+		$.plusReady(function() {
+			$.each(webviews, function(index, webview) {
+				$.createWindow($.extend(webview, {
+					preload: true
+				}));
+			});
+
+		});
+	});
+	$.supportStatusbarOffset = function() {
+		return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7;
+	};
+	$.ready(function() {
+		//标识当前环境支持statusbar
+		if($.supportStatusbarOffset()) {
+			document.body.classList.add('mui-statusbar');
+		}
+	});
+})(mui);
+
+/**
+ * mui back
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	/**
+	 * register back
+	 * @param {type} back
+	 * @returns {$.gestures}
+	 */
+	$.addBack = function(back) {
+		return $.addAction('backs', back);
+	};
+	/**
+	 * default
+	 */
+	$.addBack({
+		name: 'browser',
+		index: 100,
+		handle: function() {
+			if (window.history.length > 1) {
+				window.history.back();
+				return true;
+			}
+			return false;
+		}
+	});
+	/**
+	 * 后退
+	 */
+	$.back = function() {
+		if (typeof $.options.beforeback === 'function') {
+			if ($.options.beforeback() === false) {
+				return;
+			}
+		}
+		$.doAction('backs');
+	};
+	window.addEventListener('tap', function(e) {
+		var action = $.targets.action;
+		if (action && action.classList.contains('mui-action-back')) {
+			$.back();
+			$.targets.action = false;
+		}
+	});
+	window.addEventListener('swiperight', function(e) {
+		var detail = e.detail;
+		if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) {
+			$.back();
+		}
+	});
+
+})(mui, window);
+/**
+ * mui back 5+
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	if ($.os.plus && $.os.android) {
+		$.addBack({
+			name: 'mui',
+			index: 5,
+			handle: function() {
+				//后续重新设计此处,将back放到各个空间内部实现
+				//popover
+				if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) {
+					$($.targets._popover).popover('hide');
+					return true;
+				}
+				//offcanvas
+				var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active');
+				if (offCanvas) {
+					$(offCanvas).offCanvas('close');
+					return true;
+				}
+				var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage();
+				if (previewImage && previewImage.isShown()) {
+					previewImage.close();
+					return true;
+				}
+				//popup
+				return $.closePopup();
+			}
+		});
+	}
+	//首次按下back按键的时间
+	$.__back__first = null;
+	/**
+	 * 5+ back
+	 */
+	$.addBack({
+		name: '5+',
+		index: 10,
+		handle: function() {
+			if (!window.plus) {
+				return false;
+			}
+			var wobj = plus.webview.currentWebview();
+			var parent = wobj.parent();
+			if (parent) {
+				parent.evalJS('mui&&mui.back();');
+			} else {
+				wobj.canBack(function(e) {
+					//by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回;
+					if (e.canBack) { //webview history back
+						window.history.back();
+					} else { //webview close or hide
+						//fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close
+						if (wobj.id === plus.runtime.appid) { //首页
+							//首页不存在opener的情况下,后退实际上应该是退出应用;
+							//首次按键,提示‘再按一次退出应用’
+							if (!$.__back__first) {
+								$.__back__first = new Date().getTime();
+								mui.toast('再按一次退出应用');
+								setTimeout(function() {
+									$.__back__first = null;
+								}, 2000);
+							} else {
+								if (new Date().getTime() - $.__back__first < 2000) {
+									plus.runtime.quit();
+								}
+							}
+						} else { //其他页面,
+							if (wobj.preload) {
+								wobj.hide("auto");
+							} else {
+								//关闭页面时,需要将其打开的所有子页面全部关闭;
+								$.closeAll(wobj);
+							}
+						}
+					}
+				});
+			}
+			return true;
+		}
+	});
+
+
+	$.menu = function() {
+		var menu = document.querySelector('.mui-action-menu');
+		if (menu) {
+			$.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题
+			$.trigger(menu, 'tap');
+		} else { //执行父窗口的menu
+			if (window.plus) {
+				var wobj = $.currentWebview;
+				var parent = wobj.parent();
+				if (parent) { //又得evalJS
+					parent.evalJS('mui&&mui.menu();');
+				}
+			}
+		}
+	};
+	var __back = function() {
+		$.back();
+	};
+	var __menu = function() {
+		$.menu();
+	};
+	//默认监听
+	$.plusReady(function() {
+		if ($.options.keyEventBind.backbutton) {
+			plus.key.addEventListener('backbutton', __back, false);
+		}
+		if ($.options.keyEventBind.menubutton) {
+			plus.key.addEventListener('menubutton', __menu, false);
+		}
+	});
+	//处理按键监听事件
+	$.addInit({
+		name: 'keyEventBind',
+		index: 1000,
+		handle: function() {
+			$.plusReady(function() {
+				//如果不为true,则移除默认监听
+				if (!$.options.keyEventBind.backbutton) {
+					plus.key.removeEventListener('backbutton', __back);
+				}
+				if (!$.options.keyEventBind.menubutton) {
+					plus.key.removeEventListener('menubutton', __menu);
+				}
+			});
+		}
+	});
+})(mui, window);
+/**
+ * mui.init pulldownRefresh
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.addInit({
+		name: 'pullrefresh',
+		index: 1000,
+		handle: function() {
+			var options = $.options;
+			var pullRefreshOptions = options.pullRefresh || {};
+			var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback');
+			var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback');
+			if(hasPulldown || hasPullup) {
+				var container = pullRefreshOptions.container;
+				if(container) {
+					var $container = $(container);
+					if($container.length === 1) {
+						if($.os.plus) { //5+环境
+							if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈
+								$.plusReady(function() {
+									//这里改写$.fn.pullRefresh
+									$.fn.pullRefresh = $.fn.pullRefresh_native;
+									$container.pullRefresh(pullRefreshOptions);
+								});
+
+							} else if($.os.android) { //非原生转圈,但是Android环境
+								$.plusReady(function() {
+									//这里改写$.fn.pullRefresh
+									$.fn.pullRefresh = $.fn.pullRefresh_native
+									var webview = plus.webview.currentWebview();
+									if(window.__NWin_Enable__ === false) { //不支持多webview
+										$container.pullRefresh(pullRefreshOptions);
+									} else {
+										if(hasPullup) {
+											//当前页面初始化pullup
+											var upOptions = {};
+											upOptions.up = pullRefreshOptions.up;
+											upOptions.webviewId = webview.id || webview.getURL();
+											$container.pullRefresh(upOptions);
+										}
+										if(hasPulldown) {
+											var parent = webview.parent();
+											var id = webview.id || webview.getURL();
+											if(parent) {
+												if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法
+													$container.pullRefresh({
+														webviewId: id
+													});
+												}
+												var downOptions = {
+													webviewId: id//子页面id
+												};
+												downOptions.down = $.extend({}, pullRefreshOptions.down);
+												downOptions.down.callback = '_CALLBACK';
+												//改写父页面的$.fn.pullRefresh
+												parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native");
+												//父页面初始化pulldown
+												parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')");
+											}
+										}
+									}
+								});
+							} else { //非原生转圈,iOS环境
+								$container.pullRefresh(pullRefreshOptions);
+							}
+						} else {
+							$container.pullRefresh(pullRefreshOptions);
+						}
+					}
+				}
+			}
+		}
+	});
+})(mui);
+/**
+ * mui ajax
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, window, undefined) {
+
+	var jsonType = 'application/json';
+	var htmlType = 'text/html';
+	var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
+	var scriptTypeRE = /^(?:text|application)\/javascript/i;
+	var xmlTypeRE = /^(?:text|application)\/xml/i;
+	var blankRE = /^\s*$/;
+
+	$.ajaxSettings = {
+		type: 'GET',
+		beforeSend: $.noop,
+		success: $.noop,
+		error: $.noop,
+		complete: $.noop,
+		context: null,
+		xhr: function(protocol) {
+			return new window.XMLHttpRequest();
+		},
+		accepts: {
+			script: 'text/javascript, application/javascript, application/x-javascript',
+			json: jsonType,
+			xml: 'application/xml, text/xml',
+			html: htmlType,
+			text: 'text/plain'
+		},
+		timeout: 0,
+		processData: true,
+		cache: true
+	};
+	var ajaxBeforeSend = function(xhr, settings) {
+		var context = settings.context
+		if(settings.beforeSend.call(context, xhr, settings) === false) {
+			return false;
+		}
+	};
+	var ajaxSuccess = function(data, xhr, settings) {
+		settings.success.call(settings.context, data, 'success', xhr);
+		ajaxComplete('success', xhr, settings);
+	};
+	// type: "timeout", "error", "abort", "parsererror"
+	var ajaxError = function(error, type, xhr, settings) {
+		settings.error.call(settings.context, xhr, type, error);
+		ajaxComplete(type, xhr, settings);
+	};
+	// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
+	var ajaxComplete = function(status, xhr, settings) {
+		settings.complete.call(settings.context, xhr, status);
+	};
+
+	var serialize = function(params, obj, traditional, scope) {
+		var type, array = $.isArray(obj),
+			hash = $.isPlainObject(obj);
+		$.each(obj, function(key, value) {
+			type = $.type(value);
+			if(scope) {
+				key = traditional ? scope :
+					scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
+			}
+			// handle data in serializeArray() format
+			if(!scope && array) {
+				params.add(value.name, value.value);
+			}
+			// recurse into nested objects
+			else if(type === "array" || (!traditional && type === "object")) {
+				serialize(params, value, traditional, key);
+			} else {
+				params.add(key, value);
+			}
+		});
+	};
+	var serializeData = function(options) {
+		if(options.processData && options.data && typeof options.data !== "string") {
+			var contentType = options.contentType;
+			if(!contentType && options.headers) {
+				contentType = options.headers['Content-Type'];
+			}
+			if(contentType && ~contentType.indexOf(jsonType)) { //application/json
+				options.data = JSON.stringify(options.data);
+			} else {
+				options.data = $.param(options.data, options.traditional);
+			}
+		}
+		if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
+			options.url = appendQuery(options.url, options.data);
+			options.data = undefined;
+		}
+	};
+	var appendQuery = function(url, query) {
+		if(query === '') {
+			return url;
+		}
+		return(url + '&' + query).replace(/[&?]{1,2}/, '?');
+	};
+	var mimeToDataType = function(mime) {
+		if(mime) {
+			mime = mime.split(';', 2)[0];
+		}
+		return mime && (mime === htmlType ? 'html' :
+			mime === jsonType ? 'json' :
+			scriptTypeRE.test(mime) ? 'script' :
+			xmlTypeRE.test(mime) && 'xml') || 'text';
+	};
+	var parseArguments = function(url, data, success, dataType) {
+		if($.isFunction(data)) {
+			dataType = success, success = data, data = undefined;
+		}
+		if(!$.isFunction(success)) {
+			dataType = success, success = undefined;
+		}
+		return {
+			url: url,
+			data: data,
+			success: success,
+			dataType: dataType
+		};
+	};
+	$.ajax = function(url, options) {
+		if(typeof url === "object") {
+			options = url;
+			url = undefined;
+		}
+		var settings = options || {};
+		settings.url = url || settings.url;
+		for(var key in $.ajaxSettings) {
+			if(settings[key] === undefined) {
+				settings[key] = $.ajaxSettings[key];
+			}
+		}
+		serializeData(settings);
+		var dataType = settings.dataType;
+
+		if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
+			settings.url = appendQuery(settings.url, '_=' + $.now());
+		}
+		var mime = settings.accepts[dataType && dataType.toLowerCase()];
+		var headers = {};
+		var setHeader = function(name, value) {
+			headers[name.toLowerCase()] = [name, value];
+		};
+		var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;        
+		var xhr = settings.xhr(settings);
+        
+        if(location.protocol === 'file:' && $.os.ios && window.webkit && window.webkit.messageHandlers && !(xhr instanceof plus.net.XMLHttpRequest)){
+            console.error("当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误")
+        }
+		var nativeSetHeader = xhr.setRequestHeader;
+		var abortTimeout;
+
+		setHeader('X-Requested-With', 'XMLHttpRequest');
+		setHeader('Accept', mime || '*/*');
+		if(!!(mime = settings.mimeType || mime)) {
+			if(mime.indexOf(',') > -1) {
+				mime = mime.split(',', 2)[0];
+			}
+			xhr.overrideMimeType && xhr.overrideMimeType(mime);
+		}
+		if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
+			setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
+		}
+		if(settings.headers) {
+			for(var name in settings.headers)
+				setHeader(name, settings.headers[name]);
+		}
+		xhr.setRequestHeader = setHeader;
+
+		xhr.onreadystatechange = function() {
+			if(xhr.readyState === 4) {
+				xhr.onreadystatechange = $.noop;
+				clearTimeout(abortTimeout);
+				var result, error = false;
+				var isLocal = protocol === 'file:';
+				if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
+					dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
+					result = xhr.responseText;
+					try {
+						// http://perfectionkills.com/global-eval-what-are-the-options/
+						if(dataType === 'script') {
+							(1, eval)(result);
+						} else if(dataType === 'xml') {
+							result = xhr.responseXML;
+						} else if(dataType === 'json') {
+							result = blankRE.test(result) ? null : $.parseJSON(result);
+						}
+					} catch(e) {
+						error = e;
+					}
+
+					if(error) {
+						ajaxError(error, 'parsererror', xhr, settings);
+					} else {
+						ajaxSuccess(result, xhr, settings);
+					}
+				} else {
+					var status = xhr.status ? 'error' : 'abort';
+					var statusText = xhr.statusText || null;
+					if(isLocal) {
+						status = 'error';
+						statusText = '404';
+					}
+					ajaxError(statusText, status, xhr, settings);
+				}
+			}
+		};
+		if(ajaxBeforeSend(xhr, settings) === false) {
+			xhr.abort();
+			ajaxError(null, 'abort', xhr, settings);
+			return xhr;
+		}
+
+		if(settings.xhrFields) {
+			for(var name in settings.xhrFields) {
+				xhr[name] = settings.xhrFields[name];
+			}
+		}
+
+		var async = 'async' in settings ? settings.async : true;
+
+		xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
+
+		for(var name in headers) {
+			if(headers.hasOwnProperty(name)) {
+				nativeSetHeader.apply(xhr, headers[name]);
+			}
+		}
+		if(settings.timeout > 0) {
+			abortTimeout = setTimeout(function() {
+				xhr.onreadystatechange = $.noop;
+				xhr.abort();
+				ajaxError(null, 'timeout', xhr, settings);
+			}, settings.timeout);
+		}
+		xhr.send(settings.data ? settings.data : null);
+		return xhr;
+	};
+
+	$.param = function(obj, traditional) {
+		var params = [];
+		params.add = function(k, v) {
+			this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
+		};
+		serialize(params, obj, traditional);
+		return params.join('&').replace(/%20/g, '+');
+	};
+	$.get = function( /* url, data, success, dataType */ ) {
+		return $.ajax(parseArguments.apply(null, arguments));
+	};
+
+	$.post = function( /* url, data, success, dataType */ ) {
+		var options = parseArguments.apply(null, arguments);
+		options.type = 'POST';
+		return $.ajax(options);
+	};
+
+	$.getJSON = function( /* url, data, success */ ) {
+		var options = parseArguments.apply(null, arguments);
+		options.dataType = 'json';
+		return $.ajax(options);
+	};
+
+	$.fn.load = function(url, data, success) {
+		if(!this.length)
+			return this;
+		var self = this,
+			parts = url.split(/\s/),
+			selector,
+			options = parseArguments(url, data, success),
+			callback = options.success;
+		if(parts.length > 1)
+			options.url = parts[0], selector = parts[1];
+		options.success = function(response) {
+			if(selector) {
+				var div = document.createElement('div');
+				div.innerHTML = response.replace(rscript, "");
+				var selectorDiv = document.createElement('div');
+				var childs = div.querySelectorAll(selector);
+				if(childs && childs.length > 0) {
+					for(var i = 0, len = childs.length; i < len; i++) {
+						selectorDiv.appendChild(childs[i]);
+					}
+				}
+				self[0].innerHTML = selectorDiv.innerHTML;
+			} else {
+				self[0].innerHTML = response;
+			}
+			callback && callback.apply(self, arguments);
+		};
+		$.ajax(options);
+		return this;
+	};
+
+})(mui, window);
+/**
+ * 5+ ajax
+ */
+(function($) {
+	var originAnchor = document.createElement('a');
+	originAnchor.href = window.location.href;
+	$.plusReady(function() {
+		$.ajaxSettings = $.extend($.ajaxSettings, {
+			xhr: function(settings) {
+				if (settings.crossDomain) { //强制使用plus跨域
+					return new plus.net.XMLHttpRequest();
+				}
+				//仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest
+				if (originAnchor.protocol !== 'file:') {
+					var urlAnchor = document.createElement('a');
+					urlAnchor.href = settings.url;
+					urlAnchor.href = urlAnchor.href;
+					settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host);
+					if (settings.crossDomain) {
+						return new plus.net.XMLHttpRequest();
+					}
+				}
+				if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr
+                    return new plus.net.XMLHttpRequest();
+                }
+				return new window.XMLHttpRequest();
+			}
+		});
+	});
+})(mui);
+/**
+ * mui layout(offset[,position,width,height...])
+ * @param {type} $
+ * @param {type} window
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, undefined) {
+	$.offset = function(element) {
+		var box = {
+			top : 0,
+			left : 0
+		};
+		if ( typeof element.getBoundingClientRect !== undefined) {
+			box = element.getBoundingClientRect();
+		}
+		return {
+			top : box.top + window.pageYOffset - element.clientTop,
+			left : box.left + window.pageXOffset - element.clientLeft
+		};
+	};
+})(mui, window); 
+/**
+ * mui animation
+ */
+(function($, window) {
+	/**
+	 * scrollTo
+	 */
+	$.scrollTo = function(scrollTop, duration, callback) {
+		duration = duration || 1000;
+		var scroll = function(duration) {
+			if (duration <= 0) {
+				window.scrollTo(0, scrollTop);
+				callback && callback();
+				return;
+			}
+			var distaince = scrollTop - window.scrollY;
+			setTimeout(function() {
+				window.scrollTo(0, window.scrollY + distaince / duration * 10);
+				scroll(duration - 10);
+			}, 16.7);
+		};
+		scroll(duration);
+	};
+	$.animationFrame = function(cb) {
+		var args, isQueued, context;
+		return function() {
+			args = arguments;
+			context = this;
+			if (!isQueued) {
+				isQueued = true;
+				requestAnimationFrame(function() {
+					cb.apply(context, args);
+					isQueued = false;
+				});
+			}
+		};
+	};
+
+})(mui, window);
+(function($) {
+	var initializing = false,
+		fnTest = /xyz/.test(function() {
+			xyz;
+		}) ? /\b_super\b/ : /.*/;
+
+	var Class = function() {};
+	Class.extend = function(prop) {
+		var _super = this.prototype;
+		initializing = true;
+		var prototype = new this();
+		initializing = false;
+		for (var name in prop) {
+			prototype[name] = typeof prop[name] == "function" &&
+				typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+				(function(name, fn) {
+					return function() {
+						var tmp = this._super;
+
+						this._super = _super[name];
+
+						var ret = fn.apply(this, arguments);
+						this._super = tmp;
+
+						return ret;
+					};
+				})(name, prop[name]) :
+				prop[name];
+		}
+		function Class() {
+			if (!initializing && this.init)
+				this.init.apply(this, arguments);
+		}
+		Class.prototype = prototype;
+		Class.prototype.constructor = Class;
+		Class.extend = arguments.callee;
+		return Class;
+	};
+	$.Class = Class;
+})(mui);
+(function($, document, undefined) {
+    var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket';
+    var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket';
+    var CLASS_PULL = 'mui-pull';
+    var CLASS_PULL_LOADING = 'mui-pull-loading';
+    var CLASS_PULL_CAPTION = 'mui-pull-caption';
+    var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
+    var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
+    var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
+
+    var CLASS_ICON = 'mui-icon';
+    var CLASS_SPINNER = 'mui-spinner';
+    var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown';
+
+    var CLASS_BLOCK = 'mui-block';
+    var CLASS_HIDDEN = 'mui-hidden';
+    var CLASS_VISIBILITY = 'mui-visibility';
+
+    var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
+    var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
+    var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER;
+
+    var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join('');
+
+    var PullRefresh = {
+        init: function(element, options) {
+            this._super(element, $.extend(true, {
+                scrollY: true,
+                scrollX: false,
+                indicators: true,
+                deceleration: 0.003,
+                down: {
+                    height: 50,
+                    contentinit: '下拉可以刷新',
+                    contentdown: '下拉可以刷新',
+                    contentover: '释放立即刷新',
+                    contentrefresh: '正在刷新...'
+                },
+                up: {
+                    height: 50,
+                    auto: false,
+                    contentinit: '上拉显示更多',
+                    contentdown: '上拉显示更多',
+                    contentrefresh: '正在加载...',
+                    contentnomore: '没有更多数据了',
+                    duration: 300
+                }
+            }, options));
+        },
+        _init: function() {
+            this._super();
+            this._initPocket();
+        },
+        _initPulldownRefresh: function() {
+            this.pulldown = true;
+            if (this.topPocket) {
+                this.pullPocket = this.topPocket;
+                this.pullPocket.classList.add(CLASS_BLOCK);
+                this.pullPocket.classList.add(CLASS_VISIBILITY);
+                this.pullCaption = this.topCaption;
+                this.pullLoading = this.topLoading;
+            }
+        },
+        _initPullupRefresh: function() {
+            this.pulldown = false;
+            if (this.bottomPocket) {
+                this.pullPocket = this.bottomPocket;
+                this.pullPocket.classList.add(CLASS_BLOCK);
+                this.pullPocket.classList.add(CLASS_VISIBILITY);
+                this.pullCaption = this.bottomCaption;
+                this.pullLoading = this.bottomLoading;
+            }
+        },
+        _initPocket: function() {
+            var options = this.options;
+            if (options.down && options.down.hasOwnProperty('callback')) {
+                this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET);
+                if (!this.topPocket) {
+                    this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN);
+                    this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild);
+                }
+                this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING);
+                this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION);
+            }
+            if (options.up && options.up.hasOwnProperty('callback')) {
+                this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET);
+                if (!this.bottomPocket) {
+                    this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING);
+                    this.scroller.appendChild(this.bottomPocket);
+                }
+                this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING);
+                this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION);
+                //TODO only for h5
+                this.wrapper.addEventListener('scrollbottom', this);
+            }
+        },
+        _createPocket: function(clazz, options, iconClass) {
+            var pocket = document.createElement('div');
+            pocket.className = clazz;
+            pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass);
+            return pocket;
+        },
+        _resetPullDownLoading: function() {
+            var loading = this.pullLoading;
+            if (loading) {
+                this.pullCaption.innerHTML = this.options.down.contentdown;
+                loading.style.webkitTransition = "";
+                loading.style.webkitTransform = "";
+                loading.style.webkitAnimation = "";
+                loading.className = CLASS_LOADING_DOWN;
+            }
+        },
+        _setCaptionClass: function(isPulldown, caption, title) {
+            if (!isPulldown) {
+                switch (title) {
+                    case this.options.up.contentdown:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                        break;
+                    case this.options.up.contentrefresh:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH
+                        break;
+                    case this.options.up.contentnomore:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
+                        break;
+                }
+            }
+        },
+        _setCaption: function(title, reset) {
+            if (this.loading) {
+                return;
+            }
+            var options = this.options;
+            var pocket = this.pullPocket;
+            var caption = this.pullCaption;
+            var loading = this.pullLoading;
+            var isPulldown = this.pulldown;
+            var self = this;
+            if (pocket) {
+                if (reset) {
+                    setTimeout(function() {
+                        caption.innerHTML = self.lastTitle = title;
+                        if (isPulldown) {
+                            loading.className = CLASS_LOADING_DOWN;
+                        } else {
+                            self._setCaptionClass(false, caption, title);
+                            loading.className = CLASS_LOADING;
+                        }
+                        loading.style.webkitAnimation = "";
+                        loading.style.webkitTransition = "";
+                        loading.style.webkitTransform = "";
+                    }, 100);
+                } else {
+                    if (title !== this.lastTitle) {
+                        caption.innerHTML = title;
+                        if (isPulldown) {
+                            if (title === options.down.contentrefresh) {
+                                loading.className = CLASS_LOADING;
+                                loading.style.webkitAnimation = "spinner-spin 1s step-end infinite";
+                            } else if (title === options.down.contentover) {
+                                loading.className = CLASS_LOADING_UP;
+                                loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
+                                loading.style.webkitTransform = "rotate(180deg)";
+                            } else if (title === options.down.contentdown) {
+                                loading.className = CLASS_LOADING_DOWN;
+                                loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
+                                loading.style.webkitTransform = "rotate(0deg)";
+                            }
+                        } else {
+                            if (title === options.up.contentrefresh) {
+                                loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY;
+                            } else {
+                                loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN;
+                            }
+                            self._setCaptionClass(false, caption, title);
+                        }
+                        this.lastTitle = title;
+                    }
+                }
+
+            }
+        }
+    };
+    $.PullRefresh = PullRefresh;
+})(mui, document);
+(function($, window, document, undefined) {
+	var CLASS_SCROLL = 'mui-scroll';
+	var CLASS_SCROLLBAR = 'mui-scrollbar';
+	var CLASS_INDICATOR = 'mui-scrollbar-indicator';
+	var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical';
+	var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal';
+
+	var CLASS_ACTIVE = 'mui-active';
+
+	var ease = {
+		quadratic: {
+			style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
+			fn: function(k) {
+				return k * (2 - k);
+			}
+		},
+		circular: {
+			style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',
+			fn: function(k) {
+				return Math.sqrt(1 - (--k * k));
+			}
+		},
+		outCirc: {
+			style: 'cubic-bezier(0.075, 0.82, 0.165, 1)'
+		},
+		outCubic: {
+			style: 'cubic-bezier(0.165, 0.84, 0.44, 1)'
+		}
+	}
+	var Scroll = $.Class.extend({
+		init: function(element, options) {
+			this.wrapper = this.element = element;
+			this.scroller = this.wrapper.children[0];
+			this.scrollerStyle = this.scroller && this.scroller.style;
+			this.stopped = false;
+
+			this.options = $.extend(true, {
+				scrollY: true, //是否竖向滚动
+				scrollX: false, //是否横向滚动
+				startX: 0, //初始化时滚动至x
+				startY: 0, //初始化时滚动至y
+
+				indicators: true, //是否显示滚动条
+				stopPropagation: false,
+				hardwareAccelerated: true,
+				fixedBadAndorid: false,
+				preventDefaultException: {
+					tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
+				},
+				momentum: true,
+
+				snapX: 0.5, //横向切换距离(以当前容器宽度为基准)
+				snap: false, //图片轮播,拖拽式选项卡
+
+				bounce: true, //是否启用回弹
+				bounceTime: 500, //回弹动画时间
+				bounceEasing: ease.outCirc, //回弹动画曲线
+
+				scrollTime: 500,
+				scrollEasing: ease.outCubic, //轮播动画曲线
+
+				directionLockThreshold: 5,
+
+				parallaxElement: false, //视差元素
+				parallaxRatio: 0.5
+			}, options);
+
+			this.x = 0;
+			this.y = 0;
+			this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : '';
+
+			this._init();
+			if (this.scroller) {
+				this.refresh();
+				//				if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看
+				this.scrollTo(this.options.startX, this.options.startY);
+				//				}
+			}
+		},
+		_init: function() {
+			this._initParallax();
+			this._initIndicators();
+			this._initEvent();
+		},
+		_initParallax: function() {
+			if (this.options.parallaxElement) {
+				this.parallaxElement = document.querySelector(this.options.parallaxElement);
+				this.parallaxStyle = this.parallaxElement.style;
+				this.parallaxHeight = this.parallaxElement.offsetHeight;
+				this.parallaxImgStyle = this.parallaxElement.querySelector('img').style;
+			}
+		},
+		_initIndicators: function() {
+			var self = this;
+			self.indicators = [];
+			if (!this.options.indicators) {
+				return;
+			}
+			var indicators = [],
+				indicator;
+
+			// Vertical scrollbar
+			if (self.options.scrollY) {
+				indicator = {
+					el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL),
+					listenX: false
+				};
+
+				this.wrapper.appendChild(indicator.el);
+				indicators.push(indicator);
+			}
+
+			// Horizontal scrollbar
+			if (this.options.scrollX) {
+				indicator = {
+					el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL),
+					listenY: false
+				};
+
+				this.wrapper.appendChild(indicator.el);
+				indicators.push(indicator);
+			}
+
+			for (var i = indicators.length; i--;) {
+				this.indicators.push(new Indicator(this, indicators[i]));
+			}
+
+		},
+		_initSnap: function() {
+			this.currentPage = {};
+			this.pages = [];
+			var snaps = this.snaps;
+			var length = snaps.length;
+			var m = 0;
+			var n = -1;
+			var x = 0;
+			var leftX = 0;
+			var rightX = 0;
+			var snapX = 0;
+			for (var i = 0; i < length; i++) {
+				var snap = snaps[i];
+				var offsetLeft = snap.offsetLeft;
+				var offsetWidth = snap.offsetWidth;
+				if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) {
+					m = 0;
+					n++;
+				}
+				if (!this.pages[m]) {
+					this.pages[m] = [];
+				}
+				x = this._getSnapX(offsetLeft);
+				snapX = Math.round((offsetWidth) * this.options.snapX);
+				leftX = x - snapX;
+				rightX = x - offsetWidth + snapX;
+				this.pages[m][n] = {
+					x: x,
+					leftX: leftX,
+					rightX: rightX,
+					pageX: m,
+					element: snap
+				}
+				if (snap.classList.contains(CLASS_ACTIVE)) {
+					this.currentPage = this.pages[m][0];
+				}
+				if (x >= this.maxScrollX) {
+					m++;
+				}
+			}
+			this.options.startX = this.currentPage.x || 0;
+		},
+		_getSnapX: function(offsetLeft) {
+			return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX);
+		},
+		_gotoPage: function(index) {
+			this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0];
+			for (var i = 0, len = this.snaps.length; i < len; i++) {
+				if (i === index) {
+					this.snaps[i].classList.add(CLASS_ACTIVE);
+				} else {
+					this.snaps[i].classList.remove(CLASS_ACTIVE);
+				}
+			}
+			this.scrollTo(this.currentPage.x, 0, this.options.scrollTime);
+		},
+		_nearestSnap: function(x) {
+			if (!this.pages.length) {
+				return {
+					x: 0,
+					pageX: 0
+				};
+			}
+			var i = 0;
+			var length = this.pages.length;
+			if (x > 0) {
+				x = 0;
+			} else if (x < this.maxScrollX) {
+				x = this.maxScrollX;
+			}
+			for (; i < length; i++) {
+				var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX;
+				if (x >= nearestX) {
+					return this.pages[i][0];
+				}
+			}
+			return {
+				x: 0,
+				pageX: 0
+			};
+		},
+		_initEvent: function(detach) {
+			var action = detach ? 'removeEventListener' : 'addEventListener';
+			window[action]('orientationchange', this);
+			window[action]('resize', this);
+
+			this.scroller[action]('webkitTransitionEnd', this);
+
+			this.wrapper[action]($.EVENT_START, this);
+			this.wrapper[action]($.EVENT_CANCEL, this);
+			this.wrapper[action]($.EVENT_END, this);
+			this.wrapper[action]('drag', this);
+			this.wrapper[action]('dragend', this);
+			this.wrapper[action]('flick', this);
+			this.wrapper[action]('scrollend', this);
+			if (this.options.scrollX) {
+				this.wrapper[action]('swiperight', this);
+			}
+			var segmentedControl = this.wrapper.querySelector('.mui-segmented-control');
+			if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见
+				mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault);
+			}
+
+			this.wrapper[action]('scrollstart', this);
+			this.wrapper[action]('refresh', this);
+		},
+		_handleIndicatorScrollend: function() {
+			this.indicators.map(function(indicator) {
+				indicator.fade();
+			});
+		},
+		_handleIndicatorScrollstart: function() {
+			this.indicators.map(function(indicator) {
+				indicator.fade(1);
+			});
+		},
+		_handleIndicatorRefresh: function() {
+			this.indicators.map(function(indicator) {
+				indicator.refresh();
+			});
+		},
+		handleEvent: function(e) {
+			if (this.stopped) {
+				this.resetPosition();
+				return;
+			}
+
+			switch (e.type) {
+				case $.EVENT_START:
+					this._start(e);
+					break;
+				case 'drag':
+					this.options.stopPropagation && e.stopPropagation();
+					this._drag(e);
+					break;
+				case 'dragend':
+				case 'flick':
+					this.options.stopPropagation && e.stopPropagation();
+					this._flick(e);
+					break;
+				case $.EVENT_CANCEL:
+				case $.EVENT_END:
+					this._end(e);
+					break;
+				case 'webkitTransitionEnd':
+					this.transitionTimer && this.transitionTimer.cancel();
+					this._transitionEnd(e);
+					break;
+				case 'scrollstart':
+					this._handleIndicatorScrollstart(e);
+					break;
+				case 'scrollend':
+					this._handleIndicatorScrollend(e);
+					this._scrollend(e);
+					e.stopPropagation();
+					break;
+				case 'orientationchange':
+				case 'resize':
+					this._resize();
+					break;
+				case 'swiperight':
+					e.stopPropagation();
+					break;
+				case 'refresh':
+					this._handleIndicatorRefresh(e);
+					break;
+
+			}
+		},
+		_start: function(e) {
+			this.moved = this.needReset = false;
+			this._transitionTime();
+			if (this.isInTransition) {
+				this.needReset = true;
+				this.isInTransition = false;
+				var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
+				this.setTranslate(Math.round(pos.x), Math.round(pos.y));
+				//				this.resetPosition(); //reset
+				$.trigger(this.scroller, 'scrollend', this);
+				//				e.stopPropagation();
+				e.preventDefault();
+			}
+			this.reLayout();
+			$.trigger(this.scroller, 'beforescrollstart', this);
+		},
+		_getDirectionByAngle: function(angle) {
+			if (angle < -80 && angle > -100) {
+				return 'up';
+			} else if (angle >= 80 && angle < 100) {
+				return 'down';
+			} else if (angle >= 170 || angle <= -170) {
+				return 'left';
+			} else if (angle >= -35 && angle <= 10) {
+				return 'right';
+			}
+			return null;
+		},
+		_drag: function(e) {
+			//			if (this.needReset) {
+			//				e.stopPropagation(); //disable parent drag(nested scroller)
+			//				return;
+			//			}
+			var detail = e.detail;
+			if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下
+				//ios8 hack
+				if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发
+					var clientY = detail.gesture.touches[0].clientY;
+					//下拉刷新 or 上拉加载
+					if ((clientY + 10) > window.innerHeight || clientY < 10) {
+						this.resetPosition(this.options.bounceTime);
+						return;
+					}
+				}
+			}
+			var isPreventDefault = isReturn = false;
+			var direction = this._getDirectionByAngle(detail.angle);
+			if (detail.direction === 'left' || detail.direction === 'right') {
+				if (this.options.scrollX) {
+					isPreventDefault = true;
+					if (!this.moved) { //识别角度(该角度导致轮播不灵敏)
+						//						if (direction !== 'left' && direction !== 'right') {
+						//							isReturn = true;
+						//						} else {
+						$.gestures.session.lockDirection = true; //锁定方向
+						$.gestures.session.startDirection = detail.direction;
+						//						}
+					}
+				} else if (this.options.scrollY && !this.moved) {
+					isReturn = true;
+				}
+			} else if (detail.direction === 'up' || detail.direction === 'down') {
+				if (this.options.scrollY) {
+					isPreventDefault = true;
+					//					if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证
+					//						if (direction !== 'up' && direction !== 'down') {
+					//							isReturn = true;
+					//						}
+					//					}
+					if (!this.moved) {
+						$.gestures.session.lockDirection = true; //锁定方向
+						$.gestures.session.startDirection = detail.direction;
+					}
+				} else if (this.options.scrollX && !this.moved) {
+					isReturn = true;
+				}
+			} else {
+				isReturn = true;
+			}
+			if (this.moved || isPreventDefault) {
+				e.stopPropagation(); //阻止冒泡(scroll类嵌套)
+				detail.gesture && detail.gesture.preventDefault();
+			}
+			if (isReturn) { //禁止非法方向滚动
+				return;
+			}
+			if (!this.moved) {
+				$.trigger(this.scroller, 'scrollstart', this);
+			} else {
+				e.stopPropagation(); //move期间阻止冒泡(scroll嵌套)
+			}
+			var deltaX = 0;
+			var deltaY = 0;
+			if (!this.moved) { //start
+				deltaX = detail.deltaX;
+				deltaY = detail.deltaY;
+			} else { //move
+				deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX;
+				deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY;
+			}
+			var absDeltaX = Math.abs(detail.deltaX);
+			var absDeltaY = Math.abs(detail.deltaY);
+			if (absDeltaX > absDeltaY + this.options.directionLockThreshold) {
+				deltaY = 0;
+			} else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) {
+				deltaX = 0;
+			}
+
+			deltaX = this.hasHorizontalScroll ? deltaX : 0;
+			deltaY = this.hasVerticalScroll ? deltaY : 0;
+			var newX = this.x + deltaX;
+			var newY = this.y + deltaY;
+			// Slow down if outside of the boundaries
+			if (newX > 0 || newX < this.maxScrollX) {
+				newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
+			}
+			if (newY > 0 || newY < this.maxScrollY) {
+				newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
+			}
+
+			if (!this.requestAnimationFrame) {
+				this._updateTranslate();
+			}
+			this.direction = detail.deltaX > 0 ? 'right' : 'left';
+			this.moved = true;
+			this.x = newX;
+			this.y = newY;
+			$.trigger(this.scroller, 'scroll', this);
+		},
+		_flick: function(e) {
+			//			if (!this.moved || this.needReset) {
+			//				return;
+			//			}
+			if (!this.moved) {
+				return;
+			}
+			e.stopPropagation();
+			var detail = e.detail;
+			this._clearRequestAnimationFrame();
+			if (e.type === 'dragend' && detail.flick) { //dragend
+				return;
+			}
+
+			var newX = Math.round(this.x);
+			var newY = Math.round(this.y);
+
+			this.isInTransition = false;
+			// reset if we are outside of the boundaries
+			if (this.resetPosition(this.options.bounceTime)) {
+				return;
+			}
+
+			this.scrollTo(newX, newY); // ensures that the last position is rounded
+
+			if (e.type === 'dragend') { //dragend
+				$.trigger(this.scroller, 'scrollend', this);
+				return;
+			}
+			var time = 0;
+			var easing = '';
+			// start momentum animation if needed
+			if (this.options.momentum && detail.flickTime < 300) {
+				momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : {
+					destination: newX,
+					duration: 0
+				};
+				momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : {
+					destination: newY,
+					duration: 0
+				};
+				newX = momentumX.destination;
+				newY = momentumY.destination;
+				time = Math.max(momentumX.duration, momentumY.duration);
+				this.isInTransition = true;
+			}
+
+			if (newX != this.x || newY != this.y) {
+				if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
+					easing = ease.quadratic;
+				}
+				this.scrollTo(newX, newY, time, easing);
+				return;
+			}
+
+			$.trigger(this.scroller, 'scrollend', this);
+			//			e.stopPropagation();
+		},
+		_end: function(e) {
+			this.needReset = false;
+			if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) {
+				this.resetPosition();
+			}
+		},
+		_transitionEnd: function(e) {
+			if (e.target != this.scroller || !this.isInTransition) {
+				return;
+			}
+			this._transitionTime();
+			if (!this.resetPosition(this.options.bounceTime)) {
+				this.isInTransition = false;
+				$.trigger(this.scroller, 'scrollend', this);
+			}
+		},
+		_scrollend: function(e) {
+			if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) {
+				$.trigger(this.scroller, 'scrollbottom', this);
+			}
+		},
+		_resize: function() {
+			var that = this;
+			clearTimeout(that.resizeTimeout);
+			that.resizeTimeout = setTimeout(function() {
+				that.refresh();
+			}, that.options.resizePolling);
+		},
+		_transitionTime: function(time) {
+			time = time || 0;
+			this.scrollerStyle['webkitTransitionDuration'] = time + 'ms';
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				this.parallaxStyle['webkitTransitionDuration'] = time + 'ms';
+			}
+			if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
+				this.scrollerStyle['webkitTransitionDuration'] = '0.001s';
+				if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+					this.parallaxStyle['webkitTransitionDuration'] = '0.001s';
+				}
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].transitionTime(time);
+				}
+			}
+			if (time) { //自定义timer,保证webkitTransitionEnd始终触发
+				this.transitionTimer && this.transitionTimer.cancel();
+				this.transitionTimer = $.later(function() {
+					$.trigger(this.scroller, 'webkitTransitionEnd');
+				}, time + 100, this);
+			}
+		},
+		_transitionTimingFunction: function(easing) {
+			this.scrollerStyle['webkitTransitionTimingFunction'] = easing;
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				this.parallaxStyle['webkitTransitionDuration'] = easing;
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].transitionTimingFunction(easing);
+				}
+			}
+		},
+		_translate: function(x, y) {
+			this.x = x;
+			this.y = y;
+		},
+		_clearRequestAnimationFrame: function() {
+			if (this.requestAnimationFrame) {
+				cancelAnimationFrame(this.requestAnimationFrame);
+				this.requestAnimationFrame = null;
+			}
+		},
+		_updateTranslate: function() {
+			var self = this;
+			if (self.x !== self.lastX || self.y !== self.lastY) {
+				self.setTranslate(self.x, self.y);
+			}
+			self.requestAnimationFrame = requestAnimationFrame(function() {
+				self._updateTranslate();
+			});
+		},
+		_createScrollBar: function(clazz) {
+			var scrollbar = document.createElement('div');
+			var indicator = document.createElement('div');
+			scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz;
+			indicator.className = CLASS_INDICATOR;
+			scrollbar.appendChild(indicator);
+			if (clazz === CLASS_SCROLLBAR_VERTICAL) {
+				this.scrollbarY = scrollbar;
+				this.scrollbarIndicatorY = indicator;
+			} else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) {
+				this.scrollbarX = scrollbar;
+				this.scrollbarIndicatorX = indicator;
+			}
+			this.wrapper.appendChild(scrollbar);
+			return scrollbar;
+		},
+		_preventDefaultException: function(el, exceptions) {
+			for (var i in exceptions) {
+				if (exceptions[i].test(el[i])) {
+					return true;
+				}
+			}
+			return false;
+		},
+		_reLayout: function() {
+			if (!this.hasHorizontalScroll) {
+				this.maxScrollX = 0;
+				this.scrollerWidth = this.wrapperWidth;
+			}
+
+			if (!this.hasVerticalScroll) {
+				this.maxScrollY = 0;
+				this.scrollerHeight = this.wrapperHeight;
+			}
+
+			this.indicators.map(function(indicator) {
+				indicator.refresh();
+			});
+
+			//以防slider类嵌套使用
+			if (this.options.snap && typeof this.options.snap === 'string') {
+				var items = this.scroller.querySelectorAll(this.options.snap);
+				this.itemLength = 0;
+				this.snaps = [];
+				for (var i = 0, len = items.length; i < len; i++) {
+					var item = items[i];
+					if (item.parentNode === this.scroller) {
+						this.itemLength++;
+						this.snaps.push(item);
+					}
+				}
+				this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整
+			}
+		},
+		_momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) {
+			var speed = parseFloat(Math.abs(distance) / time),
+				destination,
+				duration;
+
+			deceleration = deceleration === undefined ? 0.0006 : deceleration;
+			destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1);
+			duration = speed / deceleration;
+			if (destination < lowerMargin) {
+				destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin;
+				distance = Math.abs(destination - current);
+				duration = distance / speed;
+			} else if (destination > 0) {
+				destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0;
+				distance = Math.abs(current) + destination;
+				duration = distance / speed;
+			}
+
+			return {
+				destination: Math.round(destination),
+				duration: duration
+			};
+		},
+		_getTranslateStr: function(x, y) {
+			if (this.options.hardwareAccelerated) {
+				return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ;
+			}
+			return 'translate(' + x + 'px,' + y + 'px) ';
+		},
+		//API
+		setStopped: function(stopped) {
+			// this.stopped = !!stopped;
+
+			// fixed ios双webview模式下拉刷新
+			if(stopped) {
+				this.disablePullupToRefresh();
+				this.disablePulldownToRefresh();
+			} else {
+				this.enablePullupToRefresh();
+				this.enablePulldownToRefresh();
+			}
+		},
+		setTranslate: function(x, y) {
+			this.x = x;
+			this.y = y;
+			this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y);
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				var parallaxY = y * this.options.parallaxRatio;
+				var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2);
+				if (scale > 1) {
+					this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio;
+					this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')';
+				} else {
+					this.parallaxImgStyle['opacity'] = 1;
+					this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)';
+				}
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].updatePosition();
+				}
+			}
+			this.lastX = this.x;
+			this.lastY = this.y;
+			$.trigger(this.scroller, 'scroll', this);
+		},
+		reLayout: function() {
+			this.wrapper.offsetHeight;
+
+			var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0;
+			var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0;
+			var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0;
+			var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0;
+
+			var clientWidth = this.wrapper.clientWidth;
+			var clientHeight = this.wrapper.clientHeight;
+
+			this.scrollerWidth = this.scroller.offsetWidth;
+			this.scrollerHeight = this.scroller.offsetHeight;
+
+			this.wrapperWidth = clientWidth - paddingLeft - paddingRight;
+			this.wrapperHeight = clientHeight - paddingTop - paddingBottom;
+
+			this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
+			this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0);
+			this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
+			this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
+			this._reLayout();
+		},
+		resetPosition: function(time) {
+			var x = this.x,
+				y = this.y;
+
+			time = time || 0;
+			if (!this.hasHorizontalScroll || this.x > 0) {
+				x = 0;
+			} else if (this.x < this.maxScrollX) {
+				x = this.maxScrollX;
+			}
+
+			if (!this.hasVerticalScroll || this.y > 0) {
+				y = 0;
+			} else if (this.y < this.maxScrollY) {
+				y = this.maxScrollY;
+			}
+
+			if (x == this.x && y == this.y) {
+				return false;
+			}
+			this.scrollTo(x, y, time, this.options.scrollEasing);
+
+			return true;
+		},
+		_reInit: function() {
+			var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL);
+			for (var i = 0, len = groups.length; i < len; i++) {
+				if (groups[i].parentNode === this.wrapper) {
+					this.scroller = groups[i];
+					break;
+				}
+			}
+			this.scrollerStyle = this.scroller && this.scroller.style;
+		},
+		refresh: function() {
+			this._reInit();
+			this.reLayout();
+			$.trigger(this.scroller, 'refresh', this);
+			this.resetPosition();
+		},
+		scrollTo: function(x, y, time, easing) {
+			var easing = easing || ease.circular;
+			//			this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y);
+			//暂不严格判断x,y,否则会导致部分版本上不正常触发轮播
+			this.isInTransition = time > 0;
+			if (this.isInTransition) {
+				this._clearRequestAnimationFrame();
+				this._transitionTimingFunction(easing.style);
+				this._transitionTime(time);
+				this.setTranslate(x, y);
+			} else {
+				this.setTranslate(x, y);
+			}
+
+		},
+		scrollToBottom: function(time, easing) {
+			time = time || this.options.scrollTime;
+			this.scrollTo(0, this.maxScrollY, time, easing);
+		},
+		gotoPage: function(index) {
+			this._gotoPage(index);
+		},
+		destroy: function() {
+			this._initEvent(true); //detach
+			delete $.data[this.wrapper.getAttribute('data-scroll')];
+			this.wrapper.setAttribute('data-scroll', '');
+		}
+	});
+	//Indicator
+	var Indicator = function(scroller, options) {
+		this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
+		this.wrapperStyle = this.wrapper.style;
+		this.indicator = this.wrapper.children[0];
+		this.indicatorStyle = this.indicator.style;
+		this.scroller = scroller;
+
+		this.options = $.extend({
+			listenX: true,
+			listenY: true,
+			fade: false,
+			speedRatioX: 0,
+			speedRatioY: 0
+		}, options);
+
+		this.sizeRatioX = 1;
+		this.sizeRatioY = 1;
+		this.maxPosX = 0;
+		this.maxPosY = 0;
+
+		if (this.options.fade) {
+			this.wrapperStyle['webkitTransform'] = this.scroller.translateZ;
+			this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms';
+			this.wrapperStyle.opacity = '0';
+		}
+	}
+	Indicator.prototype = {
+		handleEvent: function(e) {
+
+		},
+		transitionTime: function(time) {
+			time = time || 0;
+			this.indicatorStyle['webkitTransitionDuration'] = time + 'ms';
+			if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
+				this.indicatorStyle['webkitTransitionDuration'] = '0.001s';
+			}
+		},
+		transitionTimingFunction: function(easing) {
+			this.indicatorStyle['webkitTransitionTimingFunction'] = easing;
+		},
+		refresh: function() {
+			this.transitionTime();
+
+			if (this.options.listenX && !this.options.listenY) {
+				this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
+			} else if (this.options.listenY && !this.options.listenX) {
+				this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
+			} else {
+				this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
+			}
+
+			this.wrapper.offsetHeight; // force refresh
+
+			if (this.options.listenX) {
+				this.wrapperWidth = this.wrapper.clientWidth;
+				this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
+				this.indicatorStyle.width = this.indicatorWidth + 'px';
+
+				this.maxPosX = this.wrapperWidth - this.indicatorWidth;
+
+				this.minBoundaryX = 0;
+				this.maxBoundaryX = this.maxPosX;
+
+				this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
+			}
+
+			if (this.options.listenY) {
+				this.wrapperHeight = this.wrapper.clientHeight;
+				this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
+				this.indicatorStyle.height = this.indicatorHeight + 'px';
+
+				this.maxPosY = this.wrapperHeight - this.indicatorHeight;
+
+				this.minBoundaryY = 0;
+				this.maxBoundaryY = this.maxPosY;
+
+				this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
+			}
+
+			this.updatePosition();
+		},
+
+		updatePosition: function() {
+			var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
+				y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
+
+			if (x < this.minBoundaryX) {
+				this.width = Math.max(this.indicatorWidth + x, 8);
+				this.indicatorStyle.width = this.width + 'px';
+				x = this.minBoundaryX;
+			} else if (x > this.maxBoundaryX) {
+				this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
+				this.indicatorStyle.width = this.width + 'px';
+				x = this.maxPosX + this.indicatorWidth - this.width;
+			} else if (this.width != this.indicatorWidth) {
+				this.width = this.indicatorWidth;
+				this.indicatorStyle.width = this.width + 'px';
+			}
+
+			if (y < this.minBoundaryY) {
+				this.height = Math.max(this.indicatorHeight + y * 3, 8);
+				this.indicatorStyle.height = this.height + 'px';
+				y = this.minBoundaryY;
+			} else if (y > this.maxBoundaryY) {
+				this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
+				this.indicatorStyle.height = this.height + 'px';
+				y = this.maxPosY + this.indicatorHeight - this.height;
+			} else if (this.height != this.indicatorHeight) {
+				this.height = this.indicatorHeight;
+				this.indicatorStyle.height = this.height + 'px';
+			}
+
+			this.x = x;
+			this.y = y;
+
+			this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y);
+
+		},
+		fade: function(val, hold) {
+			if (hold && !this.visible) {
+				return;
+			}
+
+			clearTimeout(this.fadeTimeout);
+			this.fadeTimeout = null;
+
+			var time = val ? 250 : 500,
+				delay = val ? 0 : 300;
+
+			val = val ? '1' : '0';
+
+			this.wrapperStyle['webkitTransitionDuration'] = time + 'ms';
+
+			this.fadeTimeout = setTimeout((function(val) {
+				this.wrapperStyle.opacity = val;
+				this.visible = +val;
+			}).bind(this, val), delay);
+		}
+	};
+
+	$.Scroll = Scroll;
+
+	$.fn.scroll = function(options) {
+		var scrollApis = [];
+		this.each(function() {
+			var scrollApi = null;
+			var self = this;
+			var id = self.getAttribute('data-scroll');
+			if (!id) {
+				id = ++$.uuid;
+				var _options = $.extend({}, options);
+				if (self.classList.contains('mui-segmented-control')) {
+					_options = $.extend(_options, {
+						scrollY: false,
+						scrollX: true,
+						indicators: false,
+						snap: '.mui-control-item'
+					});
+				}
+				$.data[id] = scrollApi = new Scroll(self, _options);
+				self.setAttribute('data-scroll', id);
+			} else {
+				scrollApi = $.data[id];
+			}
+			scrollApis.push(scrollApi);
+		});
+		return scrollApis.length === 1 ? scrollApis[0] : scrollApis;
+	};
+})(mui, window, document);
+(function($, window, document, undefined) {
+
+    var CLASS_VISIBILITY = 'mui-visibility';
+    var CLASS_HIDDEN = 'mui-hidden';
+
+    var PullRefresh = $.Scroll.extend($.extend({
+        handleEvent: function(e) {
+            this._super(e);
+            if (e.type === 'scrollbottom') {
+                if (e.target === this.scroller) {
+                    this._scrollbottom();
+                }
+            }
+        },
+        _scrollbottom: function() {
+            if (!this.pulldown && !this.loading) {
+                this.pulldown = false;
+                this._initPullupRefresh();
+                this.pullupLoading();
+            }
+        },
+        _start: function(e) {
+            //仅下拉刷新在start阻止默认事件
+            if (e.touches && e.touches.length && e.touches[0].clientX > 30) {
+                e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
+            }
+            if (!this.loading) {
+                this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false
+            }
+            this._super(e);
+        },
+        _drag: function(e) {
+            if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新
+                return;
+            }
+            this._super(e);
+            if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) {
+                this._initPulldownRefresh();
+            }
+            if (this.pulldown) {
+                this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown);
+            }
+        },
+
+        _reLayout: function() {
+            this.hasVerticalScroll = true;
+            this._super();
+        },
+        //API
+        resetPosition: function(time) {
+            if (this.pulldown && !this.disablePulldown) {
+                if (this.y >= this.options.down.height) {
+                    this.pulldownLoading(undefined, time || 0);
+                    return true;
+                } else {
+                    !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY);
+                }
+            }
+            return this._super(time);
+        },
+        pulldownLoading: function(y, time) {
+            typeof y === 'undefined' && (y = this.options.down.height); //默认高度
+            this.scrollTo(0, y, time, this.options.bounceEasing);
+            if (this.loading) {
+                return;
+            }
+            //			if (!this.pulldown) {
+            this._initPulldownRefresh();
+            //			}
+            this._setCaption(this.options.down.contentrefresh);
+            this.loading = true;
+            this.indicators.map(function(indicator) {
+                indicator.fade(0);
+            });
+            var callback = this.options.down.callback;
+            callback && callback.call(this);
+        },
+        endPulldownToRefresh: function() {
+            var self = this;
+            if (self.topPocket && self.loading && this.pulldown) {
+                self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing);
+                self.loading = false;
+                self._setCaption(self.options.down.contentdown, true);
+                setTimeout(function() {
+                    self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY);
+                }, 350);
+            }
+        },
+        pullupLoading: function(callback, x, time) {
+            x = x || 0;
+            this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing);
+            if (this.loading) {
+                return;
+            }
+            this._initPullupRefresh();
+            this._setCaption(this.options.up.contentrefresh);
+            this.indicators.map(function(indicator) {
+                indicator.fade(0);
+            });
+            this.loading = true;
+            callback = callback || this.options.up.callback;
+            callback && callback.call(this);
+        },
+        endPullupToRefresh: function(finished) {
+            var self = this;
+            if (self.bottomPocket) { // && self.loading && !this.pulldown
+                self.loading = false;
+                if (finished) {
+                    this.finished = true;
+                    self._setCaption(self.options.up.contentnomore);
+                    //					self.bottomPocket.classList.remove(CLASS_VISIBILITY);
+                    //					self.bottomPocket.classList.add(CLASS_HIDDEN);
+                    self.wrapper.removeEventListener('scrollbottom', self);
+                } else {
+                    self._setCaption(self.options.up.contentdown);
+                    //					setTimeout(function() {
+                    self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY);
+                    //					}, 300);
+                }
+            }
+        },
+        disablePullupToRefresh: function() {
+            this._initPullupRefresh();
+            this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
+            this.wrapper.removeEventListener('scrollbottom', this);
+        },
+        disablePulldownToRefresh: function() {
+            this._initPulldownRefresh();
+            this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN;
+            this.disablePulldown = true;
+        },
+        enablePulldownToRefresh: function() {
+            this._initPulldownRefresh();
+            this.topPocket.classList.remove(CLASS_HIDDEN);
+            this._setCaption(this.options.down.contentdown);
+            this.disablePulldown = false;
+        },
+        enablePullupToRefresh: function() {
+            this._initPullupRefresh();
+            this.bottomPocket.classList.remove(CLASS_HIDDEN);
+            this._setCaption(this.options.up.contentdown);
+            this.wrapper.addEventListener('scrollbottom', this);
+        },
+        refresh: function(isReset) {
+            if (isReset && this.finished) {
+                this.enablePullupToRefresh();
+                this.finished = false;
+            }
+            this._super();
+        },
+    }, $.PullRefresh));
+    $.fn.pullRefresh = function(options) {
+        if (this.length === 1) {
+            var self = this[0];
+            var pullRefreshApi = null;
+            var id = self.getAttribute('data-pullrefresh');
+            if (!id && typeof options === 'undefined') {
+                return false;
+            }
+            options = options || {};
+            if (!id) {
+                id = ++$.uuid;
+                $.data[id] = pullRefreshApi = new PullRefresh(self, options);
+                self.setAttribute('data-pullrefresh', id);
+            } else {
+                pullRefreshApi = $.data[id];
+            }
+            if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
+                pullRefreshApi.pulldownLoading(options.down.autoY);
+            } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
+                pullRefreshApi.pullupLoading();
+            }
+            //暂不提供这种调用方式吧			
+            //			if (typeof options === 'string') {
+            //				var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1));
+            //				if (methodValue !== undefined) {
+            //					return methodValue;
+            //				}
+            //			}
+            return pullRefreshApi;
+        }
+    };
+})(mui, window, document);
+/**
+ * snap 重构
+ * @param {Object} $
+ * @param {Object} window
+ */
+(function($, window) {
+	var CLASS_SLIDER = 'mui-slider';
+	var CLASS_SLIDER_GROUP = 'mui-slider-group';
+	var CLASS_SLIDER_LOOP = 'mui-slider-loop';
+	var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator';
+	var CLASS_ACTION_PREVIOUS = 'mui-action-previous';
+	var CLASS_ACTION_NEXT = 'mui-action-next';
+	var CLASS_SLIDER_ITEM = 'mui-slider-item';
+
+	var CLASS_ACTIVE = 'mui-active';
+
+	var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM;
+	var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR;
+	var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar';
+
+	var Slider = $.Slider = $.Scroll.extend({
+		init: function(element, options) {
+			this._super(element, $.extend(true, {
+				fingers: 1,
+				interval: 0, //设置为0,则不定时轮播
+				scrollY: false,
+				scrollX: true,
+				indicators: false,
+				scrollTime: 1000,
+				startX: false,
+				slideTime: 0, //滑动动画时间
+				snap: SELECTOR_SLIDER_ITEM
+			}, options));
+			if (this.options.startX) {
+				//				$.trigger(this.wrapper, 'scrollend', this);
+			}
+		},
+		_init: function() {
+			this._reInit();
+			if (this.scroller) {
+				this.scrollerStyle = this.scroller.style;
+				this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR);
+				if (this.progressBar) {
+					this.progressBarWidth = this.progressBar.offsetWidth;
+					this.progressBarStyle = this.progressBar.style;
+				}
+				//忘记这个代码是干什么的了?
+				//				this.x = this._getScroll();
+				//				if (this.options.startX === false) {
+				//					this.options.startX = this.x;
+				//				}
+				//根据active修正startX
+
+				this._super();
+				this._initTimer();
+			}
+		},
+		_triggerSlide: function() {
+			var self = this;
+			self.isInTransition = false;
+			var page = self.currentPage;
+			self.slideNumber = self._fixedSlideNumber();
+			if (self.loop) {
+				if (self.slideNumber === 0) {
+					self.setTranslate(self.pages[1][0].x, 0);
+				} else if (self.slideNumber === self.itemLength - 3) {
+					self.setTranslate(self.pages[self.itemLength - 2][0].x, 0);
+				}
+			}
+			if (self.lastSlideNumber != self.slideNumber) {
+				self.lastSlideNumber = self.slideNumber;
+				self.lastPage = self.currentPage;
+				$.trigger(self.wrapper, 'slide', {
+					slideNumber: self.slideNumber
+				});
+			}
+			self._initTimer();
+		},
+		_handleSlide: function(e) {
+			var self = this;
+			if (e.target !== self.wrapper) {
+				return;
+			}
+			var detail = e.detail;
+			detail.slideNumber = detail.slideNumber || 0;
+			var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM);
+			var items = [];
+			for (var i = 0, len = temps.length; i < len; i++) {
+				var item = temps[i];
+				if (item.parentNode === self.scroller) {
+					items.push(item);
+				}
+			}
+			var _slideNumber = detail.slideNumber;
+			if (self.loop) {
+				_slideNumber += 1;
+			}
+			if (!self.wrapper.classList.contains('mui-segmented-control')) {
+				for (var i = 0, len = items.length; i < len; i++) {
+					var item = items[i];
+					if (item.parentNode === self.scroller) {
+						if (i === _slideNumber) {
+							item.classList.add(CLASS_ACTIVE);
+						} else {
+							item.classList.remove(CLASS_ACTIVE);
+						}
+					}
+				}
+			}
+			var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator');
+			if (indicatorWrap) {
+				if (indicatorWrap.getAttribute('data-scroll')) { //scroll
+					$(indicatorWrap).scroll().gotoPage(detail.slideNumber);
+				}
+				var indicators = indicatorWrap.querySelectorAll('.mui-indicator');
+				if (indicators.length > 0) { //图片轮播
+					for (var i = 0, len = indicators.length; i < len; i++) {
+						indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
+					}
+				} else {
+					var number = indicatorWrap.querySelector('.mui-number span');
+					if (number) { //图文表格
+						number.innerText = (detail.slideNumber + 1);
+					} else { //segmented controls
+						var controlItems = indicatorWrap.querySelectorAll('.mui-control-item');
+						for (var i = 0, len = controlItems.length; i < len; i++) {
+							controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
+						}
+					}
+				}
+			}
+			e.stopPropagation();
+		},
+		_handleTabShow: function(e) {
+			var self = this;
+			self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime);
+		},
+		_handleIndicatorTap: function(event) {
+			var self = this;
+			var target = event.target;
+			if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) {
+				self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem']();
+				event.stopPropagation();
+			}
+		},
+		_initEvent: function(detach) {
+			var self = this;
+			self._super(detach);
+			var action = detach ? 'removeEventListener' : 'addEventListener';
+			self.wrapper[action]('slide', this);
+			self.wrapper[action]($.eventName('shown', 'tab'), this);
+		},
+		handleEvent: function(e) {
+			this._super(e);
+			switch (e.type) {
+				case 'slide':
+					this._handleSlide(e);
+					break;
+				case $.eventName('shown', 'tab'):
+					if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show
+						this._handleTabShow(e);
+					}
+					break;
+			}
+		},
+		_scrollend: function(e) {
+			this._super(e);
+			this._triggerSlide(e);
+		},
+		_drag: function(e) {
+			this._super(e);
+			var direction = e.detail.direction;
+			if (direction === 'left' || direction === 'right') {
+				//拖拽期间取消定时
+				var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer');
+				slidershowTimer && window.clearTimeout(slidershowTimer);
+
+				e.stopPropagation();
+			}
+		},
+		_initTimer: function() {
+			var self = this;
+			var slider = self.wrapper;
+			var interval = self.options.interval;
+			var slidershowTimer = slider.getAttribute('data-slidershowTimer');
+			slidershowTimer && window.clearTimeout(slidershowTimer);
+			if (interval) {
+				slidershowTimer = window.setTimeout(function() {
+					if (!slider) {
+						return;
+					}
+					//仅slider显示状态进行自动轮播
+					if (!!(slider.offsetWidth || slider.offsetHeight)) {
+						self.nextItem(true);
+						//下一个
+					}
+					self._initTimer();
+				}, interval);
+				slider.setAttribute('data-slidershowTimer', slidershowTimer);
+			}
+		},
+
+		_fixedSlideNumber: function(page) {
+			page = page || this.currentPage;
+			var slideNumber = page.pageX;
+			if (this.loop) {
+				if (page.pageX === 0) {
+					slideNumber = this.itemLength - 3;
+				} else if (page.pageX === (this.itemLength - 1)) {
+					slideNumber = 0;
+				} else {
+					slideNumber = page.pageX - 1;
+				}
+			}
+			return slideNumber;
+		},
+		_reLayout: function() {
+			this.hasHorizontalScroll = true;
+			this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP);
+			this._super();
+		},
+		_getScroll: function() {
+			var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
+			return result ? result.x : 0;
+		},
+		_transitionEnd: function(e) {
+			if (e.target !== this.scroller || !this.isInTransition) {
+				return;
+			}
+			this._transitionTime();
+			this.isInTransition = false;
+			$.trigger(this.wrapper, 'scrollend', this);
+		},
+		_flick: function(e) {
+			if (!this.moved) { //无moved
+				return;
+			}
+			var detail = e.detail;
+			var direction = detail.direction;
+			this._clearRequestAnimationFrame();
+			this.isInTransition = true;
+			//			if (direction === 'up' || direction === 'down') {
+			//				this.resetPosition(this.options.bounceTime);
+			//				return;
+			//			}
+			if (e.type === 'flick') {
+				if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime
+					this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x;
+				}
+				this.resetPosition(this.options.bounceTime);
+			} else if (e.type === 'dragend' && !detail.flick) {
+				this.resetPosition(this.options.bounceTime);
+			}
+			e.stopPropagation();
+		},
+		_initSnap: function() {
+			this.scrollerWidth = this.itemLength * this.scrollerWidth;
+			this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
+			this._super();
+			if (!this.currentPage.x) {
+				//当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题
+				var currentPage = this.pages[this.loop ? 1 : 0];
+				currentPage = currentPage || this.pages[0];
+				if (!currentPage) {
+					return;
+				}
+				this.currentPage = currentPage[0];
+				this.slideNumber = 0;
+				this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber;
+			} else {
+				this.slideNumber = this._fixedSlideNumber();
+				this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber;
+			}
+			this.options.startX = this.currentPage.x || 0;
+		},
+		_getSnapX: function(offsetLeft) {
+			return Math.max(-offsetLeft, this.maxScrollX);
+		},
+		_getPage: function(slideNumber, isFlick) {
+			if (this.loop) {
+				if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) {
+					slideNumber = 1;
+					time = 0;
+				} else if (slideNumber < (isFlick ? -1 : 0)) {
+					slideNumber = this.itemLength - 2;
+					time = 0;
+				} else {
+					slideNumber += 1;
+				}
+			} else {
+				if (!isFlick) {
+					if (slideNumber > (this.itemLength - 1)) {
+						slideNumber = 0;
+						time = 0;
+					} else if (slideNumber < 0) {
+						slideNumber = this.itemLength - 1;
+						time = 0;
+					}
+				}
+				slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1);
+			}
+			return this.pages[slideNumber][0];
+		},
+		_gotoItem: function(slideNumber, time) {
+			this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画)
+			this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
+			if (time === 0) {
+				$.trigger(this.wrapper, 'scrollend', this);
+			}
+		},
+		//API
+		setTranslate: function(x, y) {
+			this._super(x, y);
+			var progressBar = this.progressBar;
+			if (progressBar) {
+				this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0);
+			}
+		},
+		resetPosition: function(time) {
+			time = time || 0;
+			if (this.x > 0) {
+				this.x = 0;
+			} else if (this.x < this.maxScrollX) {
+				this.x = this.maxScrollX;
+			}
+			this.currentPage = this._nearestSnap(this.x);
+			this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
+			return true;
+		},
+		gotoItem: function(slideNumber, time) {
+			this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time);
+		},
+		nextItem: function() {
+			this._gotoItem(this.slideNumber + 1, this.options.scrollTime);
+		},
+		prevItem: function() {
+			this._gotoItem(this.slideNumber - 1, this.options.scrollTime);
+		},
+		getSlideNumber: function() {
+			return this.slideNumber || 0;
+		},
+		_reInit: function() {
+			var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP);
+			for (var i = 0, len = groups.length; i < len; i++) {
+				if (groups[i].parentNode === this.wrapper) {
+					this.scroller = groups[i];
+					break;
+				}
+			}
+			this.scrollerStyle = this.scroller && this.scroller.style;
+			if (this.progressBar) {
+				this.progressBarWidth = this.progressBar.offsetWidth;
+				this.progressBarStyle = this.progressBar.style;
+			}
+		},
+		refresh: function(options) {
+			if (options) {
+				$.extend(this.options, options);
+				this._super();
+				this._initTimer();
+			} else {
+				this._super();
+			}
+		},
+		destroy: function() {
+			this._initEvent(true); //detach
+			delete $.data[this.wrapper.getAttribute('data-slider')];
+			this.wrapper.setAttribute('data-slider', '');
+		}
+	});
+	$.fn.slider = function(options) {
+		var slider = null;
+		this.each(function() {
+			var sliderElement = this;
+			if (!this.classList.contains(CLASS_SLIDER)) {
+				sliderElement = this.querySelector('.' + CLASS_SLIDER);
+			}
+			if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) {
+				var id = sliderElement.getAttribute('data-slider');
+				if (!id) {
+					id = ++$.uuid;
+					$.data[id] = slider = new Slider(sliderElement, options);
+					sliderElement.setAttribute('data-slider', id);
+				} else {
+					slider = $.data[id];
+					if (slider && options) {
+						slider.refresh(options);
+					}
+				}
+			}
+		});
+		return slider;
+	};
+	$.ready(function() {
+		//		setTimeout(function() {
+		$('.mui-slider').slider();
+		$('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({
+			scrollY: false,
+			scrollX: true,
+			indicators: false,
+			snap: '.mui-control-item'
+		});
+		//		}, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的)
+
+	});
+})(mui, window);
+/**
+ * pullRefresh 5+
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, document) {
+    if (!($.os.plus)) { //仅在5+android支持多webview的使用
+        return;
+    }
+    $.plusReady(function() {
+        if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新
+            return;
+        }
+        var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh';
+        var CLASS_VISIBILITY = 'mui-visibility';
+        var CLASS_HIDDEN = 'mui-hidden';
+        var CLASS_BLOCK = 'mui-block';
+
+        var CLASS_PULL_CAPTION = 'mui-pull-caption';
+        var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
+        var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
+        var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
+
+        var PlusPullRefresh = $.Class.extend({
+            init: function(element, options) {
+                this.element = element;
+                this.options = options;
+                this.wrapper = this.scroller = element;
+                this._init();
+                this._initPulldownRefreshEvent();
+            },
+            _init: function() {
+                var self = this;
+                //document.addEventListener('plusscrollbottom', this);
+                window.addEventListener('dragup', self);
+                document.addEventListener("plusscrollbottom", self);
+                self.scrollInterval = window.setInterval(function() {
+                    if (self.isScroll && !self.loading) {
+                        if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) {
+                            self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化
+                            if (self.bottomPocket) {
+                                self.pullupLoading();
+                            }
+                        }
+                    }
+                }, 100);
+            },
+            _initPulldownRefreshEvent: function() {
+                var self = this;
+                $.plusReady(function() {
+                    if (self.options.down.style == "circle") {
+                        //单webview、原生转圈
+                        self.options.webview = plus.webview.currentWebview();
+                        self.options.webview.setPullToRefresh({
+                            support: true,
+                            color: self.options.down.color || '#2BD009',
+                            height: self.options.down.height || '50px',
+                            range: self.options.down.range || '100px',
+                            style: 'circle',
+                            offset: self.options.down.offset || '0px'
+                        }, function() {
+                            self.options.down.callback();
+                        });
+                    } else if (self.topPocket && self.options.webviewId) {
+                        var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口
+                        if (!webview) {
+                            return;
+                        }
+                        self.options.webview = webview;
+                        var downOptions = self.options.down;
+                        var height = downOptions.height;
+                        webview.addEventListener('close', function() {
+                            var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/" 
+                            self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId);
+                        });
+                        webview.addEventListener("dragBounce", function(e) {
+                            if (!self.pulldown) {
+                                self._initPulldownRefresh();
+                            } else {
+                                self.pullPocket.classList.add(CLASS_BLOCK);
+                            }
+                            switch (e.status) {
+                                case "beforeChangeOffset": //下拉可刷新状态
+                                    self._setCaption(downOptions.contentdown);
+                                    break;
+                                case "afterChangeOffset": //松开可刷新状态
+                                    self._setCaption(downOptions.contentover);
+                                    break;
+                                case "dragEndAfterChangeOffset": //正在刷新状态
+                                    //执行下拉刷新所在webview的回调函数
+                                    webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()");
+                                    self._setCaption(downOptions.contentrefresh);
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }, false);
+
+                        webview.setBounce({
+                            position: {
+                                top: height * 2 + 'px'
+                            },
+                            changeoffset: {
+                                top: height + 'px'
+                            }
+                        });
+
+                    }
+                });
+            },
+            handleEvent: function(e) {
+                var self = this;
+                if (self.stopped) {
+                    return;
+                }
+                self.isScroll = false;
+                if (e.type === 'dragup' || e.type === 'plusscrollbottom') {
+                    self.isScroll = true;
+                    setTimeout(function() {
+                        self.isScroll = false;
+                    }, 1000);
+                }
+            }
+        }).extend($.extend({
+            setStopped: function(stopped) { //该方法是子页面调用的
+                this.stopped = !!stopped;
+                // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG
+                if (this.stopped) {
+                    this.disablePullupToRefresh();
+                    this.disablePulldownToRefresh();
+                } else {
+                    this.enablePullupToRefresh();
+                    this.enablePulldownToRefresh();
+                }
+            },
+            beginPulldown: function() {
+                var self = this;
+                $.plusReady(function() {
+                    //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的
+                    setTimeout(function() {
+                        if (self.options.down.style == "circle") { //单webview下拉刷新
+                            plus.webview.currentWebview().beginPullToRefresh();
+                        } else { //双webview模式
+                            var webview = self.options.webview;
+                            if (webview) {
+                                webview.setBounce({
+                                    offset: {
+                                        top: self.options.down.height + "px"
+                                    }
+                                });
+                            }
+                        }
+                    }, 15);
+                }.bind(this));
+            },
+            pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API
+                this.beginPulldown();
+            },
+            _pulldownLoading: function() { //该方法是父页面调用的
+                var self = this;
+                $.plusReady(function() {
+                    var childWebview = plus.webview.getWebviewById(self.options.webviewId);
+                    childWebview && childWebview.setBounce({
+                        offset: {
+                            top: self.options.down.height + "px"
+                        }
+                    });
+                });
+            },
+            endPulldown: function() {
+                var _wv = plus.webview.currentWebview();
+                //双webview的下拉刷新,需要修改父窗口提示信息
+                if (_wv.parent() && this.options.down.style !== "circle") {
+                    _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({
+                        webviewId: _wv.id
+                    }) + "')._endPulldownToRefresh()");
+                } else {
+                    _wv.endPullToRefresh();
+                }
+            },
+            endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API
+                this.endPulldown();
+            },
+            _endPulldownToRefresh: function() { //该方法是父页面调用的
+                var self = this;
+                if (self.topPocket && self.options.webview) {
+                    self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹
+                    self.loading = false;
+                    self._setCaption(self.options.down.contentdown, true);
+                    setTimeout(function() {
+                        self.loading || self.topPocket.classList.remove(CLASS_BLOCK);
+                    }, 350);
+                }
+            },
+            beginPullup: function(callback) { //开始上拉加载
+                var self = this;
+                if (self.isLoading) return;
+                self.isLoading = true;
+                if (self.pulldown !== false) {
+                    self._initPullupRefresh();
+                } else {
+                    this.pullPocket.classList.add(CLASS_BLOCK);
+                }
+                setTimeout(function() {
+                    self.pullLoading.classList.add(CLASS_VISIBILITY);
+                    self.pullLoading.classList.remove(CLASS_HIDDEN);
+                    self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的)
+                    self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH;
+                    self.pullCaption.innerHTML = self.options.up.contentrefresh;
+                    callback = callback || self.options.up.callback;
+                    callback && callback.call(self);
+                }, 300);
+            },
+            pullupLoading: function(callback) { //兼容老的API
+                this.beginPullup(callback);
+            },
+            endPullup: function(finished) { //上拉加载结束
+                var self = this;
+                if (self.pullLoading) {
+                    self.pullLoading.classList.remove(CLASS_VISIBILITY);
+                    self.pullLoading.classList.add(CLASS_HIDDEN);
+                    self.isLoading = false;
+                    if (finished) {
+                        self.finished = true;
+                        self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
+                        self.pullCaption.innerHTML = self.options.up.contentnomore;
+                        //取消5+的plusscrollbottom事件
+                        document.removeEventListener('plusscrollbottom', self);
+                        window.removeEventListener('dragup', self);
+                    } else { //初始化时隐藏,后续不再隐藏
+                        self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                        self.pullCaption.innerHTML = self.options.up.contentdown;
+                    }
+                }
+            },
+            endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API
+                this.endPullup(finished);
+            },
+            disablePulldownToRefresh: function() {
+                var webview = plus.webview.currentWebview();
+                if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新
+                    this.options.webview.setPullToRefresh({
+                        support: false,
+                        style: 'circle'
+                    });
+                } else { // 双webview模式禁止下拉刷新
+                    webview.setStyle({
+                        bounce: 'none'
+                    });
+                    webview.setBounce({
+                        position: {
+                            top: 'none'
+                        }
+                    });
+                }
+            },
+            enablePulldownToRefresh: function() {
+                var self = this,
+                    webview = plus.webview.currentWebview(),
+                    height = this.options.down.height;
+                // 单webview模式禁止原生下拉刷新
+                if (this.options.down.style && this.options.down.style == 'circle') {
+                    webview.setPullToRefresh({
+                        support: true,
+                        height: height || '50px',
+                        range: self.options.down.range || '100px',
+                        style: 'circle',
+                        offset: self.options.down.offset || '0px'
+                    });
+                } else { // 重新初始化双webview模式下拉刷新
+                    webview.setStyle({
+                        bounce: 'vertical'
+                    });
+                    webview.setBounce({
+                        position: {
+                            top: height * 2 + 'px'
+                        },
+                        changeoffset: {
+                            top: height + 'px'
+                        }
+                    });
+                }
+            },
+            disablePullupToRefresh: function() {
+                this._initPullupRefresh();
+                this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
+                window.removeEventListener('dragup', this);
+            },
+            enablePullupToRefresh: function() {
+                this._initPullupRefresh();
+                this.bottomPocket.classList.remove(CLASS_HIDDEN);
+                this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                this.pullCaption.innerHTML = this.options.up.contentdown;
+                document.addEventListener("plusscrollbottom", this);
+                window.addEventListener('dragup', this);
+            },
+            scrollTo: function(x, y, time) {
+                $.scrollTo(y, time);
+            },
+            scrollToBottom: function(time) {
+                $.scrollTo(document.documentElement.scrollHeight, time);
+            },
+            refresh: function(isReset) {
+                if (isReset && this.finished) {
+                    this.enablePullupToRefresh();
+                    this.finished = false;
+                }
+            }
+        }, $.PullRefresh));
+
+        //override h5 pullRefresh
+        $.fn.pullRefresh_native = function(options) {
+            var self;
+            if (this.length === 0) {
+                self = document.createElement('div');
+                self.className = 'mui-content';
+                document.body.appendChild(self);
+            } else {
+                self = this[0];
+            }
+            var args = options;
+            //一个父需要支持多个子下拉刷新
+            options = options || {}
+            if (typeof options === 'string') {
+                options = $.parseJSON(options);
+            };
+            !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL()));
+            var pullRefreshApi = null;
+            var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/"
+            var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId);
+            if (!id && typeof args === 'undefined') {
+                return false;
+            }
+            if (!id) { //避免重复初始化5+ pullrefresh
+                id = ++$.uuid;
+                self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id);
+                document.body.classList.add(CLASS_PLUS_PULLREFRESH);
+                $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options);
+            } else {
+                pullRefreshApi = $.data[id];
+            }
+            if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
+                //pullRefreshApi._pulldownLoading(); //parent webview
+                pullRefreshApi.beginPulldown();
+            } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
+                pullRefreshApi.beginPullup();
+            }
+            return pullRefreshApi;
+        };
+    });
+
+})(mui, document);
+/**
+ * off-canvas
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} action
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+	var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left';
+	var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right';
+	var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop';
+	var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap';
+
+	var CLASS_SLIDE_IN = 'mui-slide-in';
+	var CLASS_ACTIVE = 'mui-active';
+
+
+	var CLASS_TRANSITIONING = 'mui-transitioning';
+
+	var SELECTOR_INNER_WRAP = '.mui-inner-wrap';
+
+
+	var OffCanvas = $.Class.extend({
+		init: function(element, options) {
+			this.wrapper = this.element = element;
+			this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+			this.classList = this.wrapper.classList;
+			if (this.scroller) {
+				this.options = $.extend(true, {
+					dragThresholdX: 10,
+					scale: 0.8,
+					opacity: 0.1,
+					preventDefaultException: {
+						tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
+					},
+				}, options);
+				document.body.classList.add('mui-fullscreen'); //fullscreen
+				this.refresh();
+				this.initEvent();
+			}
+		},
+		_preventDefaultException: function(el, exceptions) {
+			for (var i in exceptions) {
+				if (exceptions[i].test(el[i])) {
+					return true;
+				}
+			}
+			return false;
+		},
+		refresh: function(offCanvas) {
+			//			offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE);
+			this.slideIn = this.classList.contains(CLASS_SLIDE_IN);
+			this.scalable = this.classList.contains('mui-scalable') && !this.slideIn;
+			this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+			//			!offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING);
+			//			!offCanvas && this.scroller.setAttribute('style', '');
+			this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT);
+			this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT);
+			if (offCanvas) {
+				if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
+					this.offCanvasLeft = offCanvas;
+				} else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
+					this.offCanvasRight = offCanvas;
+				}
+			} else {
+				this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT);
+				this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT);
+			}
+			this.offCanvasRightWidth = this.offCanvasLeftWidth = 0;
+			this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false;
+			if (this.offCanvasRight) {
+				this.offCanvasRightWidth = this.offCanvasRight.offsetWidth;
+				this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper);
+				//				this.offCanvasRight.classList.remove(CLASS_TRANSITIONING);
+				//				this.offCanvasRight.classList.remove(CLASS_ACTIVE);
+				//				this.offCanvasRight.setAttribute('style', '');
+			}
+			if (this.offCanvasLeft) {
+				this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth;
+				this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper);
+				//				this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING);
+				//				this.offCanvasLeft.classList.remove(CLASS_ACTIVE);
+				//				this.offCanvasLeft.setAttribute('style', '');
+			}
+			this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP);
+
+			this.options.dragThresholdX = this.options.dragThresholdX || 10;
+
+			this.visible = false;
+			this.startX = null;
+			this.lastX = null;
+			this.offsetX = null;
+			this.lastTranslateX = null;
+		},
+		handleEvent: function(e) {
+			switch (e.type) {
+				case $.EVENT_START:
+					e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
+					break;
+				case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况
+					if (e.target === this.scroller) {
+						this._dispatchEvent();
+					}
+					break;
+				case 'drag':
+					var detail = e.detail;
+					if (!this.startX) {
+						this.startX = detail.center.x;
+						this.lastX = this.startX;
+					} else {
+						this.lastX = detail.center.x;
+					}
+					if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) {
+						if (this.slideIn) {
+							this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+							if (this.classList.contains(CLASS_ACTIVE)) {
+								if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								} else {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								}
+							} else {
+								if (detail.direction === 'left' && this.offCanvasRight) {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								} else if (detail.direction === 'right' && this.offCanvasLeft) {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.scroller = null;
+								}
+							}
+						} else {
+							if (this.classList.contains(CLASS_ACTIVE)) {
+								if (detail.direction === 'left') {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								}
+							} else {
+								if (detail.direction === 'right') {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								}
+							}
+						}
+						if (this.offCanvas && this.scroller) {
+							this.startX = this.lastX;
+							this.isDragging = true;
+
+							$.gestures.session.lockDirection = true; //锁定方向
+							$.gestures.session.startDirection = detail.direction;
+
+							this.offCanvas.classList.remove(CLASS_TRANSITIONING);
+							this.scroller.classList.remove(CLASS_TRANSITIONING);
+							this.offsetX = this.getTranslateX();
+							this._initOffCanvasVisible();
+						}
+					}
+					if (this.isDragging) {
+						this.updateTranslate(this.offsetX + (this.lastX - this.startX));
+						detail.gesture.preventDefault();
+						e.stopPropagation();
+					}
+					break;
+				case 'dragend':
+					if (this.isDragging) {
+						var detail = e.detail;
+						var direction = detail.direction;
+						this.isDragging = false;
+						this.offCanvas.classList.add(CLASS_TRANSITIONING);
+						this.scroller.classList.add(CLASS_TRANSITIONING);
+						var ratio = 0;
+						var x = this.getTranslateX();
+						if (!this.slideIn) {
+							if (x >= 0) {
+								ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
+							} else {
+								ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
+							}
+							if (ratio === 0) {
+								this.openPercentage(0);
+								this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch
+								return;
+							}
+							if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开
+								this.openPercentage(100);
+							} else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio < 0.5) { //右滑还原打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio > 0.5) { //左滑还原打开
+								this.openPercentage(100);
+							} else { //默认关闭
+								this.openPercentage(0);
+							}
+							if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch
+								this._dispatchEvent();
+							}
+						} else {
+							if (x >= 0) {
+								ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
+							} else {
+								ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
+							}
+							if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开
+								this.openPercentage(100);
+							} else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开
+								this.openPercentage(100);
+							} else {
+								this.openPercentage(0);
+							}
+							if (ratio === 1 || ratio === -1 || ratio === 0) {
+								this._dispatchEvent();
+								return;
+							}
+
+						}
+					}
+					break;
+			}
+		},
+		_dispatchEvent: function() {
+			if (this.classList.contains(CLASS_ACTIVE)) {
+				$.trigger(this.wrapper, 'shown', this);
+			} else {
+				$.trigger(this.wrapper, 'hidden', this);
+			}
+		},
+		_initOffCanvasVisible: function() {
+			if (!this.visible) {
+				this.visible = true;
+				if (this.offCanvasLeft) {
+					this.offCanvasLeft.style.visibility = 'visible';
+				}
+				if (this.offCanvasRight) {
+					this.offCanvasRight.style.visibility = 'visible';
+				}
+			}
+		},
+		initEvent: function() {
+			var self = this;
+			if (self.backdrop) {
+				self.backdrop.addEventListener('tap', function(e) {
+					self.close();
+					e.detail.gesture.preventDefault();
+				});
+			}
+			if (this.classList.contains('mui-draggable')) {
+				this.wrapper.addEventListener($.EVENT_START, this); //临时处理
+				this.wrapper.addEventListener('drag', this);
+				this.wrapper.addEventListener('dragend', this);
+			}
+			this.wrapper.addEventListener('webkitTransitionEnd', this);
+		},
+		openPercentage: function(percentage) {
+			var p = percentage / 100;
+			if (!this.slideIn) {
+				if (this.offCanvasLeft && percentage >= 0) {
+					this.updateTranslate(this.offCanvasLeftWidth * p);
+					this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				} else if (this.offCanvasRight && percentage <= 0) {
+					this.updateTranslate(this.offCanvasRightWidth * p);
+					this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				}
+				this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+			} else {
+				if (this.offCanvasLeft && percentage >= 0) {
+					p = p === 0 ? -1 : 0;
+					this.updateTranslate(this.offCanvasLeftWidth * p);
+					this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				} else if (this.offCanvasRight && percentage <= 0) {
+					p = p === 0 ? 1 : 0;
+					this.updateTranslate(this.offCanvasRightWidth * p);
+					this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				}
+				this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+			}
+		},
+		updateTranslate: function(x) {
+			if (x !== this.lastTranslateX) {
+				if (!this.slideIn) {
+					if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) {
+						this.setTranslateX(0);
+						return;
+					}
+					if (this.leftShowing && x > this.offCanvasLeftWidth) {
+						this.setTranslateX(this.offCanvasLeftWidth);
+						return;
+					}
+					if (this.rightShowing && x < -this.offCanvasRightWidth) {
+						this.setTranslateX(-this.offCanvasRightWidth);
+						return;
+					}
+					this.setTranslateX(x);
+					if (x >= 0) {
+						this.leftShowing = true;
+						this.rightShowing = false;
+						if (x > 0) {
+							if (this.offCanvasLeft) {
+								$.each(this.offCanvasLefts, function(index, offCanvas) {
+									if (offCanvas === this.offCanvasLeft) {
+										this.offCanvasLeft.style.zIndex = 0;
+									} else {
+										offCanvas.style.zIndex = -1;
+									}
+								}.bind(this));
+							}
+							if (this.offCanvasRight) {
+								this.offCanvasRight.style.zIndex = -1;
+							}
+						}
+					} else {
+						this.rightShowing = true;
+						this.leftShowing = false;
+						if (this.offCanvasRight) {
+							$.each(this.offCanvasRights, function(index, offCanvas) {
+								if (offCanvas === this.offCanvasRight) {
+									offCanvas.style.zIndex = 0;
+								} else {
+									offCanvas.style.zIndex = -1;
+								}
+							}.bind(this));
+						}
+						if (this.offCanvasLeft) {
+							this.offCanvasLeft.style.zIndex = -1;
+						}
+					}
+				} else {
+					if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
+						if (x < 0) {
+							this.setTranslateX(0);
+							return;
+						}
+						if (x > this.offCanvasRightWidth) {
+							this.setTranslateX(this.offCanvasRightWidth);
+							return;
+						}
+					} else {
+						if (x > 0) {
+							this.setTranslateX(0);
+							return;
+						}
+						if (x < -this.offCanvasLeftWidth) {
+							this.setTranslateX(-this.offCanvasLeftWidth);
+							return;
+						}
+					}
+					this.setTranslateX(x);
+				}
+				this.lastTranslateX = x;
+			}
+		},
+		setTranslateX: $.animationFrame(function(x) {
+			if (this.scroller) {
+				if (this.scalable && this.offCanvas.parentNode === this.wrapper) {
+					var percent = Math.abs(x) / this.offCanvasWidth;
+					var zoomOutScale = 1 - (1 - this.options.scale) * percent;
+					var zoomInScale = this.options.scale + (1 - this.options.scale) * percent;
+					var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent;
+					var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent;
+					if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
+						this.offCanvas.style.webkitTransformOrigin = '-100%';
+						this.scroller.style.webkitTransformOrigin = 'left';
+					} else {
+						this.offCanvas.style.webkitTransformOrigin = '200%';
+						this.scroller.style.webkitTransformOrigin = 'right';
+					}
+					this.offCanvas.style.opacity = zoomInOpacity;
+					this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')';
+					this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')';
+				} else {
+					if (this.slideIn) {
+						this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
+					} else {
+						this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
+					}
+				}
+			}
+		}),
+		getTranslateX: function() {
+			if (this.offCanvas) {
+				var scroller = this.slideIn ? this.offCanvas : this.scroller;
+				var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform'));
+				return (result && result.x) || 0;
+			}
+			return 0;
+		},
+		isShown: function(direction) {
+			var shown = false;
+			if (!this.slideIn) {
+				var x = this.getTranslateX();
+				if (direction === 'right') {
+					shown = this.classList.contains(CLASS_ACTIVE) && x < 0;
+				} else if (direction === 'left') {
+					shown = this.classList.contains(CLASS_ACTIVE) && x > 0;
+				} else {
+					shown = this.classList.contains(CLASS_ACTIVE) && x !== 0;
+				}
+			} else {
+				if (direction === 'left') {
+					shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
+				} else if (direction === 'right') {
+					shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE);
+				} else {
+					shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE));
+				}
+			}
+			return shown;
+		},
+		close: function() {
+			this._initOffCanvasVisible();
+			this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
+			this.offCanvasWidth = this.offCanvas.offsetWidth;
+			if (this.scroller) {
+				this.offCanvas.offsetHeight;
+				this.offCanvas.classList.add(CLASS_TRANSITIONING);
+				this.scroller.classList.add(CLASS_TRANSITIONING);
+				this.openPercentage(0);
+			}
+		},
+		show: function(direction) {
+			this._initOffCanvasVisible();
+			if (this.isShown(direction)) {
+				return false;
+			}
+			if (!direction) {
+				direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left';
+			}
+			if (direction === 'right') {
+				this.offCanvas = this.offCanvasRight;
+				this.offCanvasWidth = this.offCanvasRightWidth;
+			} else {
+				this.offCanvas = this.offCanvasLeft;
+				this.offCanvasWidth = this.offCanvasLeftWidth;
+			}
+			if (this.scroller) {
+				this.offCanvas.offsetHeight;
+				this.offCanvas.classList.add(CLASS_TRANSITIONING);
+				this.scroller.classList.add(CLASS_TRANSITIONING);
+				this.openPercentage(direction === 'left' ? 100 : -100);
+			}
+			return true;
+		},
+		toggle: function(directionOrOffCanvas) {
+			var direction = directionOrOffCanvas;
+			if (directionOrOffCanvas && directionOrOffCanvas.classList) {
+				direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right';
+				this.refresh(directionOrOffCanvas);
+			}
+			if (!this.show(direction)) {
+				this.close();
+			}
+		}
+	});
+
+	//hash to offcanvas
+	var findOffCanvasContainer = function(target) {
+		parentNode = target.parentNode;
+		if (parentNode) {
+			if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+				return parentNode;
+			} else {
+				parentNode = parentNode.parentNode;
+				if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+					return parentNode;
+				}
+			}
+		}
+	};
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			var offcanvas = document.getElementById(target.hash.replace('#', ''));
+			if (offcanvas) {
+				var container = findOffCanvasContainer(offcanvas);
+				if (container) {
+					$.targets._container = container;
+					return offcanvas;
+				}
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 60,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	window.addEventListener('tap', function(e) {
+		if (!$.targets.offcanvas) {
+			return;
+		}
+		//TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好
+		var target = e.target;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) {
+				e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange
+				$($.targets._container).offCanvas().toggle($.targets.offcanvas);
+				$.targets.offcanvas = $.targets._container = null;
+				break;
+			}
+		}
+	});
+
+	$.fn.offCanvas = function(options) {
+		var offCanvasApis = [];
+		this.each(function() {
+			var offCanvasApi = null;
+			var self = this;
+			//hack old version
+			if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+				self = findOffCanvasContainer(self);
+			}
+			var id = self.getAttribute('data-offCanvas');
+			if (!id) {
+				id = ++$.uuid;
+				$.data[id] = offCanvasApi = new OffCanvas(self, options);
+				self.setAttribute('data-offCanvas', id);
+			} else {
+				offCanvasApi = $.data[id];
+			}
+			if (options === 'show' || options === 'close' || options === 'toggle') {
+				offCanvasApi.toggle();
+			}
+			offCanvasApis.push(offCanvasApi);
+		});
+		return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis;
+	};
+	$.ready(function() {
+		$('.mui-off-canvas-wrap').offCanvas();
+	});
+})(mui, window, document, 'offcanvas');
+/**
+ * actions
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var CLASS_ACTION = 'mui-action';
+
+	var handle = function(event, target) {
+		var className = target.className || '';
+		if (typeof className !== 'string') { //svg className(SVGAnimatedString)
+			className = '';
+		}
+		if (className && ~className.indexOf(CLASS_ACTION)) {
+			if (target.classList.contains('mui-action-back')) {
+				event.preventDefault();
+			}
+			return target;
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 50,
+		handle: handle,
+		target: false,
+		isContinue: true
+	});
+
+})(mui, 'action');
+/**
+ * Modals
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+	var CLASS_MODAL = 'mui-modal';
+
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			var modal = document.getElementById(target.hash.replace('#', ''));
+			if (modal && modal.classList.contains(CLASS_MODAL)) {
+				return modal;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 50,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	window.addEventListener('tap', function(event) {
+		if ($.targets.modal) {
+			event.detail.gesture.preventDefault(); //fixed hashchange
+			$.targets.modal.classList.toggle('mui-active');
+		}
+	});
+})(mui, window, document, 'modal');
+/**
+ * Popovers
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} name
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+
+	var CLASS_POPOVER = 'mui-popover';
+	var CLASS_POPOVER_ARROW = 'mui-popover-arrow';
+	var CLASS_ACTION_POPOVER = 'mui-popover-action';
+	var CLASS_BACKDROP = 'mui-backdrop';
+	var CLASS_BAR_POPOVER = 'mui-bar-popover';
+	var CLASS_BAR_BACKDROP = 'mui-bar-backdrop';
+	var CLASS_ACTION_BACKDROP = 'mui-backdrop-action';
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_BOTTOM = 'mui-bottom';
+
+
+
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			$.targets._popover = document.getElementById(target.hash.replace('#', ''));
+			if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) {
+				return target;
+			} else {
+				$.targets._popover = null;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 60,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	var onPopoverShown = function(e) {
+		this.removeEventListener('webkitTransitionEnd', onPopoverShown);
+		this.addEventListener($.EVENT_MOVE, $.preventDefault);
+		$.trigger(this, 'shown', this);
+	}
+	var onPopoverHidden = function(e) {
+		setStyle(this, 'none');
+		this.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+		this.removeEventListener($.EVENT_MOVE, $.preventDefault);
+		$.trigger(this, 'hidden', this);
+	};
+
+	var backdrop = (function() {
+		var element = document.createElement('div');
+		element.classList.add(CLASS_BACKDROP);
+		element.addEventListener($.EVENT_MOVE, $.preventDefault);
+		element.addEventListener('tap', function(e) {
+			var popover = $.targets._popover;
+			if (popover) {
+				popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
+				popover.classList.remove(CLASS_ACTIVE);
+				removeBackdrop(popover);
+			}
+		});
+
+		return element;
+	}());
+	var removeBackdropTimer;
+	var removeBackdrop = function(popover) {
+		backdrop.setAttribute('style', 'opacity:0');
+		$.targets.popover = $.targets._popover = null; //reset
+		removeBackdropTimer = $.later(function() {
+			if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) {
+				document.body.removeChild(backdrop);
+			}
+		}, 350);
+	};
+	window.addEventListener('tap', function(e) {
+		if (!$.targets.popover) {
+			return;
+		}
+		var toggle = false;
+		var target = e.target;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target === $.targets.popover) {
+				toggle = true;
+			}
+		}
+		if (toggle) {
+			e.detail.gesture.preventDefault(); //fixed hashchange
+			togglePopover($.targets._popover, $.targets.popover);
+		}
+
+	});
+
+	var togglePopover = function(popover, anchor, state) {
+		if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) {
+			return;
+		}
+		removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer
+		//remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove
+		popover.removeEventListener('webkitTransitionEnd', onPopoverShown);
+		popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+		backdrop.classList.remove(CLASS_BAR_BACKDROP);
+		backdrop.classList.remove(CLASS_ACTION_BACKDROP);
+		var _popover = document.querySelector('.mui-popover.mui-active');
+		if (_popover) {
+			//			_popover.setAttribute('style', '');
+			_popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
+			_popover.classList.remove(CLASS_ACTIVE);
+			//			_popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+			//同一个弹出则直接返回,解决同一个popover的toggle
+			if (popover === _popover) {
+				removeBackdrop(_popover);
+				return;
+			}
+		}
+		var isActionSheet = false;
+		if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar
+			if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover
+				isActionSheet = true;
+				backdrop.classList.add(CLASS_ACTION_BACKDROP);
+			} else { //bar popover
+				backdrop.classList.add(CLASS_BAR_BACKDROP);
+				//				if (anchor) {
+				//					if (anchor.parentNode) {
+				//						var offsetWidth = anchor.offsetWidth;
+				//						var offsetLeft = anchor.offsetLeft;
+				//						var innerWidth = window.innerWidth;
+				//						popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px";
+				//					} else {
+				//						//TODO anchor is position:{left,top,bottom,right}
+				//					}
+				//				}
+			}
+		}
+		setStyle(popover, 'block'); //actionsheet transform
+		popover.offsetHeight;
+		popover.classList.add(CLASS_ACTIVE);
+		backdrop.setAttribute('style', '');
+		document.body.appendChild(backdrop);
+		calPosition(popover, anchor, isActionSheet); //position
+		backdrop.classList.add(CLASS_ACTIVE);
+		popover.addEventListener('webkitTransitionEnd', onPopoverShown);
+	};
+	var setStyle = function(popover, display, top, left) {
+		var style = popover.style;
+		if (typeof display !== 'undefined')
+			style.display = display;
+		if (typeof top !== 'undefined')
+			style.top = top + 'px';
+		if (typeof left !== 'undefined')
+			style.left = left + 'px';
+	};
+	var calPosition = function(popover, anchor, isActionSheet) {
+		if (!popover || !anchor) {
+			return;
+		}
+
+		if (isActionSheet) { //actionsheet
+			setStyle(popover, 'block')
+			return;
+		}
+
+		var wWidth = window.innerWidth;
+		var wHeight = window.innerHeight;
+
+		var pWidth = popover.offsetWidth;
+		var pHeight = popover.offsetHeight;
+
+		var aWidth = anchor.offsetWidth;
+		var aHeight = anchor.offsetHeight;
+		var offset = $.offset(anchor);
+
+		var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW);
+		if (!arrow) {
+			arrow = document.createElement('div');
+			arrow.className = CLASS_POPOVER_ARROW;
+			popover.appendChild(arrow);
+		}
+		var arrowSize = arrow && arrow.offsetWidth / 2 || 0;
+
+
+
+		var pTop = 0;
+		var pLeft = 0;
+		var diff = 0;
+		var arrowLeft = 0;
+		var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5;
+
+		var position = 'top';
+		if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top
+			pTop = offset.top - pHeight - arrowSize;
+		} else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom
+			position = 'bottom';
+			pTop = offset.top + aHeight + arrowSize;
+		} else { //middle
+			position = 'middle';
+			pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0);
+			pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0);
+		}
+		if (position === 'top' || position === 'bottom') {
+			pLeft = aWidth / 2 + offset.left - pWidth / 2;
+			diff = pLeft;
+			if (pLeft < defaultPadding) pLeft = defaultPadding;
+			if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding;
+
+			if (arrow) {
+				if (position === 'top') {
+					arrow.classList.add(CLASS_BOTTOM);
+				} else {
+					arrow.classList.remove(CLASS_BOTTOM);
+				}
+				diff = diff - pLeft;
+				arrowLeft = (pWidth / 2 - arrowSize / 2 + diff);
+				arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6);
+				arrow.setAttribute('style', 'left:' + arrowLeft + 'px');
+			}
+		} else if (position === 'middle') {
+			arrow.setAttribute('style', 'display:none');
+		}
+		setStyle(popover, 'block', pTop, pLeft);
+	};
+
+	$.createMask = function(callback) {
+		var element = document.createElement('div');
+		element.classList.add(CLASS_BACKDROP);
+		element.addEventListener($.EVENT_MOVE, $.preventDefault);
+		element.addEventListener('tap', function() {
+			mask.close();
+		});
+		var mask = [element];
+		mask._show = false;
+		mask.show = function() {
+			mask._show = true;
+			element.setAttribute('style', 'opacity:1');
+			document.body.appendChild(element);
+			return mask;
+		};
+		mask._remove = function() {
+			if (mask._show) {
+				mask._show = false;
+				element.setAttribute('style', 'opacity:0');
+				$.later(function() {
+					var body = document.body;
+					element.parentNode === body && body.removeChild(element);
+				}, 350);
+			}
+			return mask;
+		};
+		mask.close = function() {
+			if (callback) {
+				if (callback() !== false) {
+					mask._remove();
+				}
+			} else {
+				mask._remove();
+			}
+		};
+		return mask;
+	};
+	$.fn.popover = function() {
+		var args = arguments;
+		this.each(function() {
+			$.targets._popover = this;
+			if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') {
+				togglePopover(this, args[1], args[0]);
+			}
+		});
+	};
+
+})(mui, window, document, 'popover');
+/**
+ * segmented-controllers
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, document, name, undefined) {
+
+    var CLASS_CONTROL_ITEM = 'mui-control-item';
+    var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control';
+    var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical';
+    var CLASS_CONTROL_CONTENT = 'mui-control-content';
+    var CLASS_TAB_BAR = 'mui-bar-tab';
+    var CLASS_TAB_ITEM = 'mui-tab-item';
+    var CLASS_SLIDER_ITEM = 'mui-slider-item';
+
+   var handle = function(event, target) {
+        if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) {
+            if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) {
+                //vertical 如果preventDefault会导致无法滚动
+            } else {
+
+                    event.preventDefault();      
+                    // if(target.tagName == 'A') {
+                    //     // fixed 底部选项卡href 无法跳转 && stop hash change
+                    //     var curr_href = location.hostname + location.pathname,
+                    //         target_href = target.hostname + target.pathname;
+                   
+                    //     if (curr_href == target_href && target.hash !== "") {
+                    //         event.preventDefault();
+                    //         return target;
+                    //     }else{
+                    //             return false
+                    //     }
+                    // }
+            }
+            //          if (target.hash) {
+            return target;
+            //          }
+        }
+        return false;
+    };
+
+    $.registerTarget({
+        name: name,
+        index: 80,
+        handle: handle,
+        target: false
+    });
+
+    window.addEventListener('tap', function(e) {
+
+        var targetTab = $.targets.tab;
+        if (!targetTab) {
+            return;
+        }
+        var activeTab;
+        var activeBodies;
+        var targetBody;
+        var className = 'mui-active';
+        var classSelector = '.' + className;
+        var segmentedControl = targetTab.parentNode;
+
+        for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) {
+            if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) {
+                activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM);
+                break;
+            } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) {
+                activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM);
+            }
+        }
+
+        if (activeTab) {
+            activeTab.classList.remove(className);
+        }
+
+        var isLastActive = targetTab === activeTab;
+        if (targetTab) {
+            targetTab.classList.add(className);
+        }
+
+        if (!targetTab.hash) {
+            return;
+        }
+        targetBody = document.getElementById(targetTab.hash.replace('#', ''));
+
+        if (!targetBody) {
+            return;
+        }
+        if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover
+            targetTab.classList[isLastActive ? 'remove' : 'add'](className);
+            return;
+        }
+        if (isLastActive) { //same
+            return;
+        }
+        var parentNode = targetBody.parentNode;
+        activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector);
+        for (var i = 0; i < activeBodies.length; i++) {
+            var activeBody = activeBodies[i];
+            activeBody.parentNode === parentNode && activeBody.classList.remove(className);
+        }
+
+        targetBody.classList.add(className);
+
+        var contents = [];
+        var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT);
+        for (var i = 0; i < _contents.length; i++) { //查找直属子节点
+            _contents[i].parentNode === parentNode && (contents.push(_contents[i]));
+        }
+        $.trigger(targetBody, $.eventName('shown', name), {
+            tabNumber: Array.prototype.indexOf.call(contents, targetBody)
+        });
+        e.detail && e.detail.gesture.preventDefault(); //fixed hashchange
+    });
+
+})(mui, window, document, 'tab');
+/**
+ * Toggles switch
+ * @param {type} $
+ * @param {type} window
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, window, name) {
+
+	var CLASS_SWITCH = 'mui-switch';
+	var CLASS_SWITCH_HANDLE = 'mui-switch-handle';
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_DRAGGING = 'mui-dragging';
+
+	var CLASS_DISABLED = 'mui-disabled';
+
+	var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
+
+	var handle = function(event, target) {
+		if (target.classList && target.classList.contains(CLASS_SWITCH)) {
+			return target;
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 100,
+		handle: handle,
+		target: false
+	});
+
+
+	var Toggle = function(element) {
+		this.element = element;
+		this.classList = this.element.classList;
+		this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
+		this.init();
+		this.initEvent();
+	};
+	Toggle.prototype.init = function() {
+		this.toggleWidth = this.element.offsetWidth;
+		this.handleWidth = this.handle.offsetWidth;
+		this.handleX = this.toggleWidth - this.handleWidth - 3;
+	};
+	Toggle.prototype.initEvent = function() {
+		this.element.addEventListener($.EVENT_START, this);
+		this.element.addEventListener('drag', this);
+		this.element.addEventListener('swiperight', this);
+		this.element.addEventListener($.EVENT_END, this);
+		this.element.addEventListener($.EVENT_CANCEL, this);
+
+	};
+	Toggle.prototype.handleEvent = function(e) {
+		if (this.classList.contains(CLASS_DISABLED)) {
+			return;
+		}
+		switch (e.type) {
+			case $.EVENT_START:
+				this.start(e);
+				break;
+			case 'drag':
+				this.drag(e);
+				break;
+			case 'swiperight':
+				this.swiperight();
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				this.end(e);
+				break;
+		}
+	};
+	Toggle.prototype.start = function(e) {
+		this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
+		this.classList.add(CLASS_DRAGGING);
+		if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化
+			this.init();
+		}
+	};
+	Toggle.prototype.drag = function(e) {
+		var detail = e.detail;
+		if (!this.isDragging) {
+			if (detail.direction === 'left' || detail.direction === 'right') {
+				this.isDragging = true;
+				this.lastChanged = undefined;
+				this.initialState = this.classList.contains(CLASS_ACTIVE);
+			}
+		}
+		if (this.isDragging) {
+			this.setTranslateX(detail.deltaX);
+			e.stopPropagation();
+			detail.gesture.preventDefault();
+		}
+	};
+	Toggle.prototype.swiperight = function(e) {
+		if (this.isDragging) {
+			e.stopPropagation();
+		}
+	};
+	Toggle.prototype.end = function(e) {
+		this.classList.remove(CLASS_DRAGGING);
+		if (this.isDragging) {
+			this.isDragging = false;
+			e.stopPropagation();
+			$.trigger(this.element, 'toggle', {
+				isActive: this.classList.contains(CLASS_ACTIVE)
+			});
+		} else {
+			this.toggle();
+		}
+	};
+	Toggle.prototype.toggle = function(animate) {
+		var classList = this.classList;
+		if (animate === false) {
+			this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
+		} else {
+			this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
+		}
+		if (classList.contains(CLASS_ACTIVE)) {
+			classList.remove(CLASS_ACTIVE);
+			this.handle.style.webkitTransform = 'translate(0,0)';
+		} else {
+			classList.add(CLASS_ACTIVE);
+			this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
+		}
+		$.trigger(this.element, 'toggle', {
+			isActive: this.classList.contains(CLASS_ACTIVE)
+		});
+	};
+	Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
+		if (!this.isDragging) {
+			return;
+		}
+		var isChanged = false;
+		if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
+			isChanged = true;
+		}
+		if (this.lastChanged !== isChanged) {
+			if (isChanged) {
+				this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
+				this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
+			} else {
+				this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
+				this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
+			}
+			this.lastChanged = isChanged;
+		}
+
+	});
+
+	$.fn['switch'] = function(options) {
+		var switchApis = [];
+		this.each(function() {
+			var switchApi = null;
+			var id = this.getAttribute('data-switch');
+			if (!id) {
+				id = ++$.uuid;
+				$.data[id] = new Toggle(this);
+				this.setAttribute('data-switch', id);
+			} else {
+				switchApi = $.data[id];
+			}
+			switchApis.push(switchApi);
+		});
+		return switchApis.length > 1 ? switchApis : switchApis[0];
+	};
+	$.ready(function() {
+		$('.' + CLASS_SWITCH)['switch']();
+	});
+})(mui, window, 'toggle');
+/**
+ * Tableviews
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_SELECTED = 'mui-selected';
+	var CLASS_GRID_VIEW = 'mui-grid-view';
+	var CLASS_RADIO_VIEW = 'mui-table-view-radio';
+	var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell';
+	var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content';
+	var CLASS_DISABLED = 'mui-disabled';
+	var CLASS_TOGGLE = 'mui-switch';
+	var CLASS_BTN = 'mui-btn';
+
+	var CLASS_SLIDER_HANDLE = 'mui-slider-handle';
+	var CLASS_SLIDER_LEFT = 'mui-slider-left';
+	var CLASS_SLIDER_RIGHT = 'mui-slider-right';
+	var CLASS_TRANSITIONING = 'mui-transitioning';
+
+
+	var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE;
+	var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT;
+	var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT;
+	var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
+	var SELECTOR_BUTTON = '.' + CLASS_BTN;
+	var overFactor = 0.8;
+	var cell, a;
+
+	var isMoved = isOpened = openedActions = progress = false;
+	var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
+	var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0;
+
+
+
+	var toggleActive = function(isActive) {
+		if (isActive) {
+			if (a) {
+				a.classList.add(CLASS_ACTIVE);
+			} else if (cell) {
+				cell.classList.add(CLASS_ACTIVE);
+			}
+		} else {
+			timer && timer.cancel();
+			if (a) {
+				a.classList.remove(CLASS_ACTIVE);
+			} else if (cell) {
+				cell.classList.remove(CLASS_ACTIVE);
+			}
+		}
+	};
+
+	var updateTranslate = function() {
+		if (translateX !== lastTranslateX) {
+			if (buttonsRight && buttonsRight.length > 0) {
+				progress = translateX / sliderActionRightWidth;
+				if (translateX < -sliderActionRightWidth) {
+					translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor);
+				}
+				for (var i = 0, len = buttonsRight.length; i < len; i++) {
+					var buttonRight = buttonsRight[i];
+					if (typeof buttonRight._buttonOffset === 'undefined') {
+						buttonRight._buttonOffset = buttonRight.offsetLeft;
+					}
+					buttonOffset = buttonRight._buttonOffset;
+					setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1))));
+				}
+			}
+			if (buttonsLeft && buttonsLeft.length > 0) {
+				progress = translateX / sliderActionLeftWidth;
+				if (translateX > sliderActionLeftWidth) {
+					translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor);
+				}
+				for (var i = 0, len = buttonsLeft.length; i < len; i++) {
+					var buttonLeft = buttonsLeft[i];
+					if (typeof buttonLeft._buttonOffset === 'undefined') {
+						buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
+					}
+					buttonOffset = buttonLeft._buttonOffset;
+					if (buttonsLeft.length > 1) {
+						buttonLeft.style.zIndex = buttonsLeft.length - i;
+					}
+					setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1))));
+				}
+			}
+			setTranslate(sliderHandle, translateX);
+			lastTranslateX = translateX;
+		}
+		sliderRequestAnimationFrame = requestAnimationFrame(function() {
+			updateTranslate();
+		});
+	};
+	var setTranslate = function(element, x) {
+		if (element) {
+			element.style.webkitTransform = 'translate(' + x + 'px,0)';
+		}
+	};
+
+	window.addEventListener($.EVENT_START, function(event) {
+		if (cell) {
+			toggleActive(false);
+		}
+		cell = a = false;
+		isMoved = isOpened = openedActions = false;
+		var target = event.target;
+		var isDisabled = false;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.classList) {
+				var classList = target.classList;
+				if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) {
+					isDisabled = true;
+				}
+				if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content
+					break;
+				}
+				if (classList.contains(CLASS_TABLE_VIEW_CELL)) {
+					cell = target;
+					//TODO swipe to delete close
+					var selected = cell.parentNode.querySelector(SELECTOR_SELECTED);
+					if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) {
+						$.swipeoutClose(selected);
+						cell = isDisabled = false;
+						return;
+					}
+					if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) {
+						var link = cell.querySelector('a');
+						if (link && link.parentNode === cell) { //li>a
+							a = link;
+						}
+					}
+					var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
+					if (handle) {
+						toggleEvents(cell);
+						event.stopPropagation();
+					}
+					if (!isDisabled) {
+						if (handle) {
+							if (timer) {
+								timer.cancel();
+							}
+							timer = $.later(function() {
+								toggleActive(true);
+							}, 100);
+						} else {
+							toggleActive(true);
+						}
+					}
+					break;
+				}
+			}
+		}
+	});
+	window.addEventListener($.EVENT_MOVE, function(event) {
+		toggleActive(false);
+	});
+
+	var handleEvent = {
+		handleEvent: function(event) {
+			switch (event.type) {
+				case 'drag':
+					this.drag(event);
+					break;
+				case 'dragend':
+					this.dragend(event);
+					break;
+				case 'flick':
+					this.flick(event);
+					break;
+				case 'swiperight':
+					this.swiperight(event);
+					break;
+				case 'swipeleft':
+					this.swipeleft(event);
+					break;
+			}
+		},
+		drag: function(event) {
+			if (!cell) {
+				return;
+			}
+			if (!isMoved) { //init
+				sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
+				sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
+				if (sliderHandle) {
+					sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT);
+					sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT);
+					if (sliderActionLeft) {
+						sliderActionLeftWidth = sliderActionLeft.offsetWidth;
+						buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON);
+					}
+					if (sliderActionRight) {
+						sliderActionRightWidth = sliderActionRight.offsetWidth;
+						buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON);
+					}
+					cell.classList.remove(CLASS_TRANSITIONING);
+					isOpened = cell.classList.contains(CLASS_SELECTED);
+					if (isOpened) {
+						openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right';
+					}
+				}
+			}
+			var detail = event.detail;
+			var direction = detail.direction;
+			var angle = detail.angle;
+			if (direction === 'left' && (angle > 150 || angle < -150)) {
+				if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态
+					isMoved = true;
+				}
+			} else if (direction === 'right' && (angle > -30 && angle < 30)) {
+				if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态
+					isMoved = true;
+				}
+			}
+			if (isMoved) {
+				event.stopPropagation();
+				event.detail.gesture.preventDefault();
+				var translate = event.detail.deltaX;
+				if (isOpened) {
+					if (openedActions === 'right') {
+						translate = translate - sliderActionRightWidth;
+					} else {
+						translate = translate + sliderActionLeftWidth;
+					}
+				}
+				if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) {
+					if (!isOpened) {
+						return;
+					}
+					translate = 0;
+				}
+				if (translate < 0) {
+					sliderDirection = 'toLeft';
+				} else if (translate > 0) {
+					sliderDirection = 'toRight';
+				} else {
+					if (!sliderDirection) {
+						sliderDirection = 'toLeft';
+					}
+				}
+				if (!sliderRequestAnimationFrame) {
+					updateTranslate();
+				}
+				translateX = translate;
+			}
+		},
+		flick: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		swipeleft: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		swiperight: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		dragend: function(event) {
+			if (!isMoved) {
+				return;
+			}
+			event.stopPropagation();
+			if (sliderRequestAnimationFrame) {
+				cancelAnimationFrame(sliderRequestAnimationFrame);
+				sliderRequestAnimationFrame = null;
+			}
+			var detail = event.detail;
+			isMoved = false;
+			var action = 'close';
+			var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth;
+			var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2);
+			if (isToggle) {
+				if (!isOpened) {
+					action = 'open';
+				} else if (detail.direction === 'left' && openedActions === 'right') {
+					action = 'open';
+				} else if (detail.direction === 'right' && openedActions === 'left') {
+					action = 'open';
+				}
+
+			}
+			cell.classList.add(CLASS_TRANSITIONING);
+			var buttons;
+			if (action === 'open') {
+				var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth;
+				setTranslate(sliderHandle, newTranslate);
+				buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft;
+				if (typeof buttons !== 'undefined') {
+					var button = null;
+					for (var i = 0; i < buttons.length; i++) {
+						button = buttons[i];
+						setTranslate(button, newTranslate);
+					}
+					button.parentNode.classList.add(CLASS_SELECTED);
+					cell.classList.add(CLASS_SELECTED);
+					if (!isOpened) {
+						$.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright');
+					}
+				}
+			} else {
+				setTranslate(sliderHandle, 0);
+				sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED);
+				sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED);
+				cell.classList.remove(CLASS_SELECTED);
+			}
+			var buttonOffset;
+			if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
+				for (var i = 0, len = buttonsLeft.length; i < len; i++) {
+					var buttonLeft = buttonsLeft[i];
+					buttonOffset = buttonLeft._buttonOffset;
+					if (typeof buttonOffset === 'undefined') {
+						buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
+					}
+					setTranslate(buttonLeft, buttonOffset);
+				}
+			}
+			if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
+				for (var i = 0, len = buttonsRight.length; i < len; i++) {
+					var buttonRight = buttonsRight[i];
+					buttonOffset = buttonRight._buttonOffset;
+					if (typeof buttonOffset === 'undefined') {
+						buttonRight._buttonOffset = buttonRight.offsetLeft;
+					}
+					setTranslate(buttonRight, -buttonOffset);
+				}
+			}
+		}
+	};
+
+	function toggleEvents(element, isRemove) {
+		var method = !!isRemove ? 'removeEventListener' : 'addEventListener';
+		element[method]('drag', handleEvent);
+		element[method]('dragend', handleEvent);
+		element[method]('swiperight', handleEvent);
+		element[method]('swipeleft', handleEvent);
+		element[method]('flick', handleEvent);
+	};
+	/**
+	 * 打开滑动菜单
+	 * @param {Object} el
+	 * @param {Object} direction
+	 */
+	$.swipeoutOpen = function(el, direction) {
+		if (!el) return;
+		var classList = el.classList;
+		if (classList.contains(CLASS_SELECTED)) return;
+		if (!direction) {
+			if (el.querySelector(SELECTOR_SLIDER_RIGHT)) {
+				direction = 'right';
+			} else {
+				direction = 'left';
+			}
+		}
+		var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
+		if (!swipeoutAction) return;
+		swipeoutAction.classList.add(CLASS_SELECTED);
+		classList.add(CLASS_SELECTED);
+		classList.remove(CLASS_TRANSITIONING);
+		var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
+		var swipeoutWidth = swipeoutAction.offsetWidth;
+		var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth;
+		var length = buttons.length;
+		var button;
+		for (var i = 0; i < length; i++) {
+			button = buttons[i];
+			if (direction === 'right') {
+				setTranslate(button, -button.offsetLeft);
+			} else {
+				setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
+			}
+		}
+		classList.add(CLASS_TRANSITIONING);
+		for (var i = 0; i < length; i++) {
+			setTranslate(buttons[i], translate);
+		}
+		setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate);
+	};
+	/**
+	 * 关闭滑动菜单
+	 * @param {Object} el
+	 */
+	$.swipeoutClose = function(el) {
+		if (!el) return;
+		var classList = el.classList;
+		if (!classList.contains(CLASS_SELECTED)) return;
+		var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left';
+		var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
+		if (!swipeoutAction) return;
+		swipeoutAction.classList.remove(CLASS_SELECTED);
+		classList.remove(CLASS_SELECTED);
+		classList.add(CLASS_TRANSITIONING);
+		var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
+		var swipeoutWidth = swipeoutAction.offsetWidth;
+		var length = buttons.length;
+		var button;
+		setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0);
+		for (var i = 0; i < length; i++) {
+			button = buttons[i];
+			if (direction === 'right') {
+				setTranslate(button, (-button.offsetLeft));
+			} else {
+				setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
+			}
+		}
+	};
+
+	window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
+		if (!cell) {
+			return;
+		}
+		toggleActive(false);
+		sliderHandle && toggleEvents(cell, true);
+	});
+	window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
+		if (!cell) {
+			return;
+		}
+		toggleActive(false);
+		sliderHandle && toggleEvents(cell, true);
+	});
+	var radioOrCheckboxClick = function(event) {
+		var type = event.target && event.target.type || '';
+		if (type === 'radio' || type === 'checkbox') {
+			return;
+		}
+		var classList = cell.classList;
+		if (classList.contains('mui-radio')) {
+			var input = cell.querySelector('input[type=radio]');
+			if (input) {
+				//				input.click();
+				if (!input.disabled && !input.readOnly) {
+					input.checked = !input.checked;
+					$.trigger(input, 'change');
+				}
+			}
+		} else if (classList.contains('mui-checkbox')) {
+			var input = cell.querySelector('input[type=checkbox]');
+			if (input) {
+				//				input.click();
+				if (!input.disabled && !input.readOnly) {
+					input.checked = !input.checked;
+					$.trigger(input, 'change');
+				}
+			}
+		}
+	};
+	//fixed hashchange(android)
+	window.addEventListener($.EVENT_CLICK, function(e) {
+		if (cell && cell.classList.contains('mui-collapse')) {
+			e.preventDefault();
+		}
+	});
+	window.addEventListener('doubletap', function(event) {
+		if (cell) {
+			radioOrCheckboxClick(event);
+		}
+	});
+	var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
+	window.addEventListener('tap', function(event) {
+		if (!cell) {
+			return;
+		}
+		var isExpand = false;
+		var classList = cell.classList;
+		var ul = cell.parentNode;
+		if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) {
+			if (classList.contains(CLASS_SELECTED)) {
+				return;
+			}
+			var selected = ul.querySelector('li' + SELECTOR_SELECTED);
+			if (selected) {
+				selected.classList.remove(CLASS_SELECTED);
+			}
+			classList.add(CLASS_SELECTED);
+			$.trigger(cell, 'selected', {
+				el: cell
+			});
+			return;
+		}
+		if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) {
+			if (!preventDefaultException.test(event.target.tagName)) {
+				event.detail.gesture.preventDefault();
+			}
+
+			if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类
+				var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active');
+				if (collapse) {
+					collapse.classList.remove(CLASS_ACTIVE);
+				}
+				isExpand = true;
+			}
+			classList.toggle(CLASS_ACTIVE);
+			if (isExpand) {
+				//触发展开事件
+				$.trigger(cell, 'expand');
+
+				//scroll
+				//暂不滚动
+				// var offsetTop = $.offset(cell).top;
+				// var scrollTop = document.body.scrollTop;
+				// var height = window.innerHeight;
+				// var offsetHeight = cell.offsetHeight;
+				// var cellHeight = (offsetTop - scrollTop + offsetHeight);
+				// if (offsetHeight > height) {
+				// 	$.scrollTo(offsetTop, 300);
+				// } else if (cellHeight > height) {
+				// 	$.scrollTo(cellHeight - height + scrollTop, 300);
+				// }
+			}
+		} else {
+			radioOrCheckboxClick(event);
+		}
+	});
+})(mui, window, document);
+(function($, window) {
+	/**
+	 * 警告消息框
+	 */
+	$.alert = function(message, title, btnValue, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+				if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnValue = '确定';
+				} else if (typeof btnValue === 'function') {
+					callback = btnValue;
+					btnValue = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.alert(message, callback, title, btnValue);
+				});
+			}
+
+		} else {
+			//TODO H5版本
+			window.alert(message);
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	/**
+	 * 确认消息框
+	 */
+	$.confirm = function(message, title, btnArray, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+				if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnArray = null;
+				} else if (typeof btnArray === 'function') {
+					callback = btnArray;
+					btnArray = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.confirm(message, callback, title, btnArray);
+				});
+			}
+
+		} else {
+			//H5版本,0为确认,1为取消
+			if (window.confirm(message)) {
+				callback({
+					index: 0
+				});
+			} else {
+				callback({
+					index: 1
+				});
+			}
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	/**
+	 * 输入对话框
+	 */
+	$.prompt = function(text, defaultText, title, btnArray, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+
+				if (typeof defaultText === 'function') {
+					callback = defaultText;
+					defaultText = null;
+					title = null;
+					btnArray = null;
+				} else if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnArray = null;
+				} else if (typeof btnArray === 'function') {
+					callback = btnArray;
+					btnArray = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.prompt(text, callback, title, defaultText, btnArray);
+				});
+			}
+
+		} else {
+			//H5版本(确认index为0,取消index为1)
+			var result = window.prompt(text);
+			if (result) {
+				callback({
+					index: 0,
+					value: result
+				});
+			} else {
+				callback({
+					index: 1,
+					value: ''
+				});
+			}
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	var CLASS_ACTIVE = 'mui-active';
+	/**
+	 * 自动消失提示框
+	 */
+	$.toast = function(message,options) {
+		var durations = {
+		    'long': 3500,
+		    'short': 2000
+		};
+
+		//计算显示时间
+		 options = $.extend({
+	        duration: 'short'
+	    }, options || {});
+
+
+		if ($.os.plus && options.type !== 'div') {
+			//默认显示在底部;
+			$.plusReady(function() {
+				plus.nativeUI.toast(message, {
+					verticalAlign: 'bottom',
+					duration:options.duration
+				});
+			});
+		} else {
+			if (typeof options.duration === 'number') {
+		        duration = options.duration>0 ? options.duration:durations['short'];
+		    } else {
+		        duration = durations[options.duration];
+		    }
+		    if (!duration) {
+		        duration = durations['short'];
+		    }
+			var toast = document.createElement('div');
+			toast.classList.add('mui-toast-container');
+			toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>';
+			toast.addEventListener('webkitTransitionEnd', function() {
+				if (!toast.classList.contains(CLASS_ACTIVE)) {
+					toast.parentNode.removeChild(toast);
+					toast = null;
+				}
+			});
+			//点击则自动消失
+			toast.addEventListener('click', function() {
+		        toast.parentNode.removeChild(toast);
+		        toast = null;
+		    });
+			document.body.appendChild(toast);
+			toast.offsetHeight;
+			toast.classList.add(CLASS_ACTIVE);
+			setTimeout(function() {
+				toast && toast.classList.remove(CLASS_ACTIVE);
+			}, duration);
+			
+			return {
+		        isVisible: function() {return !!toast;}
+		    }
+		}   
+	};
+
+})(mui, window);
+/**
+ * Popup(alert,confirm,prompt)  
+ * @param {Object} $
+ * @param {Object} window
+ * @param {Object} document
+ */
+(function($, window, document) {
+    var CLASS_POPUP = 'mui-popup';
+    var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
+    var CLASS_POPUP_IN = 'mui-popup-in';
+    var CLASS_POPUP_OUT = 'mui-popup-out';
+    var CLASS_POPUP_INNER = 'mui-popup-inner';
+    var CLASS_POPUP_TITLE = 'mui-popup-title';
+    var CLASS_POPUP_TEXT = 'mui-popup-text';
+    var CLASS_POPUP_INPUT = 'mui-popup-input';
+    var CLASS_POPUP_BUTTONS = 'mui-popup-buttons';
+    var CLASS_POPUP_BUTTON = 'mui-popup-button';
+    var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold';
+    var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
+    var CLASS_ACTIVE = 'mui-active';
+
+    var popupStack = [];
+    var backdrop = (function() {
+        var element = document.createElement('div');
+        element.classList.add(CLASS_POPUP_BACKDROP);
+        element.addEventListener($.EVENT_MOVE, $.preventDefault);
+        element.addEventListener('webkitTransitionEnd', function() {
+            if (!this.classList.contains(CLASS_ACTIVE)) {
+                element.parentNode && element.parentNode.removeChild(element);
+            }
+        });
+        return element;
+    }());
+
+    var createInput = function(placeholder) {
+        return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>';
+    };
+    var createInner = function(message, title, extra) {
+        return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>';
+    };
+    var createButtons = function(btnArray) {
+        var length = btnArray.length;
+        var btns = [];
+        for (var i = 0; i < length; i++) {
+            btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>');
+        }
+        return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>';
+    };
+
+    var createPopup = function(html, callback) {
+        var popupElement = document.createElement('div');
+        popupElement.className = CLASS_POPUP;
+        popupElement.innerHTML = html;
+        var removePopupElement = function() {
+            popupElement.parentNode && popupElement.parentNode.removeChild(popupElement);
+            popupElement = null;
+        };
+        popupElement.addEventListener($.EVENT_MOVE, $.preventDefault);
+        popupElement.addEventListener('webkitTransitionEnd', function(e) {
+            if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) {
+                removePopupElement();
+            }
+        });
+        popupElement.style.display = 'block';
+        document.body.appendChild(popupElement);
+        popupElement.offsetHeight;
+        popupElement.classList.add(CLASS_POPUP_IN);
+
+        if (!backdrop.classList.contains(CLASS_ACTIVE)) {
+            backdrop.style.display = 'block';
+            document.body.appendChild(backdrop);
+            backdrop.offsetHeight;
+            backdrop.classList.add(CLASS_ACTIVE);
+        }
+        var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement);
+        var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input');
+        var popup = {
+            element: popupElement,
+            close: function(index, animate) {
+                if (popupElement) {
+                    var result = callback && callback({
+                        index: index || 0,
+                        value: input && input.value || ''
+                    });
+                    if (result === false) { //返回false则不关闭当前popup
+                        return;
+                    }
+                    if (animate !== false) {
+                        popupElement.classList.remove(CLASS_POPUP_IN);
+                        popupElement.classList.add(CLASS_POPUP_OUT);
+                    } else {
+                        removePopupElement();
+                    }
+                    popupStack.pop();
+                    //如果还有其他popup,则不remove backdrop
+                    if (popupStack.length) {
+                        popupStack[popupStack.length - 1]['show'](animate);
+                    } else {
+                        backdrop.classList.remove(CLASS_ACTIVE);
+                    }
+                }
+            }
+        };
+        var handleEvent = function(e) {
+            popup.close(btns.indexOf(e.target));
+        };
+        $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent);
+        if (popupStack.length) {
+            popupStack[popupStack.length - 1]['hide']();
+        }
+        popupStack.push({
+            close: popup.close,
+            show: function(animate) {
+                popupElement.style.display = 'block';
+                popupElement.offsetHeight;
+                popupElement.classList.add(CLASS_POPUP_IN);
+            },
+            hide: function() {
+                popupElement.style.display = 'none';
+                popupElement.classList.remove(CLASS_POPUP_IN);
+            }
+        });
+        return popup;
+    };
+    var createAlert = function(message, title, btnValue, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof title === 'function') {
+                callback = title;
+                type = btnValue;
+                title = null;
+                btnValue = null;
+            } else if (typeof btnValue === 'function') {
+                type = callback;
+                callback = btnValue;
+                btnValue = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback);
+        }
+        return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定');
+    };
+    var createConfirm = function(message, title, btnArray, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof title === 'function') {
+                callback = title;
+                type = btnArray;
+                title = null;
+                btnArray = null;
+            } else if (typeof btnArray === 'function') {
+                type = callback;
+                callback = btnArray;
+                btnArray = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback);
+        }
+        return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']);
+    };
+    var createPrompt = function(message, placeholder, title, btnArray, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof placeholder === 'function') {
+                callback = placeholder;
+                type = title;
+                placeholder = null;
+                title = null;
+                btnArray = null;
+            } else if (typeof title === 'function') {
+                callback = title;
+                type = btnArray;
+                title = null;
+                btnArray = null;
+            } else if (typeof btnArray === 'function') {
+                type = callback;
+                callback = btnArray;
+                btnArray = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback);
+        }
+        return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']);
+    };
+    var closePopup = function() {
+        if (popupStack.length) {
+            popupStack[popupStack.length - 1]['close']();
+            return true;
+        } else {
+            return false;
+        }
+    };
+    var closePopups = function() {
+        while (popupStack.length) {
+            popupStack[popupStack.length - 1]['close']();
+        }
+    };
+
+    $.closePopup = closePopup;
+    $.closePopups = closePopups;
+    $.alert = createAlert;
+    $.confirm = createConfirm;
+    $.prompt = createPrompt;
+})(mui, window, document);
+(function($, document) {
+	var CLASS_PROGRESSBAR = 'mui-progressbar';
+	var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in';
+	var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out';
+	var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite';
+
+	var SELECTOR_PROGRESSBAR = '.mui-progressbar';
+
+	var _findProgressbar = function(container) {
+		container = $(container || 'body');
+		if (container.length === 0) return;
+		container = container[0];
+		if (container.classList.contains(CLASS_PROGRESSBAR)) {
+			return container;
+		}
+		var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR);
+		if (progressbars) {
+			for (var i = 0, len = progressbars.length; i < len; i++) {
+				var progressbar = progressbars[i];
+				if (progressbar.parentNode === container) {
+					return progressbar;
+				}
+			}
+		}
+	};
+	/**
+	 * 创建并显示进度条 
+	 * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper
+	 * @param {Object} progress 可选,undefined表示循环,数字表示具体进度
+	 * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数)
+	 */
+	var showProgressbar = function(container, progress, color) {
+		if (typeof container === 'number') {
+			color = progress;
+			progress = container;
+			container = 'body';
+		}
+		container = $(container || 'body');
+		if (container.length === 0) return;
+		container = container[0];
+		var progressbar;
+		if (container.classList.contains(CLASS_PROGRESSBAR)) {
+			progressbar = container;
+		} else {
+			var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')');
+			if (progressbars) {
+				for (var i = 0, len = progressbars.length; i < len; i++) {
+					var _progressbar = progressbars[i];
+					if (_progressbar.parentNode === container) {
+						progressbar = _progressbar;
+						break;
+					}
+				}
+			}
+			if (!progressbar) {
+				progressbar = document.createElement('span');
+				progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : '');
+				if (typeof progress !== 'undefined') {
+					progressbar.innerHTML = '<span></span>';
+				}
+				container.appendChild(progressbar);
+			} else {
+				progressbar.classList.add(CLASS_PROGRESSBAR_IN);
+			}
+		}
+		if (progress) setProgressbar(container, progress);
+		return progressbar;
+	};
+	/**
+	 * 关闭进度条 
+	 * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
+	 */
+	var hideProgressbar = function(container) {
+		var progressbar = _findProgressbar(container);
+		if (!progressbar) {
+			return;
+		}
+		var classList = progressbar.classList;
+		if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) {
+			return;
+		}
+		classList.remove(CLASS_PROGRESSBAR_IN);
+		classList.add(CLASS_PROGRESSBAR_OUT);
+		progressbar.addEventListener('webkitAnimationEnd', function() {
+			progressbar.parentNode && progressbar.parentNode.removeChild(progressbar);
+			progressbar = null;
+		});
+		return;
+	};
+	/**
+	 * 设置指定进度条进度 
+	 * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper
+	 * @param {Object} progress 可选,默认0 取值范围[0-100]
+	 * @param {Object} speed 进度条动画时间
+	 */
+	var setProgressbar = function(container, progress, speed) {
+		if (typeof container === 'number') {
+			speed = progress;
+			progress = container;
+			container = false;
+		}
+		var progressbar = _findProgressbar(container);
+		if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) {
+			return;
+		}
+		if (progress) progress = Math.min(Math.max(progress, 0), 100);
+		progressbar.offsetHeight;
+		var span = progressbar.querySelector('span');
+		if (span) {
+			var style = span.style;
+			style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)';
+			if (typeof speed !== 'undefined') {
+				style.webkitTransitionDuration = speed + 'ms';
+			} else {
+				style.webkitTransitionDuration = '';
+			}
+		}
+		return progressbar;
+	};
+	$.fn.progressbar = function(options) {
+		var progressbarApis = [];
+		options = options || {};
+		this.each(function() {
+			var self = this;
+			var progressbarApi = self.mui_plugin_progressbar;
+			if (!progressbarApi) {
+				self.mui_plugin_progressbar = progressbarApi = {
+					options: options,
+					setOptions: function(options) {
+						this.options = options;
+					},
+					show: function() {
+						return showProgressbar(self, this.options.progress, this.options.color);
+					},
+					setProgress: function(progress) {
+						return setProgressbar(self, progress);
+					},
+					hide: function() {
+						return hideProgressbar(self);
+					}
+				};
+			} else if (options) {
+				progressbarApi.setOptions(options);
+			}
+			progressbarApis.push(progressbarApi);
+		});
+		return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis;
+	};
+	//	$.setProgressbar = setProgressbar;
+	//	$.showProgressbar = showProgressbar;
+	//	$.hideProgressbar = hideProgressbar;
+})(mui, document);
+/**
+ * Input(TODO resize)
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+	var CLASS_ICON = 'mui-icon';
+	var CLASS_ICON_CLEAR = 'mui-icon-clear';
+	var CLASS_ICON_SPEECH = 'mui-icon-speech';
+	var CLASS_ICON_SEARCH = 'mui-icon-search';
+	var CLASS_ICON_PASSWORD = 'mui-icon-eye';
+	var CLASS_INPUT_ROW = 'mui-input-row';
+	var CLASS_PLACEHOLDER = 'mui-placeholder';
+	var CLASS_TOOLTIP = 'mui-tooltip';
+	var CLASS_HIDDEN = 'mui-hidden';
+	var CLASS_FOCUSIN = 'mui-focusin';
+	var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
+	var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
+	var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
+	var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
+	var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
+
+	var findRow = function(target) {
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
+				return target;
+			}
+		}
+		return null;
+	};
+	var Input = function(element, options) {
+		this.element = element;
+		this.options = options || {
+			actions: 'clear'
+		};
+		if (~this.options.actions.indexOf('slider')) { //slider
+			this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
+			this.sliderActionSelector = SELECTOR_TOOLTIP;
+		} else { //clear,speech,search
+			if (~this.options.actions.indexOf('clear')) {
+				this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
+				this.clearActionSelector = SELECTOR_ICON_CLOSE;
+			}
+			if (~this.options.actions.indexOf('speech')) { //only for 5+
+				this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
+				this.speechActionSelector = SELECTOR_ICON_SPEECH;
+			}
+			if (~this.options.actions.indexOf('search')) {
+				this.searchActionClass = CLASS_PLACEHOLDER;
+				this.searchActionSelector = SELECTOR_PLACEHOLDER;
+			}
+			if (~this.options.actions.indexOf('password')) {
+				this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
+				this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
+			}
+		}
+		this.init();
+	};
+	Input.prototype.init = function() {
+		this.initAction();
+		this.initElementEvent();
+	};
+	Input.prototype.initAction = function() {
+		var self = this;
+
+		var row = self.element.parentNode;
+		if (row) {
+			if (self.sliderActionClass) {
+				self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
+			} else {
+				if (self.searchActionClass) {
+					self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
+					self.searchAction.addEventListener('tap', function(e) {
+						$.focus(self.element);
+						e.stopPropagation();
+					});
+				}
+				if (self.speechActionClass) {
+					self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
+					self.speechAction.addEventListener('click', $.stopPropagation);
+					self.speechAction.addEventListener('tap', function(event) {
+						self.speechActionClick(event);
+					});
+				}
+				if (self.clearActionClass) {
+					self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
+					self.clearAction.addEventListener('tap', function(event) {
+						self.clearActionClick(event);
+					});
+				}
+				if (self.passwordActionClass) {
+					self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
+					self.passwordAction.addEventListener('tap', function(event) {
+						self.passwordActionClick(event);
+					});
+				}
+			}
+		}
+	};
+	Input.prototype.createAction = function(row, actionClass, actionSelector) {
+		var action = row.querySelector(actionSelector);
+		if (!action) {
+			var action = document.createElement('span');
+			action.className = actionClass;
+			if (actionClass === this.searchActionClass) {
+				action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>';
+				this.element.setAttribute('placeholder', '');
+				if (this.element.value.trim()) {
+					row.classList.add('mui-active');
+				}
+			}
+			row.insertBefore(action, this.element.nextSibling);
+		}
+		return action;
+	};
+	Input.prototype.initElementEvent = function() {
+		var element = this.element;
+
+		if (this.sliderActionClass) {
+			var tooltip = this.sliderAction;
+			var timer = null;
+			var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
+				tooltip.classList.remove(CLASS_HIDDEN);
+				var offsetLeft = element.offsetLeft;
+				var width = element.offsetWidth - 28;
+				var tooltipWidth = tooltip.offsetWidth;
+				var distince = Math.abs(element.max - element.min);
+				var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
+				tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
+				tooltip.innerText = element.value;
+				if (timer) {
+					clearTimeout(timer);
+				}
+				timer = setTimeout(function() {
+					tooltip.classList.add(CLASS_HIDDEN);
+				}, 1000);
+			};
+			element.addEventListener('input', showTip);
+			element.addEventListener('tap', showTip);
+			element.addEventListener($.EVENT_MOVE, function(e) {
+				e.stopPropagation();
+			});
+		} else {
+			if (this.clearActionClass) {
+				var action = this.clearAction;
+				if (!action) {
+					return;
+				}
+				$.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
+					(function(type) {
+						element.addEventListener(type, function() {
+							action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
+						});
+					})(type);
+				});
+				element.addEventListener('blur', function() {
+					action.classList.add(CLASS_HIDDEN);
+				});
+			}
+			if (this.searchActionClass) {
+				element.addEventListener('focus', function() {
+					element.parentNode.classList.add('mui-active');
+				});
+				element.addEventListener('blur', function() {
+					if (!element.value.trim()) {
+						element.parentNode.classList.remove('mui-active');
+					}
+				});
+			}
+		}
+	};
+	Input.prototype.setPlaceholder = function(text) {
+		if (this.searchActionClass) {
+			var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
+			placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
+		} else {
+			this.element.setAttribute('placeholder', text);
+		}
+	};
+	Input.prototype.passwordActionClick = function(event) {
+		if (this.element.type === 'text') {
+			this.element.type = 'password';
+		} else {
+			this.element.type = 'text';
+		}
+		this.passwordAction.classList.toggle('mui-active');
+		event.preventDefault();
+	};
+	Input.prototype.clearActionClick = function(event) {
+		var self = this;
+		self.element.value = '';
+		$.focus(self.element);
+		self.clearAction.classList.add(CLASS_HIDDEN);
+		event.preventDefault();
+	};
+	Input.prototype.speechActionClick = function(event) {
+		if (window.plus) {
+			var self = this;
+			var oldValue = self.element.value;
+			self.element.value = '';
+			document.body.classList.add(CLASS_FOCUSIN);
+			plus.speech.startRecognize({
+				engine: 'iFly'
+			}, function(s) {
+				self.element.value += s;
+				$.focus(self.element);
+				plus.speech.stopRecognize();
+				$.trigger(self.element, 'recognized', {
+					value: self.element.value
+				});
+				if (oldValue !== self.element.value) {
+					$.trigger(self.element, 'change');
+					$.trigger(self.element, 'input');
+				}
+				// document.body.classList.remove(CLASS_FOCUSIN);
+			}, function(e) {
+				document.body.classList.remove(CLASS_FOCUSIN);
+			});
+		} else {
+			alert('only for 5+');
+		}
+		event.preventDefault();
+	};
+	$.fn.input = function(options) {
+		var inputApis = [];
+		this.each(function() {
+			var inputApi = null;
+			var actions = [];
+			var row = findRow(this.parentNode);
+			if (this.type === 'range' && row.classList.contains('mui-input-range')) {
+				actions.push('slider');
+			} else {
+				var classList = this.classList;
+				if (classList.contains('mui-input-clear')) {
+					actions.push('clear');
+				}
+				if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) {
+					actions.push('speech');
+				}
+				if (classList.contains('mui-input-password')) {
+					actions.push('password');
+				}
+				if (this.type === 'search' && row.classList.contains('mui-search')) {
+					actions.push('search');
+				}
+			}
+			var id = this.getAttribute('data-input-' + actions[0]);
+			if (!id) {
+				id = ++$.uuid;
+				inputApi = $.data[id] = new Input(this, {
+					actions: actions.join(',')
+				});
+				for (var i = 0, len = actions.length; i < len; i++) {
+					this.setAttribute('data-input-' + actions[i], id);
+				}
+			} else {
+				inputApi = $.data[id];
+			}
+			inputApis.push(inputApi);
+		});
+		return inputApis.length === 1 ? inputApis[0] : inputApis;
+	};
+	$.ready(function() {
+		$('.mui-input-row input').input();
+	});
+})(mui, window, document);
+(function($, window) {
+    var CLASS_ACTIVE = 'mui-active';
+    var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/;
+    var getColor = function(colorStr) {
+        var matches = colorStr.match(rgbaRegex);
+        if (matches && matches.length === 5) {
+            return [
+                matches[1],
+                matches[2],
+                matches[3],
+                matches[4]
+            ];
+        }
+        return [];
+    };
+    var Transparent = function(element, options) {
+        this.element = element;
+        this.options = $.extend({
+            top: 0, //距离顶部高度(到达该高度即触发)
+            offset: 150, //滚动透明距离
+            duration: 16, //过渡时间
+            scrollby: window//监听滚动距离容器
+        }, options || {});
+
+        this.scrollByElem = this.options.scrollby || window;
+        if (!this.scrollByElem) {
+            throw new Error("监听滚动的元素不存在");
+        }
+        this.isNativeScroll = false;
+        if (this.scrollByElem === window) {
+            this.isNativeScroll = true;
+        } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) {
+            this.isNativeScroll = true;
+        }
+
+        this._style = this.element.style;
+        this._bgColor = this._style.backgroundColor;
+        var color = getColor(mui.getStyles(this.element, 'backgroundColor'));
+        if (color.length) {
+            this._R = color[0];
+            this._G = color[1];
+            this._B = color[2];
+            this._A = parseFloat(color[3]);
+            this.lastOpacity = this._A;
+            this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this);
+            this.initEvent();
+        } else {
+            throw new Error("元素背景颜色必须为RGBA");
+        }
+    };
+
+    Transparent.prototype.initEvent = function() {
+        this.scrollByElem.addEventListener('scroll', this._bufferFn);
+        if (this.isNativeScroll) { //原生scroll
+            this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn);
+        }
+    }
+    Transparent.prototype.handleScroll = function(e) {
+        var y = window.scrollY;
+        if (!this.isNativeScroll && e && e.detail) {
+            y = -e.detail.y;
+        }
+        var opacity = (y - this.options.top) / this.options.offset + this._A;
+        opacity = Math.min(Math.max(this._A, opacity), 1);
+        this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')';
+        if (opacity > this._A) {
+            this.element.classList.add(CLASS_ACTIVE);
+        } else {
+            this.element.classList.remove(CLASS_ACTIVE);
+        }
+        if (this.lastOpacity !== opacity) {
+            $.trigger(this.element, 'alpha', {
+                alpha: opacity
+            });
+            this.lastOpacity = opacity;
+        }
+    };
+    Transparent.prototype.destory = function() {
+        this.scrollByElem.removeEventListener('scroll', this._bufferFn);
+        this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn);
+        this.element.style.backgroundColor = this._bgColor;
+        this.element.mui_plugin_transparent = null;
+    };
+    $.fn.transparent = function(options) {
+        options = options || {};
+        var transparentApis = [];
+        this.each(function() {
+            var transparentApi = this.mui_plugin_transparent;
+            if (!transparentApi) {
+                var top = this.getAttribute('data-top');
+                var offset = this.getAttribute('data-offset');
+                var duration = this.getAttribute('data-duration');
+                var scrollby = this.getAttribute('data-scrollby');
+                if (top !== null && typeof options.top === 'undefined') {
+                    options.top = top;
+                }
+                if (offset !== null && typeof options.offset === 'undefined') {
+                    options.offset = offset;
+                }
+                if (duration !== null && typeof options.duration === 'undefined') {
+                    options.duration = duration;
+                }
+                if (scrollby !== null && typeof options.scrollby === 'undefined') {
+                    options.scrollby = document.querySelector(scrollby) || window;
+                }
+                transparentApi = this.mui_plugin_transparent = new Transparent(this, options);
+            }
+            transparentApis.push(transparentApi);
+        });
+        return transparentApis.length === 1 ? transparentApis[0] : transparentApis;
+    };
+    $.ready(function() {
+        $('.mui-bar-transparent').transparent();
+    });
+})(mui, window);
+/**
+ * 数字输入框
+ * varstion 1.0.1
+ * by Houfeng
+ * Houfeng@DCloud.io
+ */
+
+(function($) {
+
+    var touchSupport = ('ontouchstart' in document);
+    var tapEventName = touchSupport ? 'tap' : 'click';
+    var changeEventName = 'change';
+    var holderClassName = 'mui-numbox';
+    var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
+    var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
+    var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
+
+    var Numbox = $.Numbox = $.Class.extend({
+        /**
+         * 构造函数
+         **/
+        init: function(holder, options) {
+            var self = this;
+            if (!holder) {
+                throw "构造 numbox 时缺少容器元素";
+            }
+            self.holder = holder;
+            options = options || {};
+            options.step = parseInt(options.step || 1);
+            self.options = options;
+            self.input = $.qsa(inputClassSelector, self.holder)[0];
+            self.plus = $.qsa(plusClassSelector, self.holder)[0];
+            self.minus = $.qsa(minusClassSelector, self.holder)[0];
+            self.checkValue();
+            self.initEvent();
+        },
+        /**
+         * 初始化事件绑定
+         **/
+        initEvent: function() {
+            var self = this;
+            self.plus.addEventListener(tapEventName, function(event) {
+                var val = parseInt(self.input.value) + self.options.step;
+                self.input.value = val.toString();
+                $.trigger(self.input, changeEventName, null);
+            });
+            self.minus.addEventListener(tapEventName, function(event) {
+                var val = parseInt(self.input.value) - self.options.step;
+                self.input.value = val.toString();
+                $.trigger(self.input, changeEventName, null);
+            });
+            self.input.addEventListener(changeEventName, function(event) {
+                self.checkValue();
+                var val = parseInt(self.input.value);
+                //触发顶层容器
+                $.trigger(self.holder, changeEventName, {
+                    value: val
+                });
+            });
+        },
+        /**
+         * 获取当前值
+         **/
+        getValue: function() {
+            var self = this;
+            return parseInt(self.input.value);
+        },
+        /**
+         * 验证当前值是法合法
+         **/
+        checkValue: function() {
+            var self = this;
+            var val = self.input.value;
+            if (val == null || val == '' || isNaN(val)) {
+                self.input.value = self.options.min || 0;
+                self.minus.disabled = self.options.min != null;
+            } else {
+                var val = parseInt(val);
+                if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) {
+                    val = self.options.max;
+                    self.plus.disabled = true;
+                } else {
+                    self.plus.disabled = false;
+                }
+                if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) {
+                    val = self.options.min;
+                    self.minus.disabled = true;
+                } else {
+                    self.minus.disabled = false;
+                }
+                self.input.value = val;
+            }
+        },
+        /**
+         * 更新选项
+         **/
+        setOption: function(name, value) {
+            var self = this;
+            self.options[name] = value;
+        },
+        /**
+         * 动态设置新值
+         **/
+        setValue: function(value) {
+            this.input.value = value;
+            this.checkValue();
+        }
+    });
+
+    $.fn.numbox = function(options) {
+        var instanceArray = [];
+        //遍历选择的元素
+        this.each(function(i, element) {
+            if (element.numbox) {
+                return;
+            }
+            if (options) {
+                element.numbox = new Numbox(element, options);
+            } else {
+                var optionsText = element.getAttribute('data-numbox-options');
+                var options = optionsText ? JSON.parse(optionsText) : {};
+                options.step = element.getAttribute('data-numbox-step') || options.step;
+                options.min = element.getAttribute('data-numbox-min') || options.min;
+                options.max = element.getAttribute('data-numbox-max') || options.max;
+                element.numbox = new Numbox(element, options);
+            }
+        });
+        return this[0] ? this[0].numbox : null;
+    }
+
+    //自动处理 class='mui-locker' 的 dom
+    $.ready(function() {
+        $('.' + holderClassName).numbox();
+    });
+
+}(mui));
+/**
+ * Button
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+    var CLASS_ICON = 'mui-icon';
+    var CLASS_DISABLED = 'mui-disabled';
+
+    var STATE_RESET = 'reset';
+    var STATE_LOADING = 'loading';
+
+    var defaultOptions = {
+        loadingText: 'Loading...', //文案
+        loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空
+        loadingIconPosition: 'left' //图标所处位置,仅支持left|right
+    };
+
+    var Button = function(element, options) {
+        this.element = element;
+        this.options = $.extend({}, defaultOptions, options);
+        if (!this.options.loadingText) {
+            this.options.loadingText = defaultOptions.loadingText;
+        }
+        if (this.options.loadingIcon === null) {
+            this.options.loadingIcon = 'mui-spinner';
+            if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') {
+                this.options.loadingIcon += ' ' + 'mui-spinner-white';
+            }
+        }
+        this.isInput = this.element.tagName === 'INPUT';
+        this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML;
+        this.state = '';
+    };
+    Button.prototype.loading = function() {
+        this.setState(STATE_LOADING);
+    };
+    Button.prototype.reset = function() {
+        this.setState(STATE_RESET);
+    };
+    Button.prototype.setState = function(state) {
+        if (this.state === state) {
+            return false;
+        }
+        this.state = state;
+        if (state === STATE_RESET) {
+            this.element.disabled = false;
+            this.element.classList.remove(CLASS_DISABLED);
+            this.setHtml(this.resetHTML);
+        } else if (state === STATE_LOADING) {
+            this.element.disabled = true;
+            this.element.classList.add(CLASS_DISABLED);
+            var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>');
+            if (this.options.loadingIcon && !this.isInput) {
+                if (this.options.loadingIconPosition === 'right') {
+                    html += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>';
+                } else {
+                    html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + html;
+                }
+            }
+            this.setHtml(html);
+        }
+    };
+    Button.prototype.setHtml = function(html) {
+        if (this.isInput) {
+            this.element.value = html;
+        } else {
+            this.element.innerHTML = html;
+        }
+    }
+    $.fn.button = function(state) {
+        var buttonApis = [];
+        this.each(function() {
+            var buttonApi = this.mui_plugin_button;
+            if (!buttonApi) {
+                var loadingText = this.getAttribute('data-loading-text');
+                var loadingIcon = this.getAttribute('data-loading-icon');
+                var loadingIconPosition = this.getAttribute('data-loading-icon-position');
+                this.mui_plugin_button = buttonApi = new Button(this, {
+                    loadingText: loadingText,
+                    loadingIcon: loadingIcon,
+                    loadingIconPosition: loadingIconPosition
+                });
+            }
+            if (state === STATE_LOADING || state === STATE_RESET) {
+                buttonApi.setState(state);
+            }
+            buttonApis.push(buttonApi);
+        });
+        return buttonApis.length === 1 ? buttonApis[0] : buttonApis;
+    };
+})(mui, window, document);

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5 - 0
hbuild/online/js/mui.min.js


+ 170 - 0
hbuild/online/manifest.json

@@ -0,0 +1,170 @@
+{
+    "@platforms" : [ "android", "iPhone", "iPad" ],
+    "id" : "H5B1E7795", /*应用的标识,创建应用时自动生成,勿手动修改*/
+    "name" : "小飞龙", /*应用名称,程序桌面图标名称*/
+    "version" : {
+        "name" : "1.0.0", /*应用版本名称*/
+        "code" : 1
+    },
+    "description" : "小飞龙在线课程平台", /*应用描述信息*/
+    "icons" : {
+        "72" : "icon.png"
+    },
+    "launch_path" : "index.html", /*应用的入口页面,默认为根目录下的index.html;支持网络地址,必须以http://或https://开头*/
+    "developer" : {
+        "name" : "", /*开发者名称*/
+        "email" : "", /*开发者邮箱地址*/
+        "url" : "http://www.dcloud.io"
+    },
+    "permissions" : {
+        "Cache" : {
+            "description" : "管理应用缓存"
+        },
+        "Console" : {
+            "description" : "跟踪调试输出日志"
+        },
+        "Contacts" : {
+            "description" : "访问系统联系人信息"
+        },
+        "Events" : {
+            "description" : "应用扩展事件"
+        },
+        "Messaging" : {
+            "description" : "访问通讯能力"
+        },
+        "Maps" : {
+            "description" : "管理地图插件"
+        },
+        "Speech" : {
+            "description" : "管理语音识别插件"
+        },
+        "Bluetooth" : {}
+    },
+    "plus" : {
+        "splashscreen" : {
+            "autoclose" : true, /*是否自动关闭程序启动界面,true表示应用加载应用入口页面后自动关闭;false则需调plus.navigator.closeSplashscreen()关闭*/
+            "waiting" : true,
+            "delay" : 0
+        },
+        "runmode" : "liberate", /*应用的首次启动运行模式,可取liberate或normal,liberate模式在第一次启动时将解压应用资源(Android平台File API才可正常访问_www目录)*/
+        "signature" : "Sk9JTiBVUyBtYWlsdG86aHIyMDEzQGRjbG91ZC5pbw==", /*可选,保留给应用签名,暂不使用*/
+        "distribute" : {
+            "apple" : {
+                "appid" : "", /*iOS应用标识,苹果开发网站申请的appid,如io.dcloud.HelloH5*/
+                "mobileprovision" : "", /*iOS应用打包配置文件*/
+                "password" : "", /*iOS应用打包个人证书导入密码*/
+                "p12" : "", /*iOS应用打包个人证书,打包配置文件关联的个人证书*/
+                "devices" : "universal", /*iOS应用支持的设备类型,可取值iphone/ipad/universal*/
+                "frameworks" : []
+            },
+            "google" : {
+                "packagename" : "", /*Android应用包名,如io.dcloud.HelloH5*/
+                "keystore" : "", /*Android应用打包使用的密钥库文件*/
+                "password" : "", /*Android应用打包使用密钥库中证书的密码*/
+                "aliasname" : "", /*Android应用打包使用密钥库中证书的别名*/
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"com.android.launcher.permission.UNINSTALL_SHORTCUT\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"com.android.launcher.permission.INSTALL_SHORTCUT\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            "orientation" : [ "portrait-primary", "portrait-secondary" ], /*应用支持的方向,portrait-primary:竖屏正方向;portrait-secondary:竖屏反方向;landscape-primary:横屏正方向;landscape-secondary:横屏反方向*/
+            "icons" : {
+                "ios" : {
+                    "prerendered" : true, /*应用图标是否已经高亮处理,在iOS6及以下设备上有效*/
+                    "auto" : "", /*应用图标,分辨率:512x512,用于自动生成各种尺寸程序图标*/
+                    "iphone" : {
+                        "normal" : "", /*iPhone普通屏幕程序图标,分辨率:57x57*/
+                        "retina" : "", /*iPhone高分屏程序图标,分辨率:114x114*/
+                        "retina7" : "", /*iPhone iOS7高分屏程序图标,分辨率:120x120*/
+                        "spotlight-normal" : "", /*iPhone Spotlight搜索程序图标,分辨率:29x29*/
+                        "spotlight-retina" : "", /*iPhone高分屏Spotlight搜索程序图标,分辨率:58x58*/
+                        "spotlight-retina7" : "", /*iPhone iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/
+                        "settings-normal" : "", /*iPhone设置页面程序图标,分辨率:29x29*/
+                        "settings-retina" : ""
+                    },
+                    "ipad" : {
+                        "normal" : "", /*iPad普通屏幕程序图标,分辨率:72x72*/
+                        "retina" : "", /*iPad高分屏程序图标,分辨率:144x144*/
+                        "normal7" : "", /*iPad iOS7程序图标,分辨率:76x76*/
+                        "retina7" : "", /*iPad iOS7高分屏程序图标,分辨率:152x152*/
+                        "spotlight-normal" : "", /*iPad Spotlight搜索程序图标,分辨率:50x50*/
+                        "spotlight-retina" : "", /*iPad高分屏Spotlight搜索程序图标,分辨率:100x100*/
+                        "spotlight-normal7" : "", /*iPad iOS7 Spotlight搜索程序图标,分辨率:40x40*/
+                        "spotlight-retina7" : "", /*iPad iOS7高分屏Spotlight搜索程序图标,分辨率:80x80*/
+                        "settings-normal" : "", /*iPad设置页面程序图标,分辨率:29x29*/
+                        "settings-retina" : ""
+                    }
+                },
+                "android" : {
+                    "mdpi" : "", /*普通屏程序图标,分辨率:48x48*/
+                    "ldpi" : "", /*大屏程序图标,分辨率:48x48*/
+                    "hdpi" : "D:/wwwroot/flyong/icon/1024.png", /*高分屏程序图标,分辨率:72x72*/
+                    "xhdpi" : "D:/wwwroot/flyong/icon/1024.png", /*720P高分屏程序图标,分辨率:96x96*/
+                    "xxhdpi" : "D:/wwwroot/flyong/icon/1024.png",
+                    "xxxhdpi" : "D:/wwwroot/flyong/icon/1024.png"
+                }
+            },
+            "splashscreen" : {
+                "ios" : {
+                    "iphone" : {
+                        "default" : "", /*iPhone3启动图片选,分辨率:320x480*/
+                        "retina35" : "", /*3.5英寸设备(iPhone4)启动图片,分辨率:640x960*/
+                        "retina40" : ""
+                    },
+                    "ipad" : {
+                        "portrait" : "", /*iPad竖屏启动图片,分辨率:768x1004*/
+                        "portrait-retina" : "", /*iPad高分屏竖屏图片,分辨率:1536x2008*/
+                        "landscape" : "", /*iPad横屏启动图片,分辨率:1024x748*/
+                        "landscape-retina" : "", /*iPad高分屏横屏启动图片,分辨率:2048x1496*/
+                        "portrait7" : "", /*iPad iOS7竖屏启动图片,分辨率:768x1024*/
+                        "portrait-retina7" : "", /*iPad iOS7高分屏竖屏图片,分辨率:1536x2048*/
+                        "landscape7" : "", /*iPad iOS7横屏启动图片,分辨率:1024x768*/
+                        "landscape-retina7" : ""
+                    }
+                },
+                "android" : {
+                    "mdpi" : "", /*普通屏启动图片,分辨率:240x282*/
+                    "ldpi" : "", /*大屏启动图片,分辨率:320x442*/
+                    "hdpi" : "", /*高分屏启动图片,分辨率:480x762*/
+                    "xhdpi" : "", /*720P高分屏启动图片,分辨率:720x1242*/
+                    "xxhdpi" : ""
+                }
+            },
+            "plugins" : {
+                "speech" : {
+                    "ifly" : {}
+                },
+                "geolocation" : {
+                    "amap" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appkey_ios" : "",
+                        "appkey_android" : ""
+                    }
+                }
+            }
+        }
+    },
+    "screenOrientation" : [ "landscape-primary" ]
+}

+ 21 - 0
online/.gitignore

@@ -0,0 +1,21 @@
+.DS_Store
+node_modules
+/dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 5 - 0
online/babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

+ 50 - 0
online/package.json

@@ -0,0 +1,50 @@
+{
+  "name": "GoAllOut",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "axios": "^0.19.2",
+    "chart.js": "^2.9.3",
+    "core-js": "^3.6.4",
+    "muse-ui": "^3.0.2",
+    "muse-ui-loading": "^0.2.0",
+    "muse-ui-message": "^0.2.1",
+    "muse-ui-progress": "^0.1.0",
+    "muse-ui-toast": "^0.3.0",
+    "vue": "^2.6.11",
+    "vue-router": "^3.1.5"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "~4.2.0",
+    "@vue/cli-plugin-eslint": "~4.2.0",
+    "@vue/cli-plugin-router": "^4.2.2",
+    "@vue/cli-service": "~4.2.0",
+    "babel-eslint": "^10.0.3",
+    "eslint": "^6.7.2",
+    "eslint-plugin-vue": "^6.1.2",
+    "vue-cli-plugin-axios": "0.0.4",
+    "vue-template-compiler": "^2.6.11"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/essential",
+      "eslint:recommended"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions"
+  ]
+}

BIN
online/public/favicon.ico


+ 20 - 0
online/public/index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+<!--    <meta name="viewport" content="width=device-width,initial-scale=1.0">-->
+    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <title><%= htmlWebpackPlugin.options.title %></title>
+    <link rel="stylesheet" href="https://cdn.bootcss.com/material-design-icons/3.0.1/iconfont/material-icons.css">
+</head>
+<body>
+<noscript>
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
+        Please enable it to continue.</strong>
+</noscript>
+<div id="app"></div>
+<!-- built files will be auto injected -->
+</body>
+</html>

+ 47 - 0
online/src/App.vue

@@ -0,0 +1,47 @@
+<template>
+    <div id="app">
+        <transition name="fade">
+            <router-view/>
+        </transition>
+    </div>
+</template>
+
+<style>
+    #app {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        height: 100%;
+        overflow-y: hidden;
+    }
+
+    ul, li {
+        list-style: none;
+        padding: 0;
+    }
+
+    s, i, em {
+        text-decoration: none;
+        font-style: normal;
+    }
+
+    /*叹号问题*/
+    .mu-warning-text-color {
+      float: left;
+    }
+</style>
+<script>
+window.onload = function() {
+  document.addEventListener('touchstart', function(event) {
+    if (event.touches.length > 1) {
+      event.preventDefault()
+    }
+  })
+  document.addEventListener('gesturestart', function(event) {
+    event.preventDefault()
+  })
+}
+</script>

+ 150 - 0
online/src/Global.js

@@ -0,0 +1,150 @@
+headapi = process.env.NODE_ENV === 'development' ? '/api/' : '../';
+
+//Toast
+Toast = function (message, color) {
+    // normal.open = true;
+    // normal.message = message;
+    // normal.color = !color ? 'warning' : color;
+    // normal.timer = setTimeout(() => {
+    //     normal.open = false;
+    // }, normal.timeout);
+    this.$toast.message(message);
+};
+
+// Toast default setting
+normal = {
+    color: 'warning', // ['success', 'info', 'error', 'warning'],
+    position: 'top',
+    message: 'Hello World, Snackbar !',
+    open: false,
+    timeout: 3000
+};
+
+globaltime2StringNoMin = function (time) {
+    let datetime = new Date();
+    datetime.setTime(time);
+    let year = datetime.getFullYear();
+    let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
+    let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
+    let hour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
+    let minus = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
+    return year + "-" + month + "-" + date;
+};
+
+globalBt2 = function () {
+    const et = new Date();
+    const bt = new Date();
+    bt.setTime(bt.getTime() - 3600 * 1000 * 24 * 7);
+    return [bt, et];
+};
+
+globalTimeToYY = function () {
+    let datetime = new Date();
+    let year = datetime.getFullYear();
+    let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
+    let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
+    console.log(year + "-" + month + "-" + date);
+    return year + "-" + month + "-" + date;
+
+};
+// 获取当前时间
+globalcurrent = function () {
+    let date = new Date();
+    let seperator1 = "-";
+    let year = date.getFullYear();
+    let month = date.getMonth() + 1;
+    let strDate = date.getDate();
+    if (month >= 1 && month <= 9) {
+        month = "0" + month;
+    }
+    if (strDate >= 0 && strDate <= 9) {
+        strDate = "0" + strDate;
+    }
+    let thisdata = year + seperator1 + month + seperator1 + strDate;
+    return thisdata;
+};
+
+// 手机号码格式
+globalCheckPhone = function (val) {
+    let re = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/;
+    val = val.toString();
+    if (val.search(re) == -1) {
+        return false;
+    } else {
+        return true;
+    }
+};
+
+// 格式化时间
+globalfmtDate = function (datetime, length) {
+    if ((datetime == '') || (datetime == undefined))
+        return '';
+    if ((datetime == '1900-01-01') || (datetime == '1900-01-01 00:00:00.000'))
+        return '';
+    length = !length ? 10 : length;//缺省参数
+    return (datetime != null) ? datetime.substr(0, length) : '';
+};
+//格式化日期  年月日
+globaltime2String = function (time) {
+    let datetime = new Date();
+    datetime.setTime(time);
+    let year = datetime.getFullYear();
+    let month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1;
+    let date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate();
+    let hour = datetime.getHours() < 10 ? "0" + datetime.getHours() : datetime.getHours();
+    let minus = datetime.getMinutes() < 10 ? "0" + datetime.getMinutes() : datetime.getMinutes();
+    return year + "-" + month + "-" + date + " " + hour + ":" + minus + ":00";
+};
+
+address = {
+    '北京': ['北京'],
+    '广东': ['广州', '深圳', '珠海', '汕头', '韶关', '佛山', '江门', '湛江', '茂名', '肇庆', '惠州', '梅州', '汕尾', '河源', '阳江', '清远', '东莞', '中山', '潮州', '揭阳', '云浮'],
+    '上海': ['上海'],
+    '天津': ['天津'],
+    '重庆': ['重庆'],
+    '辽宁': ['沈阳', '大连', '鞍山', '抚顺', '本溪', '丹东', '锦州', '营口', '阜新', '辽阳', '盘锦', '铁岭', '朝阳', '葫芦岛'],
+    '江苏': ['南京', '苏州', '无锡', '常州', '镇江', '南通', '泰州', '扬州', '盐城', '连云港', '徐州', '淮安', '宿迁'],
+    '湖北': ['武汉', '黄石', '十堰', '荆州', '宜昌', '襄樊', '鄂州', '荆门', '孝感', '黄冈', '咸宁', '随州', '恩施土家族苗族自治州', '仙桃', '天门', '潜江', '神农架林区'],
+    '四川': ['成都', '自贡', '攀枝花', '泸州', '德阳', '绵阳', '广元', '遂宁', '内江', '乐山', '南充', '眉山', '宜宾', '广安', '达州', '雅安', '巴中', '资阳', '阿坝藏族羌族自治州', '甘孜藏族自治州', '凉山彝族自治州'],
+    '陕西': ['西安', '铜川', '宝鸡', '咸阳', '渭南', '延安', '汉中', '榆林', '安康', '商洛'],
+    '河北': ['石家庄', '唐山', '秦皇岛', '邯郸', '邢台', '保定', '张家口', '承德', '沧州', '廊坊', '衡水'],
+    '山西': ['太原', '大同', '阳泉', '长治', '晋城', '朔州', '晋中', '运城', '忻州', '临汾', '吕梁'],
+    '河南': ['郑州', '开封', '洛阳', '平顶山', '安阳', '鹤壁', '新乡', '焦作', '濮阳', '许昌', '漯河', '三门峡', '南阳', '商丘', '信阳', '周口', '驻马店'],
+    '吉林': ['长春', '吉林', '四平', '辽源', '通化', '白山', '松原', '白城', '延边朝鲜族自治州'],
+    '黑龙江': ['哈尔滨', '齐齐哈尔', '鹤岗', '双鸭山', '鸡西', '大庆', '伊春', '牡丹江', '佳木斯', '七台河', '黑河', '绥化', '大兴安岭地区'],
+    '内蒙古': ['呼和浩特', '包头', '乌海', '赤峰', '通辽', '鄂尔多斯', '呼伦贝尔', '巴彦淖尔', '乌兰察布', '锡林郭勒盟', '兴安盟', '阿拉善盟'],
+    '山东': ['济南', '青岛', '淄博', '枣庄', '东营', '烟台', '潍坊', '济宁', '泰安', '威海', '日照', '莱芜', '临沂', '德州', '聊城', '滨州', '菏泽'],
+    '安徽': ['合肥', '芜湖', '蚌埠', '淮南', '马鞍山', '淮北', '铜陵', '安庆', '黄山', '滁州', '阜阳', '宿州', '巢湖', '六安', '亳州', '池州', '宣城'],
+    '浙江': ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州', '舟山', '台州', '丽水'],
+    '福建': ['福州', '厦门', '莆田', '三明', '泉州', '漳州', '南平', '龙岩', '宁德'],
+    '湖南': ['长沙', '株洲', '湘潭', '衡阳', '邵阳', '岳阳', '常德', '张家界', '益阳', '郴州', '永州', '怀化', '娄底', '湘西土家族苗族自治州'],
+    '广西': ['南宁', '柳州', '桂林', '梧州', '北海', '防城港', '钦州', '贵港', '玉林', '百色', '贺州', '河池', '来宾', '崇左'],
+    '江西': ['南昌', '景德镇', '萍乡', '九江', '新余', '鹰潭', '赣州', '吉安', '宜春', '抚州', '上饶'],
+    '贵州': ['贵阳', '六盘水', '遵义', '安顺', '铜仁地区', '毕节地区', '黔西南布依族苗族自治州', '黔东南苗族侗族自治州', '黔南布依族苗族自治州'],
+    '云南': ['昆明', '曲靖', '玉溪', '保山', '昭通', '丽江', '普洱', '临沧', '德宏傣族景颇族自治州', '怒江傈僳族自治州', '迪庆藏族自治州', '大理白族自治州', '楚雄彝族自治州', '红河哈尼族彝族自治州', '文山壮族苗族自治州', '西双版纳傣族自治州'],
+    '西藏': ['拉萨', '那曲地区', '昌都地区', '林芝地区', '山南地区', '日喀则地区', '阿里地区'],
+    '海南': ['海口', '三亚', '五指山', '琼海', '儋州', '文昌', '万宁', '东方', '澄迈县', '定安县', '屯昌县', '临高县', '白沙黎族自治县', '昌江黎族自治县', '乐东黎族自治县', '陵水黎族自治县', '保亭黎族苗族自治县', '琼中黎族苗族自治县'],
+    '甘肃': ['兰州', '嘉峪关', '金昌', '白银', '天水', '武威', '酒泉', '张掖', '庆阳', '平凉', '定西', '陇南', '临夏回族自治州', '甘南藏族自治州'],
+    '宁夏': ['银川', '石嘴山', '吴忠', '固原', '中卫'],
+    '青海': ['西宁', '海东地区', '海北藏族自治州', '海南藏族自治州', '黄南藏族自治州', '果洛藏族自治州', '玉树藏族自治州', '海西蒙古族藏族自治州'],
+    '新疆': ['乌鲁木齐', '克拉玛依', '吐鲁番地区', '哈密地区', '和田地区', '阿克苏地区', '喀什地区', '克孜勒苏柯尔克孜自治州', '巴音郭楞蒙古自治州', '昌吉回族自治州', '博尔塔拉蒙古自治州', '石河子', '阿拉尔', '图木舒克', '五家渠', '伊犁哈萨克自治州'],
+    '香港': ['香港'],
+    '澳门': ['澳门'],
+    '台湾': ['台北市', '高雄市', '台北县', '桃园县', '新竹县', '苗栗县', '台中县', '彰化县', '南投县', '云林县', '嘉义县', '台南县', '高雄县', '屏东县', '宜兰县', '花莲县', '台东县', '澎湖县', '基隆市', '新竹市', '台中市', '嘉义市', '台南市']
+};
+if (localStorage.language == 'zh') {
+    dayAbbreviation = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    dayList = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+    monthList = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月',
+        '十月', '十一月', '十二月'];
+    monthLongList = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月',
+        '十月', '十一月', '十二月'];
+} else {
+    dayAbbreviation = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
+    dayList = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
+    monthList = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+        'Oct', 'Nov', 'Dec'];
+    monthLongList = ['January', 'February', 'March', 'April', 'May', 'June',
+        'July', 'August', 'September', 'October', 'November', 'December'];
+
+}

+ 145 - 0
online/src/Mock/index.js

@@ -0,0 +1,145 @@
+import Mock from 'mockjs'
+
+let Random = Mock.Random;
+
+// worldDetail
+let worldDetail = function () {
+    let item = [];
+    for (var i = 0; i < 30; i++) {
+        item.push({
+            "id": "@guid",
+            "name": "@region",
+            "Confirmed": "@integer(36844, 368449)",
+            "Deaths": "@integer(1099, 10993)",
+            "Recovered": "@integer(1986, 19865)",
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testPic = function () {
+    let res = {
+        pic:  Random.image('200x100', '#894FC4', '#FFF', '@natural(1111, 9999)'),
+        id: "@guid",
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testTable = function () {
+    let item = [];
+
+    let members = [
+        {id: 1, name: '霍元甲', userCode: '15253135600', vipType: 1},
+        {id: 2, name: '陈真', userCode: '15253135602', vipType: 2},
+        {id: 3, name: '成龙', userCode: '15253135604', vipType: 1},
+    ]
+
+    for (var i = 0; i < 6; i++) {
+        item.push({
+            "id": "@guid",
+            "userCode": "@integer(15253135600, 15253135699)",
+            "name": "@region",
+            "tel": "@integer(15253135600, 15253135699)",
+            "shop": "@region",
+            "create": "@datetime",
+            "expTime": "@date",
+            "valid": "@datetime",
+            "Confirmed": "@integer(36844, 368449)",
+            "Deaths": "@integer(1099, 10993)",
+            "kick": "@integer(199, 993)",
+            "Recovered": "@integer(1986, 9999)",
+            "Status": "0",
+            "level": "0",
+            // "Status": "@integer(1, 2)",
+            "color": "@hex",
+            "memo": "@paragraph(1, 1)",
+            "dialogValue": "@range(1, 3)",
+            "vipType": "@integer(1, 2)",
+            "members": members,
+            "wxVisible": "@integer(0, 1)",
+            "timeLong": "14:00-16:00",
+            "timeScope":  [new Date(2016, 9, 10, 8, 40), new Date(2016, 9, 10, 9, 40)],
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let testSelect = function () {
+    let item = [];
+    for (var i = 0; i < 30; i++) {
+        item.push({
+            "key": i + 1,
+            "value": i + 1,
+            "label": "@region",
+        })
+    }
+
+    let res = {
+        Rs: item,
+        Code: 0,
+        Memo: ''
+    };
+    return res;
+};
+
+let SignIn = function () {
+
+    let Rs = {
+        token: "@guid"
+    };
+    let res = {
+        Rs: Rs,
+        Code: 0,
+        Memo: '登陆成功'
+    };
+    return res;
+};
+
+let editbasicinfo = function () {
+
+    let res = {
+        Code: 0,
+        Memo: '修改成功'
+    };
+    return res;
+};
+
+let modPwd = function () {
+    let res = {
+        Code: 0,
+        Memo: '修改成功'
+    };
+    return res;
+};
+let logout = function () {
+    let res = {
+        Code: 0,
+        Memo: '退出成功'
+    };
+    return res;
+};
+
+Mock.mock('/api/testPic', 'post', testPic());
+Mock.mock('/api/testSelect', 'post', testSelect());
+Mock.mock('/api/testTable', 'post', testTable());
+Mock.mock('/api/worldDetail', 'post', worldDetail());
+Mock.mock('/api/SignIn', 'post', SignIn());//用户登录
+Mock.mock('/api/editbasicinfo', 'post', editbasicinfo());//用户设置修改
+Mock.mock('/api/modPwd', 'post', modPwd());//密码修改
+Mock.mock('/api/logout', 'post', logout());//退出登陆
+
+export default Mock;

+ 167 - 0
online/src/api/getApiRes.js

@@ -0,0 +1,167 @@
+import axios from 'axios';
+import global from '../Global.js'
+// 基础方法进行封装
+function getApiBasic(url, postdata) {
+    return  axios.post(url, postdata).then(function(data){
+        let json = data.data;
+        return json
+    },function(response){
+        console.info(response);
+    })
+}
+
+// 调用的api改写成方法
+export function worldDetail(postdata) {
+        let url = headapi + 'worldDetail';
+        return getApiBasic(url,postdata);
+}
+
+
+
+export function editbasicinfo(postdata) {
+    let url = headapi + 'editbasicinfo';
+    return getApiBasic(url,postdata);
+}
+export function modPwd(postdata) {
+    let url = headapi + 'modPwd';
+    return getApiBasic(url,postdata);
+}
+export function logout(postdata) {
+    let url = headapi + 'logout';
+    return getApiBasic(url,postdata);
+}
+
+// 调用的api改写成方法
+export function testTable(postdata) {
+    let url = headapi + 'testTable';
+    return getApiBasic(url,postdata);
+}
+export function testSelect(postdata) {
+    let url = headapi + 'testSelect';
+    return getApiBasic(url,postdata);
+}
+
+export function testPic(postdata) {
+    let url = headapi + 'testPic';
+    return getApiBasic(url,postdata);
+}
+
+
+// 正式接口
+
+// 获取验证图片
+export function GenVerifyPic(postdata) {
+    let url = headapi + 'v1/Auth/GenVerifyPic';
+    return getApiBasic(url, postdata);
+}
+
+// 手机获取验证码
+export function GetPhoneVFCode(postdata) {
+    let url = headapi + 'v1/Auth/GetPhoneVFCode';
+    return getApiBasic(url, postdata);
+}
+
+export function SignIn(postdata) {
+    let url = headapi + 'v1/Auth/SignIn';
+    return getApiBasic(url,postdata);
+}
+// 手机登录
+export function PhoneSignIn(postdata) {
+    let url = headapi + 'v1/Auth/PhoneSignIn';
+    return getApiBasic(url,postdata);
+}
+
+// 用户微信绑定
+export function WXBind(postdata) {
+    let url = headapi + 'v1/Auth/WXBind';
+    return getApiBasic(url,postdata);
+}
+
+// 用户微信登录
+export function WXSignIn(postdata) {
+    let url = headapi + 'v1/Auth/WXSignIn';
+    return getApiBasic(url,postdata);
+}
+
+// 用户微信解除绑定
+export function WXUnbind(postdata) {
+    let url = headapi + 'v1/Auth/WXUnbind';
+    return getApiBasic(url,postdata);
+}
+
+
+// Weixin
+
+// 预约课程
+export function OderAddByVipUser(postdata) {
+    let url = headapi + 'v1/Weixin/OderAddByVipUser';
+    return getApiBasic(url,postdata);
+}
+
+// 取消预约
+export function OderCancelByVipUser(postdata) {
+    let url = headapi + 'v1/Weixin/OderCancelByVipUser';
+    return getApiBasic(url,postdata);
+}
+// 预约记录查询
+export function OrderListQuery(postdata) {
+    let url = headapi + 'v1/Weixin/OrderListQuery';
+    return getApiBasic(url,postdata);
+}
+// 可预约店铺信息查询
+export function OrderShopQuery(postdata) {
+    let url = headapi + 'v1/Weixin/OrderShopQuery';
+    return getApiBasic(url,postdata);
+}
+// 可预约课程列表查询(未完成)
+export function CanOrderSchoolTimeTableListQuery(postdata) {
+    let url = headapi + 'v1/Weixin/CanOrderSchoolTimeTableListQuery';
+    return getApiBasic(url,postdata);
+}
+// 消费记录查询
+export function VipUserConsumeListQuery(postdata) {
+    let url = headapi + 'v1/Weixin/VipUserConsumeListQuery';
+    return getApiBasic(url,postdata);
+}
+// 用户自身信息查询
+export function VipUserSelfQuery(postdata) {
+    let url = headapi + 'v1/Weixin/VipUserSelfQuery';
+    return getApiBasic(url,postdata);
+}
+
+// 某日课程表查询
+export function SchoolTimeQueryByDate(postdata) {
+    let url = headapi + 'v1/Weixin/SchoolTimeQueryByDate';
+    return getApiBasic(url,postdata);
+}
+
+// 通过session查询用户自身信息
+export function ManagerSelfQuery(postdata) {
+    let url = headapi + 'v1/User/ManagerSelfQuery';
+    return getApiBasic(url,postdata);
+}
+
+// 课程表预览
+export function SchoolTimetablePreview(postdata) {
+    let url = headapi + 'v1/SchoolTimeTable/SchoolTimetablePreview';
+    return getApiBasic(url, postdata);
+}
+// CleCk查询
+export function VipUserCleCkSum(postdata) {
+    let url = headapi + 'v1/Weixin/VipUserCleCkSum';
+    return getApiBasic(url, postdata);
+}
+// 查询下周是否有课
+export function QueryNextWeek(postdata) {
+    let url = headapi + 'v1/Weixin/QueryNextWeek';
+    return getApiBasic(url, postdata);
+}
+
+
+// 用户店铺信息查询
+export function MyShopQuery(postdata) {
+    let url = headapi + 'v1/Weixin/MyShopQuery';
+    return getApiBasic(url, postdata);
+}
+
+

+ 110 - 0
online/src/components/BaseCharts.js

@@ -0,0 +1,110 @@
+import Chart from 'chart.js'
+
+export function generateChart (chartId, chartType) {
+    return {
+        render: function (createElement) {
+            return createElement(
+                'div', {
+                    style: this.styles,
+                    class: this.cssClasses
+                },
+                [
+                    createElement(
+                        'canvas', {
+                            attrs: {
+                                id: this.chartId,
+                                width: this.width,
+                                height: this.height
+                            },
+                            ref: 'canvas'
+                        }
+                    )
+                ]
+            )
+        },
+
+        props: {
+            chartId: {
+                default: chartId,
+                type: String
+            },
+            width: {
+                default: 400,
+                type: Number
+            },
+            height: {
+                default: 400,
+                type: Number
+            },
+            cssClasses: {
+                type: String,
+                default: ''
+            },
+            styles: {
+                type: Object
+            },
+            plugins: {
+                type: Array,
+                default () {
+                    return []
+                }
+            }
+        },
+
+        data () {
+            return {
+                _chart: null,
+                _plugins: this.plugins
+            }
+        },
+
+        methods: {
+            addPlugin (plugin) {
+                this.$data._plugins.push(plugin)
+            },
+            generateLegend () {
+                if (this.$data._chart) {
+                    return this.$data._chart.generateLegend()
+                }
+            },
+            renderChart (data, options) {
+                if (this.$data._chart) this.$data._chart.destroy()
+                this.$data._chart = new Chart(
+                    this.$refs.canvas.getContext('2d'), {
+                        type: chartType,
+                        data: data,
+                        options: options,
+                        plugins: this.$data._plugins
+                    }
+                )
+            }
+        },
+        beforeDestroy () {
+            if (this.$data._chart) {
+                this.$data._chart.destroy()
+            }
+        }
+    }
+}
+
+export const Bar = generateChart('bar-chart', 'bar')
+export const HorizontalBar = generateChart('horizontalbar-chart', 'horizontalBar')
+export const Doughnut = generateChart('doughnut-chart', 'doughnut')
+export const Line = generateChart('line-chart', 'line')
+export const Pie = generateChart('pie-chart', 'pie')
+export const PolarArea = generateChart('polar-chart', 'polarArea')
+export const Radar = generateChart('radar-chart', 'radar')
+export const Bubble = generateChart('bubble-chart', 'bubble')
+export const Scatter = generateChart('scatter-chart', 'scatter')
+
+export default {
+    Bar,
+    HorizontalBar,
+    Doughnut,
+    Line,
+    Pie,
+    PolarArea,
+    Radar,
+    Bubble,
+    Scatter
+}

+ 63 - 0
online/src/components/LineExample.js

@@ -0,0 +1,63 @@
+import {Line} from './BaseCharts'
+import axios from 'axios';
+
+let qs = require('qs');
+export default {
+    extends: Line,
+    data() {
+        return {
+            labels: [],
+            datasets: [],
+        }
+    },
+    props: ['dataLabels','datadatasets'],
+    watch:{
+        dataLabels(e){
+            this.drawCanvas();
+        },
+        datadatasets(e){
+            this.drawCanvas();
+        }
+    },
+    mounted() {
+      this.drawCanvas();
+    },
+    methods:{
+        drawCanvas(){
+            this.renderChart({
+                labels: this.dataLabels,
+                datasets: [
+                    {
+                        title: {
+                            display: false,
+                            text: 'Custom Chart Title'
+                        },
+                        Legend: {
+                            display: false,
+                        },
+                        label: '',
+                        color: '#FFA200',
+                        borderColor: '#FFA200',
+                        backgroundColor: 'rgba(255,255,255,0)',
+                        data: this.datadatasets
+                    }
+                ]
+            }, {
+                responsive: false,
+                maintainAspectRatio: false,
+                scales: {
+                    yAxes: [{
+                        ticks: {
+                            beginAtZero: true,
+                            callback: function (value) {
+                                if (value % 1 === 0) {
+                                    return value;
+                                }
+                            }
+                        }
+                    }]
+                }
+            })
+        }
+    }
+}

+ 93 - 0
online/src/components/LineExample2.js

@@ -0,0 +1,93 @@
+import { Line } from './BaseCharts'
+export default {
+    extends: Line,
+    props: {
+        firstDate: {  // 必须提供字段
+            required: true,
+            default:false
+        },
+        labels: {  // 必须提供字段
+            required: false,
+            default:false
+        },
+    },
+    watch: {
+        // 动态加载
+        firstDate(curVal, oldVal) {
+            const that = this;
+            if (curVal) {
+                this.firstDate = curVal;
+                that.renderChart({
+                    datasets: this.firstDate,
+                    labels: this.labels,
+                    // labels: '',
+                }, {
+                    responsive: true,
+                    maintainAspectRatio: false,
+                    cutoutPercentage: 90,//环粗细
+                    showTooltips:false,
+                    title:false,
+                    tooltips:{
+                        mode:'index',
+                        intersect:false
+                    },
+                    legend: {
+                        position:'bottom',
+                        labels: {
+                            boxWidth:12,
+                            fontSize:10
+                        }
+                    },
+                    scales: {
+                        yAxes: [{
+                            ticks: {
+                                beginAtZero: true,
+                                callback: function (value) {
+                                    if (value % 1 === 0) {
+                                        return value;
+                                    }
+                                }
+                            }
+                        }]
+                    }
+                })
+            }
+        },
+    },
+    mounted() {
+        const that = this;
+        that.renderChart({
+            labels: this.labels,
+            datasets:this.firstDate
+        }, {
+            responsive: true,
+            maintainAspectRatio: false,
+            cutoutPercentage: 90,//环粗细
+            showTooltips:false,
+            title:false,
+            tooltips:{
+                mode:'index',
+                intersect:false
+            },
+            legend: {
+                position:'bottom',
+                labels: {
+                    boxWidth:12,
+                    fontSize:10
+                }
+            },
+            scales: {
+                yAxes: [{
+                    ticks: {
+                        beginAtZero: true,
+                        callback: function (value) {
+                            if (value % 1 === 0) {
+                                return value;
+                            }
+                        }
+                    }
+                }]
+            }
+        })
+    }
+}

+ 3833 - 0
online/src/components/address3.json

@@ -0,0 +1,3833 @@
+{
+  "北京市": {
+    "市辖区": [
+      "东城区",
+      "西城区",
+      "朝阳区",
+      "丰台区",
+      "石景山区",
+      "海淀区",
+      "门头沟区",
+      "房山区",
+      "通州区",
+      "顺义区",
+      "昌平区",
+      "大兴区",
+      "怀柔区",
+      "平谷区",
+      "密云区",
+      "延庆区"
+    ]
+  },
+  "天津市": {
+    "市辖区": [
+      "和平区",
+      "河东区",
+      "河西区",
+      "南开区",
+      "河北区",
+      "红桥区",
+      "东丽区",
+      "西青区",
+      "津南区",
+      "北辰区",
+      "武清区",
+      "宝坻区",
+      "滨海新区",
+      "宁河区",
+      "静海区",
+      "蓟州区"
+    ]
+  },
+  "河北省": {
+    "石家庄市": [
+      "长安区",
+      "桥西区",
+      "新华区",
+      "井陉矿区",
+      "裕华区",
+      "藁城区",
+      "鹿泉区",
+      "栾城区",
+      "井陉县",
+      "正定县",
+      "行唐县",
+      "灵寿县",
+      "高邑县",
+      "深泽县",
+      "赞皇县",
+      "无极县",
+      "平山县",
+      "元氏县",
+      "赵县",
+      "石家庄高新技术产业开发区",
+      "石家庄循环化工园区",
+      "辛集市",
+      "晋州市",
+      "新乐市"
+    ],
+    "唐山市": [
+      "路南区",
+      "路北区",
+      "古冶区",
+      "开平区",
+      "丰南区",
+      "丰润区",
+      "曹妃甸区",
+      "滦南县",
+      "乐亭县",
+      "迁西县",
+      "玉田县",
+      "唐山市芦台经济技术开发区",
+      "唐山市汉沽管理区",
+      "唐山高新技术产业开发区",
+      "河北唐山海港经济开发区",
+      "遵化市",
+      "迁安市",
+      "滦州市"
+    ],
+    "秦皇岛市": [
+      "海港区",
+      "山海关区",
+      "北戴河区",
+      "抚宁区",
+      "青龙满族自治县",
+      "昌黎县",
+      "卢龙县",
+      "秦皇岛市经济技术开发区",
+      "北戴河新区"
+    ],
+    "邯郸市": [
+      "邯山区",
+      "丛台区",
+      "复兴区",
+      "峰峰矿区",
+      "肥乡区",
+      "永年区",
+      "临漳县",
+      "成安县",
+      "大名县",
+      "涉县",
+      "磁县",
+      "邱县",
+      "鸡泽县",
+      "广平县",
+      "馆陶县",
+      "魏县",
+      "曲周县",
+      "邯郸经济技术开发区",
+      "邯郸冀南新区",
+      "武安市"
+    ],
+    "邢台市": [
+      "桥东区",
+      "桥西区",
+      "邢台县",
+      "临城县",
+      "内丘县",
+      "柏乡县",
+      "隆尧县",
+      "任县",
+      "南和县",
+      "宁晋县",
+      "巨鹿县",
+      "新河县",
+      "广宗县",
+      "平乡县",
+      "威县",
+      "清河县",
+      "临西县",
+      "河北邢台经济开发区",
+      "南宫市",
+      "沙河市"
+    ],
+    "保定市": [
+      "竞秀区",
+      "莲池区",
+      "满城区",
+      "清苑区",
+      "徐水区",
+      "涞水县",
+      "阜平县",
+      "定兴县",
+      "唐县",
+      "高阳县",
+      "容城县",
+      "涞源县",
+      "望都县",
+      "安新县",
+      "易县",
+      "曲阳县",
+      "蠡县",
+      "顺平县",
+      "博野县",
+      "雄县",
+      "保定高新技术产业开发区",
+      "保定白沟新城",
+      "涿州市",
+      "定州市",
+      "安国市",
+      "高碑店市"
+    ],
+    "张家口市": [
+      "桥东区",
+      "桥西区",
+      "宣化区",
+      "下花园区",
+      "万全区",
+      "崇礼区",
+      "张北县",
+      "康保县",
+      "沽源县",
+      "尚义县",
+      "蔚县",
+      "阳原县",
+      "怀安县",
+      "怀来县",
+      "涿鹿县",
+      "赤城县",
+      "张家口市高新技术产业开发区",
+      "张家口市察北管理区",
+      "张家口市塞北管理区"
+    ],
+    "承德市": [
+      "双桥区",
+      "双滦区",
+      "鹰手营子矿区",
+      "承德县",
+      "兴隆县",
+      "滦平县",
+      "隆化县",
+      "丰宁满族自治县",
+      "宽城满族自治县",
+      "围场满族蒙古族自治县",
+      "承德高新技术产业开发区",
+      "平泉市"
+    ],
+    "沧州市": [
+      "新华区",
+      "运河区",
+      "沧县",
+      "青县",
+      "东光县",
+      "海兴县",
+      "盐山县",
+      "肃宁县",
+      "南皮县",
+      "吴桥县",
+      "献县",
+      "孟村回族自治县",
+      "河北沧州经济开发区",
+      "沧州高新技术产业开发区",
+      "沧州渤海新区",
+      "泊头市",
+      "任丘市",
+      "黄骅市",
+      "河间市"
+    ],
+    "廊坊市": [
+      "安次区",
+      "广阳区",
+      "固安县",
+      "永清县",
+      "香河县",
+      "大城县",
+      "文安县",
+      "大厂回族自治县",
+      "廊坊经济技术开发区",
+      "霸州市",
+      "三河市"
+    ],
+    "衡水市": [
+      "桃城区",
+      "冀州区",
+      "枣强县",
+      "武邑县",
+      "武强县",
+      "饶阳县",
+      "安平县",
+      "故城县",
+      "景县",
+      "阜城县",
+      "河北衡水高新技术产业开发区",
+      "衡水滨湖新区",
+      "深州市"
+    ]
+  },
+  "山西省": {
+    "太原市": [
+      "小店区",
+      "迎泽区",
+      "杏花岭区",
+      "尖草坪区",
+      "万柏林区",
+      "晋源区",
+      "清徐县",
+      "阳曲县",
+      "娄烦县",
+      "山西转型综合改革示范区",
+      "古交市"
+    ],
+    "大同市": [
+      "新荣区",
+      "平城区",
+      "云冈区",
+      "云州区",
+      "阳高县",
+      "天镇县",
+      "广灵县",
+      "灵丘县",
+      "浑源县",
+      "左云县",
+      "山西大同经济开发区"
+    ],
+    "阳泉市": [
+      "城区",
+      "矿区",
+      "郊区",
+      "平定县",
+      "盂县"
+    ],
+    "长治市": [
+      "潞州区",
+      "上党区",
+      "屯留区",
+      "潞城区",
+      "襄垣县",
+      "平顺县",
+      "黎城县",
+      "壶关县",
+      "长子县",
+      "武乡县",
+      "沁县",
+      "沁源县",
+      "山西长治高新技术产业园区"
+    ],
+    "晋城市": [
+      "城区",
+      "沁水县",
+      "阳城县",
+      "陵川县",
+      "泽州县",
+      "高平市"
+    ],
+    "朔州市": [
+      "朔城区",
+      "平鲁区",
+      "山阴县",
+      "应县",
+      "右玉县",
+      "山西朔州经济开发区",
+      "怀仁市"
+    ],
+    "晋中市": [
+      "榆次区",
+      "榆社县",
+      "左权县",
+      "和顺县",
+      "昔阳县",
+      "寿阳县",
+      "太谷县",
+      "祁县",
+      "平遥县",
+      "灵石县",
+      "介休市"
+    ],
+    "运城市": [
+      "盐湖区",
+      "临猗县",
+      "万荣县",
+      "闻喜县",
+      "稷山县",
+      "新绛县",
+      "绛县",
+      "垣曲县",
+      "夏县",
+      "平陆县",
+      "芮城县",
+      "永济市",
+      "河津市"
+    ],
+    "忻州市": [
+      "忻府区",
+      "定襄县",
+      "五台县",
+      "代县",
+      "繁峙县",
+      "宁武县",
+      "静乐县",
+      "神池县",
+      "五寨县",
+      "岢岚县",
+      "河曲县",
+      "保德县",
+      "偏关县",
+      "五台山风景名胜区",
+      "原平市"
+    ],
+    "临汾市": [
+      "尧都区",
+      "曲沃县",
+      "翼城县",
+      "襄汾县",
+      "洪洞县",
+      "古县",
+      "安泽县",
+      "浮山县",
+      "吉县",
+      "乡宁县",
+      "大宁县",
+      "隰县",
+      "永和县",
+      "蒲县",
+      "汾西县",
+      "侯马市",
+      "霍州市"
+    ],
+    "吕梁市": [
+      "离石区",
+      "文水县",
+      "交城县",
+      "兴县",
+      "临县",
+      "柳林县",
+      "石楼县",
+      "岚县",
+      "方山县",
+      "中阳县",
+      "交口县",
+      "孝义市",
+      "汾阳市"
+    ]
+  },
+  "内蒙古自治区": {
+    "呼和浩特市": [
+      "新城区",
+      "回民区",
+      "玉泉区",
+      "赛罕区",
+      "土默特左旗",
+      "托克托县",
+      "和林格尔县",
+      "清水河县",
+      "武川县",
+      "呼和浩特金海工业园区",
+      "呼和浩特经济技术开发区"
+    ],
+    "包头市": [
+      "东河区",
+      "昆都仑区",
+      "青山区",
+      "石拐区",
+      "白云鄂博矿区",
+      "九原区",
+      "土默特右旗",
+      "固阳县",
+      "达尔罕茂明安联合旗",
+      "包头稀土高新技术产业开发区"
+    ],
+    "乌海市": [
+      "海勃湾区",
+      "海南区",
+      "乌达区"
+    ],
+    "赤峰市": [
+      "红山区",
+      "元宝山区",
+      "松山区",
+      "阿鲁科尔沁旗",
+      "巴林左旗",
+      "巴林右旗",
+      "林西县",
+      "克什克腾旗",
+      "翁牛特旗",
+      "喀喇沁旗",
+      "宁城县",
+      "敖汉旗"
+    ],
+    "通辽市": [
+      "科尔沁区",
+      "科尔沁左翼中旗",
+      "科尔沁左翼后旗",
+      "开鲁县",
+      "库伦旗",
+      "奈曼旗",
+      "扎鲁特旗",
+      "通辽经济技术开发区",
+      "霍林郭勒市"
+    ],
+    "鄂尔多斯市": [
+      "东胜区",
+      "康巴什区",
+      "达拉特旗",
+      "准格尔旗",
+      "鄂托克前旗",
+      "鄂托克旗",
+      "杭锦旗",
+      "乌审旗",
+      "伊金霍洛旗"
+    ],
+    "呼伦贝尔市": [
+      "海拉尔区",
+      "扎赉诺尔区",
+      "阿荣旗",
+      "莫力达瓦达斡尔族自治旗",
+      "鄂伦春自治旗",
+      "鄂温克族自治旗",
+      "陈巴尔虎旗",
+      "新巴尔虎左旗",
+      "新巴尔虎右旗",
+      "满洲里市",
+      "牙克石市",
+      "扎兰屯市",
+      "额尔古纳市",
+      "根河市"
+    ],
+    "巴彦淖尔市": [
+      "临河区",
+      "五原县",
+      "磴口县",
+      "乌拉特前旗",
+      "乌拉特中旗",
+      "乌拉特后旗",
+      "杭锦后旗"
+    ],
+    "乌兰察布市": [
+      "集宁区",
+      "卓资县",
+      "化德县",
+      "商都县",
+      "兴和县",
+      "凉城县",
+      "察哈尔右翼前旗",
+      "察哈尔右翼中旗",
+      "察哈尔右翼后旗",
+      "四子王旗",
+      "丰镇市"
+    ],
+    "兴安盟": [
+      "乌兰浩特市",
+      "阿尔山市",
+      "科尔沁右翼前旗",
+      "科尔沁右翼中旗",
+      "扎赉特旗",
+      "突泉县"
+    ],
+    "锡林郭勒盟": [
+      "二连浩特市",
+      "锡林浩特市",
+      "阿巴嘎旗",
+      "苏尼特左旗",
+      "苏尼特右旗",
+      "东乌珠穆沁旗",
+      "西乌珠穆沁旗",
+      "太仆寺旗",
+      "镶黄旗",
+      "正镶白旗",
+      "正蓝旗",
+      "多伦县",
+      "乌拉盖管委会"
+    ],
+    "阿拉善盟": [
+      "阿拉善左旗",
+      "阿拉善右旗",
+      "额济纳旗",
+      "内蒙古阿拉善经济开发区"
+    ]
+  },
+  "辽宁省": {
+    "沈阳市": [
+      "和平区",
+      "沈河区",
+      "大东区",
+      "皇姑区",
+      "铁西区",
+      "苏家屯区",
+      "浑南区",
+      "沈北新区",
+      "于洪区",
+      "辽中区",
+      "康平县",
+      "法库县",
+      "新民市"
+    ],
+    "大连市": [
+      "中山区",
+      "西岗区",
+      "沙河口区",
+      "甘井子区",
+      "旅顺口区",
+      "金州区",
+      "普兰店区",
+      "长海县",
+      "瓦房店市",
+      "庄河市"
+    ],
+    "鞍山市": [
+      "铁东区",
+      "铁西区",
+      "立山区",
+      "千山区",
+      "台安县",
+      "岫岩满族自治县",
+      "海城市"
+    ],
+    "抚顺市": [
+      "新抚区",
+      "东洲区",
+      "望花区",
+      "顺城区",
+      "抚顺县",
+      "新宾满族自治县",
+      "清原满族自治县"
+    ],
+    "本溪市": [
+      "平山区",
+      "溪湖区",
+      "明山区",
+      "南芬区",
+      "本溪满族自治县",
+      "桓仁满族自治县"
+    ],
+    "丹东市": [
+      "元宝区",
+      "振兴区",
+      "振安区",
+      "宽甸满族自治县",
+      "东港市",
+      "凤城市"
+    ],
+    "锦州市": [
+      "古塔区",
+      "凌河区",
+      "太和区",
+      "黑山县",
+      "义县",
+      "凌海市",
+      "北镇市"
+    ],
+    "营口市": [
+      "站前区",
+      "西市区",
+      "鲅鱼圈区",
+      "老边区",
+      "盖州市",
+      "大石桥市"
+    ],
+    "阜新市": [
+      "海州区",
+      "新邱区",
+      "太平区",
+      "清河门区",
+      "细河区",
+      "阜新蒙古族自治县",
+      "彰武县"
+    ],
+    "辽阳市": [
+      "白塔区",
+      "文圣区",
+      "宏伟区",
+      "弓长岭区",
+      "太子河区",
+      "辽阳县",
+      "灯塔市"
+    ],
+    "盘锦市": [
+      "双台子区",
+      "兴隆台区",
+      "大洼区",
+      "盘山县"
+    ],
+    "铁岭市": [
+      "银州区",
+      "清河区",
+      "铁岭县",
+      "西丰县",
+      "昌图县",
+      "调兵山市",
+      "开原市"
+    ],
+    "朝阳市": [
+      "双塔区",
+      "龙城区",
+      "朝阳县",
+      "建平县",
+      "喀喇沁左翼蒙古族自治县",
+      "北票市",
+      "凌源市"
+    ],
+    "葫芦岛市": [
+      "连山区",
+      "龙港区",
+      "南票区",
+      "绥中县",
+      "建昌县",
+      "兴城市"
+    ]
+  },
+  "吉林省": {
+    "长春市": [
+      "南关区",
+      "宽城区",
+      "朝阳区",
+      "二道区",
+      "绿园区",
+      "双阳区",
+      "九台区",
+      "农安县",
+      "长春经济技术开发区",
+      "长春净月高新技术产业开发区",
+      "长春高新技术产业开发区",
+      "长春汽车经济技术开发区",
+      "榆树市",
+      "德惠市"
+    ],
+    "吉林市": [
+      "昌邑区",
+      "龙潭区",
+      "船营区",
+      "丰满区",
+      "永吉县",
+      "吉林经济开发区",
+      "吉林高新技术产业开发区",
+      "吉林中国新加坡食品区",
+      "蛟河市",
+      "桦甸市",
+      "舒兰市",
+      "磐石市"
+    ],
+    "四平市": [
+      "铁西区",
+      "铁东区",
+      "梨树县",
+      "伊通满族自治县",
+      "公主岭市",
+      "双辽市"
+    ],
+    "辽源市": [
+      "龙山区",
+      "西安区",
+      "东丰县",
+      "东辽县"
+    ],
+    "通化市": [
+      "东昌区",
+      "二道江区",
+      "通化县",
+      "辉南县",
+      "柳河县",
+      "梅河口市",
+      "集安市"
+    ],
+    "白山市": [
+      "浑江区",
+      "江源区",
+      "抚松县",
+      "靖宇县",
+      "长白朝鲜族自治县",
+      "临江市"
+    ],
+    "松原市": [
+      "宁江区",
+      "前郭尔罗斯蒙古族自治县",
+      "长岭县",
+      "乾安县",
+      "吉林松原经济开发区",
+      "扶余市"
+    ],
+    "白城市": [
+      "洮北区",
+      "镇赉县",
+      "通榆县",
+      "吉林白城经济开发区",
+      "洮南市",
+      "大安市"
+    ],
+    "延边朝鲜族自治州": [
+      "延吉市",
+      "图们市",
+      "敦化市",
+      "珲春市",
+      "龙井市",
+      "和龙市",
+      "汪清县",
+      "安图县"
+    ]
+  },
+  "黑龙江省": {
+    "哈尔滨市": [
+      "道里区",
+      "南岗区",
+      "道外区",
+      "平房区",
+      "松北区",
+      "香坊区",
+      "呼兰区",
+      "阿城区",
+      "双城区",
+      "依兰县",
+      "方正县",
+      "宾县",
+      "巴彦县",
+      "木兰县",
+      "通河县",
+      "延寿县",
+      "尚志市",
+      "五常市"
+    ],
+    "齐齐哈尔市": [
+      "龙沙区",
+      "建华区",
+      "铁锋区",
+      "昂昂溪区",
+      "富拉尔基区",
+      "碾子山区",
+      "梅里斯达斡尔族区",
+      "龙江县",
+      "依安县",
+      "泰来县",
+      "甘南县",
+      "富裕县",
+      "克山县",
+      "克东县",
+      "拜泉县",
+      "讷河市"
+    ],
+    "鸡西市": [
+      "鸡冠区",
+      "恒山区",
+      "滴道区",
+      "梨树区",
+      "城子河区",
+      "麻山区",
+      "鸡东县",
+      "虎林市",
+      "密山市"
+    ],
+    "鹤岗市": [
+      "向阳区",
+      "工农区",
+      "南山区",
+      "兴安区",
+      "东山区",
+      "兴山区",
+      "萝北县",
+      "绥滨县"
+    ],
+    "双鸭山市": [
+      "尖山区",
+      "岭东区",
+      "四方台区",
+      "宝山区",
+      "集贤县",
+      "友谊县",
+      "宝清县",
+      "饶河县"
+    ],
+    "大庆市": [
+      "萨尔图区",
+      "龙凤区",
+      "让胡路区",
+      "红岗区",
+      "大同区",
+      "肇州县",
+      "肇源县",
+      "林甸县",
+      "杜尔伯特蒙古族自治县",
+      "大庆高新技术产业开发区"
+    ],
+    "伊春市": [
+      "伊春区",
+      "南岔区",
+      "友好区",
+      "西林区",
+      "翠峦区",
+      "新青区",
+      "美溪区",
+      "金山屯区",
+      "五营区",
+      "乌马河区",
+      "汤旺河区",
+      "带岭区",
+      "乌伊岭区",
+      "红星区",
+      "上甘岭区",
+      "嘉荫县",
+      "铁力市"
+    ],
+    "佳木斯市": [
+      "向阳区",
+      "前进区",
+      "东风区",
+      "郊区",
+      "桦南县",
+      "桦川县",
+      "汤原县",
+      "同江市",
+      "富锦市",
+      "抚远市"
+    ],
+    "七台河市": [
+      "新兴区",
+      "桃山区",
+      "茄子河区",
+      "勃利县"
+    ],
+    "牡丹江市": [
+      "东安区",
+      "阳明区",
+      "爱民区",
+      "西安区",
+      "林口县",
+      "牡丹江经济技术开发区",
+      "绥芬河市",
+      "海林市",
+      "宁安市",
+      "穆棱市",
+      "东宁市"
+    ],
+    "黑河市": [
+      "爱辉区",
+      "嫩江县",
+      "逊克县",
+      "孙吴县",
+      "北安市",
+      "五大连池市"
+    ],
+    "绥化市": [
+      "北林区",
+      "望奎县",
+      "兰西县",
+      "青冈县",
+      "庆安县",
+      "明水县",
+      "绥棱县",
+      "安达市",
+      "肇东市",
+      "海伦市"
+    ],
+    "大兴安岭地区": [
+      "漠河市",
+      "呼玛县",
+      "塔河县",
+      "加格达奇区",
+      "松岭区",
+      "新林区",
+      "呼中区"
+    ]
+  },
+  "上海市": {
+    "市辖区": [
+      "黄浦区",
+      "徐汇区",
+      "长宁区",
+      "静安区",
+      "普陀区",
+      "虹口区",
+      "杨浦区",
+      "闵行区",
+      "宝山区",
+      "嘉定区",
+      "浦东新区",
+      "金山区",
+      "松江区",
+      "青浦区",
+      "奉贤区",
+      "崇明区"
+    ]
+  },
+  "江苏省": {
+    "南京市": [
+      "玄武区",
+      "秦淮区",
+      "建邺区",
+      "鼓楼区",
+      "浦口区",
+      "栖霞区",
+      "雨花台区",
+      "江宁区",
+      "六合区",
+      "溧水区",
+      "高淳区"
+    ],
+    "无锡市": [
+      "锡山区",
+      "惠山区",
+      "滨湖区",
+      "梁溪区",
+      "新吴区",
+      "江阴市",
+      "宜兴市"
+    ],
+    "徐州市": [
+      "鼓楼区",
+      "云龙区",
+      "贾汪区",
+      "泉山区",
+      "铜山区",
+      "丰县",
+      "沛县",
+      "睢宁县",
+      "徐州经济技术开发区",
+      "新沂市",
+      "邳州市"
+    ],
+    "常州市": [
+      "天宁区",
+      "钟楼区",
+      "新北区",
+      "武进区",
+      "金坛区",
+      "溧阳市"
+    ],
+    "苏州市": [
+      "虎丘区",
+      "吴中区",
+      "相城区",
+      "姑苏区",
+      "吴江区",
+      "苏州工业园区",
+      "常熟市",
+      "张家港市",
+      "昆山市",
+      "太仓市"
+    ],
+    "南通市": [
+      "崇川区",
+      "港闸区",
+      "通州区",
+      "如东县",
+      "南通经济技术开发区",
+      "启东市",
+      "如皋市",
+      "海门市",
+      "海安市"
+    ],
+    "连云港市": [
+      "连云区",
+      "海州区",
+      "赣榆区",
+      "东海县",
+      "灌云县",
+      "灌南县",
+      "连云港经济技术开发区",
+      "连云港高新技术产业开发区"
+    ],
+    "淮安市": [
+      "淮安区",
+      "淮阴区",
+      "清江浦区",
+      "洪泽区",
+      "涟水县",
+      "盱眙县",
+      "金湖县",
+      "淮安经济技术开发区"
+    ],
+    "盐城市": [
+      "亭湖区",
+      "盐都区",
+      "大丰区",
+      "响水县",
+      "滨海县",
+      "阜宁县",
+      "射阳县",
+      "建湖县",
+      "盐城经济技术开发区",
+      "东台市"
+    ],
+    "扬州市": [
+      "广陵区",
+      "邗江区",
+      "江都区",
+      "宝应县",
+      "扬州经济技术开发区",
+      "仪征市",
+      "高邮市"
+    ],
+    "镇江市": [
+      "京口区",
+      "润州区",
+      "丹徒区",
+      "镇江新区",
+      "丹阳市",
+      "扬中市",
+      "句容市"
+    ],
+    "泰州市": [
+      "海陵区",
+      "高港区",
+      "姜堰区",
+      "泰州医药高新技术产业开发区",
+      "兴化市",
+      "靖江市",
+      "泰兴市"
+    ],
+    "宿迁市": [
+      "宿城区",
+      "宿豫区",
+      "沭阳县",
+      "泗阳县",
+      "泗洪县",
+      "宿迁经济技术开发区"
+    ]
+  },
+  "浙江省": {
+    "杭州市": [
+      "上城区",
+      "下城区",
+      "江干区",
+      "拱墅区",
+      "西湖区",
+      "滨江区",
+      "萧山区",
+      "余杭区",
+      "富阳区",
+      "临安区",
+      "桐庐县",
+      "淳安县",
+      "建德市"
+    ],
+    "宁波市": [
+      "海曙区",
+      "江北区",
+      "北仑区",
+      "镇海区",
+      "鄞州区",
+      "奉化区",
+      "象山县",
+      "宁海县",
+      "余姚市",
+      "慈溪市"
+    ],
+    "温州市": [
+      "鹿城区",
+      "龙湾区",
+      "瓯海区",
+      "洞头区",
+      "永嘉县",
+      "平阳县",
+      "苍南县",
+      "文成县",
+      "泰顺县",
+      "温州经济技术开发区",
+      "瑞安市",
+      "乐清市"
+    ],
+    "嘉兴市": [
+      "南湖区",
+      "秀洲区",
+      "嘉善县",
+      "海盐县",
+      "海宁市",
+      "平湖市",
+      "桐乡市"
+    ],
+    "湖州市": [
+      "吴兴区",
+      "南浔区",
+      "德清县",
+      "长兴县",
+      "安吉县"
+    ],
+    "绍兴市": [
+      "越城区",
+      "柯桥区",
+      "上虞区",
+      "新昌县",
+      "诸暨市",
+      "嵊州市"
+    ],
+    "金华市": [
+      "婺城区",
+      "金东区",
+      "武义县",
+      "浦江县",
+      "磐安县",
+      "兰溪市",
+      "义乌市",
+      "东阳市",
+      "永康市"
+    ],
+    "衢州市": [
+      "柯城区",
+      "衢江区",
+      "常山县",
+      "开化县",
+      "龙游县",
+      "江山市"
+    ],
+    "舟山市": [
+      "定海区",
+      "普陀区",
+      "岱山县",
+      "嵊泗县"
+    ],
+    "台州市": [
+      "椒江区",
+      "黄岩区",
+      "路桥区",
+      "三门县",
+      "天台县",
+      "仙居县",
+      "温岭市",
+      "临海市",
+      "玉环市"
+    ],
+    "丽水市": [
+      "莲都区",
+      "青田县",
+      "缙云县",
+      "遂昌县",
+      "松阳县",
+      "云和县",
+      "庆元县",
+      "景宁畲族自治县",
+      "龙泉市"
+    ]
+  },
+  "安徽省": {
+    "合肥市": [
+      "瑶海区",
+      "庐阳区",
+      "蜀山区",
+      "包河区",
+      "长丰县",
+      "肥东县",
+      "肥西县",
+      "庐江县",
+      "合肥高新技术产业开发区",
+      "合肥经济技术开发区",
+      "合肥新站高新技术产业开发区",
+      "巢湖市"
+    ],
+    "芜湖市": [
+      "镜湖区",
+      "弋江区",
+      "鸠江区",
+      "三山区",
+      "芜湖县",
+      "繁昌县",
+      "南陵县",
+      "无为县",
+      "芜湖经济技术开发区",
+      "安徽芜湖长江大桥经济开发区"
+    ],
+    "蚌埠市": [
+      "龙子湖区",
+      "蚌山区",
+      "禹会区",
+      "淮上区",
+      "怀远县",
+      "五河县",
+      "固镇县",
+      "蚌埠市高新技术开发区",
+      "蚌埠市经济开发区"
+    ],
+    "淮南市": [
+      "大通区",
+      "田家庵区",
+      "谢家集区",
+      "八公山区",
+      "潘集区",
+      "凤台县",
+      "寿县"
+    ],
+    "马鞍山市": [
+      "花山区",
+      "雨山区",
+      "博望区",
+      "当涂县",
+      "含山县",
+      "和县"
+    ],
+    "淮北市": [
+      "杜集区",
+      "相山区",
+      "烈山区",
+      "濉溪县"
+    ],
+    "铜陵市": [
+      "铜官区",
+      "义安区",
+      "郊区",
+      "枞阳县"
+    ],
+    "安庆市": [
+      "迎江区",
+      "大观区",
+      "宜秀区",
+      "怀宁县",
+      "太湖县",
+      "宿松县",
+      "望江县",
+      "岳西县",
+      "安徽安庆经济开发区",
+      "桐城市",
+      "潜山市"
+    ],
+    "黄山市": [
+      "屯溪区",
+      "黄山区",
+      "徽州区",
+      "歙县",
+      "休宁县",
+      "黟县",
+      "祁门县"
+    ],
+    "滁州市": [
+      "琅琊区",
+      "南谯区",
+      "来安县",
+      "全椒县",
+      "定远县",
+      "凤阳县",
+      "苏滁现代产业园",
+      "滁州经济技术开发区",
+      "天长市",
+      "明光市"
+    ],
+    "阜阳市": [
+      "颍州区",
+      "颍东区",
+      "颍泉区",
+      "临泉县",
+      "太和县",
+      "阜南县",
+      "颍上县",
+      "阜阳合肥现代产业园区",
+      "阜阳经济技术开发区",
+      "界首市"
+    ],
+    "宿州市": [
+      "埇桥区",
+      "砀山县",
+      "萧县",
+      "灵璧县",
+      "泗县",
+      "宿州马鞍山现代产业园区",
+      "宿州经济技术开发区"
+    ],
+    "六安市": [
+      "金安区",
+      "裕安区",
+      "叶集区",
+      "霍邱县",
+      "舒城县",
+      "金寨县",
+      "霍山县"
+    ],
+    "亳州市": [
+      "谯城区",
+      "涡阳县",
+      "蒙城县",
+      "利辛县"
+    ],
+    "池州市": [
+      "贵池区",
+      "东至县",
+      "石台县",
+      "青阳县"
+    ],
+    "宣城市": [
+      "宣州区",
+      "郎溪县",
+      "广德县",
+      "泾县",
+      "绩溪县",
+      "旌德县",
+      "宣城市经济开发区",
+      "宁国市"
+    ]
+  },
+  "福建省": {
+    "福州市": [
+      "鼓楼区",
+      "台江区",
+      "仓山区",
+      "马尾区",
+      "晋安区",
+      "长乐区",
+      "闽侯县",
+      "连江县",
+      "罗源县",
+      "闽清县",
+      "永泰县",
+      "平潭县",
+      "福清市"
+    ],
+    "厦门市": [
+      "思明区",
+      "海沧区",
+      "湖里区",
+      "集美区",
+      "同安区",
+      "翔安区"
+    ],
+    "莆田市": [
+      "城厢区",
+      "涵江区",
+      "荔城区",
+      "秀屿区",
+      "仙游县"
+    ],
+    "三明市": [
+      "梅列区",
+      "三元区",
+      "明溪县",
+      "清流县",
+      "宁化县",
+      "大田县",
+      "尤溪县",
+      "沙县",
+      "将乐县",
+      "泰宁县",
+      "建宁县",
+      "永安市"
+    ],
+    "泉州市": [
+      "鲤城区",
+      "丰泽区",
+      "洛江区",
+      "泉港区",
+      "惠安县",
+      "安溪县",
+      "永春县",
+      "德化县",
+      "金门县",
+      "石狮市",
+      "晋江市",
+      "南安市"
+    ],
+    "漳州市": [
+      "芗城区",
+      "龙文区",
+      "云霄县",
+      "漳浦县",
+      "诏安县",
+      "长泰县",
+      "东山县",
+      "南靖县",
+      "平和县",
+      "华安县",
+      "龙海市"
+    ],
+    "南平市": [
+      "延平区",
+      "建阳区",
+      "顺昌县",
+      "浦城县",
+      "光泽县",
+      "松溪县",
+      "政和县",
+      "邵武市",
+      "武夷山市",
+      "建瓯市"
+    ],
+    "龙岩市": [
+      "新罗区",
+      "永定区",
+      "长汀县",
+      "上杭县",
+      "武平县",
+      "连城县",
+      "漳平市"
+    ],
+    "宁德市": [
+      "蕉城区",
+      "霞浦县",
+      "古田县",
+      "屏南县",
+      "寿宁县",
+      "周宁县",
+      "柘荣县",
+      "福安市",
+      "福鼎市"
+    ]
+  },
+  "江西省": {
+    "南昌市": [
+      "东湖区",
+      "西湖区",
+      "青云谱区",
+      "湾里区",
+      "青山湖区",
+      "新建区",
+      "南昌县",
+      "安义县",
+      "进贤县"
+    ],
+    "景德镇市": [
+      "昌江区",
+      "珠山区",
+      "浮梁县",
+      "乐平市"
+    ],
+    "萍乡市": [
+      "安源区",
+      "湘东区",
+      "莲花县",
+      "上栗县",
+      "芦溪县"
+    ],
+    "九江市": [
+      "濂溪区",
+      "浔阳区",
+      "柴桑区",
+      "武宁县",
+      "修水县",
+      "永修县",
+      "德安县",
+      "都昌县",
+      "湖口县",
+      "彭泽县",
+      "瑞昌市",
+      "共青城市",
+      "庐山市"
+    ],
+    "新余市": [
+      "渝水区",
+      "分宜县"
+    ],
+    "鹰潭市": [
+      "月湖区",
+      "余江区",
+      "贵溪市"
+    ],
+    "赣州市": [
+      "章贡区",
+      "南康区",
+      "赣县区",
+      "信丰县",
+      "大余县",
+      "上犹县",
+      "崇义县",
+      "安远县",
+      "龙南县",
+      "定南县",
+      "全南县",
+      "宁都县",
+      "于都县",
+      "兴国县",
+      "会昌县",
+      "寻乌县",
+      "石城县",
+      "瑞金市"
+    ],
+    "吉安市": [
+      "吉州区",
+      "青原区",
+      "吉安县",
+      "吉水县",
+      "峡江县",
+      "新干县",
+      "永丰县",
+      "泰和县",
+      "遂川县",
+      "万安县",
+      "安福县",
+      "永新县",
+      "井冈山市"
+    ],
+    "宜春市": [
+      "袁州区",
+      "奉新县",
+      "万载县",
+      "上高县",
+      "宜丰县",
+      "靖安县",
+      "铜鼓县",
+      "丰城市",
+      "樟树市",
+      "高安市"
+    ],
+    "抚州市": [
+      "临川区",
+      "东乡区",
+      "南城县",
+      "黎川县",
+      "南丰县",
+      "崇仁县",
+      "乐安县",
+      "宜黄县",
+      "金溪县",
+      "资溪县",
+      "广昌县"
+    ],
+    "上饶市": [
+      "信州区",
+      "广丰区",
+      "上饶县",
+      "玉山县",
+      "铅山县",
+      "横峰县",
+      "弋阳县",
+      "余干县",
+      "鄱阳县",
+      "万年县",
+      "婺源县",
+      "德兴市"
+    ]
+  },
+  "山东省": {
+    "济南市": [
+      "历下区",
+      "市中区",
+      "槐荫区",
+      "天桥区",
+      "历城区",
+      "长清区",
+      "章丘区",
+      "济阳区",
+      "平阴县",
+      "商河县",
+      "济南高新技术产业开发区"
+    ],
+    "青岛市": [
+      "市南区",
+      "市北区",
+      "黄岛区",
+      "崂山区",
+      "李沧区",
+      "城阳区",
+      "即墨区",
+      "青岛高新技术产业开发区",
+      "胶州市",
+      "平度市",
+      "莱西市"
+    ],
+    "淄博市": [
+      "淄川区",
+      "张店区",
+      "博山区",
+      "临淄区",
+      "周村区",
+      "桓台县",
+      "高青县",
+      "沂源县"
+    ],
+    "枣庄市": [
+      "市中区",
+      "薛城区",
+      "峄城区",
+      "台儿庄区",
+      "山亭区",
+      "滕州市"
+    ],
+    "东营市": [
+      "东营区",
+      "河口区",
+      "垦利区",
+      "利津县",
+      "广饶县",
+      "东营经济技术开发区",
+      "东营港经济开发区"
+    ],
+    "烟台市": [
+      "芝罘区",
+      "福山区",
+      "牟平区",
+      "莱山区",
+      "长岛县",
+      "烟台高新技术产业开发区",
+      "烟台经济技术开发区",
+      "龙口市",
+      "莱阳市",
+      "莱州市",
+      "蓬莱市",
+      "招远市",
+      "栖霞市",
+      "海阳市"
+    ],
+    "潍坊市": [
+      "潍城区",
+      "寒亭区",
+      "坊子区",
+      "奎文区",
+      "临朐县",
+      "昌乐县",
+      "潍坊滨海经济技术开发区",
+      "青州市",
+      "诸城市",
+      "寿光市",
+      "安丘市",
+      "高密市",
+      "昌邑市"
+    ],
+    "济宁市": [
+      "任城区",
+      "兖州区",
+      "微山县",
+      "鱼台县",
+      "金乡县",
+      "嘉祥县",
+      "汶上县",
+      "泗水县",
+      "梁山县",
+      "济宁高新技术产业开发区",
+      "曲阜市",
+      "邹城市"
+    ],
+    "泰安市": [
+      "泰山区",
+      "岱岳区",
+      "宁阳县",
+      "东平县",
+      "新泰市",
+      "肥城市"
+    ],
+    "威海市": [
+      "环翠区",
+      "文登区",
+      "威海火炬高技术产业开发区",
+      "威海经济技术开发区",
+      "威海临港经济技术开发区",
+      "荣成市",
+      "乳山市"
+    ],
+    "日照市": [
+      "东港区",
+      "岚山区",
+      "五莲县",
+      "莒县",
+      "日照经济技术开发区"
+    ],
+    "莱芜市": [
+      "莱城区",
+      "钢城区"
+    ],
+    "临沂市": [
+      "兰山区",
+      "罗庄区",
+      "河东区",
+      "沂南县",
+      "郯城县",
+      "沂水县",
+      "兰陵县",
+      "费县",
+      "平邑县",
+      "莒南县",
+      "蒙阴县",
+      "临沭县",
+      "临沂高新技术产业开发区",
+      "临沂经济技术开发区",
+      "临沂临港经济开发区"
+    ],
+    "德州市": [
+      "德城区",
+      "陵城区",
+      "宁津县",
+      "庆云县",
+      "临邑县",
+      "齐河县",
+      "平原县",
+      "夏津县",
+      "武城县",
+      "德州经济技术开发区",
+      "德州运河经济开发区",
+      "乐陵市",
+      "禹城市"
+    ],
+    "聊城市": [
+      "东昌府区",
+      "阳谷县",
+      "莘县",
+      "茌平县",
+      "东阿县",
+      "冠县",
+      "高唐县",
+      "临清市"
+    ],
+    "滨州市": [
+      "滨城区",
+      "沾化区",
+      "惠民县",
+      "阳信县",
+      "无棣县",
+      "博兴县",
+      "邹平市"
+    ],
+    "菏泽市": [
+      "牡丹区",
+      "定陶区",
+      "曹县",
+      "单县",
+      "成武县",
+      "巨野县",
+      "郓城县",
+      "鄄城县",
+      "东明县",
+      "菏泽经济技术开发区",
+      "菏泽高新技术开发区"
+    ]
+  },
+  "河南省": {
+    "郑州市": [
+      "中原区",
+      "二七区",
+      "管城回族区",
+      "金水区",
+      "上街区",
+      "惠济区",
+      "中牟县",
+      "郑州经济技术开发区",
+      "郑州高新技术产业开发区",
+      "郑州航空港经济综合实验区",
+      "巩义市",
+      "荥阳市",
+      "新密市",
+      "新郑市",
+      "登封市"
+    ],
+    "开封市": [
+      "龙亭区",
+      "顺河回族区",
+      "鼓楼区",
+      "禹王台区",
+      "祥符区",
+      "杞县",
+      "通许县",
+      "尉氏县",
+      "兰考县"
+    ],
+    "洛阳市": [
+      "老城区",
+      "西工区",
+      "瀍河回族区",
+      "涧西区",
+      "吉利区",
+      "洛龙区",
+      "孟津县",
+      "新安县",
+      "栾川县",
+      "嵩县",
+      "汝阳县",
+      "宜阳县",
+      "洛宁县",
+      "伊川县",
+      "洛阳高新技术产业开发区",
+      "偃师市"
+    ],
+    "平顶山市": [
+      "新华区",
+      "卫东区",
+      "石龙区",
+      "湛河区",
+      "宝丰县",
+      "叶县",
+      "鲁山县",
+      "郏县",
+      "平顶山高新技术产业开发区",
+      "平顶山市新城区",
+      "舞钢市",
+      "汝州市"
+    ],
+    "安阳市": [
+      "文峰区",
+      "北关区",
+      "殷都区",
+      "龙安区",
+      "安阳县",
+      "汤阴县",
+      "滑县",
+      "内黄县",
+      "安阳高新技术产业开发区",
+      "林州市"
+    ],
+    "鹤壁市": [
+      "鹤山区",
+      "山城区",
+      "淇滨区",
+      "浚县",
+      "淇县",
+      "鹤壁经济技术开发区"
+    ],
+    "新乡市": [
+      "红旗区",
+      "卫滨区",
+      "凤泉区",
+      "牧野区",
+      "新乡县",
+      "获嘉县",
+      "原阳县",
+      "延津县",
+      "封丘县",
+      "长垣县",
+      "新乡高新技术产业开发区",
+      "新乡经济技术开发区",
+      "新乡市平原城乡一体化示范区",
+      "卫辉市",
+      "辉县市"
+    ],
+    "焦作市": [
+      "解放区",
+      "中站区",
+      "马村区",
+      "山阳区",
+      "修武县",
+      "博爱县",
+      "武陟县",
+      "温县",
+      "焦作城乡一体化示范区",
+      "沁阳市",
+      "孟州市"
+    ],
+    "濮阳市": [
+      "华龙区",
+      "清丰县",
+      "南乐县",
+      "范县",
+      "台前县",
+      "濮阳县",
+      "河南濮阳工业园区",
+      "濮阳经济技术开发区"
+    ],
+    "许昌市": [
+      "魏都区",
+      "建安区",
+      "鄢陵县",
+      "襄城县",
+      "许昌经济技术开发区",
+      "禹州市",
+      "长葛市"
+    ],
+    "漯河市": [
+      "源汇区",
+      "郾城区",
+      "召陵区",
+      "舞阳县",
+      "临颍县",
+      "漯河经济技术开发区"
+    ],
+    "三门峡市": [
+      "湖滨区",
+      "陕州区",
+      "渑池县",
+      "卢氏县",
+      "河南三门峡经济开发区",
+      "义马市",
+      "灵宝市"
+    ],
+    "南阳市": [
+      "宛城区",
+      "卧龙区",
+      "南召县",
+      "方城县",
+      "西峡县",
+      "镇平县",
+      "内乡县",
+      "淅川县",
+      "社旗县",
+      "唐河县",
+      "新野县",
+      "桐柏县",
+      "南阳高新技术产业开发区",
+      "南阳市城乡一体化示范区",
+      "邓州市"
+    ],
+    "商丘市": [
+      "梁园区",
+      "睢阳区",
+      "民权县",
+      "睢县",
+      "宁陵县",
+      "柘城县",
+      "虞城县",
+      "夏邑县",
+      "豫东综合物流产业聚集区",
+      "河南商丘经济开发区",
+      "永城市"
+    ],
+    "信阳市": [
+      "浉河区",
+      "平桥区",
+      "罗山县",
+      "光山县",
+      "新县",
+      "商城县",
+      "固始县",
+      "潢川县",
+      "淮滨县",
+      "息县",
+      "信阳高新技术产业开发区"
+    ],
+    "周口市": [
+      "川汇区",
+      "扶沟县",
+      "西华县",
+      "商水县",
+      "沈丘县",
+      "郸城县",
+      "淮阳县",
+      "太康县",
+      "鹿邑县",
+      "河南周口经济开发区",
+      "项城市"
+    ],
+    "驻马店市": [
+      "驿城区",
+      "西平县",
+      "上蔡县",
+      "平舆县",
+      "正阳县",
+      "确山县",
+      "泌阳县",
+      "汝南县",
+      "遂平县",
+      "新蔡县",
+      "河南驻马店经济开发区"
+    ],
+    "省直辖县级行政区划": [
+      "济源市"
+    ]
+  },
+  "湖北省": {
+    "武汉市": [
+      "江岸区",
+      "江汉区",
+      "硚口区",
+      "汉阳区",
+      "武昌区",
+      "青山区",
+      "洪山区",
+      "东西湖区",
+      "汉南区",
+      "蔡甸区",
+      "江夏区",
+      "黄陂区",
+      "新洲区"
+    ],
+    "黄石市": [
+      "黄石港区",
+      "西塞山区",
+      "下陆区",
+      "铁山区",
+      "阳新县",
+      "大冶市"
+    ],
+    "十堰市": [
+      "茅箭区",
+      "张湾区",
+      "郧阳区",
+      "郧西县",
+      "竹山县",
+      "竹溪县",
+      "房县",
+      "丹江口市"
+    ],
+    "宜昌市": [
+      "西陵区",
+      "伍家岗区",
+      "点军区",
+      "猇亭区",
+      "夷陵区",
+      "远安县",
+      "兴山县",
+      "秭归县",
+      "长阳土家族自治县",
+      "五峰土家族自治县",
+      "宜都市",
+      "当阳市",
+      "枝江市"
+    ],
+    "襄阳市": [
+      "襄城区",
+      "樊城区",
+      "襄州区",
+      "南漳县",
+      "谷城县",
+      "保康县",
+      "老河口市",
+      "枣阳市",
+      "宜城市"
+    ],
+    "鄂州市": [
+      "梁子湖区",
+      "华容区",
+      "鄂城区"
+    ],
+    "荆门市": [
+      "东宝区",
+      "掇刀区",
+      "沙洋县",
+      "钟祥市",
+      "京山市"
+    ],
+    "孝感市": [
+      "孝南区",
+      "孝昌县",
+      "大悟县",
+      "云梦县",
+      "应城市",
+      "安陆市",
+      "汉川市"
+    ],
+    "荆州市": [
+      "沙市区",
+      "荆州区",
+      "公安县",
+      "监利县",
+      "江陵县",
+      "荆州经济技术开发区",
+      "石首市",
+      "洪湖市",
+      "松滋市"
+    ],
+    "黄冈市": [
+      "黄州区",
+      "团风县",
+      "红安县",
+      "罗田县",
+      "英山县",
+      "浠水县",
+      "蕲春县",
+      "黄梅县",
+      "龙感湖管理区",
+      "麻城市",
+      "武穴市"
+    ],
+    "咸宁市": [
+      "咸安区",
+      "嘉鱼县",
+      "通城县",
+      "崇阳县",
+      "通山县",
+      "赤壁市"
+    ],
+    "随州市": [
+      "曾都区",
+      "随县",
+      "广水市"
+    ],
+    "恩施土家族苗族自治州": [
+      "恩施市",
+      "利川市",
+      "建始县",
+      "巴东县",
+      "宣恩县",
+      "咸丰县",
+      "来凤县",
+      "鹤峰县"
+    ],
+    "省直辖县级行政区划": [
+      "仙桃市",
+      "潜江市",
+      "天门市",
+      "神农架林区"
+    ]
+  },
+  "湖南省": {
+    "长沙市": [
+      "芙蓉区",
+      "天心区",
+      "岳麓区",
+      "开福区",
+      "雨花区",
+      "望城区",
+      "长沙县",
+      "浏阳市",
+      "宁乡市"
+    ],
+    "株洲市": [
+      "荷塘区",
+      "芦淞区",
+      "石峰区",
+      "天元区",
+      "渌口区",
+      "攸县",
+      "茶陵县",
+      "炎陵县",
+      "云龙示范区",
+      "醴陵市"
+    ],
+    "湘潭市": [
+      "雨湖区",
+      "岳塘区",
+      "湘潭县",
+      "湖南湘潭高新技术产业园区",
+      "湘潭昭山示范区",
+      "湘潭九华示范区",
+      "湘乡市",
+      "韶山市"
+    ],
+    "衡阳市": [
+      "珠晖区",
+      "雁峰区",
+      "石鼓区",
+      "蒸湘区",
+      "南岳区",
+      "衡阳县",
+      "衡南县",
+      "衡山县",
+      "衡东县",
+      "祁东县",
+      "衡阳综合保税区",
+      "湖南衡阳高新技术产业园区",
+      "湖南衡阳松木经济开发区",
+      "耒阳市",
+      "常宁市"
+    ],
+    "邵阳市": [
+      "双清区",
+      "大祥区",
+      "北塔区",
+      "邵东县",
+      "新邵县",
+      "邵阳县",
+      "隆回县",
+      "洞口县",
+      "绥宁县",
+      "新宁县",
+      "城步苗族自治县",
+      "武冈市"
+    ],
+    "岳阳市": [
+      "岳阳楼区",
+      "云溪区",
+      "君山区",
+      "岳阳县",
+      "华容县",
+      "湘阴县",
+      "平江县",
+      "岳阳市屈原管理区",
+      "汨罗市",
+      "临湘市"
+    ],
+    "常德市": [
+      "武陵区",
+      "鼎城区",
+      "安乡县",
+      "汉寿县",
+      "澧县",
+      "临澧县",
+      "桃源县",
+      "石门县",
+      "常德市西洞庭管理区",
+      "津市市"
+    ],
+    "张家界市": [
+      "永定区",
+      "武陵源区",
+      "慈利县",
+      "桑植县"
+    ],
+    "益阳市": [
+      "资阳区",
+      "赫山区",
+      "南县",
+      "桃江县",
+      "安化县",
+      "益阳市大通湖管理区",
+      "湖南益阳高新技术产业园区",
+      "沅江市"
+    ],
+    "郴州市": [
+      "北湖区",
+      "苏仙区",
+      "桂阳县",
+      "宜章县",
+      "永兴县",
+      "嘉禾县",
+      "临武县",
+      "汝城县",
+      "桂东县",
+      "安仁县",
+      "资兴市"
+    ],
+    "永州市": [
+      "零陵区",
+      "冷水滩区",
+      "祁阳县",
+      "东安县",
+      "双牌县",
+      "道县",
+      "江永县",
+      "宁远县",
+      "蓝山县",
+      "新田县",
+      "江华瑶族自治县",
+      "永州经济技术开发区",
+      "永州市金洞管理区",
+      "永州市回龙圩管理区"
+    ],
+    "怀化市": [
+      "鹤城区",
+      "中方县",
+      "沅陵县",
+      "辰溪县",
+      "溆浦县",
+      "会同县",
+      "麻阳苗族自治县",
+      "新晃侗族自治县",
+      "芷江侗族自治县",
+      "靖州苗族侗族自治县",
+      "通道侗族自治县",
+      "怀化市洪江管理区",
+      "洪江市"
+    ],
+    "娄底市": [
+      "娄星区",
+      "双峰县",
+      "新化县",
+      "冷水江市",
+      "涟源市"
+    ],
+    "湘西土家族苗族自治州": [
+      "吉首市",
+      "泸溪县",
+      "凤凰县",
+      "花垣县",
+      "保靖县",
+      "古丈县",
+      "永顺县",
+      "龙山县",
+      "湖南吉首经济开发区",
+      "湖南永顺经济开发区"
+    ]
+  },
+  "广东省": {
+    "广州市": [
+      "荔湾区",
+      "越秀区",
+      "海珠区",
+      "天河区",
+      "白云区",
+      "黄埔区",
+      "番禺区",
+      "花都区",
+      "南沙区",
+      "从化区",
+      "增城区"
+    ],
+    "韶关市": [
+      "武江区",
+      "浈江区",
+      "曲江区",
+      "始兴县",
+      "仁化县",
+      "翁源县",
+      "乳源瑶族自治县",
+      "新丰县",
+      "乐昌市",
+      "南雄市"
+    ],
+    "深圳市": [
+      "罗湖区",
+      "福田区",
+      "南山区",
+      "宝安区",
+      "龙岗区",
+      "盐田区",
+      "龙华区",
+      "坪山区",
+      "光明区"
+    ],
+    "珠海市": [
+      "香洲区",
+      "斗门区",
+      "金湾区"
+    ],
+    "汕头市": [
+      "龙湖区",
+      "金平区",
+      "濠江区",
+      "潮阳区",
+      "潮南区",
+      "澄海区",
+      "南澳县"
+    ],
+    "佛山市": [
+      "禅城区",
+      "南海区",
+      "顺德区",
+      "三水区",
+      "高明区"
+    ],
+    "江门市": [
+      "蓬江区",
+      "江海区",
+      "新会区",
+      "台山市",
+      "开平市",
+      "鹤山市",
+      "恩平市"
+    ],
+    "湛江市": [
+      "赤坎区",
+      "霞山区",
+      "坡头区",
+      "麻章区",
+      "遂溪县",
+      "徐闻县",
+      "廉江市",
+      "雷州市",
+      "吴川市"
+    ],
+    "茂名市": [
+      "茂南区",
+      "电白区",
+      "高州市",
+      "化州市",
+      "信宜市"
+    ],
+    "肇庆市": [
+      "端州区",
+      "鼎湖区",
+      "高要区",
+      "广宁县",
+      "怀集县",
+      "封开县",
+      "德庆县",
+      "四会市"
+    ],
+    "惠州市": [
+      "惠城区",
+      "惠阳区",
+      "博罗县",
+      "惠东县",
+      "龙门县"
+    ],
+    "梅州市": [
+      "梅江区",
+      "梅县区",
+      "大埔县",
+      "丰顺县",
+      "五华县",
+      "平远县",
+      "蕉岭县",
+      "兴宁市"
+    ],
+    "汕尾市": [
+      "城区",
+      "海丰县",
+      "陆河县",
+      "陆丰市"
+    ],
+    "河源市": [
+      "源城区",
+      "紫金县",
+      "龙川县",
+      "连平县",
+      "和平县",
+      "东源县"
+    ],
+    "阳江市": [
+      "江城区",
+      "阳东区",
+      "阳西县",
+      "阳春市"
+    ],
+    "清远市": [
+      "清城区",
+      "清新区",
+      "佛冈县",
+      "阳山县",
+      "连山壮族瑶族自治县",
+      "连南瑶族自治县",
+      "英德市",
+      "连州市"
+    ],
+    "东莞市": [
+      "东城街道",
+      "南城街道",
+      "万江街道",
+      "莞城街道",
+      "石碣镇",
+      "石龙镇",
+      "茶山镇",
+      "石排镇",
+      "企石镇",
+      "横沥镇",
+      "桥头镇",
+      "谢岗镇",
+      "东坑镇",
+      "常平镇",
+      "寮步镇",
+      "樟木头镇",
+      "大朗镇",
+      "黄江镇",
+      "清溪镇",
+      "塘厦镇",
+      "凤岗镇",
+      "大岭山镇",
+      "长安镇",
+      "虎门镇",
+      "厚街镇",
+      "沙田镇",
+      "道滘镇",
+      "洪梅镇",
+      "麻涌镇",
+      "望牛墩镇",
+      "中堂镇",
+      "高埗镇",
+      "松山湖管委会",
+      "东莞港",
+      "东莞生态园"
+    ],
+    "中山市": [
+      "石岐区街道",
+      "东区街道",
+      "火炬开发区街道",
+      "西区街道",
+      "南区街道",
+      "五桂山街道",
+      "小榄镇",
+      "黄圃镇",
+      "民众镇",
+      "东凤镇",
+      "东升镇",
+      "古镇镇",
+      "沙溪镇",
+      "坦洲镇",
+      "港口镇",
+      "三角镇",
+      "横栏镇",
+      "南头镇",
+      "阜沙镇",
+      "南朗镇",
+      "三乡镇",
+      "板芙镇",
+      "大涌镇",
+      "神湾镇"
+    ],
+    "潮州市": [
+      "湘桥区",
+      "潮安区",
+      "饶平县"
+    ],
+    "揭阳市": [
+      "榕城区",
+      "揭东区",
+      "揭西县",
+      "惠来县",
+      "普宁市"
+    ],
+    "云浮市": [
+      "云城区",
+      "云安区",
+      "新兴县",
+      "郁南县",
+      "罗定市"
+    ]
+  },
+  "广西壮族自治区": {
+    "南宁市": [
+      "兴宁区",
+      "青秀区",
+      "江南区",
+      "西乡塘区",
+      "良庆区",
+      "邕宁区",
+      "武鸣区",
+      "隆安县",
+      "马山县",
+      "上林县",
+      "宾阳县",
+      "横县"
+    ],
+    "柳州市": [
+      "城中区",
+      "鱼峰区",
+      "柳南区",
+      "柳北区",
+      "柳江区",
+      "柳城县",
+      "鹿寨县",
+      "融安县",
+      "融水苗族自治县",
+      "三江侗族自治县"
+    ],
+    "桂林市": [
+      "秀峰区",
+      "叠彩区",
+      "象山区",
+      "七星区",
+      "雁山区",
+      "临桂区",
+      "阳朔县",
+      "灵川县",
+      "全州县",
+      "兴安县",
+      "永福县",
+      "灌阳县",
+      "龙胜各族自治县",
+      "资源县",
+      "平乐县",
+      "恭城瑶族自治县",
+      "荔浦市"
+    ],
+    "梧州市": [
+      "万秀区",
+      "长洲区",
+      "龙圩区",
+      "苍梧县",
+      "藤县",
+      "蒙山县",
+      "岑溪市"
+    ],
+    "北海市": [
+      "海城区",
+      "银海区",
+      "铁山港区",
+      "合浦县"
+    ],
+    "防城港市": [
+      "港口区",
+      "防城区",
+      "上思县",
+      "东兴市"
+    ],
+    "钦州市": [
+      "钦南区",
+      "钦北区",
+      "灵山县",
+      "浦北县"
+    ],
+    "贵港市": [
+      "港北区",
+      "港南区",
+      "覃塘区",
+      "平南县",
+      "桂平市"
+    ],
+    "玉林市": [
+      "玉州区",
+      "福绵区",
+      "容县",
+      "陆川县",
+      "博白县",
+      "兴业县",
+      "北流市"
+    ],
+    "百色市": [
+      "右江区",
+      "田阳县",
+      "田东县",
+      "平果县",
+      "德保县",
+      "那坡县",
+      "凌云县",
+      "乐业县",
+      "田林县",
+      "西林县",
+      "隆林各族自治县",
+      "靖西市"
+    ],
+    "贺州市": [
+      "八步区",
+      "平桂区",
+      "昭平县",
+      "钟山县",
+      "富川瑶族自治县"
+    ],
+    "河池市": [
+      "金城江区",
+      "宜州区",
+      "南丹县",
+      "天峨县",
+      "凤山县",
+      "东兰县",
+      "罗城仫佬族自治县",
+      "环江毛南族自治县",
+      "巴马瑶族自治县",
+      "都安瑶族自治县",
+      "大化瑶族自治县"
+    ],
+    "来宾市": [
+      "兴宾区",
+      "忻城县",
+      "象州县",
+      "武宣县",
+      "金秀瑶族自治县",
+      "合山市"
+    ],
+    "崇左市": [
+      "江州区",
+      "扶绥县",
+      "宁明县",
+      "龙州县",
+      "大新县",
+      "天等县",
+      "凭祥市"
+    ]
+  },
+  "海南省": {
+    "海口市": [
+      "秀英区",
+      "龙华区",
+      "琼山区",
+      "美兰区"
+    ],
+    "三亚市": [
+      "海棠区",
+      "吉阳区",
+      "天涯区",
+      "崖州区"
+    ],
+    "三沙市": [
+      "西沙群岛",
+      "南沙群岛",
+      "中沙群岛的岛礁及其海域"
+    ],
+    "儋州市": [
+      "那大镇",
+      "和庆镇",
+      "南丰镇",
+      "大成镇",
+      "雅星镇",
+      "兰洋镇",
+      "光村镇",
+      "木棠镇",
+      "海头镇",
+      "峨蔓镇",
+      "王五镇",
+      "白马井镇",
+      "中和镇",
+      "排浦镇",
+      "东成镇",
+      "新州镇",
+      "洋浦经济开发区",
+      "华南热作学院"
+    ],
+    "省直辖县级行政区划": [
+      "五指山市",
+      "琼海市",
+      "文昌市",
+      "万宁市",
+      "东方市",
+      "定安县",
+      "屯昌县",
+      "澄迈县",
+      "临高县",
+      "白沙黎族自治县",
+      "昌江黎族自治县",
+      "乐东黎族自治县",
+      "陵水黎族自治县",
+      "保亭黎族苗族自治县",
+      "琼中黎族苗族自治县"
+    ]
+  },
+  "重庆市": {
+    "市辖区": [
+      "万州区",
+      "涪陵区",
+      "渝中区",
+      "大渡口区",
+      "江北区",
+      "沙坪坝区",
+      "九龙坡区",
+      "南岸区",
+      "北碚区",
+      "綦江区",
+      "大足区",
+      "渝北区",
+      "巴南区",
+      "黔江区",
+      "长寿区",
+      "江津区",
+      "合川区",
+      "永川区",
+      "南川区",
+      "璧山区",
+      "铜梁区",
+      "潼南区",
+      "荣昌区",
+      "开州区",
+      "梁平区",
+      "武隆区"
+    ],
+    "县": [
+      "城口县",
+      "丰都县",
+      "垫江县",
+      "忠县",
+      "云阳县",
+      "奉节县",
+      "巫山县",
+      "巫溪县",
+      "石柱土家族自治县",
+      "秀山土家族苗族自治县",
+      "酉阳土家族苗族自治县",
+      "彭水苗族土家族自治县"
+    ]
+  },
+  "四川省": {
+    "成都市": [
+      "锦江区",
+      "青羊区",
+      "金牛区",
+      "武侯区",
+      "成华区",
+      "龙泉驿区",
+      "青白江区",
+      "新都区",
+      "温江区",
+      "双流区",
+      "郫都区",
+      "金堂县",
+      "大邑县",
+      "蒲江县",
+      "新津县",
+      "都江堰市",
+      "彭州市",
+      "邛崃市",
+      "崇州市",
+      "简阳市"
+    ],
+    "自贡市": [
+      "自流井区",
+      "贡井区",
+      "大安区",
+      "沿滩区",
+      "荣县",
+      "富顺县"
+    ],
+    "攀枝花市": [
+      "东区",
+      "西区",
+      "仁和区",
+      "米易县",
+      "盐边县"
+    ],
+    "泸州市": [
+      "江阳区",
+      "纳溪区",
+      "龙马潭区",
+      "泸县",
+      "合江县",
+      "叙永县",
+      "古蔺县"
+    ],
+    "德阳市": [
+      "旌阳区",
+      "罗江区",
+      "中江县",
+      "广汉市",
+      "什邡市",
+      "绵竹市"
+    ],
+    "绵阳市": [
+      "涪城区",
+      "游仙区",
+      "安州区",
+      "三台县",
+      "盐亭县",
+      "梓潼县",
+      "北川羌族自治县",
+      "平武县",
+      "江油市"
+    ],
+    "广元市": [
+      "利州区",
+      "昭化区",
+      "朝天区",
+      "旺苍县",
+      "青川县",
+      "剑阁县",
+      "苍溪县"
+    ],
+    "遂宁市": [
+      "船山区",
+      "安居区",
+      "蓬溪县",
+      "射洪县",
+      "大英县"
+    ],
+    "内江市": [
+      "市中区",
+      "东兴区",
+      "威远县",
+      "资中县",
+      "内江经济开发区",
+      "隆昌市"
+    ],
+    "乐山市": [
+      "市中区",
+      "沙湾区",
+      "五通桥区",
+      "金口河区",
+      "犍为县",
+      "井研县",
+      "夹江县",
+      "沐川县",
+      "峨边彝族自治县",
+      "马边彝族自治县",
+      "峨眉山市"
+    ],
+    "南充市": [
+      "顺庆区",
+      "高坪区",
+      "嘉陵区",
+      "南部县",
+      "营山县",
+      "蓬安县",
+      "仪陇县",
+      "西充县",
+      "阆中市"
+    ],
+    "眉山市": [
+      "东坡区",
+      "彭山区",
+      "仁寿县",
+      "洪雅县",
+      "丹棱县",
+      "青神县"
+    ],
+    "宜宾市": [
+      "翠屏区",
+      "南溪区",
+      "叙州区",
+      "江安县",
+      "长宁县",
+      "高县",
+      "珙县",
+      "筠连县",
+      "兴文县",
+      "屏山县"
+    ],
+    "广安市": [
+      "广安区",
+      "前锋区",
+      "岳池县",
+      "武胜县",
+      "邻水县",
+      "华蓥市"
+    ],
+    "达州市": [
+      "通川区",
+      "达川区",
+      "宣汉县",
+      "开江县",
+      "大竹县",
+      "渠县",
+      "达州经济开发区",
+      "万源市"
+    ],
+    "雅安市": [
+      "雨城区",
+      "名山区",
+      "荥经县",
+      "汉源县",
+      "石棉县",
+      "天全县",
+      "芦山县",
+      "宝兴县"
+    ],
+    "巴中市": [
+      "巴州区",
+      "恩阳区",
+      "通江县",
+      "南江县",
+      "平昌县",
+      "巴中经济开发区"
+    ],
+    "资阳市": [
+      "雁江区",
+      "安岳县",
+      "乐至县"
+    ],
+    "阿坝藏族羌族自治州": [
+      "马尔康市",
+      "汶川县",
+      "理县",
+      "茂县",
+      "松潘县",
+      "九寨沟县",
+      "金川县",
+      "小金县",
+      "黑水县",
+      "壤塘县",
+      "阿坝县",
+      "若尔盖县",
+      "红原县"
+    ],
+    "甘孜藏族自治州": [
+      "康定市",
+      "泸定县",
+      "丹巴县",
+      "九龙县",
+      "雅江县",
+      "道孚县",
+      "炉霍县",
+      "甘孜县",
+      "新龙县",
+      "德格县",
+      "白玉县",
+      "石渠县",
+      "色达县",
+      "理塘县",
+      "巴塘县",
+      "乡城县",
+      "稻城县",
+      "得荣县"
+    ],
+    "凉山彝族自治州": [
+      "西昌市",
+      "木里藏族自治县",
+      "盐源县",
+      "德昌县",
+      "会理县",
+      "会东县",
+      "宁南县",
+      "普格县",
+      "布拖县",
+      "金阳县",
+      "昭觉县",
+      "喜德县",
+      "冕宁县",
+      "越西县",
+      "甘洛县",
+      "美姑县",
+      "雷波县"
+    ]
+  },
+  "贵州省": {
+    "贵阳市": [
+      "南明区",
+      "云岩区",
+      "花溪区",
+      "乌当区",
+      "白云区",
+      "观山湖区",
+      "开阳县",
+      "息烽县",
+      "修文县",
+      "清镇市"
+    ],
+    "六盘水市": [
+      "钟山区",
+      "六枝特区",
+      "水城县",
+      "盘州市"
+    ],
+    "遵义市": [
+      "红花岗区",
+      "汇川区",
+      "播州区",
+      "桐梓县",
+      "绥阳县",
+      "正安县",
+      "道真仡佬族苗族自治县",
+      "务川仡佬族苗族自治县",
+      "凤冈县",
+      "湄潭县",
+      "余庆县",
+      "习水县",
+      "赤水市",
+      "仁怀市"
+    ],
+    "安顺市": [
+      "西秀区",
+      "平坝区",
+      "普定县",
+      "镇宁布依族苗族自治县",
+      "关岭布依族苗族自治县",
+      "紫云苗族布依族自治县"
+    ],
+    "毕节市": [
+      "七星关区",
+      "大方县",
+      "黔西县",
+      "金沙县",
+      "织金县",
+      "纳雍县",
+      "威宁彝族回族苗族自治县",
+      "赫章县"
+    ],
+    "铜仁市": [
+      "碧江区",
+      "万山区",
+      "江口县",
+      "玉屏侗族自治县",
+      "石阡县",
+      "思南县",
+      "印江土家族苗族自治县",
+      "德江县",
+      "沿河土家族自治县",
+      "松桃苗族自治县"
+    ],
+    "黔西南布依族苗族自治州": [
+      "兴义市",
+      "兴仁市",
+      "普安县",
+      "晴隆县",
+      "贞丰县",
+      "望谟县",
+      "册亨县",
+      "安龙县"
+    ],
+    "黔东南苗族侗族自治州": [
+      "凯里市",
+      "黄平县",
+      "施秉县",
+      "三穗县",
+      "镇远县",
+      "岑巩县",
+      "天柱县",
+      "锦屏县",
+      "剑河县",
+      "台江县",
+      "黎平县",
+      "榕江县",
+      "从江县",
+      "雷山县",
+      "麻江县",
+      "丹寨县"
+    ],
+    "黔南布依族苗族自治州": [
+      "都匀市",
+      "福泉市",
+      "荔波县",
+      "贵定县",
+      "瓮安县",
+      "独山县",
+      "平塘县",
+      "罗甸县",
+      "长顺县",
+      "龙里县",
+      "惠水县",
+      "三都水族自治县"
+    ]
+  },
+  "云南省": {
+    "昆明市": [
+      "五华区",
+      "盘龙区",
+      "官渡区",
+      "西山区",
+      "东川区",
+      "呈贡区",
+      "晋宁区",
+      "富民县",
+      "宜良县",
+      "石林彝族自治县",
+      "嵩明县",
+      "禄劝彝族苗族自治县",
+      "寻甸回族彝族自治县",
+      "安宁市"
+    ],
+    "曲靖市": [
+      "麒麟区",
+      "沾益区",
+      "马龙区",
+      "陆良县",
+      "师宗县",
+      "罗平县",
+      "富源县",
+      "会泽县",
+      "宣威市"
+    ],
+    "玉溪市": [
+      "红塔区",
+      "江川区",
+      "澄江县",
+      "通海县",
+      "华宁县",
+      "易门县",
+      "峨山彝族自治县",
+      "新平彝族傣族自治县",
+      "元江哈尼族彝族傣族自治县"
+    ],
+    "保山市": [
+      "隆阳区",
+      "施甸县",
+      "龙陵县",
+      "昌宁县",
+      "腾冲市"
+    ],
+    "昭通市": [
+      "昭阳区",
+      "鲁甸县",
+      "巧家县",
+      "盐津县",
+      "大关县",
+      "永善县",
+      "绥江县",
+      "镇雄县",
+      "彝良县",
+      "威信县",
+      "水富市"
+    ],
+    "丽江市": [
+      "古城区",
+      "玉龙纳西族自治县",
+      "永胜县",
+      "华坪县",
+      "宁蒗彝族自治县"
+    ],
+    "普洱市": [
+      "思茅区",
+      "宁洱哈尼族彝族自治县",
+      "墨江哈尼族自治县",
+      "景东彝族自治县",
+      "景谷傣族彝族自治县",
+      "镇沅彝族哈尼族拉祜族自治县",
+      "江城哈尼族彝族自治县",
+      "孟连傣族拉祜族佤族自治县",
+      "澜沧拉祜族自治县",
+      "西盟佤族自治县"
+    ],
+    "临沧市": [
+      "临翔区",
+      "凤庆县",
+      "云县",
+      "永德县",
+      "镇康县",
+      "双江拉祜族佤族布朗族傣族自治县",
+      "耿马傣族佤族自治县",
+      "沧源佤族自治县"
+    ],
+    "楚雄彝族自治州": [
+      "楚雄市",
+      "双柏县",
+      "牟定县",
+      "南华县",
+      "姚安县",
+      "大姚县",
+      "永仁县",
+      "元谋县",
+      "武定县",
+      "禄丰县"
+    ],
+    "红河哈尼族彝族自治州": [
+      "个旧市",
+      "开远市",
+      "蒙自市",
+      "弥勒市",
+      "屏边苗族自治县",
+      "建水县",
+      "石屏县",
+      "泸西县",
+      "元阳县",
+      "红河县",
+      "金平苗族瑶族傣族自治县",
+      "绿春县",
+      "河口瑶族自治县"
+    ],
+    "文山壮族苗族自治州": [
+      "文山市",
+      "砚山县",
+      "西畴县",
+      "麻栗坡县",
+      "马关县",
+      "丘北县",
+      "广南县",
+      "富宁县"
+    ],
+    "西双版纳傣族自治州": [
+      "景洪市",
+      "勐海县",
+      "勐腊县"
+    ],
+    "大理白族自治州": [
+      "大理市",
+      "漾濞彝族自治县",
+      "祥云县",
+      "宾川县",
+      "弥渡县",
+      "南涧彝族自治县",
+      "巍山彝族回族自治县",
+      "永平县",
+      "云龙县",
+      "洱源县",
+      "剑川县",
+      "鹤庆县"
+    ],
+    "德宏傣族景颇族自治州": [
+      "瑞丽市",
+      "芒市",
+      "梁河县",
+      "盈江县",
+      "陇川县"
+    ],
+    "怒江傈僳族自治州": [
+      "泸水市",
+      "福贡县",
+      "贡山独龙族怒族自治县",
+      "兰坪白族普米族自治县"
+    ],
+    "迪庆藏族自治州": [
+      "香格里拉市",
+      "德钦县",
+      "维西傈僳族自治县"
+    ]
+  },
+  "西藏自治区": {
+    "拉萨市": [
+      "城关区",
+      "堆龙德庆区",
+      "达孜区",
+      "林周县",
+      "当雄县",
+      "尼木县",
+      "曲水县",
+      "墨竹工卡县",
+      "格尔木藏青工业园区",
+      "拉萨经济技术开发区",
+      "西藏文化旅游创意园区",
+      "达孜工业园区"
+    ],
+    "日喀则市": [
+      "桑珠孜区",
+      "南木林县",
+      "江孜县",
+      "定日县",
+      "萨迦县",
+      "拉孜县",
+      "昂仁县",
+      "谢通门县",
+      "白朗县",
+      "仁布县",
+      "康马县",
+      "定结县",
+      "仲巴县",
+      "亚东县",
+      "吉隆县",
+      "聂拉木县",
+      "萨嘎县",
+      "岗巴县"
+    ],
+    "昌都市": [
+      "卡若区",
+      "江达县",
+      "贡觉县",
+      "类乌齐县",
+      "丁青县",
+      "察雅县",
+      "八宿县",
+      "左贡县",
+      "芒康县",
+      "洛隆县",
+      "边坝县"
+    ],
+    "林芝市": [
+      "巴宜区",
+      "工布江达县",
+      "米林县",
+      "墨脱县",
+      "波密县",
+      "察隅县",
+      "朗县"
+    ],
+    "山南市": [
+      "乃东区",
+      "扎囊县",
+      "贡嘎县",
+      "桑日县",
+      "琼结县",
+      "曲松县",
+      "措美县",
+      "洛扎县",
+      "加查县",
+      "隆子县",
+      "错那县",
+      "浪卡子县"
+    ],
+    "那曲市": [
+      "色尼区",
+      "嘉黎县",
+      "比如县",
+      "聂荣县",
+      "安多县",
+      "申扎县",
+      "索县",
+      "班戈县",
+      "巴青县",
+      "尼玛县",
+      "双湖县"
+    ],
+    "阿里地区": [
+      "普兰县",
+      "札达县",
+      "噶尔县",
+      "日土县",
+      "革吉县",
+      "改则县",
+      "措勤县"
+    ]
+  },
+  "陕西省": {
+    "西安市": [
+      "新城区",
+      "碑林区",
+      "莲湖区",
+      "灞桥区",
+      "未央区",
+      "雁塔区",
+      "阎良区",
+      "临潼区",
+      "长安区",
+      "高陵区",
+      "鄠邑区",
+      "蓝田县",
+      "周至县"
+    ],
+    "铜川市": [
+      "王益区",
+      "印台区",
+      "耀州区",
+      "宜君县"
+    ],
+    "宝鸡市": [
+      "渭滨区",
+      "金台区",
+      "陈仓区",
+      "凤翔县",
+      "岐山县",
+      "扶风县",
+      "眉县",
+      "陇县",
+      "千阳县",
+      "麟游县",
+      "凤县",
+      "太白县"
+    ],
+    "咸阳市": [
+      "秦都区",
+      "杨陵区",
+      "渭城区",
+      "三原县",
+      "泾阳县",
+      "乾县",
+      "礼泉县",
+      "永寿县",
+      "长武县",
+      "旬邑县",
+      "淳化县",
+      "武功县",
+      "兴平市",
+      "彬州市"
+    ],
+    "渭南市": [
+      "临渭区",
+      "华州区",
+      "潼关县",
+      "大荔县",
+      "合阳县",
+      "澄城县",
+      "蒲城县",
+      "白水县",
+      "富平县",
+      "韩城市",
+      "华阴市"
+    ],
+    "延安市": [
+      "宝塔区",
+      "安塞区",
+      "延长县",
+      "延川县",
+      "子长县",
+      "志丹县",
+      "吴起县",
+      "甘泉县",
+      "富县",
+      "洛川县",
+      "宜川县",
+      "黄龙县",
+      "黄陵县"
+    ],
+    "汉中市": [
+      "汉台区",
+      "南郑区",
+      "城固县",
+      "洋县",
+      "西乡县",
+      "勉县",
+      "宁强县",
+      "略阳县",
+      "镇巴县",
+      "留坝县",
+      "佛坪县"
+    ],
+    "榆林市": [
+      "榆阳区",
+      "横山区",
+      "府谷县",
+      "靖边县",
+      "定边县",
+      "绥德县",
+      "米脂县",
+      "佳县",
+      "吴堡县",
+      "清涧县",
+      "子洲县",
+      "神木市"
+    ],
+    "安康市": [
+      "汉滨区",
+      "汉阴县",
+      "石泉县",
+      "宁陕县",
+      "紫阳县",
+      "岚皋县",
+      "平利县",
+      "镇坪县",
+      "旬阳县",
+      "白河县"
+    ],
+    "商洛市": [
+      "商州区",
+      "洛南县",
+      "丹凤县",
+      "商南县",
+      "山阳县",
+      "镇安县",
+      "柞水县"
+    ]
+  },
+  "甘肃省": {
+    "兰州市": [
+      "城关区",
+      "七里河区",
+      "西固区",
+      "安宁区",
+      "红古区",
+      "永登县",
+      "皋兰县",
+      "榆中县",
+      "兰州新区"
+    ],
+    "嘉峪关市": [
+      "新城镇",
+      "峪泉镇",
+      "文殊镇",
+      "雄关区",
+      "镜铁区",
+      "长城区"
+    ],
+    "金昌市": [
+      "金川区",
+      "永昌县"
+    ],
+    "白银市": [
+      "白银区",
+      "平川区",
+      "靖远县",
+      "会宁县",
+      "景泰县"
+    ],
+    "天水市": [
+      "秦州区",
+      "麦积区",
+      "清水县",
+      "秦安县",
+      "甘谷县",
+      "武山县",
+      "张家川回族自治县"
+    ],
+    "武威市": [
+      "凉州区",
+      "民勤县",
+      "古浪县",
+      "天祝藏族自治县"
+    ],
+    "张掖市": [
+      "甘州区",
+      "肃南裕固族自治县",
+      "民乐县",
+      "临泽县",
+      "高台县",
+      "山丹县"
+    ],
+    "平凉市": [
+      "崆峒区",
+      "泾川县",
+      "灵台县",
+      "崇信县",
+      "庄浪县",
+      "静宁县",
+      "华亭市"
+    ],
+    "酒泉市": [
+      "肃州区",
+      "金塔县",
+      "瓜州县",
+      "肃北蒙古族自治县",
+      "阿克塞哈萨克族自治县",
+      "玉门市",
+      "敦煌市"
+    ],
+    "庆阳市": [
+      "西峰区",
+      "庆城县",
+      "环县",
+      "华池县",
+      "合水县",
+      "正宁县",
+      "宁县",
+      "镇原县"
+    ],
+    "定西市": [
+      "安定区",
+      "通渭县",
+      "陇西县",
+      "渭源县",
+      "临洮县",
+      "漳县",
+      "岷县"
+    ],
+    "陇南市": [
+      "武都区",
+      "成县",
+      "文县",
+      "宕昌县",
+      "康县",
+      "西和县",
+      "礼县",
+      "徽县",
+      "两当县"
+    ],
+    "临夏回族自治州": [
+      "临夏市",
+      "临夏县",
+      "康乐县",
+      "永靖县",
+      "广河县",
+      "和政县",
+      "东乡族自治县",
+      "积石山保安族东乡族撒拉族自治县"
+    ],
+    "甘南藏族自治州": [
+      "合作市",
+      "临潭县",
+      "卓尼县",
+      "舟曲县",
+      "迭部县",
+      "玛曲县",
+      "碌曲县",
+      "夏河县"
+    ]
+  },
+  "青海省": {
+    "西宁市": [
+      "城东区",
+      "城中区",
+      "城西区",
+      "城北区",
+      "大通回族土族自治县",
+      "湟中县",
+      "湟源县"
+    ],
+    "海东市": [
+      "乐都区",
+      "平安区",
+      "民和回族土族自治县",
+      "互助土族自治县",
+      "化隆回族自治县",
+      "循化撒拉族自治县"
+    ],
+    "海北藏族自治州": [
+      "门源回族自治县",
+      "祁连县",
+      "海晏县",
+      "刚察县"
+    ],
+    "黄南藏族自治州": [
+      "同仁县",
+      "尖扎县",
+      "泽库县",
+      "河南蒙古族自治县"
+    ],
+    "海南藏族自治州": [
+      "共和县",
+      "同德县",
+      "贵德县",
+      "兴海县",
+      "贵南县"
+    ],
+    "果洛藏族自治州": [
+      "玛沁县",
+      "班玛县",
+      "甘德县",
+      "达日县",
+      "久治县",
+      "玛多县"
+    ],
+    "玉树藏族自治州": [
+      "玉树市",
+      "杂多县",
+      "称多县",
+      "治多县",
+      "囊谦县",
+      "曲麻莱县"
+    ],
+    "海西蒙古族藏族自治州": [
+      "格尔木市",
+      "德令哈市",
+      "茫崖市",
+      "乌兰县",
+      "都兰县",
+      "天峻县",
+      "大柴旦行政委员会"
+    ]
+  },
+  "宁夏回族自治区": {
+    "银川市": [
+      "兴庆区",
+      "西夏区",
+      "金凤区",
+      "永宁县",
+      "贺兰县",
+      "灵武市"
+    ],
+    "石嘴山市": [
+      "大武口区",
+      "惠农区",
+      "平罗县"
+    ],
+    "吴忠市": [
+      "利通区",
+      "红寺堡区",
+      "盐池县",
+      "同心县",
+      "青铜峡市"
+    ],
+    "固原市": [
+      "原州区",
+      "西吉县",
+      "隆德县",
+      "泾源县",
+      "彭阳县"
+    ],
+    "中卫市": [
+      "沙坡头区",
+      "中宁县",
+      "海原县"
+    ]
+  },
+  "新疆维吾尔自治区": {
+    "乌鲁木齐市": [
+      "天山区",
+      "沙依巴克区",
+      "新市区",
+      "水磨沟区",
+      "头屯河区",
+      "达坂城区",
+      "米东区",
+      "乌鲁木齐县",
+      "乌鲁木齐经济技术开发区",
+      "乌鲁木齐高新技术产业开发区"
+    ],
+    "克拉玛依市": [
+      "独山子区",
+      "克拉玛依区",
+      "白碱滩区",
+      "乌尔禾区"
+    ],
+    "吐鲁番市": [
+      "高昌区",
+      "鄯善县",
+      "托克逊县"
+    ],
+    "哈密市": [
+      "伊州区",
+      "巴里坤哈萨克自治县",
+      "伊吾县"
+    ],
+    "昌吉回族自治州": [
+      "昌吉市",
+      "阜康市",
+      "呼图壁县",
+      "玛纳斯县",
+      "奇台县",
+      "吉木萨尔县",
+      "木垒哈萨克自治县"
+    ],
+    "博尔塔拉蒙古自治州": [
+      "博乐市",
+      "阿拉山口市",
+      "精河县",
+      "温泉县"
+    ],
+    "巴音郭楞蒙古自治州": [
+      "库尔勒市",
+      "轮台县",
+      "尉犁县",
+      "若羌县",
+      "且末县",
+      "焉耆回族自治县",
+      "和静县",
+      "和硕县",
+      "博湖县",
+      "库尔勒经济技术开发区"
+    ],
+    "阿克苏地区": [
+      "阿克苏市",
+      "温宿县",
+      "库车县",
+      "沙雅县",
+      "新和县",
+      "拜城县",
+      "乌什县",
+      "阿瓦提县",
+      "柯坪县"
+    ],
+    "克孜勒苏柯尔克孜自治州": [
+      "阿图什市",
+      "阿克陶县",
+      "阿合奇县",
+      "乌恰县"
+    ],
+    "喀什地区": [
+      "喀什市",
+      "疏附县",
+      "疏勒县",
+      "英吉沙县",
+      "泽普县",
+      "莎车县",
+      "叶城县",
+      "麦盖提县",
+      "岳普湖县",
+      "伽师县",
+      "巴楚县",
+      "塔什库尔干塔吉克自治县"
+    ],
+    "和田地区": [
+      "和田市",
+      "和田县",
+      "墨玉县",
+      "皮山县",
+      "洛浦县",
+      "策勒县",
+      "于田县",
+      "民丰县"
+    ],
+    "伊犁哈萨克自治州": [
+      "伊宁市",
+      "奎屯市",
+      "霍尔果斯市",
+      "伊宁县",
+      "察布查尔锡伯自治县",
+      "霍城县",
+      "巩留县",
+      "新源县",
+      "昭苏县",
+      "特克斯县",
+      "尼勒克县"
+    ],
+    "塔城地区": [
+      "塔城市",
+      "乌苏市",
+      "额敏县",
+      "沙湾县",
+      "托里县",
+      "裕民县",
+      "和布克赛尔蒙古自治县"
+    ],
+    "阿勒泰地区": [
+      "阿勒泰市",
+      "布尔津县",
+      "富蕴县",
+      "福海县",
+      "哈巴河县",
+      "青河县",
+      "吉木乃县"
+    ],
+    "自治区直辖县级行政区划": [
+      "石河子市",
+      "阿拉尔市",
+      "图木舒克市",
+      "五家渠市",
+      "铁门关市"
+    ]
+  }
+}

+ 32 - 0
online/src/components/alert.vue

@@ -0,0 +1,32 @@
+<template>
+  <div>
+    <mu-dialog title="通知" width="360" :open.sync="openSimple">
+       {{text}}
+      <mu-button slot="actions" flat color="primary" @click="closeSimpleDialog">关闭</mu-button>
+    </mu-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      openSimple: false,
+      text:''
+    };
+  },
+  methods: {
+    openSimpleDialog(info) {
+      this.openSimple = true;
+      this.text = info;
+    },
+    closeSimpleDialog() {
+      this.openSimple = false;
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 388 - 0
online/src/components/appHeader.vue

@@ -0,0 +1,388 @@
+<template>
+    <div id="appHeader">
+        <div id="headerContent">
+            <mu-appbar style="width: 100%;" color="primary">
+                <mu-button icon slot="left">
+                    <mu-button ref="button" @click="open = !open">
+                        <img src="../static/images/comm/list.png" alt="" class="listBtn">
+                    </mu-button>
+                    <mu-popover cover :open.sync="open" :trigger="trigger">
+                        <mu-list>
+                            <mu-list-item button :class="[{'active':t == curLi},'modalLi' ]"
+                                          v-for="(panel,t) in panelData" :key="panel.tabs" @click="goPage(panel)">
+                                <mu-list-item-title>
+                                    <!--<span :class="panel.img"></span>-->
+                                    <mu-icon :value="panel.img"></mu-icon>
+                                    <s>{{panel.name}}</s>
+                                </mu-list-item-title>
+                            </mu-list-item>
+                        </mu-list>
+                    </mu-popover>
+                </mu-button>
+                {{curTitle}}
+                <mu-menu slot="right">
+                    <img src="../static/images/comm/user.png" alt="" class="userBtn">
+                </mu-menu>
+            </mu-appbar>
+            <div class="alertRed" v-show="alertState && title == '系统首页'">
+                <em>
+                    <i class="curIcon yellowTri"></i>
+                    发现危险设备{{dangerNum}} {{$t("item")}}
+                </em>
+                <span @click="goRuntime">{{$t("Suspicious device")}}MAC:{{mac}} 品牌:{{MacCom}} <i
+                        @click="closeAlert">×</i></span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    export default {
+        data() {
+            return {
+                open: false,
+                trigger: null,
+                curLi: 0,
+                curTitle: this.title,
+                alertState: false,
+                dangerNum: 0,
+                mac: '',
+                MacCom: '',
+                panelData: [
+                    {name: this.$t('System home page'), path: '', img: 'home', tabs: 1},
+                    {name: this.$t('User list'), path: 'usermanage', img: 'account_box', tabs: 2},
+                    {name: this.$t('Enterprise list'), path: 'enterprisemanage', img: 'assignment', tabs: 3},
+                    {name: this.$t('Detection equipment'), path: 'detector', img: 'laptop', tabs: 4},
+                    {name: this.$t('Detection record'), path: 'record', img: 'reorder', tabs: 5},
+                    {name: this.$t('Statistical report forms'), path: 'statis', img: 'receipt', tabs: 6},
+                    {name: this.$t('System setup'), path: 'setting', img: 'settings', tabs: 7},
+                    {name: this.$t('whiteList'), path: 'white', img: 'view_list', tabs: 8},
+                    {name: this.$t('Real-time monitoring'), path: 'runtime', img: 'poll', tabs: 9},
+                ]
+            }
+        },
+        props: ['title'],
+        mounted() {
+            this.trigger = this.$refs.button.$el;
+            this.timer = setInterval(() => {
+                this.readAlert();
+            }, 5000);
+        },
+        beforeDestroy() {
+            clearInterval(this.timer);
+        },
+        methods: {
+            goPage(panel) {
+                console.log(panel);
+                this.$emit('goNewpage', panel.path);
+                this.open = false;
+            },
+            goRuntime() {
+                this.alertState = false;
+                this.$emit('goNewpage', 'runtime');
+                this.open = false;
+            },
+            // 读取警告信息
+            readAlert() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectedMacs';
+                // let url = headapi + 'v1/Detector/DetectedMacsTest';//test
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        if (json.Rs) {
+                            if (localStorage.alertState == true) {
+                                that.alertState = true;
+                            } else {
+                                that.alertState = false;
+                            }
+                            that.dangerNum = json.Rs.length;
+                            that.mac = json.Rs[0].Mac;
+                            if (json.Rs[0].MacCom) {
+                                that.MacCom = json.Rs[0].MacCom.substr(0, 9) + '...';
+                            }
+
+                        }
+                    }
+                    if (json.Code == 1010) {
+                        that.$router.push({path: '/login'});
+                    }
+                }, function (response) {
+                    that.$router.push({path: '/login'});
+                    console.info(response);
+                })
+            },
+            closeAlert() {
+                this.alertState = false
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    #appHeader {
+        width: 100%;
+        height: 55px;
+        z-index: 99999;
+    }
+    #headerContent {
+        width: 100%;
+        position: absolute;
+        z-index: 99999;
+        top: 0;
+    }
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-raised-button {
+        background: none;
+        box-shadow: none;
+    }
+
+    .listBtn {
+        width: 20px;
+        height: 14px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 0px;
+    }
+
+    .userBtn {
+        width: 28px;
+        height: 28px;
+        margin-top: 15px;
+        margin-right: 15px;
+    }
+
+    .mu-appbar {
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /*icon iconHome*/
+    .iconHome {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconHome.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconHome {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconHome_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconUser {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconUser.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconUser {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconUser_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconProfile {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconProfile.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconProfile {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconProfile_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconEquipmanage {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconEquipmanage.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconEquipmanage {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconEquipmanage_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconRecord {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRecord.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconRecord {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRecord_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconStatis {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconStatis.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconStatis {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconStatis_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconMap {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconMap.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconMap {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconMap_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .iconRuntime {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRuntime.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .active .iconRuntime {
+        width: 20px;
+        height: 20px;
+        float: left;
+        margin-right: 10px;
+        background: url("../static/images/comm/iconRuntime_a.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .modalLi span {
+        width: 20px;
+        height: 20px;
+        margin-right: 0px !important;
+    }
+
+    .modalLi s {
+        text-decoration: none;
+        font-size: 14px;
+        line-height: 30px;
+        padding-left: 10px;
+        float: right;
+    }
+
+    .alertRed {
+        position: absolute;
+        width: 100%;
+        overflow: visible;
+        display: block;
+        margin: 0 auto;
+        background: #FFF8DB;
+        padding-left: 2%;
+        padding-right: 2%;
+    }
+
+    .alertRed em {
+        position: relative;
+        top: -10px;
+        width: 139px;
+        height: 18px;
+        line-height: 18px;
+        background: red;
+        color: #fff;
+        margin: 0 auto;
+        display: block;
+        border-radius: 9px;
+        text-align: center;
+        font-size: 12px;
+    }
+
+    .yellowTri {
+        width: 9px;
+        height: 8px;
+        float: left;
+        margin-left: 15px;
+        margin-top: 4px;
+        background: url("../static/images/icon/triIcon.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    .alertRed span {
+        width: 100%;
+        height: 30px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        color: red;
+        font-size: 12px;
+    }
+
+    .alertRed span i {
+        float: right;
+        color: #ccc;
+        font-size: 18px;
+        line-height: 20px;
+    }
+    /deep/ .mu-item-title s {
+        width: 65px;
+        text-align: justify;
+        text-align-last: justify;
+    }
+</style>

+ 106 - 0
online/src/components/bottomTab.vue

@@ -0,0 +1,106 @@
+<template>
+    <div id="bottomTab">
+        <mu-container style="width: 100%;" color="primary">
+            <mu-bottom-nav :value="nowTab" color="#E75296">
+                <mu-bottom-nav-item v-for="tab in tabs" :title="tab.name" :icon="tab.src" :to="tab.class" :key="tab.tabindex"
+                                    :value="tab.name"></mu-bottom-nav-item>
+            </mu-bottom-nav>
+        </mu-container>
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {
+                nowTab: this.curTab,
+                tabs: [
+                    {name: '预约课程', class: '/', src: ' ', tabindex: 1},
+                    {name: '预约记录', class: 'record', src: ' ', tabindex: 2},
+                    {name: '我的', class: 'mine', src: ' ', tabindex: 3},
+                    //laptop
+                ]
+            }
+        },
+        props: ['curTab'],
+        methods: {},
+        watch: {
+            '$route': function (e) {
+                this.nowTab = e.meta.title;
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    #bottomTab {
+        position: absolute;
+        bottom: 0;
+        width: 100%;
+        background: #fff;
+        border-top: 1px solid #eee;
+        z-index: 9999;
+    }
+
+    .container {
+        padding: 0;
+    }
+
+    /*非选中态图标 */
+    /deep/ a:nth-child(1) .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/Calendar@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+    /deep/ a:nth-child(2) .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/Newspaper@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+    /deep/ a:nth-child(3) .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/User@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+    /*选中态图标*/
+    /deep/ a:nth-child(1).mu-bottom-item-active .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/CalendarRed@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+    /deep/ a:nth-child(2).mu-bottom-item-active .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/NewspaperRed@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+    /deep/  a:nth-child(3).mu-bottom-item-active .mu-bottom-item-icon {
+        background-image: url(../static/images/bottom/UserRed@2x.png);
+        background-repeat: no-repeat;
+        width: 24px;
+        height: 24px;
+        background-size: auto 24px;
+    }
+
+     .mu-bottom-item-text {
+        color: #999999
+    }
+
+    .mu-bottom-item-active .mu-bottom-item-text {
+        color: #2b2b2b;
+    }
+</style>

+ 139 - 0
online/src/components/cityPicker.vue

@@ -0,0 +1,139 @@
+<template>
+    <div>
+        <div class="demo-picker-container citypickerContainer">
+            <p @click="pickerState = true">
+                <span> {{addressProvince}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+                <span> {{addressCity}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+                <span> {{addressCounty}} <img src="../static/images/comm/cityPicker.png" alt=""></span>
+            </p>
+            <mu-slide-picker
+                    v-show="pickerState"
+                    :slots="addressSlots"
+                             :visible-item-count="7"
+                             @change="addressChange"
+                             :values="address"></mu-slide-picker>
+            <mu-button id="closeBtn" color="warning" @click="pickerState = false" v-show="pickerState">收起</mu-button>
+
+        </div>
+    </div>
+</template>
+
+<script>
+    import myaddress from '../components/address3.json'
+
+    export default {
+        data() {
+            return {
+                addressSlots: [
+                    {
+                        width: '100%',
+                        textAlign: 'right',
+                        values: Object.keys(myaddress)
+                    }, {
+                        width: '100%',
+                        textAlign: 'left',
+                        values: Object.keys(myaddress['山东省']),
+                    }, {
+                        width: '100%',
+                        textAlign: 'left',
+                        values: myaddress['山东省']['济南市'],
+                    }
+                ],
+                address: ['山东省', '济南市', '历下区'],
+                addressProvince: '山东省',
+                addressCity: '济南市',
+                addressCounty: '历下区',
+                pickerState: false,
+            }
+        },
+        created() {
+        },
+        methods: {
+            addressChange(value, index) {
+                switch (index) {
+                    case 0:
+                        this.addressProvince = value;
+                        let ProvinceName = value.substring(0, value.length - 1);
+                        this.addressSlots[1].values = address[ProvinceName];
+                        this.addressCity = address[ProvinceName][0] + '市';
+                        break;
+                    case 1:
+                        this.addressCity = value;
+                        let arrCity = myaddress[this.addressProvince][value];
+                        this.addressSlots[2].values = arrCity;
+                        this.addressCounty = arrCity[0];
+                        break;
+                    case 2:
+                        this.addressCounty = value;
+                        break
+                }
+                this.address = [this.addressProvince, this.addressCity, this.addressCounty];
+                localStorage.defaultProv =this.addressProvince.substring(0, this.addressProvince.length - 1);
+                localStorage.defaultCity =this.addressCity.substring(0, this.addressCity.length - 1);
+                localStorage.defaultArea =this.addressCounty;
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .demo-picker-container {
+        width: 100%;
+    }
+    .citypickerContainer {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .citypickerContainer p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .citypickerContainer p span {
+        width: 94px;
+        float: left;
+        border: 1px solid #D5D5D5;
+        height: 30px;
+        line-height: 30px;
+        font-size: 12px;
+        padding-left: 10px;
+        padding-right: 10px;
+        margin-right: 3%;
+    }
+
+    .citypickerContainer p span:nth-child(3) {
+        margin-right: 0;
+        float: left;
+    }
+
+    .citypickerContainer p span img {
+        float: right;
+        width: 8px;
+        margin-top: 10px;
+    }
+    .pickerPart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .center {
+        width: 100px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+    }
+    #closeBtn {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+</style>

+ 396 - 0
online/src/components/mapDrag.vue

@@ -0,0 +1,396 @@
+<!--
+  描述:拖放地图组件,默认尺寸是 500 * 300
+  接收属性参数:
+    lat: 纬度
+    lng: 经度
+  自定义事件:
+    drag: 拖放完成事件
+  示例:
+    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
+-->
+<template>
+    <div class="m-map" :style="{ height: curheight + 'px' }">
+        <div id="js-container" class="map">
+            <h5 style="text-align: center">{{$t("Loading data")}} ...</h5>
+        </div>
+    </div>
+</template>
+
+<script>
+    import remoteLoad from '../utils/remoteLoad.js'
+    import {MapKey, MapCityName} from '../tools/map'
+
+    let qs = require('qs');
+    import axios from 'axios';
+    import Global from '../../src/Global.js'
+
+    export default {
+        data() {
+            return {
+                searchKey: '',
+                placeSearch: null,
+                dragStatus: false,
+                AMapUI: null,
+                AMap: null,
+            }
+        },
+        props: {
+            curheight: {
+                default: 310,
+                type: Number
+            }
+        },
+        watch: {
+            searchKey() {
+                if (this.searchKey === '') {
+                    this.placeSearch.clear()
+                }
+            },
+        },
+        beforeDestroy() {
+            clearInterval(this.getPoint);
+        },
+        methods: {
+            // 实例化地图
+            initMap() {
+                let AMapUI = this.AMapUI = window.AMapUI;
+                let AMap = this.AMap = window.AMap;
+                let timeInterval = 5000;
+                let lang = localStorage.language == 'zh' ? 'zh' : 'en';
+                AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
+                    let mapConfig = {
+                        resizeEnable: true, //是否监控地图容器尺寸变化
+                        // mapStyle: mapStyle,//地图颜色风格
+                        zoom: 16,
+                        cityName: MapCityName,
+                        lang: lang
+                    };
+                    let map = new AMap.Map('js-container', mapConfig);
+                    // 获取点位置
+                    this.getPoint(map);
+                    setInterval(this.getPoint(map), 5000);
+                    // 获取围栏信息
+                    this.getFenceInfo(map);
+
+                    // 启用工具条
+                    AMap.plugin(['AMap.ToolBar'], function () {
+                        map.addControl(new AMap.ToolBar({
+                            position: 'RB'
+                        }))
+                    });
+                })
+            },
+
+            // 实例化点标记
+            addMarker(map, lng, lat, content, imgState) {
+                let marker = new AMap.Marker({
+                    position: [lng, lat],
+                    offset: new AMap.Pixel(-13, -30),
+                    content: imgState,
+                });
+                marker.setMap(map);
+
+                // 弹窗偏移度
+                let infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(14, -20)});
+
+                marker.on('click', function (e) {
+                    infoWindow.setContent(content);
+                    infoWindow.open(map, e.target.getPosition());
+                });
+            },
+            // 获取所有的点位置
+            getPoint(map) {
+                const that = this;
+                let lnglats = [];
+                let url = '';
+                if (localStorage.userLevel == this.$t('单位管理员')) {
+                    url = headapi + 'v1/Company/GetRegionMapinfo';//获取 单个企业获取
+                } else {
+                    url = headapi + 'v1/Company/GetMapinfo';//获取
+                }
+                let param = {
+                    token: localStorage.token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json) {
+                        // 单个企业
+                        map.setCenter([json.Rs[0].Lng, json.Rs[0].Lat]);
+                        // todo 使用数学中心计算显示点中心
+                        localStorage.lnglats = JSON.stringify(json.Rs);
+                        if (localStorage.lnglats != JSON.stringify(lnglats)) {
+                            that.wirtePoint(map, json);
+                        }
+                        map.setFitView();
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 画点
+            wirtePoint(map, json) {
+                let that = this;
+                let markers = [];
+                let curPointName = '';
+                let lnglats = json.Rs;
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < lnglats.length; i++) {
+                    let imgState = '';
+                    curPointName = !lnglats[i].RegionName ? lnglats[i].ComName : lnglats[i].RegionName;
+                    switch (parseInt(lnglats[i].Detstatus)) {
+                        // 0 safe 1 warning 2 danger
+                        case 0:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                    }
+
+                    var position;
+                    position = [json.Rs[i].Lng, json.Rs[i].Lat];
+
+                    let content = '';
+                        var state = '';
+                        switch (parseInt(lnglats[i].Detstatus)) {
+                            // 0 safe 1 warning 2 danger
+                            case 0:
+                                state = this.$t('normal');
+                                break;
+                            case 1:
+                                state = '<span style="color:#ffe943">' + this.$t('abnormal') + '</span>';
+                                break;
+                            case 2:
+                                state = '<span style="color:#ff0000">' + this.$t('danger') + '</span>';
+                                break;
+                        }
+
+                        let DecList = !json.Rs[i].DecList ? that.$t('not found') : json.Rs[i].DecList;
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '">' +
+                            this.$t('region') + json.Rs[i].RegionName
+                            + '<br>' + this.$t('state') + ':' + state
+                            + '<br>' + this.$t('Detection') + ':' + json.Rs[i].DectorNum
+                            + '<br>' + this.$t('phone signal') + ':' + DecList
+                            + '<br>' + json.Rs[i].Wifiname + ':' + json.Rs[i].CamNum
+                            + '<br>' + this.$t('Suspicious') + json.Rs[i].Wifiname + ':' + json.Rs[i].DancapNum
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i].Regionid + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i></em>';
+
+                    that.addMarker(map, json.Rs[i].Lng, json.Rs[i].Lat, content, imgState);
+                }
+            },
+            // 获取围栏信息
+            getFenceInfo(map) {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComfencelist';
+                let param = {
+                    token: localStorage.token,
+                    comid: localStorage.comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let fence = json.Rs.Fence;
+                        let fenceArr = fence.split(",");
+                        let path = [];
+                        for (var i = 0; i < fenceArr.length; i++) {
+                            if (i % 2 == 0) {
+                                path.push([fenceArr[i], fenceArr[i + 1]]);
+                            }
+                        }
+                        let polygon = new AMap.Polygon({
+                            path: path,
+                            strokeColor: "#6496FF",
+                            strokeWeight: 6,
+                            strokeOpacity: 0.15,
+                            fillOpacity: 0.4,
+                            fillColor: '#6496FF',
+                            zIndex: 50,
+                        });
+
+                        map.add(polygon);
+
+                        // 缩放地图到合适的视野级别
+                        map.setFitView([polygon]);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 计算点中心
+            calcCenterBySingle(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i].Lat * Math.PI / 180;
+                    lon += data[i].Lng * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lon * 180 / Math.PI, lat * 180 / Math.PI];
+            },
+            // 计算多点的数学圆心
+            calcCenter(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i][0] * Math.PI / 180;
+                    lon += data[i][1] * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lat * 180 / Math.PI, lon * 180 / Math.PI];
+            }
+        },
+        async created() {
+            // 已载入高德地图API,则直接初始化地图
+            if (window.AMap && window.AMapUI) {
+                this.initMap()
+                // 未载入高德地图API,则先载入API再初始化
+            } else {
+                await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`);
+                await remoteLoad('http://webapi.amap.com/ui/1.0/main.js');
+                this.initMap()
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .m-map {
+        width: 100%;
+        /*max-height: 317px;*/
+        /*height: 317px;*/
+        position: relative;
+    }
+
+    .m-map .map {
+        width: 100%;
+        height: 100%;
+    }
+
+    .m-map .search {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+        width: 285px;
+        z-index: 1;
+    }
+
+    .m-map .search input {
+        width: 180px;
+        border: 1px solid #ccc;
+        line-height: 20px;
+        padding: 5px;
+        outline: none;
+    }
+
+    .m-map .search button {
+        line-height: 26px;
+        background: #fff;
+        border: 1px solid #ccc;
+        width: 50px;
+        text-align: center;
+    }
+
+    .m-map .result {
+        max-height: 300px;
+        overflow: auto;
+        margin-top: 10px;
+    }
+
+    /deep/ .green_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #1eff30;
+    }
+
+    /deep/ .yellow_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #f2ff24;
+    }
+
+    /deep/ .red_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        transform: scale(0.5);
+        animation: bulge 2s infinite ease-in-out;
+        background-color: #ff0000;
+        animation-delay: 0s;
+    }
+
+    /deep/ .red_point::after {
+        position: absolute;
+        display: inline-block;
+        content: '';
+        height: 100%;
+        width: 100%;
+        border-radius: 50%;
+        background-color: inherit;
+        top: 0;
+        left: 0;
+        z-index: -1;
+        transform: scale(1);
+        animation: blow 2s infinite ease-in-out;
+    }
+
+    /deep/ .point_name {
+        position: relative;
+        left: -30px;
+        top: -15px;
+        width: 100%;
+        min-width: 90px;
+        padding: 1px;
+        text-align: center;
+        background-color: rgb(26, 34, 41);
+        border: 1px solid #060D16;
+        border-radius: 10px !important;
+        color: #eeeeee;
+        display: block;
+        overflow: hidden;
+        opacity: 0.9;
+        font-size: 12px;
+    }
+
+
+    @keyframes bulge {
+        50% {
+            transform: scale(1);
+        }
+    }
+
+
+    @keyframes blow {
+        25% {
+            opacity: 0.4;
+        }
+        50% {
+            opacity: 0.1;
+        }
+        90% {
+            opacity: 0;
+        }
+        100% {
+            transform: scale(9);
+            opacity: 0;
+        }
+    }
+</style>

+ 581 - 0
online/src/components/mapPage.vue

@@ -0,0 +1,581 @@
+<!--
+  描述:拖放地图组件,默认尺寸是 500 * 300
+  接收属性参数:
+    lat: 纬度
+    lng: 经度
+  自定义事件:
+    drag: 拖放完成事件
+  示例:
+    <mapDrag @drag="dragMap" lat="22.574405" lng="114.095388"></mapDrag>
+-->
+<template>
+    <div class="m-map" :style="{ height: curheight + 'px' }">
+        <div id="js-containerPage" class="map">
+            <h5 style="text-align: center">{{$t("Loading data")}} ...</h5>
+        </div>
+        <mu-bottom-sheet :open.sync="detailState">
+            <div class="detailContianer">
+                <h5>
+                    <span class="name">{{row.RegionName}}</span>
+                </h5>
+                <ul>
+                    <li class="lt">{{$t("state")}}:<em
+                            :class="{'red':row.Detstatus != '正常','green':row.Detstatus == '正常'}">{{row.Detstatus}}</em>
+                    </li>
+                    <li class="lt">{{$t("Detection equipment")}}:{{row.DectorNum}} {{$t("pcs")}}</li>
+                    <li class="lt">{{$t("phone signal")}}:{{row.DecList}}</li>
+                    <li class="lt">{{$t("Camera")}}:{{row.CamNum}} {{$t("pcs")}}</li>
+                    <li class="lt">{{$t("Suspicious camera")}}:{{row.DancapNum}} {{$t("pcs")}}</li>
+                </ul>
+                <div class="btnContainer">
+                    <button class="goPlane" @click="goPlane">{{$t("Plane details")}}</button>
+                    <button class="goProfile" @click="goProfile">{{$t("Company details")}}</button>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+    </div>
+</template>
+
+<script>
+    import remoteLoad from '../utils/remoteLoad.js'
+    import {MapKey, MapCityName} from '../tools/map'
+
+    let qs = require('qs');
+    import axios from 'axios';
+    import Global from '../../src/Global.js'
+
+    export default {
+        data() {
+            return {
+                searchKey: '',
+                placeSearch: null,
+                dragStatus: false,
+                AMapUI: null,
+                AMap: null,
+                ComId: 0,
+                detailState: false,
+                row: {
+                    RegionName: '',
+                    Detstatus: '',
+                    DectorNum: '',
+                    CamNum: '',
+                    DecList: '',
+                    DancapNum: '',
+                    Regionid: '',
+                },
+            }
+        },
+        props: {
+            curheight: {
+                default: 310,
+                type: Number
+            }
+        },
+        watch: {
+            searchKey() {
+                if (this.searchKey === '') {
+                    this.placeSearch.clear()
+                }
+            },
+        },
+        beforeDestroy() {
+            clearInterval(this.getPoint);
+        },
+        methods: {
+            goPlane() {
+                let that = this;
+                that.$router.push({path: '/plane', query: {Regionid: that.row.Regionid, ComId: that.ComId}});
+            },
+            goProfile() {
+                let that = this;
+                that.$router.push({path: '/profile', query: {Regionid: that.row.Regionid, ComId: that.ComId}});
+            },
+            // 实例化地图
+            initMap() {
+                let AMapUI = this.AMapUI = window.AMapUI;
+                let AMap = this.AMap = window.AMap;
+                let timeInterval = 5000;
+                let lang = localStorage.language == 'zh' ? 'zh' : 'en';
+                AMapUI.loadUI(['misc/PositionPicker'], PositionPicker => {
+                    let mapConfig = {
+                        resizeEnable: true, //是否监控地图容器尺寸变化
+                        // mapStyle: mapStyle,//地图颜色风格
+                        zoom: 16,
+                        cityName: MapCityName,
+                        lang: lang
+                    };
+                    let map = new AMap.Map('js-containerPage', mapConfig);
+                    // 获取点位置
+                    this.getPoint(map);
+
+                    setInterval(this.getPoint(map), 5000);
+                    // 获取围栏信息
+                    this.getFenceInfo(map);
+                    // 启用工具条
+                    AMap.plugin(['AMap.ToolBar'], function () {
+                        map.addControl(new AMap.ToolBar({
+                            position: 'RB'
+                        }))
+                    });
+                })
+            },
+
+            // 实例化点标记
+            addMarker(map, lng, lat, content, imgState, row) {
+                let that = this;
+                let marker = new AMap.Marker({
+                    position: [lng, lat],
+                    offset: new AMap.Pixel(-13, -30),
+                    content: imgState,
+                });
+                marker.setMap(map);
+
+                // 弹窗偏移度
+                let infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(14, -20)});
+                marker.on('click', function (e) {
+                    // 自定义的弹窗
+                        that.detailState = true;
+                        that.row.RegionName = row.RegionName;
+                        that.row.Detstatus = row.Detstatus == 1 ? that.$t('normal') : that.$t('abnormal');
+                        that.row.DecList = !row.DecList ? that.$t('Not found') : row.DecList;
+                        that.row.DectorNum = row.DectorNum;
+                        that.row.CamNum = row.CamNum;
+                        that.row.DancapNum = row.DancapNum;
+                        that.row.Regionid = row.Regionid;
+                        // 原生的弹窗
+                        // infoWindow.setContent(content);
+                        // infoWindow.open(map, e.target.getPosition());
+                });
+            },
+            // 获取所有的点位置
+            getPoint(map) {
+                const that = this;
+                let lnglats = [];
+                let url = '';
+                if (localStorage.userLevel == '单位管理员') {
+                    url = headapi + 'v1/Company/GetRegionMapinfo';//获取 单个企业获取
+                } else {
+                    url = headapi + 'v1/Company/GetMapinfo';//获取
+                }
+                let param = {
+                    token: localStorage.token
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Rs) {
+                        map.setCenter([json.Rs[0].Lng, json.Rs[0].Lat]);
+                        // todo 使用数学中心计算显示点中心
+                        if (localStorage.lnglats != JSON.stringify(lnglats)) {
+                            that.wirtePoint(map, json);
+                        }
+                        localStorage.lnglats = JSON.stringify(json.Rs)
+                    }
+                    map.setFitView();
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 画点
+            wirtePoint(map, json) {
+                let that = this;
+                let markers = [];
+                let curPointName = '';
+                let lnglats = json.Rs;
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < lnglats.length; i++) {
+                    let imgState = '';
+                    curPointName = !lnglats[i].RegionName ? lnglats[i].ComName : lnglats[i].RegionName;
+                    switch (parseInt(lnglats[i].Detstatus)) {
+                        // 0 safe 1 warning 2 danger
+                        case 0:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + curPointName + '</span>';
+                            break;
+                    }
+                    var position;
+                    position = [json.Rs[i].Lng, json.Rs[i].Lat];
+
+                    let content = '';
+                    if (localStorage.userLevel == '单位管理员') {
+                        let state = json.Rs[i].Detstatus == 1 ? this.$t("normal") : '<span style="color:#ff0000">this.$t("abnormal")</span>';
+                        let DecList = !json.Rs[i].DecList ? this.$t("Not found") : json.Rs[i].DecList;
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '">' +
+                            +this.$t("region") + ':' + json.Rs[i].RegionName
+                            + '<br>' + this.$t("state") + ':' + state
+                            + '<br>' + this.$t("Detection equipment") + ':' + json.Rs[i].DectorNum
+                            + '<br>' + this.$t("phone signal") + ':' + DecList
+                            + '<br>' + json.Rs[i].Wifiname + ':' + json.Rs[i].CamNum
+                            + '<br>可疑' + json.Rs[i].Wifiname + ':' + json.Rs[i].DancapNum
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i].Regionid + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + localStorage.comId + '&Regionid=' + json.Rs[i].Regionid + '"></i></em>';
+                    } else {
+                        let state = json.Rs[i][3] == 1 ? '正常' : '<span style="color:#ff0000">异常</span>';
+                        let macAddr = !json.Rs[i][7] ? '无' : json.Rs[i][7];
+                        content =
+                            '<span class="map_a" href="profile.html?hotelid=' + json.Rs[i][8] + '">' +
+                            '企业:' + json.Rs[i][5]
+                            + '<br>' + this.$t("state") + ':' + state
+                            + '<br>' + this.$t("Detection equipment") + ':' + json.Rs[i][4]
+                            + '<br>' + this.$t("phone signal") + ':' + json.Rs[i][2]
+                            + '<br>可疑' + json.Rs[i][9] + ':' + json.Rs[i][6]
+                            + '<br>可疑MAC地址:' + macAddr
+                            + '</span><em class="jumper" Regionid=' + json.Rs[i][9] + '>' +
+                            '<i class="icon iconProfile"  href="profile.html?hotelid=' + json.Rs[i][8] + '"></i>' +
+                            '<i class="icon iconPlane" href="plane.html?hotelid=' + json.Rs[i][8] + '"></i></em>';
+                    }
+                    that.addMarker(map, json.Rs[i].Lng, json.Rs[i].Lat, content, imgState, json.Rs[i]);
+                }
+            },
+            // 给总管理员的画点
+            wirtePointForAdmin(map, json) {
+                let that = this;
+                let markers = [];
+                map.remove(markers);
+                // 根据状态判断图标显示颜色
+                for (var i = 0; i < json.length; i++) {
+                    let imgState = '';
+                    switch (parseInt(json[i][3])) {
+                        case 1:
+                            imgState = '<i class="green_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break;
+                        case 2:
+                            imgState = '<i class="yellow_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break;
+                        case 0:
+                            imgState = '<i class="red_point"></i> <span class="point_name">' + json[i][5] + '</span>';
+                            break
+                    }
+                    var position = json[i];
+                    let content = '';
+                    let state = json[i][3] == 1 ? this.$t('normal') : '<span style="color:#ff0000">' + this.$t('abnormal') + '</span>';
+                    let macAddr = !json[i][7] ? this.$t('nothing') : json[i][7];
+                    content = '<span class="map_a" href="profile.html?hotelid=' + json[i][8] + '">' +
+                        '企业:' + json[i][5]
+                        + '<br>状态:' + state
+                        + '<br>探测设备:' + json[i][4]
+                        + '<br>' + json[i][9] + ':' + json[i][2]
+                        + '<br>可疑' + json[i][9] + ':' + json[i][6]
+                        + '<br>可疑MAC地址:' + macAddr
+                        + '</span><em class="jumper" Regionid=' + json[i][9] + '>' +
+                        '<i class="icon iconProfile"  href="profile.html?hotelid=' + json[i][8] + '"></i>' +
+                        '<i class="icon iconPlane" href="plane.html?hotelid=' + json[i][8] + '"></i></em>';
+                    that.addMarker(map, json[i][0], json[i][1], content, imgState,json[i]);
+                }
+            },
+            // 获取围栏信息
+            getFenceInfo(map) {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComfencelist';
+                let param = {
+                    token: localStorage.token,
+                    comid: localStorage.comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.ComId = json.Rs.ComId;
+                        let fence = json.Rs.Fence;
+                        let fenceArr = fence.split(",");
+                        let path = [];
+                        for (var i = 0; i < fenceArr.length; i++) {
+                            if (i % 2 == 0) {
+                                path.push([fenceArr[i], fenceArr[i + 1]]);
+                            }
+                        }
+                        let polygon = new AMap.Polygon({
+                            path: path,
+                            strokeColor: "#6496FF",
+                            strokeWeight: 6,
+                            strokeOpacity: 0.15,
+                            fillOpacity: 0.4,
+                            fillColor: '#6496FF',
+                            zIndex: 50,
+                        });
+
+                        map.add(polygon);
+
+                        // 缩放地图到合适的视野级别
+                        map.setFitView([polygon]);
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 计算点中心
+            calcCenterBySingle(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i].Lat * Math.PI / 180;
+                    lon += data[i].Lng * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lon * 180 / Math.PI, lat * 180 / Math.PI];
+            },
+            // 计算多点的数学圆心
+            calcCenter(data) {
+                var total = data.length;
+                var lat = 0, lon = 0;
+                for (var i = 0; i < total; i++) {
+                    lat += data[i][0] * Math.PI / 180;
+                    lon += data[i][1] * Math.PI / 180;
+                }
+                lat /= total;
+                lon /= total;
+                return [lat * 180 / Math.PI, lon * 180 / Math.PI];
+            }
+        },
+        async created() {
+            // 已载入高德地图API,则直接初始化地图
+            if (window.AMap && window.AMapUI) {
+                this.initMap()
+                // 未载入高德地图API,则先载入API再初始化
+            } else {
+                await remoteLoad(`http://webapi.amap.com/maps?v=1.3&key=${MapKey}`);
+                await remoteLoad('http://webapi.amap.com/ui/1.0/main.js');
+                this.initMap()
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    .m-map {
+        width: 100%;
+        /*max-height: 317px;*/
+        /*height: 317px;*/
+        position: relative;
+    }
+
+    .m-map .map {
+        width: 100%;
+        height: 100%;
+    }
+
+    .m-map .search {
+        position: absolute;
+        top: 10px;
+        left: 10px;
+        width: 285px;
+        z-index: 1;
+    }
+
+    .m-map .search input {
+        width: 180px;
+        border: 1px solid #ccc;
+        line-height: 20px;
+        padding: 5px;
+        outline: none;
+    }
+
+    .m-map .search button {
+        line-height: 26px;
+        background: #fff;
+        border: 1px solid #ccc;
+        width: 50px;
+        text-align: center;
+    }
+
+    .m-map .result {
+        max-height: 300px;
+        overflow: auto;
+        margin-top: 10px;
+    }
+
+    /deep/ .green_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #1eff30;
+    }
+
+    /deep/ .yellow_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        background-color: #f2ff24;
+    }
+
+    /deep/ .red_point {
+        margin: 16px;
+        height: 16px;
+        width: 16px;
+        border-radius: 50% !important;
+        display: inline-block;
+        transform: scale(0.5);
+        animation: bulge 2s infinite ease-in-out;
+        background-color: #ff0000;
+        animation-delay: 0s;
+    }
+
+    /deep/ .red_point::after {
+        position: absolute;
+        display: inline-block;
+        content: '';
+        height: 100%;
+        width: 100%;
+        border-radius: 50%;
+        background-color: inherit;
+        top: 0;
+        left: 0;
+        z-index: -1;
+        transform: scale(1);
+        animation: blow 2s infinite ease-in-out;
+    }
+
+    /deep/ .point_name {
+        position: relative;
+        left: -30px;
+        top: -15px;
+        width: 100%;
+        min-width: 90px;
+        padding: 1px;
+        text-align: center;
+        background-color: rgb(26, 34, 41);
+        border: 1px solid #060D16;
+        border-radius: 10px !important;
+        color: #eeeeee;
+        display: block;
+        overflow: hidden;
+        opacity: 0.9;
+        font-size: 12px;
+    }
+
+    .red {
+        color: red;
+    }
+
+    .green {
+        color: greenyellow;
+    }
+
+    @keyframes bulge {
+        50% {
+            transform: scale(1);
+        }
+    }
+
+
+    @keyframes blow {
+        25% {
+            opacity: 0.4;
+        }
+        50% {
+            opacity: 0.1;
+        }
+        90% {
+            opacity: 0;
+        }
+        100% {
+            transform: scale(9);
+            opacity: 0;
+        }
+    }
+
+    .detailContianer {
+        position: absolute;
+        bottom: 85px;
+        left: 0;
+        right: 0;
+        width: 96%;
+        height: 257px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        box-shadow: #333333 0 0 7px;
+        z-index: 9999;
+        border-radius: 8px;
+        padding: 18px 10px;
+    }
+
+    .detailContianer h5 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 16px;
+    }
+
+    .detailContianer h5 .name {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+
+    .detailContianer h5 .state {
+        float: right;
+    }
+
+    .detailContianer ul {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 15px;
+        margin-bottom: 10px;
+        border-top: 1px solid #EBEBEB;
+        border-bottom: 1px solid #EBEBEB;
+        padding-top: 10px;
+        padding-bottom: 10px;
+    }
+
+    .detailContianer li {
+        width: 100%;
+        float: left;
+        margin-bottom: 3px;
+    }
+
+    .detailContianer .rt {
+        text-align: right;
+    }
+
+    .detailContianer .btnContainer {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .btnContainer button {
+        width: 120px;
+        height: 32px;
+        line-height: 32px;
+        text-align: center;
+        border-radius: 250px;
+        outline: none;
+        border: none;
+    }
+
+    .btnContainer .goPlane {
+        border: 1px solid #FFCC00;
+        background: #fff;
+    }
+
+    .btnContainer .goProfile {
+        border: 1px solid #FFCC00;
+        background: #FFCC00;
+        float: right;
+    }
+
+    /deep/ .amap-zoomcontrol {
+        bottom: 10px !important;
+    }
+</style>

+ 218 - 0
online/src/components/statischart.vue

@@ -0,0 +1,218 @@
+<template>
+    <div id="statischart">
+        <div class="time">
+    <span @click="changeTime(1)">
+    {{bt}}
+    </span>
+            <span @click="changeTime(2)">
+    {{et}}
+    </span>
+            <mu-select label="" v-model="selectVal">
+                <mu-option v-for="option in options" :key="option.optionsVal" :label="option.name"
+                           :value="option.optionsVal"></mu-option>
+            </mu-select>
+            <mu-button color="warning" @click="getNewChart" small>{{$t('search')}}</mu-button>
+        </div>
+
+        <Line-example
+                :width="390"
+                :height="200"
+                :dataLabels="dataLabels"
+                :datadatasets="datadatasets"
+        />
+
+        <mu-bottom-sheet :open.sync="open">
+            <mu-flex justify-content="between" align-items="end" wrap="wrap">
+                <mu-paper :z-depth="1" class="demo-date-picker">
+                    <mu-date-picker :date.sync="date" color="#FFA200" :date-time-format="enDateFormat"
+                                    @change="confirmDay"></mu-date-picker>
+                </mu-paper>
+            </mu-flex>
+        </mu-bottom-sheet>
+    </div>
+</template>
+<script>
+    import Global from '../Global'
+    import Vue from 'vue'
+    import LineExample from './LineExample'
+
+    let qs = require('qs');
+    import axios from 'axios';
+
+    const enDateFormat = {
+        formatDisplay(date) {
+            return `${dayList[date.getDay()]}, ${monthList[date.getMonth()]} ${date.getDate()}`;
+        },
+        formatMonth(date) {
+            return `${monthLongList[date.getMonth()]} ${date.getFullYear()}`;
+        },
+        getWeekDayArray(firstDayOfWeek) {
+            let beforeArray = [];
+            let afterArray = [];
+            for (let i = 0; i < dayAbbreviation.length; i++) {
+                if (i < firstDayOfWeek) {
+                    afterArray.push(dayAbbreviation[i]);
+                } else {
+                    beforeArray.push(dayAbbreviation[i]);
+                }
+            }
+            return beforeArray.concat(afterArray);
+        },
+        getMonthList() {
+            return monthList;
+        }
+    };
+    export default {
+        data() {
+            return {
+                enDateFormat,
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),//test
+                et: globaltime2StringNoMin(new Date()),
+                date: new Date(),
+                pickerValue: '',
+                open: false,
+                selectTime: 0,
+                selectVal: 1,
+                pickerItem: 0,
+                dataLabels: [],
+                datadatasets: [],
+                options: [
+                    {name: this.$t('Total detection record'), optionsVal: 1},
+                ]
+            }
+        },
+        mounted() {
+            this.getNewChart()
+        },
+        methods: {
+            changeTime(val) {
+                this.open = true;
+                let curVal = val == 1 ? new Date(this.bt) : new Date(this.et);
+                this.selectTime = val;
+                this.date = curVal;
+            },
+            confirmDay(date) {
+                if (this.selectTime == 1) {
+                    this.bt = globaltime2StringNoMin(date);
+                } else {
+                    this.et = globaltime2StringNoMin(date);
+                }
+                this.open = false;
+            },
+            getNewChart() {
+                const that = this;
+                let url = headapi + 'v1/Detector/GetCtNumStatisticByday';
+                let param = {
+                    token: localStorage.token,
+                    bt: that.bt + ' 00:00:00',
+                    et: that.et + ' 23:59:59',
+                    dailytype: that.selectVal,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let detectorArr = json.Rs;
+                        that.dataLabels = detectorArr.RsX;
+                        that.datadatasets = detectorArr.RsY;
+                    } else {
+                        if (!localStorage.token) { //未登录状态
+                            console.log(json.Memo);
+                        } else { //已登录状态
+                            that.Toast(that.TransMemo(json.Memo));
+                        }
+                    }
+                }, function (response) {
+                    console.info(response);
+                });
+            },
+        },
+        components: {
+            LineExample
+        },
+    }
+</script>
+
+<style scoped>
+    .container {
+        width: 100%;
+        height: 230px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    #statischart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+    }
+
+    .time {
+        width: 100%;
+        height: 48px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+        padding-top: 15px;
+        margin-bottom: 15px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .time span {
+        width: 80px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time select {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time .mint-button {
+        height: 27px;
+        border-radius: 0;
+    }
+
+    .mu-input {
+        width: 100px;
+        float: left;
+        padding: 0;
+        margin: 0;
+    }
+
+    /deep/ .mu-select-input {
+        font-size: 12px !important;
+    }
+
+    .mu-button {
+        float: left;
+        min-width: 66px;
+    }
+
+    .demo-date-picker {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    /deep/ .mu-button-wrapper {
+        color: #000 !important;
+    }
+</style>

+ 152 - 0
online/src/components/statischart2.vue

@@ -0,0 +1,152 @@
+<template>
+    <div class="container">
+        <div class="Chart">
+            <div class="time">
+                <span @click="changeTime(1)">
+                    {{bt}}
+                </span>
+                <span @click="changeTime(2)">
+                    {{et}}
+                </span>
+                <select name="" id="" v-model="selectVal">
+                    <option value="1">总探测记录</option>
+                </select>
+                <mt-button size="small" type="primary" @click="getNewChart">查询</mt-button>
+            </div>
+            <Line-example
+                    :width="414"
+                    :height="200"
+                    :dataLabels="dataLabels"
+                    :datadatasets="datadatasets"
+            />
+        </div>
+        <mt-datetime-picker
+                ref="picker"
+                type="date"
+                v-model="pickerValue"
+                @confirm="handleConfirm"
+        >
+        </mt-datetime-picker>
+    </div>
+</template>
+
+<script>
+    import {DatetimePicker} from 'mint-ui';
+    import {Toast} from 'mint-ui';
+    import LineExample from './LineExample'
+    import Global from '../Global'
+    import Vue from 'vue'
+
+    let qs = require('qs');
+    import axios from 'axios';
+
+    Vue.component(DatetimePicker.name, DatetimePicker);
+    export default {
+        data() {
+            return {
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),
+                et: globaltime2StringNoMin(new Date()),
+                pickerValue: '',
+                selectVal: 1,
+                pickerItem: 0,
+                dataLabels: [],
+                datadatasets: [],
+            }
+        },
+        mounted() {
+            this.getNewChart();
+        },
+        methods: {
+            changeTime(val) {
+                this.$refs.picker.open();
+                this.pickerValue = val == 1 ? this.bt : this.et;
+                this.pickerItem = val;
+            },
+            handleConfirm(e) {
+                let that = this;
+                console.log(this.pickerItem);
+                if (this.pickerItem == 1) {
+                    that.bt = globaltime2String(e)
+                } else {
+                    that.et = globaltime2String(e)
+                }
+                this.$refs.picker.close();
+            },
+            // 查询
+            getNewChart() {
+                const that = this;
+                let url = headapi + 'v1/Detector/GetCtNumStatisticByday';
+                let param = {
+                    token: localStorage.token,
+                    bt: that.bt + ' 00:00:00',
+                    et: that.et + ' 23:59:59',
+                    dailytype: that.selectVal,
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        let detectorArr = json.Rs;
+                        that.dataLabels = detectorArr.RsX;
+                        that.datadatasets = detectorArr.RsY;
+                    } else {
+                        // Toast(json.memo);
+                        console.log(json.Memo);
+                    }
+                }, function (response) {
+                    console.info(response);
+                });
+            }
+        },
+        components: {
+            LineExample
+        },
+    }
+</script>
+
+<style>
+    .container {
+        width: 100%;
+        height: 230px;
+        margin: 0 auto;
+    }
+
+    .time {
+        width: 96%;
+        height: 48px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+        padding-top: 15px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .time span {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time select {
+        width: 96px;
+        height: 27px;
+        float: left;
+        border: 1px solid #DEDEDE;
+        text-align: center;
+        line-height: 27px;
+        font-size: 12px;
+        margin-right: 10px;
+    }
+
+    .time .mint-button {
+        height: 27px;
+        border-radius: 0;
+    }
+</style>

+ 134 - 0
online/src/language/en-US.js

@@ -0,0 +1,134 @@
+export default {
+    "whiteList": "whiteList",
+    "search": "search",
+    "index": "index",
+    "keyword": "keyword",
+    "order": "order",
+    "detect tag": "detect tag",
+    "detect local": "detect local",
+    "be detect MAC": "be detect MAC",
+    "sign time": "sign time",
+    "operator": "operator",
+    "memo": "memo",
+    "control": "control",
+    "close": "close",
+    "remove white": "remove white",
+    "no use data": "no use data",
+    "Wireless device detection system management": "Wireless device detection system management",
+    "Management system for wireless camera detection and equipment detection": "Management system for wireless camera detection and equipment detection",
+    "login": "login",
+    "User name or email address": "User name or email address",
+    "Password": "Password",
+    "Verification Code": "Verification Code",
+    "Invisibility? Give it a try!": "Invisibility? Give it a try!",
+    "cancel": "cancel",
+    "usercode": "usercode",
+    "can not be empty": "can not be empty",
+    "least": "least",
+    "character": "character!",
+    "Limit exceeded": "Limit exceeded",
+    "The verification code has timed out. Please re-enter": "The verification code has timed out. Please re-enter",
+    "System home page": "System home page",
+    "home": "home",
+    "Real-time monitoring": "Real-time monitoring",
+    "Real-time": "Real-time",
+    "Detection record": "Detection record",
+    "Detection": "Detection",
+    "Record": "Record",
+    "item": "item",
+    "Suspicious device": "Suspicious device",
+    "Detection equipment": "Detection equipment",
+    "Supervision quantity": "Supervision quantity",
+    "Statistical report forms": "Statistical report forms",
+    "Dangerous equipment found": "Dangerous equipment found",
+    "brand": "brand",
+    "User list": "User list",
+    "Enterprise list": "Enterprise list",
+    "System setup": "System setup",
+    "Map display": "Map display",
+    "Map": "Map",
+    "Loading data": "Loading data",
+    "region": "region",
+    "state": "state",
+    "pcs": "pcs",
+    "phone signal": "phone signal",
+    "Camera": "Camera",
+    "Suspicious camera": "Suspicious camera",
+    "Plane details": "Plane details",
+    "Company details": "Company details",
+    "normal": "normal",
+    "abnormal": "abnormal",
+    "Not found": "Not found",
+    "enterprise": "enterprise",
+    "Suspicious": "Suspicious",
+    "Prohibit": "Prohibit",
+    "fault": "fault",
+    "Off-line": "Off-line",
+    "Depot repair": "Depot repair",
+    "delete": "delete",
+    "other": "other",
+    "total": "total",
+    "Back to previous page": "Back to previous page",
+    "detail": "detail",
+    "Affiliated Enterprises": "Affiliated Enterprises",
+    "Tag name": "Tag name",
+    "local": "local",
+    "wireless device": "wireless device",
+    "No mobile signal detected": "No mobile signal detected",
+    "disabled": "disabled",
+    "Enabled": "Enabled",
+    "nothing": "nothing",
+    "user management": "user management",
+    "User details": "User details",
+    "User roles": "User roles",
+    "Business management": "Business management",
+    "query criteria": "query criteria",
+    "Keyword query": "Keyword query",
+    "Reset": "Reset",
+    "query": "query",
+    "hotel": "hotel",
+    "tavern": "tavern",
+    "Prison": "Prison",
+    "Enterprise name": "Enterprise name",
+    "Enterprise types": "Enterprise types",
+    "Enterprise address": "Enterprise address",
+    "Subordinate supervision": "Subordinate supervision",
+    "Contacts": "Contacts",
+    "Total detection record": "Total detection record",
+    "to": "to",
+    "Please go to the webpage for more records": "Please go to the webpage for more records",
+    "Query already": "Query already",
+    "Please select a device first": "Please select a device first",
+    "No records found": "No records found",
+    "Alarm sound": "Alarm sound",
+    "Alarm flicker": "Alarm flicker",
+    "Quit landing": "Quit landing",
+    "Confirm to exit the current account": "Confirm to exit the current account",
+    "confirm": "confirm",
+    // error code
+    "Record does not exist": "Record does not exist",
+    "Successful implementation": "Successful implementation",
+    "The server is busy. Please try again later": "The server is busy. Please try again later",
+    "Service is temporarily unavailable": "Service is temporarily unavailable",
+    "Key does not exist": "Key does not exist",
+    "Wrong user name or password": "Wrong user name or password",
+    "Graphic verification code error": "Graphic verification code error",
+    "Password format error": "Password format error",
+    "Password error": "Password error",
+    "User already exists": "User already exists",
+    "Transmission frequency too high": "Transmission frequency too high",
+    "User is disabled": "User is disabled",
+    "Abnormal user status": "Abnormal user status",
+    "user does not exist": "user does not exist",
+    "Verification code error": "Verification code error",
+    "Logon failure": "Logon failure",
+    "MAC already exists": "MAC already exists",
+    "Is not a complete comma separated list format": "Is not a complete comma separated list format",
+    "HBase error": "HBase error",
+    "Please upload the picture again": "Please upload the picture again",
+    "not found": "not found",
+    "danger": "danger",
+    "warning": "warning",
+    "deal": "deal",
+    "white": "deal",
+};

+ 135 - 0
online/src/language/ru-RU.js

@@ -0,0 +1,135 @@
+export default {
+    "whiteList": "белый список",
+    "search": "запрос",
+    "index": "Первая страница",
+    "keyword": "ключевые слова",
+    "order": "порядковый номер",
+    "detect tag": "метка детектора",
+    "detect local": "место обнаружения",
+    "be detect MAC": "измерительное устройство MAC",
+    "sign time": "время отметки",
+    "operator": "оператор",
+    "memo": "Примечание",
+    "control": "операция",
+    "close": "Выключить",
+    "remove white": "Выключить белый список",
+    "no use data": "неиспользуемые данные",
+    "Wireless device detection system management": "управление системой обнаружения",
+    "Management system for wireless camera detection and equipment detection": "система управления обнаружением радиокамер, обнаружением фотоаппарата и т.д.",
+    "login": "входить",
+    "User name or email address": "Имя пользователя или почтовый адрес",
+    "Password": "пароль",
+    "Verification Code": "код проверки",
+    "Invisibility? Give it a try!": "не видишь?примерить кистью!",
+    "cancel": "отмена",
+    "usercode": "Имя пользователя",
+    "can not be empty": "не может быть пустым!",
+    "least": "минимум",
+    "character": "знак!",
+    "Limit exceeded": "превышать лимит",
+    "The verification code has timed out. Please re-enter": "код проверки истек, повторите ввод",
+    "System home page": "системная страница",
+    "home": "страница",
+    "Real-time monitoring": "контроль реального времени",
+    "Real-time": "истинное",
+    "Detection record": "запись обнаружения",
+    "Detection": "энергопитающая",
+    "Record": "запись",
+    "item": "полоса",
+    "Suspicious device": "подозрительное оборудование",
+    "Detection equipment": "энергопитающая",
+    "Supervision quantity": "контрольный количество",
+    "Statistical report forms": "статистический отчет",
+    "Dangerous equipment found": "обнаружение опасного оборудования",
+    "brand": "бренд",
+    "User list": "Список пользователей",
+    "Enterprise list": "Список предприятий",
+    "System setup": "Настройки системы",
+    "Map display": "карта",
+    "Map": "карта",
+    "Loading data": "Загрузка данных",
+    "region": "область",
+    "state": "состояние",
+    "pcs": "стол",
+    "phone signal": "сотовый сигнал",
+    "phone": "мобильный",
+    "Camera": "камера",
+    "Suspicious camera": "подозрительная камера",
+    "Plane details": "плоская деталь",
+    "Company details": "сведения о предприятии",
+    "normal": "нормальный",
+    "abnormal": "аномалия",
+    "Not found": "Не найдено",
+    "enterprise": "предприятие",
+    "Suspicious": "сомнительный",
+    "Prohibit": "Отключить",
+    "fault": "неисправность",
+    "Off-line": "оффлайн",
+    "Depot repair": "ремонт на заводе",
+    "delete": "Удалить",
+    "other": "Прочее",
+    "total": "весь",
+    "Back to previous page": "вернуться на предыдущую страницу",
+    "detail": "подробности",
+    "Affiliated Enterprises": "подведомственное предприятие",
+    "Tag name": "название метки",
+    "local": "место",
+    "wireless device": "радиооборудование",
+    "No mobile signal detected": "сигнал телефона не обнаружен",
+    "disabled": "Отключено",
+    "Enabled": "Включено",
+    "nothing": "Нет",
+    "user management": "Управление пользователями",
+    "User details": "сведения о пользователе",
+    "User roles": "роль пользователя",
+    "Business management": "управление предприятием",
+    "query criteria": "условия запроса",
+    "Keyword query": "запрос ключевого слова",
+    "Reset": "сбросить",
+    "query": "запрос",
+    "hotel": "гостиница",
+    "tavern": "кабак",
+    "Prison": "тюрьма",
+    "Enterprise name": "название компании",
+    "Enterprise types": "тип предприятия",
+    "Enterprise address": "адрес предприятия",
+    "Subordinate supervision": "подведомственный контроль",
+    "Contacts": "контакт",
+    "Total detection record": "запись общего обнаружения",
+    "to": "to",
+    "Please go to the webpage for more records": "Пожалуйста, Просматривайте страницу",
+    "Query already": "опрос",
+    "Please select a device first": "Выберите устройство",
+    "No records found": "Нет запроса на запись",
+    "Alarm sound": "сигнал тревоги",
+    "Alarm flicker": "мигание тревоги",
+    "Quit landing": "выход из десанта",
+    "Confirm to exit the current account": "установить выход из текущего счета",
+    "confirm": "определение",
+    // error code
+    "Record does not exist": "запись не существует",
+    "Successful implementation": "успешная реализация",
+    "The server is busy. Please try again later": "Сервер загружен, попробуйте позже",
+    "Service is temporarily unavailable": "обслуживание временно недоступно",
+    "Key does not exist.": "Key не существует",
+    "Wrong user name or password": "ошибка по имени или паролю",
+    "Graphic verification code error": "ошибка графического кода",
+    "Password format error": "ошибка формата пароля",
+    "Password error": "ошибка пароля",
+    "User already exists": "пользователь уже существует",
+    "Transmission frequency too high": "частота пересылки",
+    "User is disabled": "пользователь отключен",
+    "Abnormal user status": "аномалия состояния пользователя",
+    "user does not exist": "пользователь не существует",
+    "Verification code error": "Ошибка проверки кода",
+    "Logon failure": "Ошибка регистрации",
+    "MAC already exists": "MAC уже существует",
+    "Is not a complete comma separated list format": "не весь формат разделённых запятыми списков",
+    "HBase error": "ошибка HBase",
+    "Please upload the picture again": "Перезагрузите изображение",
+    "not found": "не найдено",
+    "danger": "Опасности",
+    "warning": "Предупреждение",
+    "deal": "Сделки",
+    "white": "Белый",
+};

+ 135 - 0
online/src/language/zh-CN.js

@@ -0,0 +1,135 @@
+export default {
+    "whiteList": "白名单",
+    "search": "搜索",
+    "index": "首页",
+    "keyword": "关键词",
+    "order": "序号",
+    "detect tag": "探测器标签",
+    "detect local": "探测位置",
+    "be detect MAC": "被测设备MAC",
+    "sign time": "标注时间",
+    "operator": "操作员",
+    "memo": "备注",
+    "control": "操作",
+    "close": "关闭",
+    "remove white": "移出白名单",
+    "no use data": "暂没有符合条件的数据",
+    "Wireless device detection system management": "无线设备探测系统管理",
+    "Management system for wireless camera detection and equipment detection": "无线摄像头探测、偷拍设备探测等管理系统",
+    "login": "登录",
+    "User name or email address": "用户名或邮件地址",
+    "Password": "密码",
+    "Verification Code": "验证码",
+    "Invisibility? Give it a try!": "看不清?刷一下试试!",
+    "cancel": "取消",
+    "usercode": "用户名",
+    "can not be empty": "不能为空!",
+    "least": "最少",
+    "character": "字符!",
+    "Limit exceeded": "超出限制数量",
+    "The verification code has timed out. Please re-enter": "验证码已超时,请重新输入",
+    "System home page": "系统首页",
+    "home": "系统首页",
+    "Real-time monitoring": "实时监控",
+    "Real-time": "实时监控",
+    "Detection record": "探测记录",
+    "Detection": "探测设备",
+    "Record": "记录",
+    "item": "条",
+    "Suspicious device": "可疑设备",
+    "Detection equipment": "探测设备",
+    "Supervision quantity": "监管数量",
+    "Statistical report forms": "统计报表",
+    "Dangerous equipment found": "发现危险设备",
+    "brand": "品牌",
+    "User list": "用户列表",
+    "Enterprise list": "企业列表",
+    "System setup": "系统设置",
+    "Map display": "地图展示",
+    "Map": "地图展示",
+    "Loading data": "正在加载数据",
+    "region": "区域",
+    "state": "状态",
+    "pcs": "台",
+    "phone signal": "手机信号",
+    "phone": "手机",
+    "Camera": "摄像头",
+    "Suspicious camera": "可疑摄像头",
+    "Plane details": "平面详情",
+    "Company details": "企业详情",
+    "normal": "正常",
+    "abnormal": "异常",
+    "Not found": "没有发现",
+    "enterprise": "企业",
+    "Suspicious": "可疑",
+    "Prohibit": "禁用",
+    "fault": "故障",
+    "Off-line": "离线",
+    "Depot repair": "返厂维修",
+    "delete": "删除",
+    "other": "其他",
+    "total": "共",
+    "Back to previous page": "返回上一页",
+    "detail": "详情",
+    "Affiliated Enterprises": "所属企业",
+    "Tag name": "标签名",
+    "local": "位置",
+    "wireless device": "无线设备",
+    "No mobile signal detected": "未检测到手机信号",
+    "disabled": "已禁用",
+    "Enabled": "已启用",
+    "nothing": "无",
+    "user management": "用户管理",
+    "User details": "用户详情",
+    "User roles": "用户角色",
+    "Business management": "企业管理",
+    "query criteria": "查询条件",
+    "Keyword query": "关键字查询",
+    "Reset": "重 置",
+    "query": "查 询",
+    "hotel": "宾馆",
+    "tavern": "酒店",
+    "Prison": "监狱",
+    "Enterprise name": "企业名称",
+    "Enterprise types": "企业类型",
+    "Enterprise address": "企业地址",
+    "Subordinate supervision": "所属监管",
+    "Contacts": "联 系 人",
+    "Total detection record": "总探测记录",
+    "to": "至",
+    "Please go to the webpage for more records": "更多记录请前往网页端查看",
+    "Query already": "已查询",
+    "Please select a device first": "请先选择一个设备",
+    "No records found": "没有查询到记录",
+    "Alarm sound": "报警声音",
+    "Alarm flicker": "报警闪烁",
+    "Quit landing": "退出登陆",
+    "Confirm to exit the current account": "确定退出当前账户",
+    "confirm": "确定",
+    // error code
+    "Record does not exist": "记录不存在",
+    "Successful implementation": "执行成功",
+    "The server is busy. Please try again later": "服务器繁忙,请稍后再试",
+    "Service is temporarily unavailable": "服务暂不可用",
+    "Key does not exist.": "key不存在",
+    "Wrong user name or password": "用户名或密码错误",
+    "Graphic verification code error": "图形验证码错误",
+    "Password format error": "密码格式错误",
+    "Password error": "密码错误",
+    "User already exists": "用户已存在",
+    "Transmission frequency too high": "发送频率过高",
+    "User is disabled": "用户被禁用",
+    "Abnormal user status": "用户状态异常",
+    "user does not exist": "用户不存在",
+    "Verification code error": "验证码错误",
+    "Logon failure": "登录失效",
+    "MAC already exists": "MAC已存在",
+    "Is not a complete comma separated list format": "不是完整的逗号分隔列表格式",
+    "HBase error": "HBase错误",
+    "Please upload the picture again": "请重新上传图片",
+    "not found": "没有发现",
+    "danger": "高危",
+    "warning": "低危",
+    "deal": "已处理",
+    "white": "白名单",
+};

+ 151 - 0
online/src/main.js

@@ -0,0 +1,151 @@
+import Vue from 'vue'
+import App from './App.vue'
+import router from './router'
+import axios from 'axios'
+import MuseUI from 'muse-ui';
+import 'muse-ui/dist/muse-ui.css';
+// 全局插件
+import Toast from 'muse-ui-toast';
+import Loading from 'muse-ui-loading';
+
+
+import Message from 'muse-ui-message';
+Vue.use(Message);
+import NProgress from 'muse-ui-progress';
+Vue.use(NProgress);
+
+// import VConsole from 'vconsole/dist/vconsole.min.js' //import vconsole
+// let vConsole = new VConsole() // 初始化
+
+Vue.use(MuseUI);
+Vue.locale = () => {
+};
+
+let ToastConfig = {
+    position: 'bottom',               // 弹出的位置
+    time: 2000,                       // 显示的时长
+    closeIcon: 'close',               // 关闭的图标
+    close: true,                      // 是否显示关闭按钮
+    successIcon: 'check_circle',      // 成功信息图标
+    infoIcon: 'info',                 // 信息信息图标
+    warningIcon: 'priority_high',     // 提醒信息图标
+    errorIcon: 'warning'
+};
+
+Vue.use(Toast, ToastConfig);
+
+Vue.use(Loading);
+
+// 演示版本数据
+require('./Mock/index.js');
+
+Vue.config.productionTip = false;
+
+new Vue({
+    render: h => h(App),
+    router,
+}).$mount('#app');
+
+Vue.prototype.axios = axios;
+
+
+//Toast
+Vue.prototype.Toast = function (e, color) {
+    let ToastColor = !color ? 'warning' : color;
+    let that = this;
+    switch (ToastColor) {
+        case 'message':
+            that.$toast.message(e);
+            break;
+        case 'success':
+            that.$toast.success(e);
+            break;
+        case 'info':
+            that.$toast.info(e);
+            break;
+        case 'warning':
+            that.$toast.warning(e);
+            break;
+        case 'error':
+            that.$toast.error(e);
+            break;
+    }
+};
+
+// loading
+Vue.prototype.Loading = function (target) {
+    let loading = this.$loading({
+        overlayColor: 'hsla(0,0%,100%,.9)',        // 背景色
+        size: 48,
+        color: 'warning',                           // color
+    });
+    setTimeout(() => {
+        loading.close();
+    }, 3000)
+};
+
+Vue.prototype.TransMemo = function (text) {
+    let that = this;
+    switch (text) {
+        case '记录不存在':
+            that.$toast.error(that.$t('Record does not exist'));
+            break;
+        case '服务器繁忙,请稍后再试':
+            that.$toast.error(that.$t('The server is busy. Please try again later'));
+            break;
+        case '服务暂不可用':
+            that.$toast.error(that.$t('Service is temporarily unavailable'));
+            break;
+        case 'key不存在':
+            that.$toast.error(that.$t('Key does not exist'));
+            break;
+        case '用户名或密码错误':
+            that.$toast.error(that.$t('Wrong user name or password'));
+            break;
+        case '图形验证码错误':
+            that.$toast.error(that.$t('Graphic verification code error'));
+            break;
+        case '密码格式错误':
+            that.$toast.error(that.$t('Password format error'));
+            break;
+        case '密码错误':
+            that.$toast.error(that.$t('Password error'));
+            break;
+        case '用户已存在':
+            that.$toast.error(that.$t('User already exists'));
+            break;
+        case '发送频率过高':
+            that.$toast.error(that.$t('Transmission frequency too high'));
+            break;
+        case '用户被禁用':
+            that.$toast.error(that.$t('User is disabled'));
+            break;
+        case '用户状态异常':
+            that.$toast.error(that.$t('Abnormal user status'));
+            break;
+        case '用户不存在':
+            that.$toast.error(that.$t('user does not exist'));
+            break;
+        case '验证码错误':
+            that.$toast.error(that.$t('Verification code error'));
+            break;
+        case '登录失效':
+            that.$toast.error(that.$t('Logon failure'));
+            break;
+        case 'MAC已存在':
+            that.$toast.error(that.$t('MAC already exists'));
+            break;
+        case '不是完整的逗号分隔列表格式':
+            that.$toast.error(that.$t('Is not a complete comma separated list format'));
+            break;
+        case 'HBase错误':
+            that.$toast.error(that.$t('HBase error'));
+            break;
+        case '请重新上传图片':
+            that.$toast.error(that.$t('Please upload the picture again'));
+            break;
+        default:
+            that.$toast.error(text);
+            break
+    }
+};

+ 81 - 0
online/src/page/404.vue

@@ -0,0 +1,81 @@
+<template>
+    <div class="container">
+        <p class="content">系统升级中
+            <br>
+            敬请期待</p>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {},
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+   #app {
+        background: cornflowerblue;
+    }
+
+    .container {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: cornflowerblue;
+        background-image: url("../static/images/404/man.png");
+        background-position: top center;
+        background-repeat: no-repeat;
+        background-size: 100%;
+    }
+
+    .container {
+        width: 100%;
+        overflow: hidden;
+        margin: 0 auto;
+        text-align: center;
+        color: #fff;
+        font-size: 36px;
+    }
+
+    .content {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 27%;
+    }
+</style>

+ 782 - 0
online/src/page/appoint.vue

@@ -0,0 +1,782 @@
+<template>
+  <div class="pages">
+
+    <div class="as">
+      <img src="../static/images/main/banner.png" height="121" width="414"/>
+      <!--<mu-tabs :value.sync="active" color="#F2F2F2" indicator-color="#ffffff" @change="getIndex" v-if="reFresh">-->
+      <!--<mu-tab v-for="day in weeks">{{ day.data }} <br> <em>{{ day.name }}</em></mu-tab>-->
+      <!--</mu-tabs>-->
+      <div class="tabs">
+        <div :class="[{'tab':true},{'activeTab':i == active}]" v-for="(day,i) in weeks" @click="changeActive(i)">
+          {{ day.name }} <br> <em>{{ day.data }}</em>
+        </div>
+      </div>
+      <span class="sum">
+        {{ today }} 预约名额剩余
+        <em class="green" v-if="num > 0">{{ num }}</em>
+        <em class="red" v-else>{{ num }}</em>
+        人
+    </span>
+    </div>
+    <div class="context">
+      <ul class="list">
+        <li v-for="l in list"
+            v-show="l.WxVisible == 1"
+            :class="[{'greenLi':l.remain > 0},{'redLi':l.Status == 1},{'yellowLi':l.remain == 0},{'whiteLi':l.WxOrder == 0}]">
+          <div class="dotContainer">
+            <!--                        正常-->
+            <i class="dot" v-if="l.remain>0 && l.WxOrder != 0"></i>
+
+            <i class="cubes" v-if="l.Status==1"></i>
+            <!--                        已满-->
+            <i class="tri" v-if="l.remain == 0 && l.remain == 0"></i>
+            <!--                        不可约-->
+            <i class="x" v-if="l.WxOrder==0"></i>
+          </div>
+          <div class="title">
+            <h5><span class="lessons" :style="{ background:l.ClassColor }">{{ l.ClassName }}</span></h5>
+            <span>{{ l.BeginStr }} - {{ l.EndStr }}</span>
+          </div>
+          <div class="current">
+            <h5>剩余
+              <em class="green" v-if="l.remain > 0">{{ l.remain }}</em>
+              <em class="red" v-else>{{ l.remain }}</em>
+              人</h5>
+            <span>总名额 {{ l.OrderToplimit }} 人</span>
+          </div>
+          <mu-button class="appointBtn greenBtn" v-if="l.remain > 0 && l.OrderId == 0 && l.WxOrder != 0"
+                     @click="appointNow(l)">
+            预约
+          </mu-button>
+          <mu-button class="appointBtn redBtn" v-if="l.remain == 0 && l.OrderId == 0" @click="isFulled">已满
+          </mu-button>
+          <mu-button class="appointBtn yellowBtn" v-if="l.OrderId != 0" @click="isAppointed(l)">已约</mu-button>
+          <mu-button class="appointBtn disableBtn" v-if="l.WxOrder == 0" @click="isDisable">不可约</mu-button>
+        </li>
+        <div class="tips" v-if="list == ''">
+          <p style="text-align: center">
+            暂无可预约的课程
+          </p>
+        </div>
+      </ul>
+      <mu-avatar color="rgb(231, 82, 150)" @click.native="goPage('lesson')">
+        <mu-icon value="reorder"></mu-icon>
+      </mu-avatar>
+    </div>
+    <bottomTab :curTab="thisTab"></bottomTab>
+    <div class="doalog">
+      <mu-dialog title="预约课程" width="600" max-width="80%" :esc-press-close="false"
+                 :overlay-close="false" :open.sync="openAlert">
+        <p>
+          是否预约 课程:{{ dialog.ClassName }} ,时间:{{ dialog.BeginStr }} - {{ dialog.EndStr }}
+          <br>
+        </p>
+        <mu-button slot="actions" flat color="primary" @click="closeAlertDialog">取消</mu-button>
+        <mu-button slot="actions" flat color="primary" @click="confirmAppoint">确定</mu-button>
+      </mu-dialog>
+    </div>
+    <alert ref="alertPart"></alert>
+  </div>
+</template>
+
+<script>
+import axios from 'axios';
+import bottomTab from '../components/bottomTab'
+import {
+  CanOrderSchoolTimeTableListQuery,
+  OderAddByVipUser,
+  OderCancelByVipUser,
+  QueryNextWeek,
+  testSelect,
+  testTable,
+} from '../api/getApiRes.js'
+
+import alert from '../components/alert'
+
+let qs = require('qs');
+import Global from '../Global.js'
+
+export default {
+  data() {
+    return {
+      num: 0,
+      thisTab: '预约课程',
+      active: 0,
+      sum: 0,
+      HaveDays: 0,
+      openAlert: false,
+      reFresh: true,
+      list: [],
+      weeks: [],
+      today: '',
+      dialog: {
+        id: '',
+        name: '',
+        timeLong: '',
+      },
+    }
+  },
+  mounted() {
+    this.getQueryNextWeek();
+    // this.alertInfo(document.body.clientWidth);
+    // this.alertInfo( window.screen.height);
+  },
+  watch: {
+    '$route'(to) {
+      if (to.name == 'appoint') {
+        this.getList();
+      }
+    },
+    'active'(to) {
+      this.getList();
+    }
+  },
+  activated() {
+    this.active = 0;
+    this.reFresh = false;
+    this.$nextTick(() => {
+      this.reFresh = true;
+      this.getQueryNextWeek();
+    });
+
+  },
+  methods: {
+    changeActive(i) {
+      this.active = i;
+    },
+    getIndex(val) {
+      console.log(val);
+    },
+    getQueryNextWeek() {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        shopId: this.$route.query.shopId,
+      };
+      let postdata = qs.stringify(param);
+      this.weeks = [];
+      QueryNextWeek(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          this.HaveDays = json.Rs;
+          this.getFurtherDays(this.HaveDays);
+        } else {
+          that.list = [];
+          that.$message.error(json.Memo);
+        }
+      })
+    },
+    alertInfo(info) {
+      this.$refs.alertPart.openSimpleDialog(info);
+    },
+    goPage(url) {
+      this.$router.push({
+        path: '/' + url, query: {
+          shopId: this.$route.query.shopId
+        }
+      });
+    },
+    // 获取未来7天的
+    getFurtherDays(HaveDays) {
+      let now = new Date();
+      let nowTime = now.getTime();
+      let oneDayTime = 24 * 60 * 60 * 1000;
+      let days = '';
+      let item = [];
+      let month = 0;
+      let day = 0;
+      this.weeks = [];
+      for (let i = 0; i < HaveDays; i++) {
+        days = new Date(nowTime + (i) * oneDayTime);//显示周日
+        month = days.getMonth() + 1;
+        day = days.getDate();
+        month = month < 10 ? '0' + month : month;
+        day = day < 10 ? '0' + day : day;
+        item = {
+          name: this.numberToWeek(days.getDay()),
+          data: days.getMonth() + 1 + '月' + days.getDate() + '日',
+          orderDate: days.getFullYear() + '-' + month + '-' + day
+        };
+        this.weeks.push(item);
+      }
+      this.today = this.weeks[0].name;
+      this.getList();
+    },
+    numberToWeek(val) {
+      switch (parseInt(val)) {
+        case 1:
+          return '星期一';
+          break;
+        case 2:
+          return '星期二';
+          break;
+        case 3:
+          return '星期三';
+          break;
+        case 4:
+          return '星期四';
+          break;
+        case 5:
+          return '星期五';
+          break;
+        case 6:
+          return '星期六';
+          break;
+        case 0:
+          return '星期天';
+          break;
+      }
+    },
+    confirmAppoint() {
+      let that = this;
+      that.openAlert = false;
+      let param = {
+        token: localStorage.token,
+        stdId: that.dialog.StdId
+      };
+      let postdata = qs.stringify(param);
+      OderAddByVipUser(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          that.alertInfo('已成功预约', 'success');
+          that.getList();
+        } else {
+          that.alertInfo(json.Memo + ', 错误码:' + json.Code);
+        }
+      })
+    },
+    closeAlertDialog() {
+      this.openAlert = false;
+    },
+    appointNow(row) {
+      this.dialog = row;
+      this.openAlert = true;
+    },
+    isFulled() {
+      let that = this;
+      that.$alert('当前课程已满,请选择其他课程或其他时间预约', '提示', {
+        okLabel: '知道了'
+      }).then(() => {
+        that.getList();
+      });
+    },
+    isAppointed(row) {
+      let that = this;
+      this.$confirm('是否取消前课程预约?', '提示', {
+        type: 'warning'
+      }).then(({result}) => {
+        if (result) {
+          let param = {
+            token: localStorage.token,
+            orderId: row.OrderId,
+          };
+          let postdata = qs.stringify(param);
+          OderCancelByVipUser(postdata).then(res => {
+            let json = res;
+            if (json.Code == 0) {
+              that.alertInfo('当前课程已取消预约', 'success');
+              that.getList();
+            } else {
+              that.alertInfo(json.Memo + ', 错误码:' + json.Code);
+            }
+          })
+        } else {
+          this.alertInfo('点击了取消');
+        }
+      });
+    },
+    isDisable(row) {
+      this.alertInfo('课程不可预约,请选择其他课程或其他时间预约', 'info');
+    },
+    getList() {
+      let that = this;
+      this.today = this.weeks[this.active].name;
+      let curDay = this.weeks[this.active].orderDate;
+      let param = {
+        token: localStorage.token,
+        orderDate: curDay,
+        shopId: this.$route.query.shopId,
+      };
+      let postdata = qs.stringify(param);
+      that.list = [];
+      that.num = 0;
+      CanOrderSchoolTimeTableListQuery(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          that.list = json.Rs;
+          if (that.list) {
+            // 计算剩余
+            that.num = 0;
+            that.list.map(function (item) {
+              item.remain = parseInt(item.OrderToplimit) - parseInt(item.OrderCount);
+              that.num = that.num + item.remain
+              console.log( that.num);
+            })
+          }
+        } else {
+          that.alertInfo(json.Memo + ', 错误码:' + json.Code);
+        }
+      })
+    },
+  },
+  components: {
+    bottomTab, alert
+  }
+}
+</script>
+
+<style scoped>
+.pages {
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+/*mu-header*/
+.mu-primary-color {
+  line-height: 60px;
+  height: 60px;
+  background: url("../static/images/comm/headerBg.png") top center no-repeat;
+  background-size: 100%;
+}
+
+/deep/ .mu-appbar-left {
+  padding-top: 15px;
+}
+
+/deep/ .material-icons {
+  color: #fff;
+}
+
+/deep/ .mu-appbar-title {
+  text-align: center;
+}
+
+/deep/ .mu-tabs {
+  /*display: flex;*/
+  /*width: 414px;*/
+  overflow-x: scroll;
+  overflow-y: hidden;
+  /*display:inline;*/
+  /*float: left;*/
+}
+
+/deep/ .mu-tab {
+  width: 85px;
+  min-width: 85px;
+  float: left;
+  height: 51px;
+  margin-right: 6px;
+}
+
+/*/deep/ .mu-tab:nth-child(5) {*/
+/*    margin-right: 0px;*/
+/*}*/
+
+/deep/ .mu-tab-wrapper {
+  height: 51px;
+  background: #f4f4f4;
+  color: #363636;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  border-radius: 8px 8px 0px 0px;
+  font-size: 14px;
+}
+
+/deep/ .mu-tab-active .mu-tab-wrapper {
+  height: 56px;
+  border-radius: 8px 8px 0px 0px;
+  background: #ffffff;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  color: #000;
+}
+
+/deep/ .mu-tab-wrapper em {
+  font-size: 12px;
+}
+
+.sum {
+  width: 100%;
+  height: 55px;
+  line-height: 55px;
+  background: #fff;
+  font-family: "PingFang SC";
+  font-weight: 300;
+  font-size: 16px;
+  text-align: center;
+  color: #909090;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+.green {
+  color: #37CB00;
+}
+
+.red {
+  color: #F8847F;
+}
+
+.list {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  margin-top: 8px;
+  padding-bottom: 30px;
+}
+
+.list li {
+  width: 100%;
+  height: 70px;
+  margin-bottom: 8px;
+  padding-top: 16px;
+  padding-bottom: 16px;
+}
+
+.list .dotContainer {
+  width: 50px;
+  float: left;
+  height: 60px;
+  padding-left: 22px;
+  padding-top: 10px;
+}
+
+.dotContainer .dot {
+  width: 12px;
+  height: 12px;
+  background: #37cb00;
+  border-radius: 250px;
+  float: left;
+}
+
+.cubes {
+  width: 12px;
+  height: 12px;
+  background: #f8847f;
+  float: left;
+}
+
+.tri {
+  width: 12px;
+  height: 12px;
+  background: url("../static/images/appoint/tri.png") top center no-repeat;
+  background-size: 100% 100%;
+  float: left;
+}
+
+.x {
+  width: 12px;
+  height: 12px;
+  background: url("../static/images/appoint/x.png") top center no-repeat;
+  background-size: 100% 100%;
+  float: left;
+}
+
+
+.yellowLi {
+  background: #FFFBED;
+}
+
+.redLi {
+  background: #FFF7F7;
+}
+
+.greenLi {
+  background: #F7FFF4;
+}
+
+.whiteLi {
+  background: #fff;
+}
+
+.list li .title {
+  /*width: 90px;*/
+  width: 27%;
+  height: 60px;
+  float: left;
+}
+
+li .title h5 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #3b3b3b;
+}
+
+li .title span {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-weight: normal;
+  font-size: 12px;
+  text-align: left;
+  color: #909090;
+}
+
+.list li .current {
+  width: 120px;
+  height: 60px;
+  float: left;
+}
+
+li .current h5 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #3b3b3b;
+}
+
+.current h5 em {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+}
+
+.current span {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 12px;
+  text-align: left;
+  color: #909090;
+}
+
+.appointBtn {
+  width: 79px;
+  height: 37px;
+  border-radius: 18.5px;
+  background: #fff;
+  float: right;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 18px;
+  margin-right: 2%;
+}
+
+.greenBtn {
+  border: 1px solid #37cb00;
+  color: #37cb00;
+}
+
+.redBtn {
+  border: 1px solid #F8847F;
+  color: #F8847F;
+}
+
+.yellowBtn {
+  border: 1px solid #FFB43C;
+  color: #fff;
+  background: #FFB43C;
+}
+
+.disableBtn {
+  border: 1px solid #C9C9C9;
+  color: #C9C9C9;
+}
+
+/deep/ .mu-tabs-center {
+  display: flex;
+  overflow-x: auto;
+  overflow-y: hidden;
+  white-space: nowrap;
+}
+
+/deep/ .mu-tabs-center::-webkit-scrollbar {
+  display: none;
+}
+
+/deep/ .mu-modal-inner {
+  width: 90%;
+  float: left;
+}
+
+/deep/ .mu-tab-link-highlight {
+  display: none !important;
+}
+
+li .title span.lessons {
+  width: auto;
+  padding: 1px 11px;
+  border-radius: 250px;
+  float: left;
+  text-align: center;
+  color: #000;
+  font-size: 14px;
+}
+
+/deep/ .mu-avatar {
+  position: fixed;
+  bottom: 9%;
+  float: left;
+  left: 1%;
+}
+
+.context {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30%;
+  bottom: 0;
+  overflow-y: scroll;
+  padding-bottom: 50px;
+}
+
+.as {
+  position: fixed;
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  z-index: 222;
+  background: #F2F2F2;
+}
+
+/deep/ .mu-raised-button {
+  box-shadow: none;
+}
+
+.tabs {
+  width: 100%;
+  justify-content: space-between;
+  white-space: nowrap;
+  overflow-y: hidden;
+  overflow-x: scroll;
+  display: flex;
+  border-bottom: 1px solid #ccc;
+}
+
+.tab {
+  font-size: 14px;
+  min-width: 72px;
+  max-width: 264px;
+  background: none;
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  text-decoration: none;
+  border: none;
+  outline: none;
+  color: inherit;
+  position: relative;
+  line-height: normal;
+  -webkit-transition: all .45s cubic-bezier(.445, .05, .55, .95);
+  transition: all .45s cubic-bezier(.445, .05, .55, .95);
+  width: 85px;
+  float: left;
+  height: 51px;
+  margin-right: 6px;
+  cursor: pointer;
+  line-height: 20px;
+  padding-top: 4px;
+  text-align: center;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  border: 1px solid #ccc;
+  border-bottom: 0;
+}
+
+.tab.activeTab {
+  color: #fff;
+  background-color: #2196f3;
+  color: hsla(0, 0%, 100%, .7);
+}
+
+/*响应式调整*/
+@media only screen and (max-width: 320px) {
+  .list .dotContainer {
+    width: 20px;
+    padding-left: 5px;
+  }
+
+  .list li .title {
+    width: 30%;
+  }
+
+  .list li .current {
+    width: 29%;
+  }
+
+  .context {
+    top: 227px;
+  }
+}
+
+@media (min-width: 321px) and (max-width: 344px) {
+  .list li .current {
+    width: 28%;
+  }
+
+  .context {
+    top: 227px;
+  }
+}
+
+@media (min-width: 345px) and (max-width: 360px) {
+  .list li .current {
+    width: 30%;
+  }
+
+  .context {
+    top: 230px;
+  }
+}
+
+@media (min-width: 361px) and (max-width: 375px) {
+  .list li .current {
+    width: 30%;
+  }
+
+  .context {
+    top: 230px;
+  }
+}
+
+@media (min-width: 376px) and (max-width: 396px) {
+  .list li .current {
+    width: 30%;
+  }
+
+  .context {
+    top: 230px;
+  }
+}
+
+@media (min-width: 397px) and (max-width: 414px) {
+  .list li .current {
+    width: 30%;
+  }
+
+  .context {
+    top: 230px;
+  }
+}
+
+@media (min-width: 415px) and (max-width: 480px) {
+  .list li .current {
+    width: 30%;
+  }
+
+  .context {
+    top: 230px;
+  }
+}
+
+@media (min-width: 481px) and (max-width: 640px) {
+  .context {
+    top: 230px;
+  }
+}
+
+
+</style>

+ 257 - 0
online/src/page/detector.vue

@@ -0,0 +1,257 @@
+<template>
+    <div class="">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <transition-group name="fade">
+                    <li v-for="list in stus" v-if="lists" @click="goPage(list)" v-bind:key="list.Id">
+                        <div class="lt">
+                            <div class="rowTop">
+                                <h5>{{list.TagName}}</h5>
+                                <!--<span>{{list.Status | typeFileter}}</span>-->
+                                <span>{{list.stusType}}</span>
+                            </div>
+                            <div class="rowDetail">
+                                <span>{{list.Mac}}</span>
+                                <span class="pull-right">{{list.Memo}}</span>
+                            </div>
+                            <div class="rowDetail">
+                                <span>{{list.RegisterTime  | timeFileter}}</span>
+                                <span class="pull-right">{{list.ComName}}{{list.Name}}</span>
+                            </div>
+                        </div>
+                        <div class="rt">
+                            <mu-icon value="keyboard_arrow_right"></mu-icon>
+                        </div>
+                    </li>
+                </transition-group>
+                <div class="tips" v-if="lists">
+                    {{$t("total")}}{{lists.length}}{{$t("pcs")}} {{$t("Detection equipment")}}
+                </div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Detection'),
+                thisTab: this.$t('Detection'),
+                lists: [],
+                show: true
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(list) {
+                this.$router.push({path: '/detectorDetail', query: {detector: JSON.stringify(list)}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectorQuery';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let prov = localStorage.defaultProv;
+                let city = localStorage.defaultCity;
+                let area = localStorage.defaultArea;
+                let comid = localStorage.Comid;
+                let searchs = '';
+                let param = {
+                    token: localStorage.token,
+                    prov: prov,
+                    city: city,
+                    area: area,
+                    supregionid: 0,
+                    regionid: 0,
+                    comid: 48,
+                    keyword: '',
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        computed: {
+            stus() {
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v) => {
+                    switch (parseInt(v.Status)) {
+                        case 0:
+                            text = that.$t('Prohibit');
+                            break;
+                        case 1:
+                            text = that.$t('normal');
+                            break;
+                        case 2:
+                            text = that.$t('Off-line');
+                            break;
+                        case 3:
+                            text = that.$t('fault');
+                            break;
+                        case 9:
+                            text = that.$t('delete');
+                            break;
+                        default:
+                            text = that.$t('other');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        filters: {
+            timeFileter: function (time) {
+                return globalfmtDate(time, 10)
+            },
+        },
+        components: {
+            appHeader, bottomTab
+        }
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 10px;
+        background: #f2f2f2;
+    }
+
+    /*!*index mu-header*!*/
+    /deep/ .mint-header {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mint-button--default {
+        background: none;
+        color: #fff;
+        font-size: 14px;
+    }
+
+    /deep/ .mint-header-title {
+        padding-top: 0 !important;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 10px 20px;
+        border-bottom: 2px solid #f2f2f2;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop {
+        margin-bottom: 10px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+    }
+
+    .deteUl .lt {
+        width: 95%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        width: 8px;
+        height: 14px;
+        margin-top: 20px;
+        margin-right: 5px;
+        color: #ccc;
+    }
+
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+
+
+</style>

+ 140 - 0
online/src/page/detectorDetail.vue

@@ -0,0 +1,140 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="titletext">
+            <router-link to="/detector" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="row">
+            <h5>{{detail.ComName}}</h5>
+            <ul>
+                <li><em>Mac:</em><span>{{detail.Mac}}</span></li>
+                <li><em>{{$t("Affiliated Enterprises")}}:</em><span>{{detail.ComName  | filterContent}}</span></li>
+                <li><em>{{$t("Tag name")}}:</em><span>{{detail.TagName  | filterContent}}</span></li>
+                <li><em>{{$t("local")}}:</em><span>{{detail.Prov}}{{detail.City}}{{detail.Area}}{{detail.Name}}</span></li>
+                <li><em>{{$t("memo")}}:</em><span>{{detail.Memo  | filterContent}}</span></li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {},
+                titletext:this.$t('Detection') + this.$t('detail'),
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            writeData() {
+                let content = this.$route.query.detector;
+                this.detail = JSON.parse(content);
+                console.log(this.detail);
+            }
+        },
+        filters: {
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        },
+        components: {}
+    }
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+    /*mu-header*/
+    /deep/ .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+
+    #pages {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 176 - 0
online/src/page/enterpriseDetail.vue

@@ -0,0 +1,176 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Company details')">
+            <router-link to="/enterprisemanage" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <h5>{{detail.ComName}}</h5>
+                <ul>
+                    <li><em>{{$t("Enterprise name")}}:</em><span>{{detail.ComName}}</span></li>
+                    <li><em>{{$t("Enterprise types")}}:</em><span>{{ComType}}</span></li>
+                    <li>
+                        <em>{{$t("Enterprise address")}}:</em><span>{{detail.ProvCode}}{{detail.CityCode}}{{detail.AreaCode}}{{detail.Addr}}</span>
+                    </li>
+                    <li><em>{{$t("Subordinate supervision")}}:</em><span>
+                        <em v-for="(org,index) in detail.Orgs">{{org.Orgname}} <i
+                                v-if="detail.Orgs.length-1 != index">、</i></em>
+                    </span></li>
+                    <li><em>{{$t("Contacts")}}:</em><span>{{Legal}}</span></li>
+                    <li><em>{{$t("phone")}}:</em><span>{{Phone}}</span></li>
+                </ul>
+            </div>
+        </div>
+    </div>
+
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {},
+                // Legal:'',
+                // Phone:'',
+                // ComType:'',
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed: {
+            Legal() {
+                if (this.detail.Legal == '' || this.detail.Legal == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+            Phone() {
+                if (this.detail.Phone == '' || this.detail.Phone == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+            ComType() {
+                if (this.detail.ComType == '' || this.detail.ComType == undefined) {
+                    return this.$t('nothing')
+                } else {
+                    return this.detail.Legal
+                }
+            },
+        },
+        methods: {
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComInfoDetail';
+                let param = {
+                    token: localStorage.token,
+                    comId: that.$route.query.ComId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.detail = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        position: absolute;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        top: 0;
+        bottom: 0;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 376 - 0
online/src/page/enterprisemanage.vue

@@ -0,0 +1,376 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Business management')">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+            <mu-button flat color="primary" slot="right" @click="showPanel">{{btnText}}</mu-button>
+        </mu-appbar>
+        <mu-bottom-sheet :open.sync="popupVisible" @close="whenClose">
+            <div class="modal-content">
+                <div class="modal-body">
+                    <div class="location">
+                        <span>{{$t("query criteria")}}</span>
+                        <cityPicker></cityPicker>
+                        <span>{{$t("Keyword query")}}</span>
+                        <input type="text" placeholder="" v-model="keywords">
+                    </div>
+                </div>
+                <div class="modalBottom">
+                    <div class="reset" @click="resetModal">
+                        {{$t("Reset")}}
+                    </div>
+                    <div class="pullUp" @click="searchModal">
+                        {{$t("query")}}
+                    </div>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <li v-for="list in stus" v-if="lists" @click="goPage(list)">
+                    <div class="lt">
+                        <div class="rowTop">
+                            <h5>{{list.ComName}}</h5>
+                            <span>{{list.stusType}}</span>
+                            <!--<span>{{list.ComType | typeFileter}}</span>-->
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.ProvCode}}{{list.CityCode}}{{list.AreaCode}}</span>
+                            <span class="pull-right" v-if="list.Orgs">{{list.Orgs[0].Orgname}}</span>
+                        </div>
+                    </div>
+                    <div class="rt">
+                        <mu-icon value="keyboard_arrow_right"></mu-icon>
+                    </div>
+                </li>
+                <div class="tips" v-if="lists">{{$t("total")}}{{lists.length}} {{$t("enterprise")}}</div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+    import cityPicker from '../components/cityPicker'
+
+    export default {
+        data() {
+            return {
+                popupVisible: false,//true false
+                keywords: '',
+                btnText: this.$t("search"),
+                lists: []
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed: {
+            stus() {
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v) => {
+                    switch (parseInt(v.Status)) {
+                        case 1:
+                            text = that.$t('hotel');
+                            break;
+                        case 2:
+                            text = that.$t('tavern');
+                            break;
+                        case 3:
+                            text = 'KTV';
+                            break;
+                        case 4:
+                            text = that.$t('Prison');
+                            break;
+                        default:
+                            text = that.$t('other');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        methods: {
+            // 重置
+            resetModal() {
+                this.keywords = '';
+                localStorage.defaultProv = '';
+                localStorage.defaultCity = '';
+                localStorage.defaultArea = '';
+            },
+            showPanel() {
+                this.popupVisible = true;
+                this.btnText = this.$t("close");
+            },
+            whenClose() {
+                this.popupVisible = false;
+                this.btnText = this.$t("search");
+            },
+            // 查询
+            searchModal() {
+                this.writeData();
+                this.popupVisible = false;
+                this.Toast('已查询', 'success');
+            },
+            goPage(list) {
+                this.$router.push({path: '/enterpriseDetail', query: {ComId: list.ComId}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Company/GetComlist';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let prov = localStorage.defaultProv;
+                let city = localStorage.defaultCity;
+                let area = localStorage.defaultArea;
+                let searchs = this.keywords;
+                let param = {
+                    token: localStorage.token,
+                    prov: prov,
+                    city: city,
+                    area: area,
+                    searchs: searchs,
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        components: {
+            cityPicker
+        }
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .mu-appbar .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        overflow-y: scroll;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+    }
+
+    .modalSkip {
+        position: absolute;
+        top: 60px;
+        left: 0;
+        bottom: 0;
+        right: 0;
+        width: 100%;
+        height: 100%;
+        min-height: 736px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: rgba(0, 0, 0, 0.35);
+    }
+
+    .listContainer {
+        width: 100%;
+        height: 100%;
+        display: block;
+        margin: 0 auto;
+        overflow-y: scroll;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-bottom: 100px;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .deteUl .lt {
+        width: 88%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        margin-top: 20px;
+    }
+
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+
+    /*mu-bottom-sheet*/
+    .mu-bottom-sheet {
+        top: 60px !important;
+        bottom: 405px;
+        background: none;
+    }
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        /*padding-bottom: 40px;*/
+    }
+
+    .location span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location input {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        text-indent: 10px;
+    }
+
+    .modal-content {
+        width: 100%;
+        display: block;
+        margin: 0 auto;
+        z-index: 99999;
+        overflow: hidden;
+    }
+
+    .modal-body {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 20px;
+        padding-left: 5%;
+        padding-right: 5%;
+        padding-bottom: 40px;
+    }
+
+    .modalBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .modalBottom .reset {
+        width: 50%;
+        float: left;
+        height: 40px;
+        line-height: 40px;
+        background: #FFF6CF;
+        text-align: center;
+    }
+
+    .modalBottom .pullUp {
+        width: 50%;
+        float: right;
+        height: 40px;
+        line-height: 40px;
+        background: #FFCC00;
+        text-align: center;
+    }
+</style>

+ 22 - 0
online/src/page/index.vue

@@ -0,0 +1,22 @@
+<template>
+    <div id="index">
+        <keep-alive>
+            <router-view></router-view>
+        </keep-alive>
+    </div>
+</template>
+
+<script>
+    export default {
+        data() {
+            return {}
+        },
+    }
+</script>
+<style>
+    #index {
+        height: 100%;
+        padding-bottom: 40px;
+        overflow-y: scroll;
+    }
+</style>

+ 600 - 0
online/src/page/lesson.vue

@@ -0,0 +1,600 @@
+<template>
+  <div class="pages">
+    <img src="../static/images/main/banner.png" height="121" width="414"/>
+    <h5 class="lessonName">
+      {{ lessonName }}
+    </h5>
+    <!--<mu-tabs :value.sync="active" color="#F2F2F2" indicator-color="#33CAF7" v-if="reFresh">-->
+    <!--<mu-tab v-for="(day,i) in weeks">{{ day.name }} <br> <em>{{ day.data }}</em></mu-tab>-->
+    <!--</mu-tabs>-->
+    <div class="tabs">
+      <div :class="[{'tab':true},{'activeTab':i == active}]" v-for="(day,i) in weeks" @click="changeActive(i)">
+        {{ day.name }} <br> <em>{{ day.data }}</em>
+      </div>
+    </div>
+    <bottomTab :curTab="thisTab"></bottomTab>
+    <div class="context">
+      <ul class="list">
+        <li v-for="(l,index) in previewDate"
+            :style="{background:l.ClassColor}"
+        >
+          <em>
+            {{ l.BeginStr }} - {{ l.EndStr }}
+          </em>
+          <span>
+                         {{ l.ClassName }}
+                    </span>
+        </li>
+      </ul>
+    </div>
+
+  </div>
+</template>
+
+<script>
+import axios from 'axios';
+import bottomTab from '../components/bottomTab'
+import {
+  SchoolTimeQueryByDate,
+  QueryNextWeek,
+} from '../api/getApiRes.js'
+
+let qs = require('qs');
+import Global from '../Global.js'
+
+export default {
+  data() {
+    return {
+      lessonName: '本周课程表',
+      num: 0,
+      thisTab: '预约课程',
+      active: 0,
+      sum: 0,
+      openAlert: false,
+      reFresh: true,
+      list: [],
+      previewDate: [],
+      weeks: [],
+      dialog: {
+        id: '',
+        name: '',
+        timeLong: '',
+      },
+    }
+  },
+  mounted() {
+    this.getQueryNextWeek();
+  },
+  beforeRouteEnter(to, from, next) {
+    next(vm => {
+      //因为当钩子执行前,组件实例还没被创建
+      // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
+      if (to.name == 'appoint') {
+        this.getQueryNextWeek();
+      }
+    });
+  },
+  watch: {
+    '$route'(to) {
+      if (to.name == 'lesson') {
+        this.getQueryNextWeek();
+      }
+    },
+    'active'() {
+      this.getList();
+    }
+  },
+  methods: {
+    changeActive(i) {
+      this.active = i;
+    },
+    getQueryNextWeek() {
+      console.log(333);
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        shopId: this.$route.query.shopId,
+      };
+      let postdata = qs.stringify(param);
+      this.weeks = [];
+      QueryNextWeek(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          this.HaveDays = json.Rs;
+          this.getFurtherDays(json.Rs);
+        } else {
+          that.list = [];
+          that.$message.error(json.Memo);
+        }
+      })
+    },
+    // 获取未来7天的
+    getFurtherDays(HaveDays) {
+      let now = new Date();
+      let nowTime = now.getTime();
+      let oneDayTime = 24 * 60 * 60 * 1000;
+      let days = '';
+      let item = [];
+      let month = 0;
+      let day = 0;
+      this.weeks = [];
+      for (let i = 0; i < HaveDays; i++) {
+        days = new Date(nowTime + (i) * oneDayTime);//显示周日
+        month = days.getMonth() + 1;
+        day = days.getDate();
+        month = month < 10 ? '0' + month : month;
+        day = day < 10 ? '0' + day : day;
+        item = {
+          name: this.numberToWeek(days.getDay()),
+          data: days.getMonth() + 1 + '月' + days.getDate() + '日',
+          orderDate: days.getFullYear() + '-' + month + '-' + day
+        };
+        this.weeks.push(item);
+      }
+      this.today = this.weeks[0].name;
+      this.getList();
+    },
+    numberToWeek(val) {
+      switch (parseInt(val)) {
+        case 1:
+          return '星期一';
+          break;
+        case 2:
+          return '星期二';
+          break;
+        case 3:
+          return '星期三';
+          break;
+        case 4:
+          return '星期四';
+          break;
+        case 5:
+          return '星期五';
+          break;
+        case 6:
+          return '星期六';
+          break;
+        case 0:
+          return '星期天';
+          break;
+      }
+    },
+    getList() {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        shopId: this.$route.query.shopId,
+        queryDate: that.weeks[that.active].orderDate,//(字符串 年-月-日  格式)
+      };
+      let postdata = qs.stringify(param);
+      that.previewDate = [];
+      SchoolTimeQueryByDate(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          // that.BigTitle = row.Name;
+          // that.smallTitle = row.BeginDate + '至' + row.EndDate;
+          that.previewDate = json.Rs;
+          // 前台排序
+          that.previewDate.sort((a, b) => a.ClassIndex - b.ClassIndex);//升序
+          that.previewShow = true;
+        } else {
+          that.$message.error(json.Memo);
+        }
+      })
+    },
+  },
+  components: {
+    bottomTab
+  }
+}
+</script>
+
+
+<style scoped>
+.pages {
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+.lessonName {
+  width: 100%;
+  height: 40px;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  text-align: center;
+  font-size: 18px;
+}
+
+/*mu-header*/
+.mu-primary-color {
+  line-height: 60px;
+  height: 60px;
+  background: url("../static/images/comm/headerBg.png") top center no-repeat;
+  background-size: 100%;
+}
+
+/deep/ .mu-appbar-left {
+  padding-top: 15px;
+}
+
+/deep/ .material-icons {
+  color: #fff;
+}
+
+/deep/ .mu-appbar-title {
+  text-align: center;
+}
+
+/deep/ .mu-tabs {
+  display: flex;
+  overflow-x: scroll;
+  float: left;
+}
+
+/deep/ .mu-tab {
+  width: 85px;
+  min-width: 85px;
+  float: left;
+  height: 51px;
+  margin-right: 6px;
+}
+
+/*/deep/ .mu-tab:nth-child(5) {*/
+/*    margin-right: 0px;*/
+/*}*/
+
+/deep/ .mu-tab-wrapper {
+  height: 51px;
+  background: #fff;
+  color: #363636;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  border-radius: 8px 8px 0px 0px;
+  font-size: 14px;
+}
+
+/deep/ .mu-tab-active .mu-tab-wrapper {
+  height: 56px;
+  border-radius: 8px 8px 0px 0px;
+  background: #33caf7;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  color: #fff;
+}
+
+/deep/ .mu-tab-wrapper em {
+  font-size: 12px;
+}
+
+.sum {
+  width: 100%;
+  height: 55px;
+  line-height: 55px;
+  background: #fff;
+  font-family: "PingFang SC";
+  font-weight: 300;
+  font-size: 16px;
+  text-align: center;
+  color: #909090;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+.green {
+  color: #37CB00;
+}
+
+.red {
+  color: #F8847F;
+}
+
+.list {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  margin-top: 8px;
+  padding-bottom: 30px;
+  border-top: 5px solid #fff;
+}
+
+.list li {
+  width: 100%;
+  height: 50px;
+  margin: 0;
+  border-bottom: 1px solid #fff;
+  list-style: none;
+  line-height: 50px;
+  /*padding-top: 16px;*/
+  /*padding-bottom: 16px;*/
+}
+
+li em {
+  width: 50%;
+  float: left;
+  padding-left: 10%;
+  /*height: 40px;*/
+  /*line-height: 40px;*/
+  overflow: hidden;
+  border-right: 1px solid #fff;
+  color: #333;
+  /*font-size: 16px;*/
+}
+
+li span {
+  width: 45%;
+  float: right;
+  padding-left: 3px;
+  /*height: 40px;*/
+  /*line-height: 40px;*/
+  overflow: hidden;
+  text-align: center;
+  color: #333;
+  /*font-size: 16px;*/
+}
+
+.list .dotContainer {
+  width: 50px;
+  float: left;
+  height: 60px;
+  padding-left: 22px;
+  padding-top: 10px;
+}
+
+.dotContainer .dot {
+  width: 12px;
+  height: 12px;
+  background: #37cb00;
+  border-radius: 250px;
+  float: left;
+}
+
+.cubes {
+  width: 12px;
+  height: 12px;
+  background: #f8847f;
+  float: left;
+}
+
+.tri {
+  width: 12px;
+  height: 12px;
+  background: url("../static/images/appoint/tri.png") top center no-repeat;
+  background-size: 100% 100%;
+  float: left;
+}
+
+.x {
+  width: 12px;
+  height: 12px;
+  background: url("../static/images/appoint/x.png") top center no-repeat;
+  background-size: 100% 100%;
+  float: left;
+}
+
+
+.yellowLi {
+  background: #FFFBED;
+}
+
+.redLi {
+  background: #FFF7F7;
+}
+
+.greenLi {
+  background: #F7FFF4;
+}
+
+.whiteLi {
+  background: #fff;
+}
+
+.list li .title {
+  width: 90px;
+  height: 60px;
+  float: left;
+}
+
+li .title h5 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #3b3b3b;
+}
+
+li .title span {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-weight: normal;
+  font-size: 12px;
+  text-align: left;
+  color: #909090;
+}
+
+.list li .current {
+  width: 120px;
+  height: 60px;
+  float: left;
+}
+
+li .current h5 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #3b3b3b;
+}
+
+.current h5 em {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+}
+
+.current span {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 12px;
+  text-align: left;
+  color: #909090;
+}
+
+.appointBtn {
+  width: 79px;
+  height: 37px;
+  border-radius: 18.5px;
+  background: #fff;
+  float: right;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 18px;
+  margin-right: 2%;
+}
+
+.greenBtn {
+  border: 1px solid #37cb00;
+  color: #37cb00;
+}
+
+.redBtn {
+  border: 1px solid #F8847F;
+  color: #F8847F;
+}
+
+.yellowBtn {
+  border: 1px solid #FFB43C;
+  color: #fff;
+  background: #FFB43C;
+}
+
+.disableBtn {
+  border: 1px solid #C9C9C9;
+  color: #C9C9C9;
+}
+
+/deep/ .mu-tabs-center {
+  display: flex;
+  overflow-x: auto;
+  overflow-y: hidden;
+  white-space: nowrap;
+}
+
+/deep/ .mu-tabs-center::-webkit-scrollbar {
+  display: none;
+}
+
+/deep/ .mu-modal-inner {
+  width: 90%;
+  float: left;
+}
+
+/deep/ .mu-tab-link-highlight {
+  display: none !important;
+}
+
+li .title span.lessons {
+  width: auto;
+  padding: 1px 11px;
+  border-radius: 250px;
+  float: left;
+  text-align: center;
+  color: #000;
+  font-size: 14px;
+}
+
+/deep/ .mu-avatar {
+  position: fixed;
+  bottom: 10%;
+  float: right;
+  right: 10%;
+}
+
+.tabs {
+  width: 100%;
+  justify-content: space-between;
+  white-space: nowrap;
+  overflow-y: hidden;
+  overflow-x: scroll;
+  display: flex;
+  border-bottom: 1px solid #ccc;
+}
+
+.tab {
+  font-size: 14px;
+  min-width: 72px;
+  max-width: 264px;
+  background: none;
+  -webkit-appearance: none;
+  -moz-appearance: none;
+  appearance: none;
+  text-decoration: none;
+  border: none;
+  outline: none;
+  color: inherit;
+  position: relative;
+  line-height: normal;
+  -webkit-transition: all .45s cubic-bezier(.445, .05, .55, .95);
+  transition: all .45s cubic-bezier(.445, .05, .55, .95);
+  width: 85px;
+  float: left;
+  height: 51px;
+  margin-right: 6px;
+  cursor: pointer;
+  line-height: 20px;
+  padding-top: 4px;
+  text-align: center;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  border: 1px solid #ccc;
+  border-bottom: 0;
+}
+
+.tab.activeTab {
+  color: #fff;
+  background-color: #2196f3;
+  color: hsla(0, 0%, 100%, .7);
+}
+
+@media only screen and (max-width: 640px) {
+
+}
+
+@media only screen and (max-width: 480px) {
+
+}
+
+@media only screen and (max-width: 375px) {
+
+}
+
+@media only screen and (max-width: 360px) {
+
+}
+
+@media only screen and (max-width: 320px) {
+  .list .dotContainer {
+    width: 20px;
+    padding-left: 5px;
+  }
+
+  .list li .title {
+    width: 85px;
+  }
+}
+
+@media only screen and (min-width: 641px) {
+
+}
+</style>

+ 354 - 0
online/src/page/listDetail.vue

@@ -0,0 +1,354 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('detail')">
+                <span @click="$router.back(-1)" slot="left">
+                       <mu-icon value="arrow_back"></mu-icon>
+                </span>
+        </mu-appbar>
+        <div class="container listContainer">
+            <div class="row ">
+                <ul class="deteUl" v-if="selected == 1">
+                    <li v-if="!lists.length">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="list in lists" v-if="lists">
+                        <div class="rowTop"><h5>{{list.Name}}</h5>
+                            <span v-if="list.DangerLevel == -1" class="green">{{$t("other")}}</span>
+                            <span v-if="list.DangerLevel == 0" class="green">{{$t("white")}}</span>
+                            <span v-if="list.DangerLevel == 2" class="yellow">{{$t("deal")}}</span>
+                            <span v-if="list.DangerLevel == 3" class="red">{{$t("warning")}}</span>
+                            <span v-if="list.DangerLevel == 4" class="red">{{$t("danger")}}</span>
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.MacCom.length > 16 ? list.MacCom.slice(0, 16)+'...':list.MacCom}}</span>
+                            <s>{{list.Mac}}</s>
+                        </div>
+                        <div class="rowBottom">
+                            {{list.Memo}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="lists"> {{$t("total")}} {{lists.length}} {{$t("pcs")}} {{$t("wireless device")}}</s>
+                </ul>
+                <ul class="phoneUl" v-if="selected == 2">
+                    <li v-if="!phones">
+                        <h4>{{$t("no use data")}}</h4>
+                    </li>
+                    <li v-for="phone in phones" v-if="phones">
+                        <div class="peTop">
+                            {{phone.DetectorName}} <span>{{phone.RegionName}}</span>
+                        </div>
+                        <div class="peMemo">
+                            {{phone.Signalstr == ''?$t('No mobile signal detected'):phone.Signalstr}}
+                        </div>
+                    </li>
+                    <s class="tips" v-if="phones">  {{$t("total")}}{{phones.length}} {{$t("pcs")}} {{$t("Detection")}}</s>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                selected: "1",
+                location: {
+                    ComName: this.$route.query.comName,
+                    Region: this.$route.query.Region,
+                },
+                RegionList: [],
+                unite: {
+                    ComName: '',
+                    Legal: '',
+                    Introduction: '',
+                },
+                lists: [],
+                phones: [],
+            }
+        },
+        mounted() {
+            this.readList();
+        },
+        methods: {
+            // 读取无线设备具体分布
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectDeviceDetailList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: this.$route.query.RegionId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            goListDetail(list) {
+                this.$router.push({path: '/list', query: {RegionId: list.RegionId}});
+            },
+            readPhone() {
+                const that = this;
+                let url = headapi + 'v1/Detector/SignalDeviceByregion';
+                let param = {
+                    token: localStorage.token,
+                    regionid: this.$route.query.RegionId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.phones = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+ #pages {
+     width: 100%;
+     overflow: hidden;
+     overflow-y: scroll;
+     display: block;
+     margin: 0 auto;
+     height: 100%;
+     position: absolute;
+     top: 0;
+     bottom: 0;
+     background: #f2f2f2;
+     padding-bottom: 20px;
+ }
+    .detail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-top: 0px;
+        padding-bottom: 20px;
+        padding-left: 2%;
+        padding-right: 2%;
+        margin-bottom: 10px;
+        background: #fff;
+    }
+    .detail ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 2%;
+        padding-right: 2%;
+    }
+
+    .detail h5 span {
+        font-size: 16px;
+    }
+
+    .detail h5 em {
+        float: right;
+        color: #666666;
+        font-size: 12px;
+        font-weight: normal;
+        text-align: right;
+    }
+
+    .detail p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #666666;
+        line-height: 16px;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected {
+        border-bottom: 3px solid #FFA200;
+        color: #FFA200;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected .mint-tab-item-label {
+        color: #FFA200;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .rowDetail span {
+        float: left;
+    }
+
+    .rowDetail s {
+        float: right;
+    }
+
+    .rowBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+    }
+
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 11px 4%;
+        font-size: 12px;
+        color: #999999;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+    }
+
+    .phoneUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .phoneUl li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .phoneUl .peTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 16px;
+        margin-bottom: 10px;
+    }
+
+    .peTop span {
+        float: right;
+        text-align: right;
+        font-size: 14px;
+    }
+
+    .peMemo {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 14px;
+        color: #999999;
+    }
+    .deteUl {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    .deteUl li h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-weight: normal;
+        line-height: 30px;
+    }
+</style>

+ 666 - 0
online/src/page/login.vue

@@ -0,0 +1,666 @@
+<template>
+  <div id="skin-blur-violate">
+    <section id="login">
+      <header>
+        <img src="../static/images/login/logo.png" height="109" width="109" id="logo"/>
+        <img src="../static/images/login/title.png" height="100%" width="274px"/>
+      </header>
+      <div class="clearfix"></div>
+      <!-- Login -->
+      <form class="box tile animated active" id="box-login">
+        <h2 class="m-t-0 m-b-15"></h2>
+        <div class="rowHeight">
+          <input type="text" class="login-control login_account" placeholder="输入手机号"
+                 v-model="login.phone">
+        </div>
+        <div class="rowHeight">
+          <input type="number" class="login-control login_valid" placeholder="输入右侧图形码"
+                 v-model="login.uservalid">
+          <img id="imgValidcode" :src="valImgSrc" :title="InvisibilityGiveitatry" @click="getValImgSrc">
+        </div>
+        <div class="rowHeight">
+          <input type="number" class="login-control login_pwd" placeholder="输入验证码" v-model="login.userpwd"
+                 @keyup.enter="pwdLoginBtn">
+          <mu-button id="getValidSms" :disabled="getValidSmsState" color="success" @click="getValidSmsBtn">
+            {{ btnText }}
+          </mu-button>
+        </div>
+        <div class="btn_center">
+          <span class="btn btn-md login_btn" @click="pwdLoginBtn">登    录</span>
+        </div>
+      </form>
+    </section>
+    <mu-snackbar :position="normal.position" :open.sync="normal.open" :color="normal.color">
+      {{ normal.message }}
+      <mu-button flat slot="action" color="secondary" @click="normal.open = false">{{ "close" }}</mu-button>
+    </mu-snackbar>
+  </div>
+</template>
+
+<script>
+import {
+  SignIn,
+  GenVerifyPic,
+  GetPhoneVFCode,
+  PhoneSignIn,
+  WXBind,
+  testSelect
+} from '../api/getApiRes.js'
+
+let qs = require('qs');
+
+export default {
+  data() {
+    let samepass = (rule, value, callback) => {
+      if (value !== this.form.newpwd) {
+        callback(new Error('两次输入密码不一致!'));
+      } else {
+        callback();
+      }
+    };
+    let pwdPass = (rule, value, callback) => {
+      let re = /^[0-9a-zA-Z_]{1,}$/;
+      if (value.search(re) == -1) {
+        callback(new Error('错了哦,密码只能由字母、数字及下划线组成'));
+      } else {
+        callback()
+      }
+    };
+    let phonetest = (rule, value, callback) => {
+      let re = /^1[3|4|5|7|8|9][0-9]\d{8}$/;
+      if (value.search(re) == -1) {
+        callback(new Error('错了哦,手机号码格式不正确'));
+      } else {
+        callback()
+      }
+    };
+    return {
+      Password: "Password",
+      VerificationCode: "Verification Code",
+      InvisibilityGiveitatry: "无效?再点一下试试吧!",
+      valImgSrc: '',//
+      picId: '',//
+      getValidSmsState: false,//
+      overtime: '',
+      btnText: '获取验证码',
+      normal: normal,
+      login: {
+        phone: '',
+        userpwd: '',
+        uservalid: '',
+      },
+      rules: {
+        username: [
+          {required: true, message: '请输入用户名', trigger: 'blur'},
+          {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+        ],
+        phone: [
+          {required: true, message: '请输入手机号', trigger: 'blur'},
+          {min: 11, max: 12, message: '手机号长度是11位', trigger: 'blur'},
+          {validator: phonetest, trigger: 'blur'}
+        ],
+        re_phonevalid: [
+          {required: true, message: '请输入验证码', trigger: 'blur'},
+          {min: 4, max: 4, message: '长度在 4 个字符', trigger: 'blur'},
+        ],
+        newpwd: [
+          {required: true, message: '请输入新密码', trigger: 'blur'},
+          {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+          {validator: pwdPass, trigger: 'blur'}
+        ],
+        again: [
+          {required: true, message: '请输入确认密码', trigger: 'blur'},
+          {min: 6, max: 32, message: '长度在 6 到 32 个字符', trigger: 'blur'},
+          {validator: pwdPass, trigger: 'blur'},
+          {validator: samepass, trigger: 'blur'},
+        ],
+      }
+    }
+  },
+  mounted() {
+    // 入口状态有 3 种
+    // 1.全新登入,拿weixinId 拿验证码 ,绑定 ,登陆
+    // 2.token 未失效用户,直接进入内页,继续凭token使用
+    // 3.token 已失效用户,删掉本地token ,重新按照1的模式登陆
+    if (localStorage.token) {
+      // 凭借旧token直接登陆
+      this.$router.push({path: '/'});
+    } else {
+      // 获取图形验证码
+      this.getValImgSrc();
+      this.overtime = new Date();
+      let from = this.$route.query.from;//获取来源
+      let userAgent = navigator.userAgent;
+      let host = window.location.host;
+      console.log(host);
+      if (from == 'app' || host == '192.168.0.162:8080') {//判断是否微信浏览器
+        // 浏览器测试
+        console.log('from app & brower');
+      } else {
+        console.log('form wx');
+        this.checkcode();
+      }
+    }
+  },
+  methods: {
+    // 获取CODE
+    checkcode() {
+      // 0213tIFa1fBjAz0OVDIa1LfXwc03tIFK
+      if (this.getUrlKey('state') == 123) {
+        // 取到值了
+        localStorage.code = this.getUrlKey('code');
+        // console.log('code:' + localStorage.code);
+      } else {
+        // 第一次加载
+        this.GetOpenId();
+      }
+    },
+    // 获取公众号ID
+    GetOpenId() {
+      let origin = location.href;
+      // let origin = 'http://wx.xfeilong.com';
+      let urlNow = encodeURIComponent(origin);
+      let scope = 'snsapi_userinfo';    //snsapi_userinfo   //静默授权 用户无感知
+      let appid = 'wx36cb8b6661d71811';//正式
+      let state = '123';
+      let url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + appid + '&redirect_uri=' + urlNow + '&response_type=code&scope=' + scope + '&state=' + state + '#wechat_redirect';
+      self.location = url;
+    },
+    getUrlKey(name) {
+      return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ""])[1].replace(/\+/g, '%20')) || null;
+    },
+    // 获取验证码
+    getValidSmsBtn() {
+      let that = this;
+      let phone = that.login.phone;
+      let uservalid = that.login.uservalid;
+      if (!phone) {
+        that.Toast('手机号不能为空');
+        return false
+      }
+      if (phone.length != 11) {
+        that.Toast('手机号只能是11位');
+        return false
+      }
+      if (!globalCheckPhone(phone)) {
+        that.Toast('手机号格式不正确');
+        return false
+      }
+      if (!uservalid) {
+        that.Toast('图形验证码不能为空');
+        return false
+      }
+      if (uservalid.length != 4) {
+        that.Toast('图形验证码只能是4位');
+        return false
+      }
+      let param = {
+        token: localStorage.token,
+        phone: phone,
+        codeType: 1,
+        picId: this.valImgId,
+        picCode: uservalid,
+      };
+      let postdata = qs.stringify(param);
+      GetPhoneVFCode(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          that.Toast('短信验证码已发送', 'success');
+          that.calcTime();
+        } else {
+          that.Toast(json.Memo);
+        }
+      })
+    },
+    calcTime() {
+      // 短信倒数计时
+      let countdown = 60;
+      let that = this;
+      //设置button效果,开始计时
+      that.getValidSmsState = true;
+      that.btnText = countdown + "S"
+      //启动计时器,1秒执行一次
+      let timer = setInterval(function () {
+        if (countdown == 0) {
+          clearInterval(timer);//停止计时器
+          that.getValidSmsState = false;
+          that.btnText = "重新发送"
+        } else {
+          countdown--;
+          that.btnText = countdown + "S"
+        }
+      }, 1000);
+    },
+    clearLogin() {
+      this.login.username = '';
+      this.login.userpwd = '';
+      this.login.uservalid = '';
+      this.getValImgSrc();
+    },
+    // 点击验证码切换
+    getValImgSrc() {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        width: 100,
+        height: 30,
+        noiseCount: 1,
+        length: 4,
+        source: 123456789,
+      };
+      let postdata = qs.stringify(param);
+      GenVerifyPic(postdata).then(res => {
+        let json = res;
+        that.valImgSrc = json.Pic;
+        that.valImgId = json.Id;
+      })
+    },
+    // pwd登录
+    pwdLoginBtn() {
+      let that = this;
+      let phone = this.login.phone;
+      let userpwd = this.login.userpwd;
+      // 重置验证码超时
+      that.overtime = new Date();
+      if (!that.globalValid(phone, 10, 12, '手机号', that)) return;
+      if (!that.globalValid(userpwd, 5, 7, '短信验证码', that)) return;
+      this.loginInfo();
+    },
+    // 校验内容长度
+    globalValid(data, mins, maxs, text, that) {
+      let thisVal = data;
+      let thisLeng = thisVal.length;
+      let min = parseInt(mins);
+      let max = parseInt(maxs);
+      let dispalyMin = min + 1;
+      if (thisVal == '') {
+        this.Toast(text + ' ' + '不能为空');
+        return false
+      } else if (thisLeng <= min) {
+        this.Toast(text + '最少' + dispalyMin + '字符');
+        return false
+      } else if (thisLeng > max) {
+        this.Toast(text + '超过限制长度');
+        return false
+      } else {
+        return true
+      }
+    },
+    // pwd登陆
+    loginInfo: function () {
+      const that = this;
+      let current = new Date();
+      let betweenTime = current - that.overtime;
+      let s = 120;
+      if (betweenTime > s * 1000) {
+        that.changeValImg();
+        that.$toast.message('验证码已超时,请重新输入');
+        return false
+      }
+      let param = {
+        phone: that.login.phone,
+        code: that.login.userpwd,
+        channel: 3
+      };
+      let postdata = qs.stringify(param);
+      PhoneSignIn(postdata).then(res => {
+        if (res.Code == 0) {
+          that.res = res.Rs;
+          // 使用token做免校验登陆
+          localStorage.token = res.Rs.token;
+          // 如果是wx登陆就执行绑定操作
+          let from = this.$route.query.from;//获取来源
+          if (from != 'app') {
+            that.bindWx();
+          }
+
+          // 607862e8828013be90c2ccb78468b43a
+          // test
+          that.$router.push({path: '/'});
+        } else {
+          this.getValImgSrc();
+          if (res.Code == 10005) {
+            that.$refs.userpwd.value = '';
+            that.Toast('密码错误,请重新输入');
+          } else {
+            that.Toast(res.Memo + ',错误代码:' + res.Code);
+            that.form.valid = '';
+          }
+        }
+      })
+    },
+    bindWx() {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        code: localStorage.code,
+      };
+      let postdata = qs.stringify(param);
+      WXBind(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          // that.$router.push({path: '/'});
+        } else {
+          // that.Toast(res.Memo + ',错误代码:' + res.Code);
+        }
+      })
+    },
+    getUserInfo(token) {
+      let that = this;
+      let param = {
+        token: token,
+      };
+      let postdata = qs.stringify(param);
+      testSelect(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          var userLevel = json.Rs.Rolesname;
+          localStorage.userLevel = userLevel;
+          localStorage.comId = json.Rs.Comid;
+          localStorage.Insname = json.Rs.Insname;
+          that.$router.push({path: '/'});
+        } else {
+          that.$toast.message(json.Memo);
+        }
+      })
+    }
+  },
+  components: {}
+}
+</script>
+
+<style scoped>
+#skin-blur-violate {
+  position: relative;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  background: #3B3B3B;
+  background: url("../static/images/login/bg.png") top center no-repeat;
+  background-size: 100% 100%;
+}
+
+#login {
+  width: 90%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+#login .box {
+  margin: 0 auto;
+  position: inherit;
+  margin-top: 20px;
+  border-radius: 9px;
+  padding: 20px 20px;
+}
+
+h1 {
+  color: #FFA200;
+  font-size: 30px;
+}
+
+header p {
+  font-size: 14px;
+  color: #7B7B7B;
+}
+
+#login header {
+  text-align: center;
+  margin-top: 15%;
+}
+
+#box-login h2 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  margin-bottom: 20px;
+  text-align: center;
+  font-size: 24px;
+  color: #fff;
+}
+
+#tableBordered {
+  margin: 0;
+  padding: 0;
+}
+
+#tableBordered h5 {
+  margin: 0;
+  text-align: center;
+  padding: 0;
+}
+
+#login .box {
+  margin: 0 auto;
+  position: inherit;
+  margin-top: 20px;
+  border-radius: 9px !important;
+}
+
+#login header {
+  text-align: center;
+  margin-top: 15%;
+}
+
+#tableBordered {
+  margin: 0;
+  padding: 0;
+}
+
+#tableBordered h5 {
+  margin: 0;
+  text-align: center;
+  padding: 0;
+}
+
+#imgValidcode {
+  position: relative;
+  float: right;
+  /*bottom: 54px;*/
+  /*width: 100px;*/
+  width: 30%;
+  height: 50px;
+  background: #eee;
+}
+
+.login_btn {
+  width: 100%;
+  height: 50px;
+  line-height: 50px;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  margin-top: 42px;
+  background: #E75296;
+  color: #fff;
+  font-size: 14px;
+  text-align: center;
+  border: none;
+  padding: 0;
+  font-size: 24px;
+  margin-bottom: 3%;
+}
+
+.clear_btn {
+  width: 100%;
+  height: 40px;
+  line-height: 40px;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  background: rgba(255, 255, 255, 0.32);
+  color: #FFCC00;
+  font-size: 14px;
+  text-align: center;
+  border: none;
+  padding: 0;
+}
+
+header p {
+  margin-top: 10px;
+}
+
+#login .login-control {
+  width: 100%;
+  height: 50px;
+  line-height: 50px;
+  background: rgba(255, 255, 255, 0.4);
+  margin-bottom: 3px;
+  text-indent: 10px;
+  border: none;
+
+}
+
+#login .login-control::placeholder {
+  color: #000000;
+  font-size: 16px;
+}
+
+#logo {
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  margin-top: 10%;
+  margin-bottom: 10px;
+}
+
+.rowHeight {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  height: 50px;
+  margin-bottom: 3px;
+}
+
+#getValidSms {
+  /*width: 100px;*/
+  width: 30%;
+  height: 50px;
+  background: #fff;
+  border: 1px solid #fff;
+  opacity: 0.6;
+  position: relative;
+  /*bottom: 55px;*/
+  float: right;
+  text-align: center;
+  color: #E75296;
+  line-height: 20px;
+  font-size: 12px;
+  min-width: 30px;
+}
+
+#login .login_valid {
+  /*width: 173px;*/
+  width:65%;
+  float: left;
+}
+
+#login .login_pwd {
+  width: 173px;
+  float: left;
+}
+
+@media only screen and (max-width: 640px) {
+
+}
+
+@media only screen and (max-width: 480px) {
+  #login .login_valid {
+    /*width: 195px;*/
+    width:65%;
+  }
+
+  #login .login_pwd {
+    /*width: 195px;*/
+    width:65%;
+  }
+}
+
+@media only screen and (max-width: 414px) {
+  #login .login_valid {
+    width:65%;
+    /*width: 223px;*/
+  }
+
+  #login .login_pwd {
+    /*width: 223px;*/
+    width:65%;
+  }
+}
+
+@media only screen and (max-width: 400px) {
+
+  #login .login_valid {
+    width:65%;
+    /*width: 218px;*/
+  }
+
+  #login .login_pwd {
+    /*width: 218px;*/
+    width:65%;
+  }
+
+  #getValidSms {
+    font-size: 13px;
+  }
+}
+
+@media only screen and (max-width: 375px) {
+  #login .login_valid {
+    /*width: 190px;*/
+    width:65%;
+  }
+
+  #login .login_pwd {
+    /*width: 190px;*/
+    width:65%;
+  }
+
+  #getValidSms {
+    font-size: 14px;
+  }
+}
+
+@media only screen and (max-width: 360px) {
+  #login .login_valid {
+    /*width: 160px;*/
+    width:65%;
+  }
+
+  #login .login_pwd {
+    /*width: 160px;*/
+    width:65%;
+  }
+
+  #getValidSms {
+    font-size: 14px;
+  }
+}
+
+@media only screen and (max-width: 320px) {
+  #login .login_valid {
+    /*width: 144px;*/
+    width:65%;
+  }
+
+  #login .login_pwd {
+    width:65%;
+    /*width: 144px;*/
+  }
+
+  #getValidSms {
+    font-size: 12px;
+  }
+}
+
+
+</style>

+ 407 - 0
online/src/page/mainpage.vue

@@ -0,0 +1,407 @@
+<template>
+    <div id="mainPage">
+        <img class="banner" src="../static/images/main/banner.png"/>
+        <span class="shopNum">
+            俱乐部场馆共 {{ list.length }} 处
+        </span>
+        <ul class="list">
+            <li v-for="l in list" @click="goAppoint(l)" v-if="parseInt(l.Status) == 1">
+                <div class="lt">
+                    <img src="../static/images/main/shop2.jpg" width="100%" height="100%" v-show="parseInt(l.ShopID) == 3"/>
+                    <img src="../static/images/main/shop.jpg" width="100%" height="100%" v-show="parseInt(l.ShopID) == 4"/>
+                    <img src="../static/images/main/shop3.png" width="100%" height="100%" v-show="parseInt(l.ShopID) == 5"/>
+                </div>
+                <div class="rt">
+                    <h4 style="background-color: #FFA310" v-if="l.ShopID == 3">{{ l.ShopName.substr(5,12) }}</h4>
+                    <h4 style="background-color: #37CB00" v-if="l.ShopID == 4">{{ l.ShopName.substr(5,12) }}</h4>
+                    <h4 style="background-color: #028FE1" v-if="l.ShopID == 5">{{ l.ShopName.substr(5,12) }}</h4>
+                    <span>今日预约名额剩余
+              <i v-if="l.RemainOrdernum > 0">{{ l.RemainOrdernum }}</i>
+              <i v-if="l.RemainOrdernum == 0" class="red">{{ l.RemainOrdernum }}</i>
+              人</span>
+                    <span>地址:{{ l.Addr }}</span>
+                    <em class="green" v-if="l.WxStatus == 1 && l.IsJoin ==1">点击预约</em>
+                    <em class="red" v-else>不可预约</em>
+                </div>
+            </li>
+            <div class="tips" v-if="list == ''">
+                <p style="text-align: center">
+                    暂无可预约的门店
+                </p>
+            </div>
+        </ul>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <alert ref="alertPart"></alert>
+    </div>
+</template>
+
+<script>
+    import {
+        ManagerSelfQuery,
+        OrderShopQuery,
+    } from '../api/getApiRes.js'
+
+    import bottomTab from '../components/bottomTab'
+    import alert from '../components/alert'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                thisTab: '预约课程',
+                shopNum: 0,
+                recordNum: 0,
+                Dannum: 0,
+                GetHotelCounts: 0,
+                GetDetectorNum: 0,
+                currShopId: 0,
+                list: [],
+            }
+        },
+        mounted() {
+            this.getManagerSelfQuery();
+            // this.alertInfo(document.body.clientWidth)
+            // navigator.geolocation.getCurrentPosition(function (position) {
+            //   console.log(position.coords.longitude);
+            // },function (err) {
+            //     console.log(err);
+            // })
+        },
+        destroyed() {
+        },
+        watch: {
+            $route(to) {
+                if (to.name == 'main') {
+                    this.getList();
+                }
+            },
+            'active'() {
+                this.getList();
+            }
+        },
+        methods: {
+            alertInfo(info) {
+                this.$refs.alertPart.openSimpleDialog(info);
+            },
+            getManagerSelfQuery() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                ManagerSelfQuery(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        this.currShopId = json.Rs.ShopId;
+                        this.getList();
+                    } else {
+                        that.alertInfo(json.Memo);
+                        if (json.Code == 1010) {
+                            localStorage.clear();
+                            console.log(1010);
+                            that.$router.push({path: '/login'});
+                        }
+                    }
+                })
+            },
+            getList() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                OrderShopQuery(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.list = json.Rs;
+                        if (that.list) {
+                            that.shopNum = json.Rs.length;
+                        }
+                    } else {
+                        that.alertInfo(json.Memo);
+                        // 权限失效后,删掉本地token
+                        if (json.Code == 1004) {
+                            localStorage.clear();
+                            console.log(1010);
+                            this.$router.push({path: '/login'});
+                        }
+                    }
+                })
+            },
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(pages) {
+                this.$router.push({path: pages});
+            },
+            goAppoint(row) {
+                let that = this;
+                if (row.IsJoin == 0) {
+                    that.alertInfo('您不是该店会员,不可预约');
+                    return false
+                }
+                if (row.Status == 2) {
+                    that.alertInfo(row.name + '不可预约');
+                    return false
+                } else {
+                    this.$router.push({
+                        path: '/appoint', query: {
+                            shopId: row.ShopID
+                        }
+                    });
+                }
+            }
+        },
+        beforeRouteEnter(to, from, next) {
+            next(vm => {
+                //因为当钩子执行前,组件实例还没被创建
+                // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
+                if (to.name == '') {
+                    vm.getList();
+                }
+            });
+        },
+        components: {
+            bottomTab, alert
+        }
+    }
+</script>
+
+<style scoped>
+    #mainPage {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    #mainPage .banner {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .goPage {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        height: 50px;
+        line-height: 50px;
+        padding: 0 20px;
+        color: #333;
+        font-size: 18px;
+        border-bottom: 1px solid #f2f2f2;
+    }
+
+    .goPage span {
+        float: left;
+    }
+
+    .goPage i {
+        float: right;
+        margin-top: 12px;
+    }
+
+    .goPage img {
+        overflow: hidden;
+        display: block;
+        width: 8px;
+        height: 14px;
+        float: right;
+        margin-top: 16px;
+        margin-right: 10px;
+    }
+
+    .goTitle i {
+        margin-top: 10px;
+        float: right;
+    }
+
+    .mapContainer {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        max-height: 317px;
+    }
+
+    .shopNum {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 14px;
+        color: #909090;
+        padding-top: 6px;
+        text-align: center;
+    }
+
+    .list {
+        width: 98%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding-left: 1%;
+        padding-right: 1%;
+        margin-top: 10px;
+        padding-bottom: 40px;
+    }
+
+    .list li {
+        width: 100%;
+        background: transparent;
+        margin-bottom: 20px;
+        border-radius: 13px;
+        background: #fff;
+        box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.16);
+        overflow: hidden;
+    }
+
+    .list img {
+        height: 100%;
+        float: left;
+    }
+    .list .lt {
+        width: 33%;
+        height: 100%;
+        overflow: hidden;
+        float: left;
+    }
+
+    .list .rt {
+        /*width: 65%;*/
+        float: left;
+        padding-left: 15px;
+    }
+
+    .list .rt h5 {
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 16px;
+        text-align: left;
+        color: #3b3b3b;
+        margin: 0;
+        margin-top: 3px;
+        margin-bottom: 0px;
+    }
+
+    .list .rt h4 {
+        width: auto;
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 16px;
+        float: left;
+        padding-left: 12px;
+        padding-right: 12px;
+        margin-top: 12px;
+        margin-bottom: 12px;
+        border-radius: 250px;
+        color: #fff;
+        text-align: center;
+    }
+
+    .list .rt span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 12px;
+        text-align: left;
+        color: #909090;
+    }
+
+    .list .rt em {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 16px;
+        padding-right: 1px;
+        margin-top: 5px;
+        float: right;
+        text-align: right;
+    }
+
+    .list .rt em.green {
+        color: #37cb00;
+    }
+
+    .list .rt em.red {
+        color: #F8847F;
+    }
+
+    .red {
+        color: #F8847F;
+    }
+
+    /*响应式调整*/
+    @media only screen and (max-width: 320px) {
+        .list .rt {
+            width: 50%;
+        }
+
+        .list .rt em {
+            font-size: 14px;
+        }
+    }
+
+    @media (min-width: 321px) and (max-width: 344px) {
+        .list .rt {
+            width: 50%;
+        }
+
+        .list .rt em {
+            font-size: 14px;
+        }
+    }
+
+    @media (min-width: 345px) and (max-width: 360px) {
+        .list .rt {
+            width: 57%;
+        }
+    }
+
+    @media (min-width: 361px) and (max-width: 375px) {
+        .list .rt {
+            width: 60%;
+            /*background-color: red;*/
+        }
+    }
+
+    @media (min-width: 376px) and (max-width: 396px) {
+        .list .rt {
+            width: 61%;
+        }
+    }
+
+    @media (min-width: 397px) and (max-width: 414px) {
+        .list .rt {
+            width: 61%;
+        }
+    }
+
+    @media (min-width: 415px) and (max-width: 480px) {
+        .list .rt {
+            width: 61%;
+        }
+    }
+
+    @media (min-width: 481px) and (max-width: 640px) {
+
+    }
+
+</style>

+ 51 - 0
online/src/page/map.vue

@@ -0,0 +1,51 @@
+<template>
+    <div id="map">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <mapPage @drag="dragMap" :curheight="curheight" :divcontainer="'js-container2'"></mapPage>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import mapPage from '../components/mapPage'
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Map'),
+                thisTab:  this.$t('Map'),
+                curheight:  window.screen.height,
+            }
+        },
+        mounted(){
+            console.log(window.screen.height);
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            dragMap() {
+            },
+        },
+      components: {
+          mapPage,appHeader,bottomTab
+      }
+    }
+</script>
+
+<style scoped>
+    #map {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        bottom: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 0px;
+        background: #f2f2f2;
+    }
+</style>

+ 545 - 0
online/src/page/mine.vue

@@ -0,0 +1,545 @@
+<template>
+    <div class="pages">
+        <img src="../static/images/main/banner.png" height="121" width="414"/>
+        <div class="context">
+              <span class="num">
+                会员卡信息
+            </span>
+            <div class="user">
+                <img src="../static/images/mine/User.png" height="53" width="53"/>
+                <span>{{ user.Name }}</span>
+                <em>{{ user.Phone | hidePhone}}</em>
+            </div>
+            <div class="value" v-for="s in schools">
+                <div class="vTitle year" v-if="s.VipType == 1"><i></i>年会员</div>
+                <div class="vTitle price" v-if="s.VipType == 2"><i></i>充值会员</div>
+                <div class="vNum">
+                    <span> {{ s.ShopName }}</span>
+                    <div class="center">
+                        总计{{ s.ClassHourToatal }}课时
+                    </div>
+                    <em v-if="s.VipType == 1">(有效期至{{ s.ExpTime |fmtTime }})</em>
+                </div>
+                <mu-flex class="linear-progress">
+                    <mu-linear-progress mode="determinate" :value="s.ClassHourRemain / s.ClassHourToatal *100"
+                                        :size="10"
+                                        color="secondary"></mu-linear-progress>
+                </mu-flex>
+                <div class="limit">
+                    <em>剩余 {{ s.ClassHourRemain }} 课时</em>
+                    <span>完成 {{ s.ClassHourConsume }} 课时</span>
+                </div>
+            </div>
+            <div class="dataSum">
+                <div class="row">
+                    <em>卡路里(月度)</em>
+                    <span>{{ ckRs.CleMonth }}</span>
+                </div>
+            </div>
+            <div class="dataSum">
+                <div class="row">
+                    <em>总卡路里</em>
+                    <span>{{ ckRs.Cle }}</span>
+                </div>
+            </div>
+            <div class="dataSum">
+                <div class="row">
+                    <em>CK(月度)</em>
+                    <span>{{ ckRs.CkMonth }}</span>
+                </div>
+            </div>
+            <div class="dataSum">
+                <div class="row">
+                    <em>总CK</em>
+                    <span>{{ ckRs.Ck }}</span>
+                </div>
+            </div>
+            <div class="btn_center">
+                <span class="btn btn-md login_btn" @click="logoutBtn">退出</span>
+            </div>
+        </div>
+        <bottomTab :curTab="thisTab"></bottomTab>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+    import bottomTab from '../components/bottomTab'
+    import {
+        VipUserSelfQuery,
+        OrderShopQuery,
+        VipUserCleCkSum,
+        MyShopQuery,
+        testSelect,
+        testTable,
+    } from '../api/getApiRes.js'
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                num: 0,
+                thisTab: '我的',
+                active: 0,
+                sum: 0,
+                openAlert: false,
+                list: [],
+                dialog: {
+                    id: '',
+                    name: '',
+                    timeLong: '',
+                },
+                user: {
+                    Ck: 0,
+                    CKMonth: 0,
+                    Cle: 0,
+                    CleMonth: 0,
+                    CalorieMonth: 0,
+                    CalorieTotal: 0,
+                    ClassFinish: 0,
+                    ClassRemain: 0,
+                    ClassTotal: 0,
+                    ExpTime: 0,
+                    Name: '',
+                    Phone: '',
+                    VipType: 0,
+                },
+                ckRs: {
+                    Ck: 0,
+                    CKMonth: 0,
+                    Cle: 0,
+                    CleMonth: 0,
+                },
+                schools: [],
+            }
+        },
+        mounted() {
+            this.getInfo();
+            this.getOrderShopQuery();
+            this.getCalorie()
+        },
+        methods: {
+            // 获得卡路里
+            getCalorie() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                VipUserCleCkSum(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.ckRs = json;
+                    } else {
+                        that.$toast.message(json.Memo);
+                    }
+                })
+            },
+            getOrderShopQuery() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                };
+                let postdata = qs.stringify(param);
+                // OrderShopQuery(postdata).then(res => {
+                MyShopQuery(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.schools = json.Rs;
+                    } else {
+                        that.$toast.message(json.Memo);
+                    }
+                })
+            },
+            logoutBtn() {
+                let that = this;
+                this.$confirm('是否退出账号?', '提示', {
+                    type: 'warning'
+                }).then(({result}) => {
+                    if (result) {
+                        localStorage.token = '';
+                        that.$router.push({path: '/login'});
+                    } else {
+                        that.$toast.message('点击了取消');
+                    }
+                });
+            },
+            getInfo() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                    active: this.active
+                };
+                let postdata = qs.stringify(param);
+                VipUserSelfQuery(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.user = json.Rs;
+                    } else {
+                        that.$toast.message(json.Memo);
+                    }
+                })
+            },
+        },
+        filters: {
+            hidePhone: function (val) {
+                var str = String(val)
+                var len = str.length;
+                if (len >= 7) {
+                    var reg = str.slice(-8, -4)
+                    return str.replace(reg, "****")
+                } else if (len < 7 && len >= 6) {
+                    var reg = str.slice(-4, -2)
+                    return str.replace(reg, "**")
+                }
+            },
+            fmtTime: function (value) {
+                if (!value) {
+                    return 0
+                } else {
+                    // js默认使用毫秒
+                    value = value * 1000
+                    let date = new Date(value);
+                    let y = date.getFullYear();
+                    let MM = date.getMonth() + 1;
+                    MM = MM < 10 ? ('0' + MM) : MM;
+                    let d = date.getDate();
+                    d = d < 10 ? ('0' + d) : d;
+                    let h = date.getHours();
+                    h = h < 10 ? ('0' + h) : h;
+                    let m = date.getMinutes();
+                    m = m < 10 ? ('0' + m) : m;
+                    let s = date.getSeconds();
+                    s = s < 10 ? ('0' + s) : s;
+                    return y + '-' + MM + '-' + d;
+                }
+            },
+        },
+        beforeRouteEnter(to, from, next) {
+            next(vm => {
+                //因为当钩子执行前,组件实例还没被创建
+                // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
+                if (to.name == 'mine') {
+                    vm.getInfo();
+                }
+            });
+        },
+        watch: {
+            'active'() {
+                console.log(123);
+                this.getList();
+            }
+        },
+        components: {
+            bottomTab
+        }
+    }
+</script>
+
+<style scoped>
+    .pages {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #F2F2F2;
+    }
+
+    .num {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 14px;
+        text-align: center;
+        color: #909090;
+        padding: 13px 0;
+    }
+
+    .user {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        height: 58px;
+        background: #fff;
+        padding: 17px 3%;
+        margin-bottom: 10px;
+    }
+
+    .user img {
+        width: 26.29px;
+        height: 26.29px;
+        float: left;
+        margin-right: 11px;
+    }
+
+    .user span {
+        font-family: "PingFang SC";
+        font-weight: 500;
+        font-size: 18px;
+        text-align: left;
+        color: #3b3b3b;
+    }
+
+    .user em {
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 18px;
+        text-align: left;
+        color: #3b3b3b;
+        float: right;
+    }
+
+    .user p {
+        font-family: "PingFang SC";
+        font-weight: normal;
+        font-size: 14px;
+        text-align: left;
+        color: #ffb43c;
+        float: right;
+        padding: 0;
+        margin: 0;
+        margin-left: 3px;
+        line-height: 26px;
+    }
+
+    .value {
+        width: 100%;
+        /*height: 131px;*/
+        background: #fff;
+        padding: 13px 0;
+    }
+
+    .value .vTitle {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 15px;
+    }
+
+    .vTitle i {
+        width: 8px;
+        height: 8px;
+        display: inline-block;
+        border-radius: 250px;
+        margin-right: 3px;
+    }
+
+    .vTitle.year {
+        color: #E75296;
+    }
+
+    .vTitle.year i {
+        background: #e75296;
+    }
+
+    .vTitle.price {
+        color: #FFB43C;
+    }
+
+    .vTitle.price i {
+        background: #FFB43C;
+    }
+
+    .vNum {
+        width: 100%;
+        /*height: 25px;*/
+        overflow: hidden;
+        display: block;
+        margin: 5px auto;
+        margin-bottom: 0;
+    }
+
+    .center {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+
+    .vNum em {
+        position: relative;
+        float: right;
+        bottom: 20px;
+        font-family: "PingFang SC";
+        font-weight: 500;
+        font-size: 12px;
+        color: #c9c9c9;
+        padding-right: 3%;
+    }
+
+    /deep/ .linear-progress {
+        width: 90%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border-radius: 250px;
+    }
+
+    .limit {
+        width: 90%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 8px;
+    }
+
+    .limit em {
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 12px;
+        text-align: right;
+        color: #e75296;
+        padding-left: 10px;
+    }
+
+    .limit span {
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 12px;
+        text-align: right;
+        color: #909090;
+        float: right;
+        text-align: right;
+        padding-right: 10px;
+    }
+
+    .dataSum {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        margin-top: 10px;
+    }
+
+    .dataSum .row {
+        width: 90%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 2% 0;
+    }
+
+    .dataSum .row em {
+        float: left;
+        font-family: "PingFang SC";
+        font-weight: 300;
+        font-size: 18px;
+        text-align: right;
+        color: #3b3b3b;
+    }
+
+    .dataSum .row span {
+        font-family: "PingFang SC";
+        font-weight: 500;
+        font-size: 18px;
+        text-align: right;
+        color: #3b3b3b;
+        float: right;
+    }
+
+    .row .mid {
+        width: 66%;
+        height: 0px;
+        background: transparent;
+        border: 1px dotted #e0e0e0;
+        float: left;
+        margin-top: 11px;
+        margin-right: 5px;
+        margin-left: 10px;
+    }
+
+    .row .midl {
+        width: 54%;
+        height: 0px;
+    }
+
+    .login_btn {
+        width: 96%;
+        height: 50px;
+        line-height: 50px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 30px;
+        padding-left: 3%;
+        padding-right: 3%;
+        background: #E75296;
+        color: #fff;
+        font-size: 14px;
+        text-align: center;
+        border: none;
+        padding: 0;
+        font-size: 24px;
+    }
+
+    /deep/ .mu-warning-text-color {
+        float: left;
+    }
+
+    .vNum span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+
+    @media only screen and (max-width: 640px) {
+
+    }
+
+    @media only screen and (max-width: 480px) {
+
+    }
+
+    @media only screen and (max-width: 375px) {
+        .vNum em {
+            padding-right: 0 !important;
+        }
+
+        .row .mid {
+            width: 49%;
+        }
+
+        .row .midl {
+            width: 44%;
+            height: 0px;
+        }
+    }
+
+    @media only screen and (max-width: 360px) {
+        .vNum em {
+            padding-right: 0 !important;
+        }
+
+        .row .mid {
+            width: 49%;
+        }
+
+        .row .midl {
+            width: 44%;
+            height: 0px;
+        }
+    }
+
+    @media only screen and (max-width: 320px) {
+
+    }
+
+    @media only screen and (min-width: 641px) {
+
+    }
+</style>

+ 47 - 0
online/src/page/modal.vue

@@ -0,0 +1,47 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" title="详情信息">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    export default {
+        data() {
+            return {
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {},
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+   /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+</style>

+ 61 - 0
online/src/page/notFound.vue

@@ -0,0 +1,61 @@
+<template>
+    <div id="pages">
+            <h5>404</h5>
+            <span @click="$router.back(-1)">{{$t("Back to previous page")}}</span>
+    </div>
+</template>
+
+<script>
+export default {
+    data () {
+    return {
+      msg: 'Welcome to Your Vue.js App'
+    }
+    },
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+    #pages {
+        position: absolute;
+        top:0;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background:#2c2e2f
+    }
+    h5 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 160px;
+        text-align: center;
+        margin-top: 10%;
+        color: #fff;
+        font-weight: normal;
+    }
+    span {
+        width: 200px;
+        height: 45px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10%;
+        background:#FFA200 ;
+        color: #fff;
+        font-size: 18px;
+        text-align: center;
+        border-radius: 250px;
+        line-height: 45px;
+        cursor: pointer;
+    }
+    span:hover {
+        background: #FFA200;
+    }
+</style>

+ 332 - 0
online/src/page/plane.vue

@@ -0,0 +1,332 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('Plane details')">
+            <router-link to="/map" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <mu-tabs :value.sync="active" inverse color="warning" full-width>
+            <mu-tab :id="Region.RegionId" v-for="(Region,index) in RegionList" :key="Region.RegionId">
+                {{Region.Region}}
+            </mu-tab>
+        </mu-tabs>
+        <div class="planeContainer">
+            <ul>
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <li v-for="(list,index) in lists" v-if="lists">
+                    <div class="basic">
+                        <h5>{{list.Region}}</h5>
+                        <span>
+                                 {{$t("Detection")}} :{{list.DetectorCount}}台|
+                                {{$t("Dangerous equipment found")}} :{{list.DangerCamCount}}台|
+                                {{$t("phone")}}:{{list.Signalstr == ' '? $t("No mobile signal detected"):list.Signalstr}}
+                            </span>
+                        <div v-if="imgSrc[index]" class="imgSrcContainer">
+                            <img :src="imgSrc[index]" alt="">
+                            <span class="imgContainer">
+                                <em :class="[{'green':pointStates[index].DetectorType == 0},{'red':pointStates[index].DetectorType != 0}]"
+                                    v-for="(point,index) in points[index]"
+                                    :style="{left:point.Width*0.30+'px',top:point.Height * -0.4+'px'}"
+                                ></em>
+                            </span>
+                        </div>
+                        <div v-else>
+                            <p class="tips">{{$t("No records found")}}</p>
+                        </div>
+                    </div>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                active: 0,
+                selected: 0,
+                RegionList: [],
+                lists: [],
+                imgSrc: [],
+                points: [],
+                pointStates: [],
+            }
+        },
+        mounted() {
+            this.RegionDetectList();
+        },
+        watch: {
+            active(val) {
+                this.readList(this.RegionList[val]['RegionId']);
+            }
+        },
+        methods: {
+            // 读取楼栋信息
+            RegionDetectList() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComRegionDetectList';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                that.RegionList = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.RegionList = json.Rs;
+                        if (json.Rs) {
+                            // that.selected = json.Rs[0].RegionId;
+                            that.selected = parseInt(that.$route.query.Regionid);
+                            that.readList( that.selected);
+                        }
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            readList(regionId) {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: regionId // regionId
+                };
+                that.lists = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                        that.imgFileter(json.Rs);
+                        that.DetectListByRegionID(json.Rs)
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            imgFileter(Rs) {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionPictureGetByRegionId';
+                that.imgSrc = [];
+                for (var i = 0; i < Rs.length; i++) {
+                    let param = {
+                        token: localStorage.token,
+                        regionID: Rs[i].RegionId// regionId
+                    };
+                    let postdata = qs.stringify(param);
+                    axios.post(url, postdata).then(function (data) {
+                        let json = data.data;
+                        if (json.Code == 0) {
+                            that.imgSrc.push(json.EncodeString);
+                        }
+                    }, function (response) {
+                        console.info(response);
+                    })
+                }
+            },
+            DetectListByRegionID(Rs) {
+                const that = this;
+                let url = headapi + 'v1/Company/DetectListByRegionID';
+                let comId = this.$route.query.ComId;
+                for (var i = 0; i < Rs.length; i++) {
+                    let param = {
+                        token: localStorage.token,
+                        comId: comId, // regionId
+                        regionId: Rs[i].RegionId// regionId
+                    };
+                    let postdata = qs.stringify(param);
+                    axios.post(url, postdata).then(function (data) {
+                        let json = data.data;
+                        if (json.Code == 0) {
+                            if (json.Rs) {
+                                that.points.push(json.Rs);
+                                console.log(that.points);
+                            } else {
+                                that.points = [];
+                            }
+                            if (json.DetectorType != undefined && json.DetectorType != null) {
+                                that.pointStates = json.DetectorType;
+                            } else {
+                                that.pointStates = [];
+                                return false
+                            }
+                        }
+                    }, function (response) {
+                        console.info(response);
+                    })
+                }
+            },
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-warning-text-color {
+        color: #FFA200;
+    }
+
+    /deep/ .mu-tab-link-highlight {
+        background-color: #FFA200 !important;
+    }
+
+    #pages {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        overflow-y: scroll;
+        display: block;
+        margin: 0 auto;
+        background-color: #f2f2f2;
+        top: 0;
+        bottom: 0;
+    }
+
+    .info {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        margin-bottom: 10px;
+        padding-left: 20px;
+    }
+
+    .planeContainer li {
+        width: 100%;
+        height: 360px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .basic {
+        width: 100%;
+        height: 360px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border-bottom: 1px solid #f2f2f2;
+        background: #fff;
+        padding: 5px 0px;
+    }
+
+    .basic h5 {
+        border: 2px solid #f2f2f2;
+        border-left: 0;
+        border-right: 0;
+        padding: 10px 0;
+        padding-left: 20px;
+        font-size: 14px;
+    }
+
+    .basic > span {
+        width: 88%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+    }
+
+    .basic img {
+        width: 96%;
+        height: 200px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 15px;
+        margin-bottom: 5px;
+    }
+
+    .red {
+        width: 20px;
+        height: 20px;
+        border-radius: 250px !important;
+        float: left;
+        margin: 0;
+        padding: 0;
+        background-color: red;
+        color: red;
+    }
+
+    .green {
+        width: 20px;
+        height: 20px;
+        border-radius: 250px !important;
+        float: left;
+        margin: 0;
+        padding: 0;
+        background-color: yellowgreen;
+        color: yellowgreen;
+    }
+    .imgSrcContainer {
+        width: 100%;
+        height: 220px;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .imgContainer {
+        position: relative;
+        bottom: 200px;
+        width: 96%;
+        height: 200px;
+        display: block;
+        margin: 0 auto;
+    }
+    .imgContainer em {
+        position: relative;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    ul li h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+    }
+</style>

+ 265 - 0
online/src/page/profile.vue

@@ -0,0 +1,265 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('detail')">
+            <router-link to="/map" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <div class="detail">
+                    <h5>
+                        <span>{{unite.ComName}}</span>
+                        <em>{{unite.Legal}}</em>
+                    </h5>
+                    <p>
+                        {{unite.Introduction}}
+                    </p>
+                </div>
+                <div class="listContainer">
+                    <ul>
+                        <li v-if="!lists.length">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <li v-for="list in lists" v-if="lists" @click="goListDetail(list)">
+                            <h5>{{list.Region}}</h5>
+                            <div>
+                                <mu-icon value="keyboard_arrow_right"></mu-icon>
+                                <span>
+                                    {{$t("Camera")}}:{{list.CamCount}}  {{$t("pcs")}} |
+                                     {{$t("Detection")}} :{{list.DetectorCount}} {{$t("pcs")}} |
+                                     {{$t("Suspicious camera")}}:{{list.DangerCamCount}} {{$t("pcs")}}
+                                </span>
+                                <span>
+                                      {{$t("phone")}}:{{list.Signalstr == ' '?  $t("No mobile signal detected"):list.Signalstr}}
+                                </span>
+                            </div>
+                        </li>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                selected: "1",
+                RegionList: [],
+                unite: {
+                    ComName: '',
+                    Legal: '',
+                    Introduction: '',
+                },
+                lists: [],
+            }
+        },
+        mounted() {
+            this.readInfo();
+            this.RegionDetectList();
+        },
+        methods: {
+            // 基本信息
+            readInfo() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComInfoDetail';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.unite.ComName = json.Rs.ComName;
+                        that.unite.Legal = json.Rs.Legal;
+                        that.unite.Introduction = json.Rs.Introduction;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 读取楼栋信息
+            RegionDetectList() {
+                const that = this;
+                let url = headapi + 'v1/Company/ComRegionDetectList';
+                let comId = this.$route.query.ComId;
+                let param = {
+                    token: localStorage.token,
+                    comId: comId
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.RegionList = json.Rs;
+                        if (json.Rs) {
+                            that.selected = json.Rs[0].RegionId;
+                            that.readList();
+                        }
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            // 读取无线设备具体分布
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Company/RegionDetectList';
+                let param = {
+                    token: localStorage.token,
+                    regionId: this.selected
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        this.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            goListDetail(list) {
+                let that = this;
+                that.$router.push(
+                    {
+                        path: '/listDetail',
+                        query: {
+                            RegionId: list.RegionId,
+                            Region: list.Region,
+                            comName: that.unite.ComName
+                        }
+                    });
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .detail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 0px;
+        padding-bottom: 20px;
+        padding-left: 2%;
+        padding-right: 2%;
+        margin-bottom: 10px;
+    }
+
+    .detail h5 span {
+        font-size: 16px;
+    }
+
+    .detail h5 em {
+        float: right;
+        color: #666666;
+        font-size: 12px;
+        font-weight: normal;
+        text-align: right;
+    }
+
+    .detail p {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #666666;
+        line-height: 16px;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected {
+        border-bottom: 3px solid #FFA200;
+        color: #FFA200;
+    }
+
+    /deep/ .mint-navbar .mint-tab-item.is-selected .mint-tab-item-label {
+        color: #FFA200;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer li h5 {
+        font-size: 14px;
+        margin: 10px 0;
+    }
+
+    .listContainer li span {
+        width: 80%;
+        float: left;
+        font-size: 12px;
+        color: #606060;
+        line-height: 20px;
+    }
+
+    .listContainer li img {
+        width: 8px;
+        height: 14px;
+        float: right;
+    }
+</style>

+ 613 - 0
online/src/page/record.vue

@@ -0,0 +1,613 @@
+<template>
+  <div class="pages">
+    <img src="../static/images/main/banner.png" height="121" width="414"/>
+    <div class="context">
+            <span class="num">
+                记录共 {{ num }} 条
+            </span>
+      <mu-tabs :value.sync="active" color="#F2F2F2" indicator-color="#ffffff" center>
+        <mu-tab>已预约</mu-tab>
+        <mu-tab>预约记录</mu-tab>
+        <mu-tab>消费记录</mu-tab>
+      </mu-tabs>
+<!--      <div class="whiteCube"></div>-->
+      <ul class="list">
+        <mu-load-more @refresh="refresh" :refreshing="refreshing" :loading="loading" @load="load">
+          <li v-for="l in list">
+            <div class="lt" v-if="active != 2">
+              <h5>{{ l.CurrentDate }}</h5>
+              <em>{{ l.CurrentDate |filterWeek}}</em>
+              <span>{{ l.BeginStr }}-{{ l.EndStr }}</span>
+            </div>
+            <div class="lt" v-if="active == 2">
+              <h5>{{ l.CreatedAt|filterTime }}</h5>
+              <span>剩余课时 {{ l.AfterNormalhour }}</span>
+            </div>
+            <div class="md">
+              <em>
+                                <span class="lessons" :style="{ background:l.ClassColor }">
+                                     {{ l.ClassName }}
+                                </span>
+              </em>
+<!--              <span class="green" v-if="l.Status == 0">-->
+<!--                            预约上课-->
+<!--                        </span>-->
+<!--              <span class="green" v-if="l.Status == 1 && active == 0">-->
+<!--                            已预约-->
+<!--                        </span>-->
+            </div>
+            <div class="rt">
+              <mu-button color="error" flat  v-if="l.Status == 0"  @click="cancleAppoint(l)">取消预约</mu-button>
+              <span v-if="l.Status == 1" class="isFinish">
+<!--                            已预约-->
+                             <mu-button color="error" flat  @click="cancleAppoint(l)">取消预约</mu-button>
+                        </span>
+              <span class="red" v-if="l.Status == 2">
+                            已取消
+                        </span>
+              <span class="red" v-if="l.Status == 3">
+                            预约未到
+                        </span>
+              <span class="green" v-if="l.Status == 4">
+                            已完成
+                        </span>
+              <em v-if="active == 2">
+                - {{ l.NormalHour }}课时
+              </em>
+            </div>
+          </li>
+        </mu-load-more>
+        <div class="tips">
+          <p v-if="active == 0 && list == null">
+            暂无已预约
+          </p>
+          <p v-if="active == 1 && list == null">
+            暂无预约记录
+          </p>
+          <p v-if="active == 2 && list == ''">
+            暂无消费记录
+          </p>
+        </div>
+      </ul>
+    </div>
+    <bottomTab :curTab="thisTab"></bottomTab>
+    <!--        <span v-if="scope.row.Status == 1">已预约</span>-->
+    <!--        <span v-if="scope.row.Status == 2">已取消</span>-->
+    <!--        <span v-if="scope.row.Status == 3">预约未到</span>-->
+    <!--        <span v-if="scope.row.Status == 4">已完成</span>-->
+    <alert ref="alertPart"></alert>
+  </div>
+</template>
+
+<script>
+import axios from 'axios';
+import bottomTab from '../components/bottomTab'
+import {
+  OrderListQuery,
+  VipUserConsumeListQuery,
+  OderCancelByVipUser,
+  testSelect,
+  testTable,
+} from '../api/getApiRes.js'
+import alert from '../components/alert'
+
+let qs = require('qs');
+import Global from '../Global.js'
+
+export default {
+  data() {
+    return {
+      num: 0,
+      thisTab: '预约记录',
+      active: 0,
+      sum: 0,
+      openAlert: false,
+      list: [],
+      dialog: {
+        id: '',
+        name: '',
+        timeLong: '',
+      },
+      refreshing: false,
+      loading: false,
+      start: 1,
+      tableMax: 6,
+    }
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    alertInfo(info){
+      this.$refs.alertPart.openSimpleDialog(info);
+    },
+    refresh() {
+    },
+    load() {
+      if (this.active != 2) {
+        return false
+      }
+      this.loading = true;
+      setTimeout(() => {
+        this.loading = false;
+        this.start = this.start + 6;
+        this.getVipUserConsumeListQuery();
+      }, 2000);
+    },
+    cancleAppoint(row) {
+      let that = this;
+      this.$confirm('是否取消' + row.ClassName + '课程预约?', '提示', {
+        type: 'warning'
+      }).then(({result}) => {
+        if (result) {
+          let param = {
+            token: localStorage.token,
+            orderId: row.OrderId,
+          };
+          let postdata = qs.stringify(param);
+          OderCancelByVipUser(postdata).then(res => {
+            let json = res;
+            if (json.Code == 0) {
+              that.alertInfo('当前课程已取消预约', 'success');
+              that.getList();
+            } else {
+              that.alertInfo(json.Memo + ', 错误码:' + json.Code);
+            }
+          })
+        } else {
+          this.alertInfo('点击了取消');
+        }
+      });
+    },
+    getOrderListQuery(statusList) {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        statusList: statusList,
+        start: 1,
+        tableMax: 299,
+      };
+      let postdata = qs.stringify(param);
+      if (parseInt(this.active) == 0 || parseInt(this.active) == 1) {
+        OrderListQuery(postdata).then(res => {
+          let json = res;
+          if (json.Code == 0) {
+            that.list = json.Rs;
+            if (that.list) {
+              that.num = json.Rs.length;
+            } else {
+              that.num = 0
+            }
+          } else {
+            that.alertInfo(json.Memo + ', 错误码:' + json.Code);
+          }
+        });
+      }
+    },
+    getVipUserConsumeListQuery() {
+      let that = this;
+      let param = {
+        token: localStorage.token,
+        start: this.start,
+        tableMax: this.tableMax,
+      };
+      let postdata = qs.stringify(param);
+      VipUserConsumeListQuery(postdata).then(res => {
+        let json = res;
+        if (json.Code == 0) {
+          // that.list = json.Rs;
+          that.list = that.list.concat(json.Rs);
+          if (that.list) {
+            that.num = json.Rs.length;
+          }
+        } else {
+          that.alertInfo(json.Memo);
+        }
+      })
+    },
+    getList() {
+      let statusList = '';
+      this.list = [];
+      switch (parseInt(this.active)) {
+          // 已预约
+        case 0:
+          statusList = 1;
+          this.getOrderListQuery(statusList);
+          break;
+          // 预约记录
+        case 1:
+          statusList = '2,3,4';
+          this.getOrderListQuery(statusList);
+          break;
+          // 消费记录
+        case 2:
+          statusList = 1;
+          this.getVipUserConsumeListQuery(statusList);
+          break;
+      }
+    },
+    numberToWeek(val) {
+      switch (parseInt(val)) {
+        case 1:
+          return '星期一'
+          break;
+        case 2:
+          return '星期二'
+          break;
+        case 3:
+          return '星期三'
+          break;
+        case 4:
+          return '星期四'
+          break;
+        case 5:
+          return '星期五'
+          break;
+        case 6:
+          return '星期六'
+          break;
+        case 0:
+          return '星期天'
+          break;
+      }
+    },
+  },
+  beforeRouteEnter(to, from, next) {
+    next(vm => {
+      //因为当钩子执行前,组件实例还没被创建
+      // vm 就是当前组件的实例相当于上面的 this,所以在 next 方法里你就可以把 vm 当 this 来用了。
+      if (to.name == 'record') {
+        vm.getList();
+      }
+    });
+  },
+  filters: {
+    filterTime: function (value) {
+      if (!value) {
+        return 0
+      } else {
+        return globalfmtDate(value);
+      }
+    },
+    filterWeek:function (value){
+      if (!value) return false
+      let days = new Date(value).getDay();
+      switch (parseInt(days)) {
+        case 1:
+          return '星期一'
+          break;
+        case 2:
+          return '星期二'
+          break;
+        case 3:
+          return '星期三'
+          break;
+        case 4:
+          return '星期四'
+          break;
+        case 5:
+          return '星期五'
+          break;
+        case 6:
+          return '星期六'
+          break;
+        case 0:
+          return '星期天'
+          break;
+      }
+    }
+  },
+  watch: {
+    '$route'(to) {
+      if (to.name == 'record') {
+        this.getList();
+      }
+    },
+    'active'() {
+      this.start = 1;
+      this.getList();
+    }
+  },
+  components: {
+    bottomTab,alert
+  }
+}
+</script>
+
+<style scoped>
+.pages {
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  background: #F2F2F2;
+}
+
+.num {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-family: "PingFang SC";
+  font-weight: 300;
+  font-size: 14px;
+  text-align: center;
+  color: #909090;
+  padding: 13px 0;
+}
+
+/deep/ .mu-appbar-title {
+  text-align: center;
+}
+
+/deep/ .mu-tab {
+  width: 115px;
+  height: 35px;
+  margin-right: 6px;
+}
+
+/deep/ .mu-tab-wrapper {
+  height: 35px;
+  line-height: 25px;
+  background: #f4f4f4;
+  color: #363636;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  border-radius: 8px 8px 0px 0px;
+  font-size: 16px;
+  padding-top: 5px;
+}
+
+/deep/ .mu-tab-active .mu-tab-wrapper {
+  height: 35px;
+  line-height: 25px;
+  border-radius: 8px 8px 0px 0px;
+  background: #ffffff;
+  box-shadow: 1px 0px 6px rgba(0, 0, 0, 0.16);
+  color: #000;
+}
+
+/deep/ .mu-tab-wrapper em {
+  font-size: 12px;
+}
+
+.list {
+  position: relative;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  width: 100%;
+  height: 100%;
+  min-height: 410px;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  padding-top: 0px;
+  padding-bottom: 30px;
+  background: #f2f2f2;
+}
+
+.list li {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  background: #fff;
+  padding: 20px 3%;
+  margin-bottom: 10px;
+}
+
+.whiteCube {
+  width: 100%;
+  height: 6px;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  background: #fff;
+  border-bottom: 1px solid #ccc;
+}
+
+.list .lt {
+  width: 100px;
+  float: left;
+  overflow: visible;
+}
+
+.list .lt h5 {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 13px;
+  text-align: center;
+  color: #4e4e4e;
+  margin: 0;
+}
+
+.list .lt span {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 12px;
+  text-align: center;
+  color: #909090;
+
+}
+.list .lt em {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  font-size: 12px;
+  text-align: center;
+}
+
+.list .md {
+  max-width: 200px;
+  /*width: 220px;*/
+  float: left;
+  margin-left: 10%;
+  padding-top: 14px;
+}
+
+.list .rt {
+  float: right;
+  margin-right: 2%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  padding-top: 9px;
+}
+
+.md em {
+  float: left;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 18px;
+  text-align: left;
+  color: #3b3b3b;
+  margin-right: 20px;
+}
+
+.md span {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  /*color: #37cb00;*/
+  line-height: 30px;
+}
+
+span.green {
+  color: #37cb00;
+}
+
+span.red {
+  color: #FF453C;
+}
+
+.rt span {
+  float: right;
+  line-height: 35px;
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #909090;
+  overflow: hidden;
+  padding-bottom: 6px;
+}
+
+.rt .red {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #f8847f;
+}
+
+.rt .cancleBtn {
+  width: 55px;
+  height: 24px;
+  border-radius: 12px;
+  background: #ff453c;
+  padding: 0;
+  overflow: hidden;
+  text-align: center;
+  color: #fff;
+  line-height: 24px;
+  margin-top: 6px;
+}
+
+.rt em {
+  font-family: "PingFang SC";
+  font-weight: normal;
+  font-size: 14px;
+  text-align: left;
+  color: #909090;
+  margin-top: 6px;
+}
+
+.tips {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+}
+
+.tips p {
+  width: 100%;
+  overflow: hidden;
+  display: block;
+  margin: 0 auto;
+  text-align: center;
+  font-size: 14px;
+  line-height: 35px;
+}
+
+.green {
+  color: #37cb00;
+}
+
+/deep/ .mu-raised-button.mu-button-small {
+  width: 54px;
+  min-width: 40px;
+  float: right;
+  padding-left: 3px;
+  padding-right: 3px;
+}
+
+.lessons {
+  width: 100%;
+  overflow: hidden;
+  padding: 1px 11px;
+  border-radius: 250px;
+  float: left;
+  text-align: center;
+  color: #333;
+}
+/deep/ .mu-button-wrapper {
+  border: 1px solid #F8847F;
+  color: #F8847F;
+  background: #FFF7F7;
+  border-radius: 5px;
+}
+
+@media only screen and (max-width: 640px) {
+
+}
+
+@media only screen and (max-width: 480px) {
+
+}
+
+@media only screen and (max-width: 375px) {
+
+}
+
+@media only screen and (max-width: 360px) {
+
+}
+
+@media only screen and (max-width: 320px) {
+  .list .lt {
+    width: 80px;
+  }
+
+  .list .lt h5 {
+    font-size: 12px;
+  }
+
+  .md em {
+    margin-right: 3px;
+  }
+}
+
+@media only screen and (min-width: 641px) {
+
+}
+</style>

+ 318 - 0
online/src/page/runtime.vue

@@ -0,0 +1,318 @@
+<template>
+    <div id="pages">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <bottomTab :curTab="thisTab"></bottomTab>
+        <div class="container">
+            <div class="row">
+                <mu-tabs :value.sync="active" inverse color="warning" full-width>
+                    <mu-tab>{{$t("wireless device")}}</mu-tab>
+                    <mu-tab> {{$t("phone signal")}}</mu-tab>
+                </mu-tabs>
+                <div class="demo-text" v-if="active === 0">
+                    <ul class="deteUl">
+                        <li v-if="!lists">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <transition-group name="fade">
+                            <li v-for="(list,i) in lists" v-if="lists"  v-bind:key="i">
+                                <div class="lt">
+                                    <div class="rowTop">
+                                        <h5>{{list.DetectorLocation}}</h5>
+                                        <span v-if="list.DangerLevel == -1" class="green">{{$t("other")}}</span>
+                                        <span v-if="list.DangerLevel == 0" class="green">{{$t("white")}}</span>
+                                        <span v-if="list.DangerLevel == 2" class="yellow">{{$t("deal")}}</span>
+                                        <span v-if="list.DangerLevel == 3" class="red">{{$t("warning")}}</span>
+                                        <span v-if="list.DangerLevel == 4" class="red">{{$t("danger")}}</span>
+                                    </div>
+                                    <div class="rowDetail">
+                                        <span>{{list.MacCom.length > 16 ? list.MacCom.slice(0, 16)+'...':list.MacCom}}</span>
+                                        <span class="pull-right">{{list.Mac}}</span>
+                                    </div>
+                                </div>
+                            </li>
+                        </transition-group>
+                        <s class="tips" v-if="lists"> {{$t("total")}}{{lists.length}}{{$t("item")}} {{$t("Record")}}</s>
+                    </ul>
+                </div>
+                <div class="demo-text" v-if="active === 1">
+                    <ul class="deteUl">
+                        <li v-if="!phones">
+                            <h4>{{$t("no use data")}}</h4>
+                        </li>
+                        <li v-for="phone in phones" v-if="phones">
+                            <div class="lt">
+                                <div class="rowTop">
+                                    <h5>{{phone.DetectorName}}</h5>
+                                    <span>{{phone.RegionName | filterContent}}</span>
+                                </div>
+                                <div class="rowDetail">
+                                    <span>{{phone.ComName}}</span>
+                                    <s :class="{'red':phone.Signalstr != ''}">{{phone.Signalstr | filterSignalstr}}</s>
+                                </div>
+                            </div>
+                        </li>
+                        <s class="tips" v-if="phones"> {{$t("total")}}{{phones.length}}{{$t("item")}}
+                            {{$t("Record")}}</s>
+                    </ul>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import bottomTab from '../components/bottomTab'
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                pagetitle: this.$t('Real-time'),
+                thisTab: this.$t('Real-time'),
+                active: 0,
+                loading: true,
+                lists: [],
+                phones: [],
+            }
+        },
+        mounted() {
+            this.readList();
+            this.readPhone();
+        },
+        filters: {
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+            filterSignalstr: function (value) {
+                switch (value) {
+                    case "":
+                        return '未检测到';
+                        break;
+                    default:
+                        return value;
+                        break;
+                }
+            }
+        },
+        watch: {
+            active(val) {
+                let that = this;
+                console.log(val);
+                if (val == 1) {
+                    that.readList();
+                } else {
+                    that.readPhone();
+                }
+            }
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            // 实时监测无线设备
+            readList() {
+                const that = this;
+                let url = headapi + 'v1/Detector/DetectedMacs';
+                // let url = headapi + 'v1/Detector/DetectedMacsTest';//test
+                let param = {
+                    token: localStorage.token,
+                };
+                this.lists = [];
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+            readPhone() {
+                const that = this;
+                let url = headapi + 'v1/Detector/SignalDeviceList';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.phones = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            },
+        },
+        components: {
+            appHeader, bottomTab
+        }
+    }
+</script>
+
+<style scoped>
+    .mu-warning-text-color {
+        color: #FFA200;
+    }
+
+    /deep/ .mu-tab-link-highlight {
+        background-color: #FFA200 !important;
+    }
+
+    /deep/ .mu-tab {
+        width: 50%;
+    }
+
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .demo-text {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .demo-text ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border-top: 2px solid #f2f2f2;
+    }
+
+    .demo-text li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        padding: 10px 20px;
+        background: #fff;
+        border-bottom: 2px solid #f2f2f2;
+    }
+
+    .deteUl h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .deteUl .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .deteUl .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+    }
+
+    .rowDetail span {
+        float: left;
+    }
+
+    .rowDetail s {
+        float: right;
+    }
+
+    .rowBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        font-size: 12px;
+        color: #999999;
+    }
+
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 10px;
+    }
+
+    .deteUl img {
+        width: 8px;
+        height: 14px;
+        margin-top: 20px;
+        float: right;
+    }
+
+    .deteUl .lt {
+        width: 100%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .row .pull-right {
+        float: right;
+        text-align: right;
+    }
+
+    .deteUl h4 {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-weight: normal;
+    }
+
+    .rowDetail s {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: left;
+    }
+
+    .red {
+        color: red;
+    }
+    .green {
+        color: yellowgreen;
+    }
+    .yellow {
+        color: rgb(255, 162, 0);
+    }
+
+    /deep/ .mu-tab-wrapper {
+        font-size: 16px;
+    }
+</style>

+ 148 - 0
online/src/page/setting.vue

@@ -0,0 +1,148 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('System setup')">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="">
+            <div class="row">
+                <mu-list>
+                    <mu-list-item button :ripple="false">
+                        <mu-list-item-title>{{$t("Alarm sound")}}</mu-list-item-title>
+                        <mu-list-item-action>
+                            <mu-switch v-model="voiceState"></mu-switch>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <mu-divider></mu-divider>
+                    <mu-list-item button :ripple="false">
+                        <mu-list-item-title>{{$t("Alarm flicker")}}</mu-list-item-title>
+                        <mu-list-item-action>
+                            <mu-switch v-model="alertState"></mu-switch>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <div class="grip"></div>
+                    <mu-list-item button :ripple="false" @click="openAlertDialog">
+                        <mu-list-item-title>{{$t("Quit landing")}}</mu-list-item-title>
+                    </mu-list-item>
+                </mu-list>
+            </div>
+        </div>
+        <mu-dialog width="600" max-width="80%" :esc-press-close="false"
+                   :overlay-close="false" :open.sync="openAlert">
+            {{$t("Confirm to exit the current account")}}?
+            <mu-button slot="actions" flat color="info" @click="closeAlertDialog">{{$t("cancel")}}</mu-button>
+            <mu-button slot="actions" flat color="warning" @click="logout">{{$t("confirm")}}</mu-button>
+        </mu-dialog>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                lists: [],
+                voiceState: false,
+                alertState: false,
+                openAlert: false
+            }
+        },
+        mounted() {
+            localStorage.voiceState = localStorage.voiceState || false;
+            localStorage.alertState = localStorage.alertState || false;
+            this.voiceState = JSON.parse(localStorage.voiceState);
+            this.alertState = JSON.parse(localStorage.alertState);
+        },
+        watch: {
+            voiceState: function (val) {
+                localStorage.voiceState = val;
+            },
+            alertState: function (val) {
+                localStorage.alertState = val;
+            },
+        },
+        methods: {
+            openAlertDialog() {
+                this.openAlert = true;
+            },
+            closeAlertDialog() {
+                this.openAlert = false;
+            },
+            // 退出
+            logout() {
+                this.openAlert = false;
+                const that = this;
+                localStorage.token = '';
+                that.$router.push({path: '/login'});
+            },
+        },
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        top: 0;
+        bottom: 0;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #f2f2f2;
+    }
+
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    .mu-button {
+        display: block;
+        margin: 0 auto;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .mu-switch-checked {
+        color: #FFCC00;
+    }
+
+    .grip {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        height: 10px;
+    }
+
+    /deep/ .mu-item-wrapper {
+        background: #fff;
+        font-size: 16px;
+        color: #000;
+    }
+</style>

+ 50 - 0
online/src/page/statis.vue

@@ -0,0 +1,50 @@
+<template>
+    <div>
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <div class="container">
+            <div class="row">
+                <statischart></statischart>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    import statischart from '../components/statischart'
+    export default {
+        data() {
+            return {
+                pagetitle:this.$t('Statistical report forms'),
+                lists: []
+            }
+        },
+        mounted() {
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+        },
+        components: {
+            statischart,appHeader
+        }
+    }
+</script>
+
+<style scoped>
+    .container {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    /deep/ #statischart {
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+</style>

+ 101 - 0
online/src/page/test.vue

@@ -0,0 +1,101 @@
+<template>
+    <div>
+        <mu-paper :z-depth="1" class="demo-loadmore-wrap">
+            <mu-container ref="container" class="demo-loadmore-content">
+                <mu-load-more @refresh="refresh" :refreshing="refreshing" :loading="loading" @load="load">
+                    <li v-for="i in list">
+                        {{text}} Item {{i.ClassName}}
+                    </li>
+
+                </mu-load-more>
+            </mu-container>
+        </mu-paper>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+    import {
+        VipUserConsumeListQuery,
+    } from '../api/getApiRes.js'
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                num: 20,
+                refreshing: false,
+                loading: false,
+                text: 'List',
+                list: [],
+                start: 1,
+                tableMax: 5,
+            }
+        },
+        mounted() {
+            this.getVipUserConsumeListQuery();
+        },
+        methods: {
+            refresh() {
+            },
+            load() {
+                this.loading = true;
+                setTimeout(() => {
+                    this.loading = false;
+                    this.start =  this.start + 5;
+                    this.getVipUserConsumeListQuery();
+                }, 2000);
+            },
+            getVipUserConsumeListQuery() {
+                let that = this;
+                let param = {
+                    token: localStorage.token,
+                    start: this.start,
+                    tableMax: this.tableMax,
+                };
+                let postdata = qs.stringify(param);
+                VipUserConsumeListQuery(postdata).then(res => {
+                    let json = res;
+                    if (json.Code == 0) {
+                        that.list =  that.list.concat(json.Rs);
+                    } else {
+                        that.Toast(json.Memo + ', 错误码:' + json.Code);
+                    }
+                })
+            },
+        }
+    };
+</script>
+
+<style scoped>
+    .demo-loadmore-wrap {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        display: flex;
+        overflow-y: scroll;
+        flex-direction: column;
+    }
+
+    .mu-appbar {
+        width: 100%;
+    }
+
+    .demo-loadmore-content {
+        flex: 1;
+        overflow: auto;
+        -webkit-overflow-scrolling: touch;
+    }
+    li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        height: 160px;
+        line-height: 160px;
+        border: 1px solid #ccc;
+        text-align: center;
+    }
+</style>

+ 157 - 0
online/src/page/userDetail.vue

@@ -0,0 +1,157 @@
+<template>
+    <div>
+        <mu-appbar style="width: 100%;" color="primary" :title="$t('User details')">
+            <router-link to="/usermanage" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+        </mu-appbar>
+        <div class="container">
+            <div class="row">
+                <h5>{{detail.Name}}</h5>
+                <ul>
+                    <li><em>{{$t("usercode")}}:</em><span>{{detail.Usercode}}</span></li>
+                    <li><em>Email:</em><span>{{detail.Email | filterContent}}</span></li>
+                    <li><em>{{$t("phone")}}:</em><span>{{detail.Phone}}</span></li>
+                    <!--<li><em>{{$t("state")}}:</em><span>{{detail.Status | typeFileter}}</span></li>-->
+                    <li><em>{{$t("state")}}:</em><span>{{Status}}</span></li>
+                    <li><em>{{$t("User roles")}}:</em><span>{{detail.Rolesname | filterContent}}</span></li>
+                    <li><em>{{$t("memo")}}:</em><span>{{detail.Memo | filterContent}}</span></li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+
+    export default {
+        data() {
+            return {
+                detail: {}
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        methods: {
+            writeData() {
+                let content = this.$route.query.detector;
+                this.detail = JSON.parse(content);
+                console.log(this.detail);
+            }
+        },
+        computed:{
+            Status() {
+                switch (this.detail.Status) {
+                    case 1:
+                        return this.$t('disabled');
+                        break;
+                    default:
+                        return this.$t('Enabled');
+                        break;
+                }
+            },
+        },
+        filters: {
+            typeFileter: function (value) {
+                switch (parseInt(value)) {
+                    case 1:
+                        return '已禁用';
+                        break;
+                    default:
+                        return '已启用';
+                        break;
+                }
+            },
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        }
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    /deep/ .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+
+    #pages {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 200px;
+        background: #f2f2f2;
+    }
+
+    .row {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .row h5 {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 20px;
+        color: #FFA200;
+        padding: 20px;
+        border-bottom: 1px solid rgba(112, 112, 112, 0.14);
+        margin-bottom: 20px;
+    }
+
+    .row ul {
+        width: 80%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+    }
+
+    .row li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 10px;
+        font-size: 16px;
+    }
+
+    .row li em {
+        float: left;
+        min-width: 80px;
+    }
+
+    .row li span {
+        color: #6E6E6E;
+    }
+</style>

+ 212 - 0
online/src/page/usermanage.vue

@@ -0,0 +1,212 @@
+<template>
+    <div id="pages">
+        <appHeader @goNewpage="onGoNewPage" :title="this.pagetitle"></appHeader>
+        <div class="listContainer">
+            <ul class="deteUl">
+                <li v-if="!lists.length">
+                    <h4>{{$t("no use data")}}</h4>
+                </li>
+                <transition-group name="fade">
+                <li v-for="list in stus" v-if="lists" @click="goPage(list)" v-bind:key="list.Id">
+                    <div class="lt">
+                        <div class="rowTop">
+                            <h5>{{list.Name}}</h5>
+                            <!--<span>{{list.Status | typeFileter}}</span>-->
+                            <span>{{list.stusType}}</span>
+                        </div>
+                        <div class="rowDetail">
+                            <span>{{list.Rolesname}}</span>
+                            <span class="pull-right">{{list.Insname | filterContent}}</span>
+                        </div>
+                    </div>
+                    <div class="rt">
+                         <mu-icon value="keyboard_arrow_right"></mu-icon>
+                    </div>
+                </li>
+                </transition-group>
+                <div class="tips" v-if="lists">{{$t("total")}} {{lists.length}} {{$t("enterprise")}}</div>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+    import appHeader from '../components/appHeader'
+    import axios from 'axios';
+    let qs = require('qs');
+    import Global from '../Global.js'
+    export default {
+        data() {
+            return {
+                pagetitle:this.$t('user management'),
+                lists: []
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        computed:{
+            stus(){
+                let that = this;
+                let text = '';
+                /*es6写法 防止用不了this.type*/
+                return this.lists.filter((v)=>{
+                    console.log(v.Status);
+                    switch (parseInt(v.Status)) {
+                        case 1:
+                            text = that.$t('disabled');
+                            break;
+                        default:
+                            text = that.$t('Enabled');
+                            break;
+                    }
+                    return v.stusType = text;
+                })
+            }
+        },
+        methods: {
+            onGoNewPage(path) {
+                this.$router.push({path: '/' + path});
+            },
+            goPage(list) {
+                this.$router.push({path: '/userDetail', query: {detector: JSON.stringify(list)}});
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/User/UserListInfo';
+                let pageIndex = 1;
+                let tableMax = 100;
+                let param = {
+                    token: localStorage.token,
+                    usertype: '0',
+                    searchs: '',
+                    pageIndex: pageIndex,
+                    tableMax: tableMax
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+        filters: {
+            typeFileter: function (value) {
+                switch (parseInt(value)) {
+                    case 1:
+                        return '已禁用';
+                        break;
+                    default:
+                        return '已启用';
+                        break;
+                }
+            },
+            filterContent: function (value) {
+                if (value == '' || value == undefined) {
+                    return '-'
+                } else {
+                    return value
+                }
+            },
+        },
+        components: {
+            appHeader
+        }
+    }
+</script>
+
+<style scoped>
+    #pages {
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        display: block;
+        margin-top: 0px;
+        padding-bottom: 20px;
+        background: #f2f2f2;
+        overflow-y: scroll;
+    }
+
+    .listContainer ul {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .listContainer li {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-bottom: 2px;
+        padding: 10px 20px;
+        background: #fff;
+    }
+
+    .listContainer .rowTop {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .rowTop .red {
+        color: #FFA200;
+    }
+
+    .listContainer h5 {
+        margin: 0;
+        float: left;
+        font-size: 16px;
+    }
+
+    .listContainer .rowTop span {
+        float: right;
+        font-size: 14px;
+    }
+
+    .listContainer .rowDetail {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        color: #999999;
+        font-size: 14px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .deteUl .lt {
+        width: 88%;
+        float: left;
+    }
+
+    .deteUl .rt {
+        float: right;
+    }
+
+    .rt i {
+        margin-top: 20px;
+    }
+    .pull-right {
+        float: right;
+        text-align: right;
+    }
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        font-size: 12px;
+        color: #999999;
+        margin-top: 20px;
+    }
+</style>

+ 360 - 0
online/src/page/white.vue

@@ -0,0 +1,360 @@
+<template>
+    <div id="pages">
+        <mu-appbar style="width: 100%;" color="primary" :title="curTitle">
+            <router-link to="/" slot="left">
+                <mu-icon value="arrow_back"></mu-icon>
+            </router-link>
+            <mu-button flat color="primary" slot="right" @click="showPanel">{{btnText}}</mu-button>
+        </mu-appbar>
+        <mu-bottom-sheet :open.sync="popupVisible">
+            <div class="modal-content">
+                <div class="modal-body">
+                    <div class="location">
+                        <span>{{$t("query criteria")}}</span>
+                        <div class="timePickerPart">
+                            <span @click="changeTime(1)">{{bt}}</span> <em>{{$t("to")}}</em>
+                            <span @click="changeTime(2)">{{et}}</span>
+                        </div>
+                        <div v-show="open">
+                            <mu-flex justify-content="between" align-items="end" wrap="wrap">
+                                <mu-paper :z-depth="1" class="demo-date-picker">
+                                    <mu-date-picker :date.sync="date" color="#FFA200" :date-time-format="enDateFormat"
+                                                    @change="confirmDay"></mu-date-picker>
+                                </mu-paper>
+                            </mu-flex>
+                        </div>
+                        <input type="text" placeholder="MAC" v-model="MAC" id="macInput">
+                        <input type="text" :placeholder="$t('keyword')" v-model="keyWord" id="keyWordInput">
+                    </div>
+                </div>
+                <div class="modalBottom">
+                    <div class="reset" @click="resetModal">
+                        {{$t("Reset")}}
+                    </div>
+                    <div class="pullUp" @click="searchModal">
+                        {{$t("query")}}
+                    </div>
+                </div>
+            </div>
+        </mu-bottom-sheet>
+        <div class="container">
+            <div class="row">
+                <p class="tips" v-if="!lists">{{$t("no use data")}}</p>
+                <mu-list textline="two-line" v-for="list in lists" :key="list.Id">
+                    <mu-list-item avatar :ripple="false" button>
+                        <mu-list-item-content>
+                            <mu-list-item-title>{{list.Name}}</mu-list-item-title>
+                            <mu-list-item-sub-title>{{list.Mac}}</mu-list-item-sub-title>
+                            <mu-list-item-sub-title>{{list.Memo}}</mu-list-item-sub-title>
+                        </mu-list-item-content>
+                        <mu-list-item-action>
+                            <mu-list-item-after-text>{{list.CreateTime | timeFileter}}</mu-list-item-after-text>
+                            <mu-list-item-after-text>{{list.Regionname}}</mu-list-item-after-text>
+                            <mu-list-item-after-text>{{$t("operator")}}: {{list.Usercode}}</mu-list-item-after-text>
+                        </mu-list-item-action>
+                    </mu-list-item>
+                    <mu-divider></mu-divider>
+                </mu-list>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+    import axios from 'axios';
+
+    let qs = require('qs');
+    import Global from '../Global.js'
+    const enDateFormat = {
+        formatDisplay (date) {
+            return `${dayList[date.getDay()]}, ${monthList[date.getMonth()]} ${date.getDate()}`;
+        },
+        formatMonth (date) {
+            return `${monthLongList[date.getMonth()]} ${date.getFullYear()}`;
+        },
+        getWeekDayArray (firstDayOfWeek) {
+            let beforeArray = [];
+            let afterArray = [];
+            for (let i = 0; i < dayAbbreviation.length; i++) {
+                if (i < firstDayOfWeek) {
+                    afterArray.push(dayAbbreviation[i]);
+                } else {
+                    beforeArray.push(dayAbbreviation[i]);
+                }
+            }
+            return beforeArray.concat(afterArray);
+        },
+        getMonthList () {
+            return monthList;
+        }
+    };
+    export default {
+        data() {
+            return {
+                enDateFormat,
+                curTitle:this.$t("whiteList"),
+                lists: [],
+                popupVisible:false,//true false
+                open:false,//true false
+                MAC:'',//
+                keyWord:'',//
+                bt: globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000),
+                et: globaltime2StringNoMin(new Date()),
+                date: new Date(),
+                btnText: this.$t("search"),
+            }
+        },
+        mounted() {
+            this.writeData();
+        },
+        filters: {
+            timeFileter: function (time) {
+                return globalfmtDate(time, 10)
+            },
+        },
+        methods: {
+            changeTime(val) {
+                this.open = true;
+                let curVal = val == 1 ? new Date(this.bt) : new Date(this.et);
+                this.selectTime = val;
+                this.date = curVal;
+            },
+            showPanel() {
+                this.popupVisible = true;
+                this.btnText = this.$t("close");
+            },
+            whenClose(){
+                this.popupVisible = false;
+                this.btnText = this.$t("search");
+            },
+            confirmDay(date) {
+                if (this.selectTime == 1) {
+                    this.bt = globaltime2StringNoMin(date);
+                } else {
+                    this.et = globaltime2StringNoMin(date);
+                }
+                this.open = false;
+            },
+            // 重置
+            resetModal() {
+                this.MAC = '';
+                this.keyWord = '';
+                this.bt = globaltime2StringNoMin(new Date() - 3 * 24 * 3600 * 1000);
+                this.et = globaltime2StringNoMin(new Date());
+                this.Toast('已重置','success');
+            },
+            // 查询
+            searchModal() {
+                let that = this;
+                this.popupVisible = false;
+                this.writeData();
+                this.Toast('已查询','success');
+            },
+            writeData() {
+                const that = this;
+                let url = headapi + 'v1/Detector/WhiteListQuery';
+                let param = {
+                    token: localStorage.token,
+                    detectedmac:that.MAC,
+                    keywords:that.keyWord,
+                    bt:that.bt + ' 00:00:00',
+                    et:that.et + ' 23:59:59',
+                };
+                let postdata = qs.stringify(param);
+                axios.post(url, postdata).then(function (data) {
+                    let json = data.data;
+                    if (json.Code == 0) {
+                        that.lists = json.Rs;
+                    } else {
+                        that.Toast(that.TransMemo(json.Memo));
+                    }
+                }, function (response) {
+                    console.info(response);
+                })
+            }
+        },
+    }
+</script>
+
+<style scoped>
+    /*mu-header*/
+    .mu-primary-color {
+        line-height: 60px;
+        height: 60px;
+        background: url("../static/images/comm/headerBg.png") top center no-repeat;
+        background-size: 100%;
+    }
+
+    /deep/ .mu-appbar-left {
+        padding-top: 15px;
+    }
+
+    /deep/ .material-icons {
+        color: #fff;
+    }
+
+    /deep/ .mu-appbar-title {
+        text-align: center;
+    }
+    #pages {
+        position: absolute;
+        top: 0;
+        bottom: 0;
+        width: 100%;
+        height: 100%;
+        overflow: hidden;
+        overflow-y: scroll;
+        display: block;
+        margin: 0 auto;
+    }
+    .modal-content {
+        width: 100%;
+        display: block;
+        margin: 0 auto;
+        z-index: 99999;
+        overflow: hidden;
+    }
+
+    /*mu-bottom-sheet*/
+    .mu-bottom-sheet {
+        top: 60px !important;
+        bottom: 410px;
+        background: none;
+    }
+
+    .location {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .location span {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location input {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        text-indent: 10px;
+    }
+
+    .modal-body {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+        padding-top: 20px;
+        padding-left: 5%;
+        padding-right: 5%;
+        padding-bottom: 20px;
+    }
+
+    .modalBottom {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        background: #fff;
+    }
+
+    .modalBottom .reset {
+        width: 50%;
+        float: left;
+        height: 40px;
+        line-height: 40px;
+        background: #FFF6CF;
+        text-align: center;
+    }
+
+    .modalBottom .pullUp {
+        width: 50%;
+        float: right;
+        height: 40px;
+        line-height: 40px;
+        background: #FFCC00;
+        text-align: center;
+    }
+
+    .location select {
+        width: 95px;
+        height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 10px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+    }
+
+    .location select#detector {
+        margin-right: 0;
+        float: left;
+    }
+
+    #macInput {
+        width: 200px;
+        margin-bottom: 10px;
+    }
+    #keyWordInput {
+        width: 200px;
+    }
+
+    .timePickerPart {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+
+    .timePickerPart em {
+        width: 25px;
+        height: 30px;
+        line-height: 50px;
+        float: left;
+    }
+
+    .timePickerPart span {
+        width: 135px;
+        height: 30px;
+        line-height: 30px;
+        border: 1px solid #D5D5D5;
+        float: left;
+        margin-right: 8px;
+        margin-top: 10px;
+        margin-bottom: 10px;
+        text-align: center;
+    }
+    .demo-date-picker {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        border: none;
+        box-shadow: none;
+    }
+    .mu-datepicker {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+    }
+    .mu-list {
+        background: #fff;
+    }
+    .tips {
+        width: 100%;
+        overflow: hidden;
+        display: block;
+        margin: 0 auto;
+        text-align: center;
+        margin-top: 20px;
+    }
+</style>

+ 127 - 0
online/src/router/index.js

@@ -0,0 +1,127 @@
+import Vue from 'vue'
+import VueRouter from 'vue-router'
+import NProgress from 'muse-ui-progress';
+
+Vue.use(VueRouter);
+
+let NPconfig = {
+    zIndex: 2000,          // progress z-index
+    top: 0,                // position fixed top
+    speed: 300,            // progress speed
+    color: '#E75296',      // color
+    size: 2,               // progress size
+    className: ''          // progress custom class
+};
+Vue.use(NProgress,NPconfig);
+
+const routes = [
+    {
+        path: '/',
+        name: '',
+        component: () => import( '../page/index.vue'),
+        meta: {index: 0},//meta对象的index用来定义当前路由的层级,由小到大,由低到高
+        children: [
+            {
+                path: '/',
+                name: 'main',
+                meta: {
+                    title: '预约课程',
+                    index: 1
+                },
+                component: () => import( '../page/mainpage.vue')
+            },
+            {
+                path: '/appoint',
+                name: 'appoint',
+                meta: {
+                    title: '预约课程',
+                    index: 2
+                },
+                component: () => import( '../page/appoint.vue')
+            },  {
+                path: '/record',
+                name: 'record',
+                meta: {
+                    title: '预约记录',
+                    index: 1
+                },
+                component: () => import( '../page/record.vue')
+            }, {
+                path: '/mine',
+                name: 'mine',
+                meta: {
+                    title: '我的',
+                    index: 1
+                },
+                component: () => import( '../page/mine.vue')
+            },{
+                path: '/lesson',
+                name: 'lesson',
+                meta: {
+                    title: '课程表',
+                    index: 1
+                },
+                component: () => import( '../page/lesson.vue')
+            },
+        ]
+    },
+    {
+        path: '/login',
+        name: 'login',
+        meta: {
+            title: '登陆',
+            index: 1
+        },
+        component: () => import( '../page/login.vue')
+        // component: () => import( '../page/404.vue')
+    }, {
+        path: '/test',
+        name: 'test',
+        meta: {
+            title: 'test',
+            index: 1
+        },
+        component: () => import( '../page/test.vue')
+    },{
+        path: '/404',
+        name: '404',
+        meta: {
+            title: '404',
+            index: 1
+        },
+        component: () => import( '../page/404.vue')
+    }, {
+        path: '*',
+        name: 'notFound',
+        meta: {
+            title: '404',
+            index: 3
+        },
+        component: () => import( '../page/notFound.vue')
+    },
+];
+
+const router = new VueRouter({
+    mode: 'history',
+    base: process.env.BASE_URL,
+    routes
+});
+
+// 路由守卫
+router.beforeEach((to,from,next)=>{
+    NProgress.start();
+    const isLogin = localStorage.token? true : false;
+    if(to.path == '/login' ){//'login'和'register'相当于是路由白名单
+        next();
+    }else{
+        //如果token存在,就正常跳转,如果不存在,则说明未登陆,则跳转到'login'
+        isLogin? next() : next("/login");
+        // next();
+    }
+});
+
+router.afterEach(() => {
+    NProgress.done()
+})
+
+export default router

BIN
online/src/static/images/404/man.png


BIN
online/src/static/images/appoint/tri.png


BIN
online/src/static/images/appoint/x.png


BIN
online/src/static/images/bottom/Calendar@2x.png


BIN
online/src/static/images/bottom/CalendarRed@2x.png


BIN
online/src/static/images/bottom/Newspaper@2x.png


BIN
online/src/static/images/bottom/NewspaperRed@2x.png


BIN
online/src/static/images/bottom/User@2x.png


BIN
online/src/static/images/bottom/UserRed@2x.png


BIN
online/src/static/images/comm/arrow-left.png


BIN
online/src/static/images/comm/b11.png


BIN
online/src/static/images/comm/b11_1.png


BIN
online/src/static/images/comm/b12.png


BIN
online/src/static/images/comm/b12_1.png


BIN
online/src/static/images/comm/b13.png


BIN
online/src/static/images/comm/b13_1.png


BIN
online/src/static/images/comm/b14.png


BIN
online/src/static/images/comm/b14_1.png


BIN
online/src/static/images/comm/cityPicker.png


BIN
online/src/static/images/comm/headerBg.png


BIN
online/src/static/images/comm/iconEquipmanage.png


BIN
online/src/static/images/comm/iconEquipmanage_a.png


BIN
online/src/static/images/comm/iconHome.png


BIN
online/src/static/images/comm/iconHome_a.png


BIN
online/src/static/images/comm/iconMap.png


BIN
online/src/static/images/comm/iconMap_a.png


BIN
online/src/static/images/comm/iconProfile.png


BIN
online/src/static/images/comm/iconProfile_a.png


BIN
online/src/static/images/comm/iconRecord.png


BIN
online/src/static/images/comm/iconRecord_a.png


BIN
online/src/static/images/comm/iconRuntime.png


BIN
online/src/static/images/comm/iconRuntime_a.png


BIN
online/src/static/images/comm/iconStatis.png


BIN
online/src/static/images/comm/iconStatis_a.png


BIN
online/src/static/images/comm/iconUser.png


BIN
online/src/static/images/comm/iconUser_a.png


BIN
online/src/static/images/comm/list.png


BIN
online/src/static/images/comm/right.png


BIN
online/src/static/images/comm/tab01.png


BIN
online/src/static/images/comm/tab01_b.png


BIN
online/src/static/images/comm/tab02.png


BIN
online/src/static/images/comm/tab02_b.png


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä