use blue theme, optimizations
use blue theme, optimizations

.switch { .switch {
position: relative; position: relative;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip: padding-box; background-clip: padding-box;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
min-width: 51px; min-width: 51px;
font-size: 17px; font-size: 17px;
padding: 0 20px; padding: 0 20px;
border: none; border: none;
overflow: visible; overflow: visible;
width: 51px; width: 51px;
height: 32px; height: 32px;
z-index: 0; z-index: 0;
text-align: left; text-align: left;
} }
.switch__input { .switch__input {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
right: 0px; right: 0px;
top: 0px; top: 0px;
left: 0px; left: 0px;
bottom: 0px; bottom: 0px;
padding: 0; padding: 0;
border: 0; border: 0;
opacity: 0.001; opacity: 0.001;
z-index: 1; z-index: 1;
vertical-align: top; vertical-align: top;
outline: none; outline: none;
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
-webkit-appearance: none; -webkit-appearance: none;
appearance: none; appearance: none;
z-index: -1; z-index: -1;
} }
.switch__toggle { .switch__toggle {
background-color: #fff; background-color: #fff;
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 0px; left: 0px;
right: 0px; right: 0px;
bottom: 0px; bottom: 0px;
-webkit-border-radius: 30px; -webkit-border-radius: 30px;
border-radius: 30px; border-radius: 30px;
-webkit-transition-property: all; -webkit-transition-property: all;
-moz-transition-property: all; -moz-transition-property: all;
-o-transition-property: all; -o-transition-property: all;
transition-property: all; transition-property: all;
-webkit-transition-duration: 0.35s; -webkit-transition-duration: 0.35s;
-moz-transition-duration: 0.35s; -moz-transition-duration: 0.35s;
-o-transition-duration: 0.35s; -o-transition-duration: 0.35s;
transition-duration: 0.35s; transition-duration: 0.35s;
-webkit-transition-timing-function: ease-out; -webkit-transition-timing-function: ease-out;
-moz-transition-timing-function: ease-out; -moz-transition-timing-function: ease-out;
-o-transition-timing-function: ease-out; -o-transition-timing-function: ease-out;
transition-timing-function: ease-out; transition-timing-function: ease-out;
-webkit-box-shadow: inset 0 0 0 2px #e5e5e5; -webkit-box-shadow: inset 0 0 0 2px #e5e5e5;
box-shadow: inset 0 0 0 2px #e5e5e5; box-shadow: inset 0 0 0 2px #e5e5e5;
} }
.switch__handle { .switch__handle {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip: padding-box; background-clip: padding-box;
position: absolute; position: absolute;
content: ''; content: '';
-webkit-border-radius: 28px; -webkit-border-radius: 28px;
border-radius: 28px; border-radius: 28px;
height: 28px; height: 28px;
width: 28px; width: 28px;
background-color: #fff; background-color: #fff;
left: 1px; left: 1px;
top: 2px; top: 2px;
-webkit-transition-property: all; -webkit-transition-property: all;
-moz-transition-property: all; -moz-transition-property: all;
-o-transition-property: all; -o-transition-property: all;
transition-property: all; transition-property: all;
-webkit-transition-duration: 0.35s; -webkit-transition-duration: 0.35s;
-moz-transition-duration: 0.35s; -moz-transition-duration: 0.35s;
-o-transition-duration: 0.35s; -o-transition-duration: 0.35s;
transition-duration: 0.35s; transition-duration: 0.35s;
-webkit-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99); -webkit-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99);
-moz-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99); -moz-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99);
-o-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99); -o-transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99);
transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99); transition-timing-function: cubic-bezier(0.59, 0.01, 0.5, 0.99);
-webkit-box-shadow: 0 0 0 1px #e4e4e4, 0 3px 2px rgba(0,0,0,0.25); -webkit-box-shadow: 0 0 0 1px #e4e4e4, 0 3px 2px rgba(0,0,0,0.25);
box-shadow: 0 0 0 1px #e4e4e4, 0 3px 2px rgba(0,0,0,0.25); box-shadow: 0 0 0 1px #e4e4e4, 0 3px 2px rgba(0,0,0,0.25);
} }
.switch--active .switch__handle { .switch--active .switch__handle {
-webkit-transition-duration: 0s; -webkit-transition-duration: 0s;
-moz-transition-duration: 0s; -moz-transition-duration: 0s;
-o-transition-duration: 0s; -o-transition-duration: 0s;
transition-duration: 0s; transition-duration: 0s;
} }
input:checked + .switch__toggle { input:checked + .switch__toggle {
-webkit-box-shadow: inset 0 0 0 2px #5198db; -webkit-box-shadow: inset 0 0 0 2px #5198db;
box-shadow: inset 0 0 0 2px #5198db; box-shadow: inset 0 0 0 2px #5198db;
background-color: #5198db; background-color: #5198db;
} }
input:checked + .switch__toggle .switch__handle { input:checked + .switch__toggle .switch__handle {
left: 21px; left: 21px;
-webkit-box-shadow: 0 3px 2px rgba(0,0,0,0.25); -webkit-box-shadow: 0 3px 2px rgba(0,0,0,0.25);
box-shadow: 0 3px 2px rgba(0,0,0,0.25); box-shadow: 0 3px 2px rgba(0,0,0,0.25);
} }
input:disabled + .switch__toggle { input:disabled + .switch__toggle {
opacity: 0.3; opacity: 0.3;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
} }
.switch__touch { .switch__touch {
position: absolute; position: absolute;
top: -5px; top: -5px;
bottom: -5px; bottom: -5px;
left: -10px; left: -10px;
right: -10px; right: -10px;
} }
.switch.switch--material { .switch.switch--material {
width: 36px; width: 36px;
height: 24px; height: 24px;
padding: 0 10px; padding: 0 10px;
min-width: 36px; min-width: 36px;
} }
.switch.switch--material .switch__toggle { .switch.switch--material .switch__toggle {
background-color: #b0afaf; background-color: #b0afaf;
margin-top: 5px; margin-top: 5px;
height: 14px; height: 14px;
-webkit-box-shadow: none; -webkit-box-shadow: none;
box-shadow: none; box-shadow: none;
} }
.switch.switch--material .switch__input { .switch.switch--material .switch__input {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
right: 0px; right: 0px;
top: 0px; top: 0px;
left: 0px; left: 0px;
bottom: 0px; bottom: 0px;
padding: 0; padding: 0;
border: 0; border: 0;
opacity: 0.001; opacity: 0.001;
z-index: 1; z-index: 1;
vertical-align: top; vertical-align: top;
outline: none; outline: none;
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
-webkit-appearance: none; -webkit-appearance: none;
appearance: none; appearance: none;
z-index: -1; z-index: -1;
} }
.switch.switch--material .switch__handle { .switch.switch--material .switch__handle {
background-color: #f1f1f1; background-color: #f1f1f1;
left: 0px; left: 0px;
margin-top: -5px; margin-top: -5px;
width: 20px; width: 20px;
height: 20px; height: 20px;
-webkit-box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.4); -webkit-box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.4);
box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.4); box-shadow: 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12), 0 2px 4px -1px rgba(0,0,0,0.4);
} }
.switch.switch--material input:checked + .switch__toggle { .switch.switch--material input:checked + .switch__toggle {
background-color: #77c2bb; background-color: #3c8dbc;
-webkit-box-shadow: none; -webkit-box-shadow: none;
box-shadow: none; box-shadow: none;
} }
.switch.switch--material input:checked + .switch__toggle .switch__handle { .switch.switch--material input:checked + .switch__toggle .switch__handle {
left: 16px; left: 16px;
background-color: #009688; background-color: #3c8dbc;
-webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); -webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2); box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
} }
.switch.switch--material input:disabled + .switch__toggle { .switch.switch--material input:disabled + .switch__toggle {
opacity: 0.3; opacity: 0.3;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
} }
.switch.switch--material .switch__handle:before { .switch.switch--material .switch__handle:before {
background: transparent; background: transparent;
content: ''; content: '';
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: 100%;
-webkit-border-radius: 50%; -webkit-border-radius: 50%;
border-radius: 50%; border-radius: 50%;
z-index: -1; z-index: -1;
-webkit-box-shadow: 0px 0px 0px 0px rgba(0,0,0,0.12); -webkit-box-shadow: 0px 0px 0px 0px rgba(0,0,0,0.12);
box-shadow: 0px 0px 0px 0px rgba(0,0,0,0.12); box-shadow: 0px 0px 0px 0px rgba(0,0,0,0.12);
-webkit-transition: -webkit-box-shadow 0.1s linear; -webkit-transition: -webkit-box-shadow 0.1s linear;
-moz-transition: box-shadow 0.1s linear; -moz-transition: box-shadow 0.1s linear;
-o-transition: box-shadow 0.1s linear; -o-transition: box-shadow 0.1s linear;
transition: box-shadow 0.1s linear; transition: box-shadow 0.1s linear;
} }
.switch.switch--material.switch--active .switch__handle:before { .switch.switch--material.switch--active .switch__handle:before {
-webkit-box-shadow: 0px 0px 0px 14px rgba(0,0,0,0.12); -webkit-box-shadow: 0px 0px 0px 14px rgba(0,0,0,0.12);
box-shadow: 0px 0px 0px 14px rgba(0,0,0,0.12); box-shadow: 0px 0px 0px 14px rgba(0,0,0,0.12);
} }
.switch.switch--material.switch--active input:checked + .switch__toggle .switch__handle:before { .switch.switch--material.switch--active input:checked + .switch__toggle .switch__handle:before {
-webkit-box-shadow: 0px 0px 0px 14px #009688; -webkit-box-shadow: 0px 0px 0px 14px #3c8dbc;
box-shadow: 0px 0px 0px 14px #009688; box-shadow: 0px 0px 0px 14px #3c8dbc;
} }
.switch.switch--material .switch__touch { .switch.switch--material .switch__touch {
position: absolute; position: absolute;
top: -10px; top: -10px;
bottom: -10px; bottom: -10px;
left: -15px; left: -15px;
right: -15px; right: -15px;
  }
   
  .tab-bar {
  font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 400;
  font-size: 17px;
  display: table;
  table-layout: fixed;
  position: absolute;
  bottom: 0px;
  left: 0px;
  right: 0px;
  white-space: nowrap;
  margin: 0;
  padding: 0;
  height: 49px;
  background-color: #fff;
  border-top: 1px solid #ccc;
  width: 100%;
  }
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .tab-bar {
  border-top: none;
  -webkit-background-size: 100% 1px;
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: top;
  background-image: -webkit-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);
  background-image: -moz-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);
  background-image: -o-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);
  background-image: linear-gradient(180deg, #ccc, #ccc 50%, transparent 50%);
  }
  }
  .tab-bar__item {
  font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 400;
  font-size: 17px;
  position: relative;
  overflow: hidden;
  display: table-cell;
  width: auto;
  -webkit-border-radius: 0;
  border-radius: 0;
  }
  .tab-bar__item > input {
  position: absolute;
  overflow: hidden;
  right: 0px;
  top: 0px;
  left: 0px;
  bottom: 0px;
  padding: 0;
  border: 0;
  opacity: 0.001;
  z-index: 1;
  vertical-align: top;
  outline: none;
  width: 100%;
  height: 100%;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
  }
  .tab-bar__button {
  position: relative;
  display: inline-block;
  vertical-align: top;
  font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 400;
  font-size: 17px;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  -webkit-background-clip: padding-box;
  background-clip: padding-box;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  background: transparent;
  border: none;
  line-height: normal;
  cursor: default;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  text-decoration: none;
  padding: 0;
  height: 49px;
  letter-spacing: 0;
  color: #999;
  text-shadow: 0 1px none;
  vertical-align: top;
  background-color: transparent;
  -webkit-box-shadow: none;
  box-shadow: none;
  border-top: none;
  width: 100%;
  font-weight: 400;
  line-height: 49px;
  }
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .tab-bar__button {
  border-top: none;
  }
  }
  .tab-bar__icon {
  font-size: 24px;
  padding: 0;
  margin: 0;
  line-height: 26px;
  display: block;
  height: 28px;
  }
  .tab-bar__label {
  font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-weight: 400;
  font-size: 17px;
  }
  .tab-bar__badge.notification {
  position: absolute;
  top: 5px;
  z-index: 10;
  font-size: 12px;
  height: 16px;
  line-height: 16px;
  -webkit-border-radius: 8px;
  border-radius: 8px;
  }
  .tab-bar__icon + .tab-bar__label {
  font-size: 10px;
  line-height: 1;
  margin: 0;
  font-weight: 400;
  }
  .tab-bar__label:first-child {
  font-size: 16px;
  line-height: 49px;
  margin: 0;
  padding: 0;
  }
  .tab-bar__button {
  color: #999;
  }
  :checked + .tab-bar__button {
  color: rgba(24,103,194,0.81);
  background-color: transparent;
  -webkit-box-shadow: none;
  box-shadow: none;
  border-top: none;
  }
  .tab-bar__button:disabled {
  opacity: 0.3;
  cursor: default;
  pointer-events: none;
  }
  .tab-bar__button:focus {
  z-index: 1;
  border-top: none;
  -webkit-box-shadow: none;
  box-shadow: none;
  outline: 0;
  }
  .tab-bar__content {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 49px;
  z-index: 0;
  }
  .tab-bar--top {
  position: relative;
  top: 0px;
  left: 0px;
  right: 0px;
  bottom: auto;
  border-top: none;
  border-bottom: 1px solid #ccc;
  }
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .tab-bar--top {
  border-bottom: none;
  -webkit-background-size: 100% 1px;
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: bottom;
  background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);
  background-image: -moz-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);
  background-image: -o-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);
  background-image: linear-gradient(0deg, #ccc, #ccc 50%, transparent 50%);
  }
  }
  .tab-bar--top__content {
  top: 49px;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 0;
  }
  .tab-bar--top-border__button {
  background-color: transparent;
  border-bottom: 4px solid transparent;
  }
  :checked + .tab-bar--top-border__button {
  background-color: transparent;
  border-bottom: 4px solid rgba(24,103,194,0.81);
  }
  .tab-bar--material {
  background-color: #3c8dbc;
  border-bottom-width: 0px;
  -webkit-box-shadow: 0 4px 2px -2px rgba(0,0,0,0.14), 0 3px 5px -2px rgba(0,0,0,0.12), 0 5px 1px -4px rgba(0,0,0,0.2);
  box-shadow: 0 4px 2px -2px rgba(0,0,0,0.14), 0 3px 5px -2px rgba(0,0,0,0.12), 0 5px 1px -4px rgba(0,0,0,0.2);
  }
  .tab-bar--material__button {
  background-color: transparent;
  color: rgba(255, 255, 255, 0.6);
  text-transform: uppercase;
  font-size: 14px;
  font-weight: 500;
  font-family: 'Roboto', 'Noto', sans-serif;
  -webkit-font-smoothing: antialiased;
  }
  .tab-bar--material__button:after {
  content: '';
  display: block;
  width: 0px;
  height: 2px;
  bottom: 0px;
  position: absolute;
  margin-top: -2px;
  background-color: #ffffff;
  }
  :checked + .tab-bar--material__button:after {
  width: 100%;
  -webkit-transition: width 0.2s ease-in-out;
  -moz-transition: width 0.2s ease-in-out;
  -o-transition: width 0.2s ease-in-out;
  transition: width 0.2s ease-in-out;
  }
  :checked + .tab-bar--material__button {
  background-color: transparent;
  color: #ffffff;
  }
  .tab-bar--material__item:not([ripple]):active {
  background-color: #3c8dbc;
  }
  .tab-bar--material__label {
  font-family: 'Roboto', 'Noto', sans-serif;
  -webkit-font-smoothing: antialiased;
  }
  .tab-bar--material__label:first-child {
  font-family: 'Roboto', 'Noto', sans-serif;
  -webkit-font-smoothing: antialiased;
  letter-spacing: 0.015em;
  font-weight: 500;
  font-size: 14px;
  }
  .tab-bar--material__icon + .tab-bar--material__label {
  font-size: 10px;
} }
   
.radio-button__input { .radio-button__input {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
right: 0px; right: 0px;
top: 0px; top: 0px;
left: 0px; left: 0px;
bottom: 0px; bottom: 0px;
padding: 0; padding: 0;
border: 0; border: 0;
opacity: 0.001; opacity: 0.001;
z-index: 1; z-index: 1;
vertical-align: top; vertical-align: top;
outline: none; outline: none;
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
-webkit-appearance: none; -webkit-appearance: none;
appearance: none; appearance: none;
} }
.radio-button__input:active, .radio-button__input:active,
.radio-button__input:focus { .radio-button__input:focus {
outline: 0; outline: 0;
-webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: rgba(0,0,0,0);
} }
.radio-button__input:checked + .radio-button__checkmark:after { .radio-button__input:checked + .radio-button__checkmark:after {
opacity: 1; opacity: 1;
} }
.radio-button__input:checked + .radio-button__checkmark:before { .radio-button__input:checked + .radio-button__checkmark:before {
background: transparent; background: transparent;
border: none; border: none;
} }
.radio-button { .radio-button {
position: relative; position: relative;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
cursor: default; cursor: default;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
line-height: 24px; line-height: 24px;
text-align: left; text-align: left;
} }
.radio-button__checkmark:before { .radio-button__checkmark:before {
content: ''; content: '';
position: absolute; position: absolute;
-webkit-border-radius: 100%; -webkit-border-radius: 100%;
border-radius: 100%; border-radius: 100%;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip: padding-box; background-clip: padding-box;
width: 24px; width: 24px;
height: 24px; height: 24px;
background: transparent; background: transparent;
border: none; border: none;
-webkit-border-radius: 16px; -webkit-border-radius: 16px;
border-radius: 16px; border-radius: 16px;
left: 0; left: 0;
} }
.radio-button__checkmark { .radio-button__checkmark {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-background-clip: padding-box; -webkit-background-clip: padding-box;
background-clip: padding-box; background-clip: padding-box;
position: relative; position: relative;
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
cursor: default; cursor: default;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
-ms-user-select: none; -ms-user-select: none;
user-select: none; user-select: none;
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
font-weight: 400; font-weight: 400;
font-size: 17px; font-size: 17px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
width: 24px; width: 24px;
height: 24px; height: 24px;
background: transparent; background: transparent;
pointer-events: none; pointer-events: none;
} }
.radio-button__input:checked + .radio-button__checkmark { .radio-button__input:checked + .radio-button__checkmark {
background: rgba(0,0,0,0); background: rgba(0,0,0,0);
} }
.radio-button__checkmark:after { .radio-button__checkmark:after {
content: ''; content: '';
position: absolute; position: absolute;
-webkit-border-radius: 100%; -webkit-border-radius: 100%;
border-radius: 100%; border-radius: 100%;
top: 50%; top: 50%;
left: 50%; left: 50%;
-webkit-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%);
-o-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
top: 6px; top: 6px;
left: 5px; left: 5px;
opacity: 0; opacity: 0;
width: 12px; width: 12px;
height: 6px; height: 6px;
background: transparent; background: transparent;
border: 3px solid rgba(24,103,194,0.81); border: 3px solid rgba(24,103,194,0.81);
border-width: 2px; border-width: 2px;
border-top: none; border-top: none;
border-right: none; border-right: none;
-webkit-border-radius: 0px; -webkit-border-radius: 0px;
border-radius: 0px; border-radius: 0px;
-webkit-transform: rotate(-45deg); -webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg); -moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg); -ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg); -o-transform: rotate(-45deg);
transform: rotate(-45deg); transform: rotate(-45deg);
} }
.radio-button__input:disabled + .radio-button__checkmark { .radio-button__input:disabled + .radio-button__checkmark {
opacity: 0.3; opacity: 0.3;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
} }
.radio-button--material { .radio-button--material {
line-height: 22px; line-height: 22px;
font-family: 'Roboto', 'Noto', sans-serif; font-family: 'Roboto', 'Noto', sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
font-weight: 100;  
} }
.radio-button--material__checkmark { .radio-button--material__checkmark {
width: 20px; width: 20px;
height: 20px; height: 20px;
overflow: visible; overflow: visible;
} }
.radio-button--material__checkmark:before { .radio-button--material__checkmark:before {
background: transparent; background: transparent;
border: 2px solid #717171; border: 2px solid #717171;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-border-radius: 50%; -webkit-border-radius: 50%;
border-radius: 50%; border-radius: 50%;
width: 20px; width: 20px;
height: 20px; height: 20px;
-webkit-transition: border 0.2s ease; -webkit-transition: border 0.2s ease;
-moz-transition: border 0.2s ease; -moz-transition: border 0.2s ease;
-o-transition: border 0.2s ease; -o-transition: border 0.2s ease;
transition: border 0.2s ease; transition: border 0.2s ease;
} }
.radio-button--material__checkmark:after { .radio-button--material__checkmark:after {
-webkit-transition: background 0.2s ease, -webkit-transform 0.2s ease; -webkit-transition: background 0.2s ease, -webkit-transform 0.2s ease;
-moz-transition: background 0.2s ease, -moz-transform 0.2s ease; -moz-transition: background 0.2s ease, -moz-transform 0.2s ease;
-o-transition: background 0.2s ease, -o-transform 0.2s ease; -o-transition: background 0.2s ease, -o-transform 0.2s ease;
transition: background 0.2s ease, transform 0.2s ease; transition: background 0.2s ease, transform 0.2s ease;
top: 5px; top: 5px;
left: 5px; left: 5px;
width: 10px; width: 10px;
height: 10px; height: 10px;
border: none; border: none;
-webkit-border-radius: 50%; -webkit-border-radius: 50%;
border-radius: 50%; border-radius: 50%;
-webkit-transform: scale(0); -webkit-transform: scale(0);
-moz-transform: scale(0); -moz-transform: scale(0);
-ms-transform: scale(0); -ms-transform: scale(0);
-o-transform: scale(0); -o-transform: scale(0);
transform: scale(0); transform: scale(0);
} }
.radio-button--material__input:checked + .radio-button__checkmark:before { .radio-button--material__input:checked + .radio-button__checkmark:before {
background: transparent; background: transparent;
border: 2px solid #009688; border: 2px solid #3c8dbc;
} }
.radio-button--material__input + .radio-button__checkmark:after { .radio-button--material__input + .radio-button__checkmark:after {
background: #717171; background: #717171;
opacity: 1; opacity: 1;
-webkit-transform: scale(0); -webkit-transform: scale(0);
-moz-transform: scale(0); -moz-transform: scale(0);
-ms-transform: scale(0); -ms-transform: scale(0);
-o-transform: scale(0); -o-transform: scale(0);
transform: scale(0); transform: scale(0);
} }
.radio-button--material__input:checked + .radio-button__checkmark:after { .radio-button--material__input:checked + .radio-button__checkmark:after {
opacity: 1; opacity: 1;
background: #009688; background: #3c8dbc;
-webkit-transform: scale(1); -webkit-transform: scale(1);
-moz-transform: scale(1); -moz-transform: scale(1);
-ms-transform: scale(1); -ms-transform: scale(1);
-o-transform: scale(1); -o-transform: scale(1);
transform: scale(1); transform: scale(1);
} }
.radio-button--material__input:disabled + .radio-button__checkmark { .radio-button--material__input:disabled + .radio-button__checkmark {
opacity: 1; opacity: 1;
} }
.radio-button--material__input:disabled + .radio-button__checkmark:after { .radio-button--material__input:disabled + .radio-button__checkmark:after {
background-color: #afafaf; background-color: #afafaf;
border-color: #afafaf; border-color: #afafaf;
} }
.radio-button--material__input:disabled + .radio-button__checkmark:before { .radio-button--material__input:disabled + .radio-button__checkmark:before {
border-color: #afafaf; border-color: #afafaf;
} }
   
.tab-bar {  
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;  
-webkit-font-smoothing: antialiased;  
-moz-osx-font-smoothing: grayscale;  
font-weight: 400;  
font-size: 17px;  
display: table;  
table-layout: fixed;  
position: absolute;  
bottom: 0px;  
left: 0px;  
right: 0px;  
white-space: nowrap;  
margin: 0;  
padding: 0;  
height: 49px;  
background-color: #fff;  
border-top: 1px solid #ccc;  
width: 100%;  
}  
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {  
.tab-bar {  
border-top: none;  
-webkit-background-size: 100% 1px;  
background-size: 100% 1px;  
background-repeat: no-repeat;  
background-position: top;  
background-image: -webkit-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -moz-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -o-linear-gradient(270deg, #ccc, #ccc 50%, transparent 50%);  
background-image: linear-gradient(180deg, #ccc, #ccc 50%, transparent 50%);  
}  
}  
.tab-bar__item {  
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;  
-webkit-font-smoothing: antialiased;  
-moz-osx-font-smoothing: grayscale;  
font-weight: 400;  
font-size: 17px;  
position: relative;  
overflow: hidden;  
display: table-cell;  
width: auto;  
-webkit-border-radius: 0;  
border-radius: 0;  
}  
.tab-bar__item > input {  
position: absolute;  
overflow: hidden;  
right: 0px;  
top: 0px;  
left: 0px;  
bottom: 0px;  
padding: 0;  
border: 0;  
opacity: 0.001;  
z-index: 1;  
vertical-align: top;  
outline: none;  
width: 100%;  
height: 100%;  
margin: 0;  
-webkit-appearance: none;  
appearance: none;  
}  
.tab-bar__button {  
position: relative;  
display: inline-block;  
vertical-align: top;  
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;  
-webkit-font-smoothing: antialiased;  
-moz-osx-font-smoothing: grayscale;  
font-weight: 400;  
font-size: 17px;  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
-webkit-background-clip: padding-box;  
background-clip: padding-box;  
padding: 0;  
margin: 0;  
font: inherit;  
color: inherit;  
background: transparent;  
border: none;  
line-height: normal;  
cursor: default;  
-webkit-user-select: none;  
-moz-user-select: none;  
-ms-user-select: none;  
user-select: none;  
text-overflow: ellipsis;  
white-space: nowrap;  
overflow: hidden;  
text-decoration: none;  
padding: 0;  
height: 49px;  
letter-spacing: 0;  
color: #999;  
text-shadow: 0 1px none;  
vertical-align: top;  
background-color: transparent;  
-webkit-box-shadow: none;  
box-shadow: none;  
border-top: none;  
width: 100%;  
font-weight: 400;  
line-height: 49px;  
}  
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {  
.tab-bar__button {  
border-top: none;  
}  
}  
.tab-bar__icon {  
font-size: 24px;  
padding: 0;  
margin: 0;  
line-height: 26px;  
display: block;  
height: 28px;  
}  
.tab-bar__label {  
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;  
-webkit-font-smoothing: antialiased;  
-moz-osx-font-smoothing: grayscale;  
font-weight: 400;  
font-size: 17px;  
}  
.tab-bar__badge.notification {  
position: absolute;  
top: 5px;  
z-index: 10;  
font-size: 12px;  
height: 16px;  
line-height: 16px;  
-webkit-border-radius: 8px;  
border-radius: 8px;  
}  
.tab-bar__icon + .tab-bar__label {  
font-size: 10px;  
line-height: 1;  
margin: 0;  
font-weight: 400;  
}  
.tab-bar__label:first-child {  
font-size: 16px;  
line-height: 49px;  
margin: 0;  
padding: 0;  
}  
.tab-bar__button {  
color: #999;  
}  
:checked + .tab-bar__button {  
color: rgba(24,103,194,0.81);  
background-color: transparent;  
-webkit-box-shadow: none;  
box-shadow: none;  
border-top: none;  
}  
.tab-bar__button:disabled {  
opacity: 0.3;  
cursor: default;  
pointer-events: none;  
}  
.tab-bar__button:focus {  
z-index: 1;  
border-top: none;  
-webkit-box-shadow: none;  
box-shadow: none;  
outline: 0;  
}  
.tab-bar__content {  
position: absolute;  
top: 0;  
left: 0;  
right: 0;  
bottom: 49px;  
z-index: 0;  
}  
.tab-bar--top {  
position: relative;  
top: 0px;  
left: 0px;  
right: 0px;  
bottom: auto;  
border-top: none;  
border-bottom: 1px solid #ccc;  
}  
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {  
.tab-bar--top {  
border-bottom: none;  
-webkit-background-size: 100% 1px;  
background-size: 100% 1px;  
background-repeat: no-repeat;  
background-position: bottom;  
background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -moz-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -o-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: linear-gradient(0deg, #ccc, #ccc 50%, transparent 50%);  
}  
}  
.tab-bar--top__content {  
top: 49px;  
left: 0;  
right: 0;  
bottom: 0;  
z-index: 0;  
}  
.tab-bar--top-border__button {  
background-color: transparent;  
border-bottom: 4px solid transparent;  
}  
:checked + .tab-bar--top-border__button {  
background-color: transparent;  
border-bottom: 4px solid rgba(24,103,194,0.81);  
}  
.tab-bar--material {  
background-color: #009688;  
border-bottom-width: 0px;  
-webkit-box-shadow: 0 4px 2px -2px rgba(0,0,0,0.14), 0 3px 5px -2px rgba(0,0,0,0.12), 0 5px 1px -4px rgba(0,0,0,0.2);  
box-shadow: 0 4px 2px -2px rgba(0,0,0,0.14), 0 3px 5px -2px rgba(0,0,0,0.12), 0 5px 1px -4px rgba(0,0,0,0.2);  
}  
.tab-bar--material__button {  
background-color: transparent;  
color: rgba(255, 255, 255, 0.6);  
text-transform: uppercase;  
font-size: 14px;  
font-weight: 500;  
font-family: 'Roboto', 'Noto', sans-serif;  
-webkit-font-smoothing: antialiased;  
}  
.tab-bar--material__button:after {  
content: '';  
display: block;  
width: 0px;  
height: 2px;  
bottom: 0px;  
position: absolute;  
margin-top: -2px;  
background-color: #ffffff;  
}  
:checked + .tab-bar--material__button:after {  
width: 100%;  
-webkit-transition: width 0.2s ease-in-out;  
-moz-transition: width 0.2s ease-in-out;  
-o-transition: width 0.2s ease-in-out;  
transition: width 0.2s ease-in-out;  
}  
:checked + .tab-bar--material__button {  
background-color: transparent;  
color: #ffffff;  
}  
.tab-bar--material__item:not([ripple]):active {  
background-color: #26a69a;  
}  
.tab-bar--material__label {  
font-family: 'Roboto', 'Noto', sans-serif;  
-webkit-font-smoothing: antialiased;  
}  
.tab-bar--material__label:first-child {  
font-family: 'Roboto', 'Noto', sans-serif;  
-webkit-font-smoothing: antialiased;  
letter-spacing: 0.015em;  
font-weight: 500;  
font-size: 14px;  
}  
.tab-bar--material__icon + .tab-bar--material__label {  
font-size: 10px;  
}  
   
.list__item__left {  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
display: -webkit-box;  
display: -webkit-flex;  
display: -moz-box;  
display: -ms-flexbox;  
display: flex;  
padding: 12px 14px 12px 0;  
-webkit-box-ordinal-group: 1;  
-webkit-order: 0;  
-moz-box-ordinal-group: 1;  
-ms-flex-order: 0;  
order: 0;  
-webkit-box-align: center;  
-webkit-align-items: center;  
-moz-box-align: center;  
-ms-flex-align: center;  
align-items: center;  
-webkit-align-self: stretch;  
-ms-flex-item-align: stretch;  
align-self: stretch;  
line-height: 1.2em;  
min-height: 44px;  
}  
.list__item__left:empty {  
width: 0;  
min-width: 0;  
padding: 0;  
margin: 0;  
}  
.list__item__center {  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
display: -webkit-box;  
display: -webkit-flex;  
display: -moz-box;  
display: -ms-flexbox;  
display: flex;  
-webkit-box-flex: 1;  
-webkit-flex-grow: 1;  
-moz-box-flex: 1;  
-ms-flex-positive: 1;  
flex-grow: 1;  
-webkit-flex-wrap: wrap;  
-ms-flex-wrap: wrap;  
flex-wrap: wrap;  
-webkit-box-orient: horizontal;  
-webkit-box-direction: normal;  
-webkit-flex-direction: row;  
-moz-box-orient: horizontal;  
-moz-box-direction: normal;  
-ms-flex-direction: row;  
flex-direction: row;  
-webkit-box-ordinal-group: 2;  
-webkit-order: 1;  
-moz-box-ordinal-group: 2;  
-ms-flex-order: 1;  
order: 1;  
margin-right: auto;  
-webkit-box-align: center;  
-webkit-align-items: center;  
-moz-box-align: center;  
-ms-flex-align: center;  
align-items: center;  
-webkit-align-self: stretch;  
-ms-flex-item-align: stretch;  
align-self: stretch;  
margin-left: 0;  
border-bottom: none;  
-webkit-background-size: 100% 1px;  
background-size: 100% 1px;  
background-repeat: no-repeat;  
background-position: bottom;  
background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: -moz-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: -o-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: linear-gradient(0deg, #ccc, #ccc 100%);  
padding: 12px 6px 12px 0;  
line-height: 1.2em;  
min-height: 44px;  
}  
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {  
.list__item__center {  
background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -moz-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -o-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: linear-gradient(0deg, #ccc, #ccc 50%, transparent 50%);  
}  
}  
.list__item__right {  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
display: -webkit-box;  
display: -webkit-flex;  
display: -moz-box;  
display: -ms-flexbox;  
display: flex;  
margin-left: auto;  
padding: 12px 12px 12px 0;  
-webkit-box-ordinal-group: 3;  
-webkit-order: 2;  
-moz-box-ordinal-group: 3;  
-ms-flex-order: 2;  
order: 2;  
-webkit-box-align: center;  
-webkit-align-items: center;  
-moz-box-align: center;  
-ms-flex-align: center;  
align-items: center;  
-webkit-align-self: stretch;  
-ms-flex-item-align: stretch;  
align-self: stretch;  
border-bottom: none;  
-webkit-background-size: 100% 1px;  
background-size: 100% 1px;  
background-repeat: no-repeat;  
background-position: bottom;  
background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: -moz-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: -o-linear-gradient(90deg, #ccc, #ccc 100%);  
background-image: linear-gradient(0deg, #ccc, #ccc 100%);  
line-height: 1.2em;  
min-height: 44px;  
}  
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {  
.list__item__right {  
background-image: -webkit-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -moz-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: -o-linear-gradient(90deg, #ccc, #ccc 50%, transparent 50%);  
background-image: linear-gradient(0deg, #ccc, #ccc 50%, transparent 50%);  
}  
}  
.list__header {  
margin: 0;  
padding: 0;  
list-style: none;  
text-align: left;  
display: block;  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
padding: 20px 0 0 15px;  
font-size: 12px;  
font-weight: 500;  
color: #1f1f21;  
text-shadow: none;  
border-top: none;  
border-bottom: 1px solid #ccc;  
-webkit-box-shadow: 0px 1px 0px 0px #fff;  
box-shadow: 0px 1px 0px 0px #fff;  
min-height: 24px;  
line-height: 24px;  
margin-top: -1px;  
text-transform: uppercase;  
position: relative;  
}  
.list__header:not(:first-of-type) {  
border-top: 1px solid #ccc;  
}  
.list {  
padding: 0;  
margin: 0;  
font: inherit;  
color: inherit;  
background: transparent;  
border: none;  
line-height: normal;  
cursor: default;  
-webkit-user-select: none;  
-moz-user-select: none;  
-ms-user-select: none;  
user-select: none;  
font-family: -apple-system, 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif;  
-webkit-font-smoothing: antialiased;  
-moz-osx-font-smoothing: grayscale;  
font-weight: 400;  
font-size: 17px;  
padding: 0;  
margin: 0;  
list-style-type: none;  
text-align: left;  
overflow: auto;  
display: block;  
-webkit-overflow-scrolling: touch;  
border-bottom: 1px solid #ccc;  
overflow: hidden;  
}  
.list__item {  
margin: 0;  
padding: 0;  
width: 100%;  
position: relative;  
list-style: none;  
-webkit-box-sizing: border-box;  
-moz-box-sizing: border-box;  
box-sizing: border-box;  
display: -webkit-box;  
display: -webkit-flex;  
display: -moz-box;  
display: -ms-flexbox;  
display: flex;  
-webkit-box-orient: horizontal;  
-webkit-box-direction: normal;  
-webkit-flex-direction: row;  
-moz-box-orient: horizontal;  
-moz-box-direction: normal;  
-ms-flex-direction: row;  
flex-direction: row;  
-webkit-box-pack: start;  
-webkit-justify-content: flex-start;  
-moz-box-pack: start;  
-ms-flex-pack: start;  
justify-content: flex-start;  
-webkit-box-align: center;  
-webkit-align-items: center;  
-moz-box-align: center;  
-ms-flex-align: center;  
align-items: center;  
padding: 0 0 0 14px;  
margin: 1px 0 -1px 0;  
color: #1f1f21;  
background-color: #fff;  
}  
.list__item:first-child {  
-webkit-box-shadow: inset 0px 1px 0px 0px #ccc;  
box-shadow: inset 0px 1px 0px 0px #ccc;  
margin-top: 0;  
}  
.list__item_active:active {  
background-color: #d9d9d9;  
-webkit-transition: none;  
-moz-transition: none;  
-o-transition: none;  
transition: none;  
}  
   
   
var iotCC = { var iotCC = {
mqttDefaultConfig: { mqttDefaultConfig: {
keepalive: 10, keepalive: 10,
protocolId: 'MQTT', protocolId: 'MQTT',
protocolVersion: 4, protocolVersion: 4,
clean: true, clean: true,
reconnectPeriod: 1000, reconnectPeriod: 1000,
connectTimeout: 30 * 1000, connectTimeout: 30 * 1000,
will: { will: {
topic: '/lwt', topic: '/lwt',
payload: 'Connection Closed abnormally..!', payload: 'Connection Closed abnormally..!',
qos: 2, qos: 2,
retain: true retain: true
}, },
rejectUnauthorized: false, rejectUnauthorized: false,
secure: false, secure: false,
simulateDevices: false, simulateDevices: false,
debug: false, debug: false,
}, },
mqttConfig: {}, mqttConfig: {},
mqttClient: null, mqttClient: null,
templates : [], templates : [],
setConfig: function(mqttConfig) { setConfig: function(mqttConfig) {
this.mqttConfig = Object.assign(this.mqttDefaultConfig, mqttConfig); this.mqttConfig = Object.assign(this.mqttDefaultConfig, mqttConfig);
}, },
getConfig: function() { getConfig: function() {
return this.mqttConfig; return this.mqttConfig;
}, },
init: function(mqttConfig) { init: function(mqttConfig) {
if ((typeof(window['mqttConfig']) == 'undefined')) { if ((typeof(window['mqttConfig']) == 'undefined')) {
console.log ('mqttConfig is not defined in config.js. see config.sample.js'); console.log ('mqttConfig is not defined in config.js. see config.sample.js');
return; return;
} else if (typeof jQuery == 'undefined') { } else if (typeof jQuery == 'undefined') {
console.log ('IoT Control center requires jQuery'); console.log ('IoT Control center requires jQuery');
return; return;
} }
this.setConfig(mqttConfig); this.setConfig(mqttConfig);
   
this.mqttClient = mqtt.connect('ws' + (this.mqttConfig.secure==true?'s':'') + '://' + this.mqttConfig.host + ':' + this.mqttConfig.port, this.mqttConfig); this.mqttClient = mqtt.connect('ws' + (this.mqttConfig.secure==true?'s':'') + '://' + this.mqttConfig.host + ':' + this.mqttConfig.port, this.mqttConfig);
   
this.mqttClient.on('error', function (err) { this.mqttClient.on('error', function (err) {
console.log(err); console.log(err);
iotCC.mqttClient.end(); iotCC.mqttClient.end();
}); });
   
this.mqttClient.on('connect', function () { this.mqttClient.on('connect', function () {
if (iotCC.mqttConfig.debug) console.log('client connected:' + iotCC.mqttConfig.clientId); if (iotCC.mqttConfig.debug) console.log('client connected:' + iotCC.mqttConfig.clientId);
}); });
   
this.mqttClient.subscribe('/iotcc/+/+/config', {qos: 1}); this.mqttClient.subscribe('/iotcc/+/+/config', {qos: 1});
this.mqttClient.subscribe('/iotcc/+/+/data', {qos: 1}); this.mqttClient.subscribe('/iotcc/+/+/data', {qos: 1});
this.mqttClient.subscribe('/iotcc/+/device', {qos: 1}); this.mqttClient.subscribe('/iotcc/+/device', {qos: 1});
   
if (typeof(window['iotCCInitEvents']) != 'undefined') { if (typeof(window['iotCCInitEvents']) != 'undefined') {
for(var i in iotCCInitEvents) { for(var i in iotCCInitEvents) {
try { try {
window[iotCCInitEvents[i]](this); window[iotCCInitEvents[i]](this);
} catch (err) { } catch (err) {
console.log (iotCCInitEvents[i] + 'is not defined'); console.log (iotCCInitEvents[i] + 'is not defined');
console.log (err); console.log (err);
} }
} }
} }
   
if (this.mqttConfig.simulateDevices) { if (this.mqttConfig.simulateDevices) {
this.simulateDevices(); this.simulateDevices();
} }
   
this.mqttClient.on('message', function (topic, message, packet) { this.mqttClient.on('message', function (topic, message, packet) {
try { try {
var json = JSON.parse(message.toString()); var json = JSON.parse(message.toString());
} catch(err){ } catch(err){
console.log ('There was a problem decoding the JSON message:\n\t' + message.toString()); console.log ('There was a problem decoding the JSON message:\n\t' + message.toString());
console.log (err); console.log (err);
return; return;
} }
var topicPath = topic.split('/'), var topicPath = topic.split('/'),
widgetId = iotCC.formatTopic(topic), widgetId = iotCC.formatTopic(topic),
widget, html; widget, html;
   
if (iotCC.mqttConfig.debug) { if (iotCC.mqttConfig.debug) {
console.log('Received Topic:= ' + topic + '\n\tMessage:= ' + message.toString()); console.log('Received Topic:= ' + topic + '\n\tMessage:= ' + message.toString());
} }
   
if (topicPath[4] == 'config') { if (topicPath[4] == 'config') {
var page = {'pageId': json.pageId, 'pageName': json.pageName, 'icon': json.icon}; var page = {'pageId': json.pageId, 'pageName': json.pageName, 'icon': json.icon};
iotCC.addPage(page); iotCC.addPage(page);
if (json.widget == 'toggle') { if (json.widget == 'toggle') {
if ($('input[name="' + widgetId + '"]').exists() == false) { if ($('input[name="' + widgetId + '"]').exists() == false) {
html = '<label class="switch switch--material">'; html = '<label class="switch switch--material">';
html += '<input type="checkbox" name="' + widgetId + '" data-widget="toggle" data-status="' + (json.checked==true?'1':'0') + '" class="switch__input switch--material__input" ' + (json.checked==true?'checked="checked"':'') + '>'; html += '<input type="checkbox" name="' + widgetId + '" data-widget="toggle" data-status="' + (json.checked==true?'1':'0') + '" class="switch__input switch--material__input" ' + (json.checked==true?'checked="checked"':'') + '>';
html += '<div class="switch__toggle switch--material__toggle">'; html += '<div class="switch__toggle switch--material__toggle">';
html += '<div class="switch__handle switch--material__handle">'; html += '<div class="switch__handle switch--material__handle">';
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
html += '</label>'; html += '</label>';
json.content = html; json.content = html;
json.widgetId = widgetId; json.widgetId = widgetId;
json.callback = function() { json.callback = function() {
if ($(this).prop('checked') == true) { if ($(this).prop('checked') == true) {
$(this).data('status', 1); $(this).data('status', 1);
iotCC.mqttClient.publish(json.topic + '/data', '{"status":1}', {qos: 1, retained: false}); iotCC.mqttClient.publish(json.topic + '/data', '{"status":1}', {qos: 1, retained: false});
} else { } else {
$(this).data('status', 0); $(this).data('status', 0);
iotCC.mqttClient.publish(json.topic + '/data', '{"status":0}', {qos: 1, retained: false}); iotCC.mqttClient.publish(json.topic + '/data', '{"status":0}', {qos: 1, retained: false});
} }
}; };
iotCC.addWidget(json); iotCC.addWidget(json);
} }
} else if (json.widget == 'radios') { } else if (json.widget == 'radios') {
html = ''; html = '';
$(json.options).each(function(k, v) { $(json.options).each(function(k, v) {
html += '<label class="radio-button radio-button--material"><input type="radio" name="' + widgetId + '" data-widget="radios" data-status="' + v.status + '" class="radio-button__input radio-button--material__input" name="r" ' + (v.checked==true?'checked="checked"':'') + '><div class="radio-button__checkmark radio-button--material__checkmark"></div>'+ v.label +'</label>'; html += '<label class="radio-button radio-button--material"><input type="radio" name="' + widgetId + '" data-widget="radios" data-status="' + v.status + '" class="radio-button__input radio-button--material__input" name="r" ' + (v.checked==true?'checked="checked"':'') + '><div class="radio-button__checkmark radio-button--material__checkmark"></div>'+ v.label +'</label>';
}); });
if ($('input[name="' + widgetId + '"]').exists() == false) { if ($('input[name="' + widgetId + '"]').exists() == false) {
json.content = html; json.content = html;
json.widgetId = widgetId; json.widgetId = widgetId;
json.callback = function() { json.callback = function() {
iotCC.mqttClient.publish(json.topic + '/data', '{"status":"' + $(this).data('status') + '"}', {qos: 1, retained: false}); iotCC.mqttClient.publish(json.topic + '/data', '{"status":"' + $(this).data('status') + '"}', {qos: 1, retained: false});
}; };
iotCC.addWidget(json); iotCC.addWidget(json);
} }
} }
} else if (topicPath[4] == 'data') { } else if (topicPath[4] == 'data') {
widget = $('*[name="' + widgetId + '"]').first().data('widget'); widget = $('*[name="' + widgetId + '"]').first().data('widget');
if (widget == 'toggle') { if (widget == 'toggle') {
if ($('input[name="' + widgetId + '"]').exists() == true) { if ($('input[name="' + widgetId + '"]').exists() == true) {
if (json.status == 1) { if (json.status == 1) {
$('input[name="' + widgetId + '"]').data('status', 1).prop('checked', true); $('input[name="' + widgetId + '"]').data('status', 1).prop('checked', true);
} else { } else {
$('input[name="' + widgetId + '"]').data('status', 0).prop('checked', false); $('input[name="' + widgetId + '"]').data('status', 0).prop('checked', false);
} }
} }
} else if (widget == 'radios') { } else if (widget == 'radios') {
if ($('input[name="' + widgetId + '"]').filter('[data-status="' + json.status + '"]').exists() == true) { if ($('input[name="' + widgetId + '"]').filter('[data-status="' + json.status + '"]').exists() == true) {
$('input[name="' + widgetId + '"]').filter('[data-status="' + json.status + '"]').prop('checked', true); $('input[name="' + widgetId + '"]').filter('[data-status="' + json.status + '"]').prop('checked', true);
} }
} }
} else if (topicPath[3] == 'device') { } else if (topicPath[3] == 'device') {
$(json.pages).each(function(k, page) { $(json.pages).each(function(k, page) {
iotCC.addPage(page); iotCC.addPage(page);
}); });
} }
if (typeof(window['iotCCMessageEvents']) != 'undefined') { if (typeof(window['iotCCMessageEvents']) != 'undefined') {
for(var i in iotCCMessageEvents) { for(var i in iotCCMessageEvents) {
try { try {
window[iotCCMessageEvents[i]](this, topic, topicPath, json); window[iotCCMessageEvents[i]](this, topic, topicPath, json);
} catch (err) { } catch (err) {
console.log (iotCCMessageEvents[i] + 'is not defined'); console.log (iotCCMessageEvents[i] + 'is not defined');
console.log (err); console.log (err);
} }
} }
} }
}); });
   
iotCC.mqttClient.on('close', function () { iotCC.mqttClient.on('close', function () {
console.log(mqttConfig.clientId + ' disconnected'); console.log(mqttConfig.clientId + ' disconnected');
}); });
}, },
formatTopic: function(topic) { formatTopic: function(topic) {
return topic.replace(/\//gi, '_').replace(/:/gi, '_').replace('_data', '').replace('_config', ''); return topic.replace(/\//gi, '_').replace(/:/gi, '_').replace('_data', '').replace('_config', '');
}, },
addWidget: function(json) { addWidget: function(json) {
if (this.templates[json.template] != undefined) { if (this.templates[json.template] != undefined) {
iotCC.addHtml(json, this.templates[json.template]); iotCC.addHtml(json, this.templates[json.template]);
} else { } else {
// TODO : fetch custom templates over HTTP // TODO : fetch custom templates over HTTP
$.get('template/' + json.template + '.html', function(html) { $.get('assets/template/' + json.template + '.html', function(html) {
iotCC.templates[json.template] = html; iotCC.templates[json.template] = html;
iotCC.addHtml(json, html); iotCC.addHtml(json, html);
}); });
} }
}, },
addHtml: function(json, html) { addHtml: function(json, html) {
for (var key in json) { for (var key in json) {
html = html.replace('{' + key + '}', json[key]); html = html.replace('{' + key + '}', json[key]);
} }
html = html.replace(/{(\w*)}/g, ''); html = html.replace(/{(\w*)}/g, '');
var section = $('section.content').filter('[data-section="dashboard"]'); var section = $('section.content').filter('[data-section="dashboard"]');
// TODO: add after sort ? // TODO: add after sort ?
/*var widgets = $(section).find('div[data-page="' + json.pageId + '"]').find('div.widgetcontainer').length; /*var widgets = $(section).find('div[data-page="' + json.pageId + '"]').find('div.widgetcontainer').length;
if (widgets > 0 && widgets%2 == 0) { if (widgets > 0 && widgets%2 == 0) {
$(section).find('div[data-page="' + json.pageId + '"]').append('<div class="clearfix visible-sm-block"></div>'); $(section).find('div[data-page="' + json.pageId + '"]').append('<div class="clearfix visible-sm-block"></div>');
}*/ }*/
$(section).find('div[data-page="' + json.pageId + '"]').append(html); $(section).find('div[data-page="' + json.pageId + '"]').append(html);
if (json.callback != undefined) { if (json.callback != undefined) {
$('input[name="' + json.widgetId + '"]').click(json.callback); $('input[name="' + json.widgetId + '"]').click(json.callback);
} }
$(section).find('div[data-page="' + json.pageId + '"]').find('div.widgetcontainer').sort(function(a,b) { $(section).find('div[data-page="' + json.pageId + '"]').find('div.widgetcontainer').sort(function(a,b) {
return $(a).data('order') > $(b).data('order'); return $(a).data('order') > $(b).data('order');
}).appendTo('div[data-page="' + json.pageId + '"]'); }).appendTo('div[data-page="' + json.pageId + '"]');
}, },
addPage: function(page) { addPage: function(page) {
if ($('div').filter('[data-page="' + page.pageId + '"]').exists() == false) { if ($('div').filter('[data-page="' + page.pageId + '"]').exists() == false) {
if ($('label').filter('[data-pagination="0"]').find('input').prop('checked') == true) { if ($('label').filter('[data-pagination="0"]').find('input').prop('checked') == true) {
var html = '<div class="row" data-page="' + page.pageId + '"></div>'; var html = '<div class="row" data-page="' + page.pageId + '"></div>';
} else { } else {
var html = '<div class="row hide" data-page="' + page.pageId + '"></div>'; var html = '<div class="row hide" data-page="' + page.pageId + '"></div>';
} }
$('section.content').filter('[data-section="dashboard"]').append(html); $('section.content').filter('[data-section="dashboard"]').append(html);
} }
if ($('div.pagination').find('label').filter('[data-pagination="' + page.pageId + '"]').exists() == false) { if ($('div.pagination').find('label').filter('[data-pagination="' + page.pageId + '"]').exists() == false) {
var html = '<label class="tab-bar__item tab-bar--material__item" data-pagination="' + page.pageId + '">'; var html = '<label class="tab-bar__item tab-bar--material__item" data-pagination="' + page.pageId + '">';
html += '<input type="radio" name="tab-bar-material-a">'; html += '<input type="radio" name="tab-bar-material-a">';
html += '<button class="tab-bar__button tab-bar--material__button">'; html += '<button class="tab-bar__button tab-bar--material__button">';
html += '<i class="tab-bar__icon tab-bar--material__icon ' + page.icon + '"></i>'; html += '<i class="tab-bar__icon tab-bar--material__icon ' + page.icon + '"></i>';
html += '<div class="tab-bar__label tab-bar--material__label">' + page.pageName + '</div>'; html += '<div class="tab-bar__label tab-bar--material__label">' + page.pageName + '</div>';
html += '</button>'; html += '</button>';
html += '</label>'; html += '</label>';
$('.pagination').append(html); $('.pagination').append(html);
$('label').filter('[data-pagination="' + page.pageId + '"]').click(function(e){ $('label').filter('[data-pagination="' + page.pageId + '"]').click(function(e){
var pageId = $(this).data('pagination'); var pageId = $(this).data('pagination');
$('div.row').addClass('hide'); $('div.row').addClass('hide');
$('div.row').filter('[data-page="' + pageId + '"]').removeClass('hide'); $('div.row').filter('[data-page="' + pageId + '"]').removeClass('hide');
}); });
} }
}, },
simulateDevices: function() { simulateDevices: function() {
//this.mqttClient.publish('/iotcc/' + mqttConfig.clientId + '/device', '{"command":"getDevice","param":""}', {qos: 1, retained: false}); //this.mqttClient.publish('/iotcc/' + mqttConfig.clientId + '/device', '{"command":"getDevice","param":""}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/heater1/device', '{"name":"House heating 1","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater1/device', '{"name":"House heating 1","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/heater1/heater/config', '{"id":"100", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Hollway Heater", "topic":"/iotcc/heater1/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-yellow", "order": 40}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater1/heater/config', '{"id":"100", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Hollway Heater", "topic":"/iotcc/heater1/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-blue", "order": 40}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/heater2/device', '{"name":"House heating 2","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater2/device', '{"name":"House heating 2","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/heater2/heater/config', '{"id":"101", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Kitchen Heater", "topic":"/iotcc/heater2/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-yellow", "order": 30}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater2/heater/config', '{"id":"101", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Kitchen Heater", "topic":"/iotcc/heater2/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-blue", "order": 30}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/heater3/device', '{"name":"House heating 3","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater3/device', '{"name":"House heating 3","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/heater3/heater/config', '{"id":"102", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Bedroom Heater", "topic":"/iotcc/heater3/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-yellow", "order": 10}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater3/heater/config', '{"id":"102", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Bedroom Heater", "topic":"/iotcc/heater3/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-blue", "order": 10}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/heater4/device', '{"name":"House heating 4","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater4/device', '{"name":"House heating 4","desc":"", "pages" : [{"pageId" : 10, "pageName" : "House heating", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/heater4/heater/config', '{"id":"103", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Living Heater", "topic":"/iotcc/heater4/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-yellow", "order": 20}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/heater4/heater/config', '{"id":"103", "pageName": "House heating", "pageId": 10, "widget":"radios", "title":"Living Heater", "topic":"/iotcc/heater4/heater", "options":[{"checked":true, "label": "Off", "status":"1"}, {"label": "Confort", "status":"2"}, {"label": "Anti freeze", "status":"3"}, {"label": "Confort -2", "status":"4"}], "template": "template-3", "icon": "ion-ios-home", "bgcolor": "bg-blue", "order": 20}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/dogsheating/device', '{"name":"Dogs heating","desc":"", "pages" : [{"pageId" : 20, "pageName" : "Dogs heating", "icon": "ion-ios-paw"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/dogsheating/device', '{"name":"Dogs heating","desc":"", "pages" : [{"pageId" : 20, "pageName" : "Dogs heating", "icon": "ion-ios-paw"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/dogsheating/toggle1/config', '{"id":"200", "pageName": "Dogs heating", "pageId": 20, "widget":"toggle", "title":"Mara", "topic":"/iotcc/dogsheating/toggle1", "checked":true, "template": "template-1", "icon": "ion-ios-paw", "order" : 10}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/dogsheating/toggle1/config', '{"id":"200", "pageName": "Dogs heating", "pageId": 20, "widget":"toggle", "title":"Mara", "topic":"/iotcc/dogsheating/toggle1", "checked":true, "template": "template-1", "icon": "ion-ios-paw", "bgcolor": "bg-green", "order" : 10}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/dogsheating/toggle2/config', '{"id":"201", "pageName": "Dogs Heating", "pageId": 20, "widget":"toggle", "title":"Linda", "topic":"/iotcc/dogsheating/toggle2", "template": "template-1", "icon": "ion-ios-paw", "order" : 20}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/dogsheating/toggle2/config', '{"id":"201", "pageName": "Dogs Heating", "pageId": 20, "widget":"toggle", "title":"Linda", "topic":"/iotcc/dogsheating/toggle2", "template": "template-1", "icon": "ion-ios-paw", "bgcolor": "bg-green", "order" : 20}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/outdoorlights1/device', '{"name":"Outdoor lighting 1","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights1/device', '{"name":"Outdoor lighting 1","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/outdoorlights1/garage/config', '{"id":"300", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"Garage", "topic":"/iotcc/outdoorlights/garage", "checked":true, "template": "template-1", "icon": "ion-model-s", "order": 40}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights1/garage/config', '{"id":"300", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"Garage", "topic":"/iotcc/outdoorlights/garage", "checked":true, "template": "template-1", "icon": "ion-model-s", "bgcolor": "bg-orange", "order": 40}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/outdoorlights2/device', '{"name":"Outdoor lighting 2","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights2/device', '{"name":"Outdoor lighting 2","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/outdoorlights2/house1/config', '{"id":"301", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House front", "topic":"/iotcc/outdoorlights/house1", "template": "template-1", "icon": "ion-ios-home", "order": 10}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights2/house1/config', '{"id":"301", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House front", "topic":"/iotcc/outdoorlights/house1", "template": "template-1", "icon": "ion-ios-home", "bgcolor": "bg-orange", "order": 10}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/outdoorlights3/device', '{"name":"Outdoor lighting 3","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights3/device', '{"name":"Outdoor lighting 3","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/outdoorlights3/house2/config', '{"id":"302", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House back", "topic":"/iotcc/outdoorlights/house2", "template": "template-1", "icon": "ion-ios-home", "order": 20}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights3/house2/config', '{"id":"302", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House back", "topic":"/iotcc/outdoorlights/house2", "template": "template-1", "icon": "ion-ios-home", "bgcolor": "bg-orange", "order": 20}', {qos: 1, retained: false});
   
this.mqttClient.publish('/iotcc/outdoorlights4/device', '{"name":"Outdoor lighting 4","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights4/device', '{"name":"Outdoor lighting 4","desc":"", "pages" : [{"pageId" : 30, "pageName" : "Outdoor Lights", "icon": "ion-ios-home"}]}', {qos: 1, retained: false});
this.mqttClient.publish('/iotcc/outdoorlights4/house3/config', '{"id":"302", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House sides", "topic":"/iotcc/outdoorlights/house3", "template": "template-1", "icon": "ion-ios-home", "order": 30}', {qos: 1, retained: false}); this.mqttClient.publish('/iotcc/outdoorlights4/house3/config', '{"id":"302", "pageName": "Outdoor lightling", "pageId": 30, "widget":"toggle", "title":"House sides", "topic":"/iotcc/outdoorlights/house3", "template": "template-1", "icon": "ion-ios-home", "bgcolor": "bg-orange", "order": 30}', {qos: 1, retained: false});
}, },
} }
   
jQuery.fn.exists = function(){return ($(this).length > 0);} jQuery.fn.exists = function(){return ($(this).length > 0);}
$(document).ready(function(){ $(document).ready(function(){
iotCC.init(mqttConfig); iotCC.init(mqttConfig);
   
$('.navigation').click(function(e){ $('.navigation').click(function(e){
e.preventDefault(); e.preventDefault();
var section = $(this).data('section'); var section = $(this).data('section');
$('.navigation').parent().removeClass('active'); $('.navigation').parent().removeClass('active');
$(this).parent().addClass('active'); $(this).parent().addClass('active');
$('section.content,section.content-header').addClass('hide'); $('section.content,section.content-header').addClass('hide');
$('section.content,section.content-header').filter('[data-section="' + section + '"]').removeClass('hide'); $('section.content,section.content-header').filter('[data-section="' + section + '"]').removeClass('hide');
}); });
$('label').filter('[data-pagination="0"]').click(function(e){ $('label').filter('[data-pagination="0"]').click(function(e){
$('div.row').removeClass('hide'); $('div.row').removeClass('hide');
}); });
}); });
   
// custom console // custom console
console = new Object(); console = new Object();
console.log = function(log) { console.log = function(log) {
$('.console').prepend(log + '<br />'); $('.console').prepend(log + '<br />');
}; };
console.debug = console.log; console.debug = console.log;
console.info = console.log; console.info = console.log;
console.warn = console.log; console.warn = console.log;
console.error = console.log; console.error = console.log;
   
  <div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}">
  <div class="info-box widget">
  <span class="info-box-icon {bgcolor}"><i class="ion {icon}"></i></span>
  <div class="info-box-content">
  <span class="info-box-text"><b>{title}</b></span>
  <span class="">
  {content}
  </span>
  <span class="info-box-text">{description}</span>
  </div>
  </div>
  </div>
  <div class="col-lg-3 col-xs-6 widgetcontainer" data-order="{order}">
  <div class="small-box {bgcolor}">
  <div class="inner">
  <h3>{title}</h3>
  <p>{content}</p>
  </div>
  <div class="icon">
  <i class="ion {icon}"></i>
  </div>
  </div>
  </div>
  <div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}">
  <div class="info-box box">
  <div class="box-header with-border {bgcolor}">
  <span class="info-box-text"><b>{title}</b></span>
  <div class="box-tools pull-right">
  <div class="icon">
  <i class="ion {icon}"></i>
  </div>
  </div>
  </div>
  <div class="box-body">
  {content}
  </div>
  </div>
  </div>
file:a/index.html -> file:b/index.html
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>IoT Control Center</title> <title>IoT Control Center</title>
<!-- Tell the browser to be responsive to screen width --> <!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
   
<link rel="stylesheet" href="bower_components/AdminLTE/dist/css/AdminLTE.min.css"> <link rel="stylesheet" href="bower_components/AdminLTE/dist/css/AdminLTE.min.css">
<link rel="stylesheet" href="bower_components/AdminLTE/dist/css/skins/_all-skins.min.css"> <link rel="stylesheet" href="bower_components/AdminLTE/dist/css/skins/_all-skins.min.css">
<link rel="stylesheet" href="assets/css/iotcc.css"> <link rel="stylesheet" href="assets/css/iotcc.css">
</head> </head>
   
<body class="hold-transition skin-yellow sidebar-mini sidebar-collapse"> <body class="hold-transition skin-blue sidebar-mini sidebar-collapse">
<div class="wrapper"> <div class="wrapper">
<header class="main-header"> <header class="main-header">
<!-- Logo --> <!-- Logo -->
<a href="#dashboard" class="logo"> <a href="#dashboard" class="logo">
<!-- mini logo for sidebar mini 50x50 pixels --> <!-- mini logo for sidebar mini 50x50 pixels -->
<span class="logo-mini"><b>IoT</b></span> <span class="logo-mini"><b>IoT</b></span>
<!-- logo for regular state and mobile devices --> <!-- logo for regular state and mobile devices -->
<span class="logo-lg"><b>IoT</b> Control Center</span> <span class="logo-lg"><b>IoT</b> Control Center</span>
</a> </a>
   
<!-- Header Navbar: style can be found in header.less --> <!-- Header Navbar: style can be found in header.less -->
<nav class="navbar navbar-static-top"> <nav class="navbar navbar-static-top">
<!-- Sidebar toggle button--> <!-- Sidebar toggle button-->
<a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button"> <a href="#" class="sidebar-toggle" data-toggle="offcanvas" role="button">
<span class="sr-only">Toggle navigation</span> <span class="sr-only">Toggle navigation</span>
</a> </a>
<!-- Navbar Right Menu --> <!-- Navbar Right Menu -->
<div class="navbar-custom-menu"> <div class="navbar-custom-menu">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<!-- Control Sidebar Toggle Button --> <!-- Control Sidebar Toggle Button -->
<li> <li>
<a href="#" data-toggle="control-sidebar"><i class="fa fa-gear"></i></a> <a href="#" data-toggle="control-sidebar"><i class="fa fa-gear"></i></a>
</li> </li>
</ul> </ul>
</div> </div>
</nav> </nav>
</header> </header>
<!-- Left side column. contains the logo and sidebar --> <!-- Left side column. contains the logo and sidebar -->
<aside class="main-sidebar"> <aside class="main-sidebar">
<!-- sidebar: style can be found in sidebar.less --> <!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar"> <section class="sidebar">
<!-- /.search form --> <!-- /.search form -->
<!-- sidebar menu: : style can be found in sidebar.less --> <!-- sidebar menu: : style can be found in sidebar.less -->
<ul class="sidebar-menu"> <ul class="sidebar-menu">
<!--li class="header">Options</li--> <!--li class="header">Options</li-->
<li class="active"> <li class="active">
<a href="#" class="navigation" data-section="dashboard"> <a href="#" class="navigation" data-section="dashboard">
<i class="fa fa-dashboard"></i> <span>Dashboard</span> <i class="fa fa-dashboard"></i> <span>Dashboard</span>
</a> </a>
</li> </li>
<li> <li>
<a href="#" class="navigation" data-section="settings"> <a href="#" class="navigation" data-section="settings">
<i class="fa fa-gears"></i> <span>Settings</span> <i class="fa fa-gears"></i> <span>Settings</span>
</a> </a>
</li> </li>
<li> <li>
<a href="#" class="navigation" data-section="log"> <a href="#" class="navigation" data-section="log">
<i class="fa fa-align-justify"></i> <span>Log</span> <i class="fa fa-align-justify"></i> <span>Log</span>
</a> </a>
</li> </li>
</ul> </ul>
</section> </section>
<!-- /.sidebar --> <!-- /.sidebar -->
</aside> </aside>
   
<!-- Content Wrapper. Contains page content --> <!-- Content Wrapper. Contains page content -->
<div class="content-wrapper"> <div class="content-wrapper">
<section class="content-header" data-section="dashboard"> <section class="content-header" data-section="dashboard">
<h1>Dashboard</h1> <h1>Dashboard</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"><i class="fa fa-dashboard"></i> Dashboard</li> <li class="active"><i class="fa fa-dashboard"></i> Dashboard</li>
</ol> </ol>
<div class=""> <div class="">
<div class="tab-bar tab-bar--top tab-bar--material pagination"> <div class="tab-bar tab-bar--top tab-bar--material pagination">
<label class="tab-bar__item tab-bar--material__item" data-pagination="0"> <label class="tab-bar__item tab-bar--material__item" data-pagination="0">
<input type="radio" name="tab-bar-material-a" checked="checked"> <input type="radio" name="tab-bar-material-a" checked="checked">
<button class="tab-bar__button tab-bar--material__button"> <button class="tab-bar__button tab-bar--material__button">
<i class="tab-bar__icon tab-bar--material__icon ion-drag"></i> <i class="tab-bar__icon tab-bar--material__icon ion-drag"></i>
<div class="tab-bar__label tab-bar--material__label">All</div> <div class="tab-bar__label tab-bar--material__label">All</div>
</button> </button>
</label> </label>
</div> </div>
</div> </div>
</section> </section>
   
<section class="content-header hide" data-section="settings"> <section class="content-header hide" data-section="settings">
<h1>Settings</h1> <h1>Settings</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"><i class="fa fa-gears"></i> Settings</li> <li class="active"><i class="fa fa-gears"></i> Settings</li>
</ol> </ol>
</section> </section>
   
<section class="content-header hide" data-section="log"> <section class="content-header hide" data-section="log">
<h1>Log</h1> <h1>Log</h1>
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="active"><i class="fa fa-gears"></i> Logs</li> <li class="active"><i class="fa fa-gears"></i> Logs</li>
</ol> </ol>
</section> </section>
   
<!-- Dashboard content --> <!-- Dashboard content -->
<section class="content" data-section="dashboard"> <section class="content" data-section="dashboard">
   
</section> </section>
   
<!-- Settings content --> <!-- Settings content -->
<section class="content hide" data-section="settings"> <section class="content hide" data-section="settings">
   
</section> </section>
<!-- /.content --> <!-- /.content -->
   
<!-- Log content --> <!-- Log content -->
<section class="content hide" data-section="log"> <section class="content hide" data-section="log">
<pre class="console"></pre> <pre class="console"></pre>
</section> </section>
<!-- /.content --> <!-- /.content -->
   
</div> </div>
<!-- /.content-wrapper --> <!-- /.content-wrapper -->
   
<footer class="main-footer"> <footer class="main-footer">
<div class="pull-right hidden-xs"> <div class="pull-right hidden-xs">
<b>Version</b> 0.1 <b>Version</b> 0.1
</div> </div>
<strong>Copyright &copy; 2017 <a href="http://www.razvi.ro">Razvan Stanga</a>.</strong> All rights reserved. <strong>Copyright &copy; 2017 <a href="http://www.razvi.ro">Razvan Stanga</a>.</strong> All rights reserved.
</footer> </footer>
   
<!-- Control Sidebar --> <!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark"> <aside class="control-sidebar control-sidebar-dark">
<!-- Create the tabs --> <!-- Create the tabs -->
<ul class="nav nav-tabs nav-justified control-sidebar-tabs"> <ul class="nav nav-tabs nav-justified control-sidebar-tabs">
<li><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li> <li><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li>
<li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gear"></i></a></li> <li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gear"></i></a></li>
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content"> <div class="tab-content">
<!-- Home tab content --> <!-- Home tab content -->
<div class="tab-pane" id="control-sidebar-home-tab"> <div class="tab-pane" id="control-sidebar-home-tab">
   
</div> </div>
<!-- /.tab-pane --> <!-- /.tab-pane -->
   
<!-- Settings tab content --> <!-- Settings tab content -->
<div class="tab-pane" id="control-sidebar-settings-tab"> <div class="tab-pane" id="control-sidebar-settings-tab">
<form method="post"> <form method="post">
<h3 class="control-sidebar-heading">General Settings</h3> <h3 class="control-sidebar-heading">General Settings</h3>
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Report panel usage Report panel usage
<input type="checkbox" class="pull-right" checked> <input type="checkbox" class="pull-right" checked>
</label> </label>
   
<p> <p>
Some information about this general settings option Some information about this general settings option
</p> </p>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Allow mail redirect Allow mail redirect
<input type="checkbox" class="pull-right" checked> <input type="checkbox" class="pull-right" checked>
</label> </label>
   
<p> <p>
Other sets of options are available Other sets of options are available
</p> </p>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Expose author name in posts Expose author name in posts
<input type="checkbox" class="pull-right" checked> <input type="checkbox" class="pull-right" checked>
</label> </label>
   
<p> <p>
Allow the user to show his name in blog posts Allow the user to show his name in blog posts
</p> </p>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
   
<h3 class="control-sidebar-heading">Chat Settings</h3> <h3 class="control-sidebar-heading">Chat Settings</h3>
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Show me as online Show me as online
<input type="checkbox" class="pull-right" checked> <input type="checkbox" class="pull-right" checked>
</label> </label>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Turn off notifications Turn off notifications
<input type="checkbox" class="pull-right"> <input type="checkbox" class="pull-right">
</label> </label>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
   
<div class="form-group"> <div class="form-group">
<label class="control-sidebar-subheading"> <label class="control-sidebar-subheading">
Delete chat history Delete chat history
<a href="javascript:void(0)" class="text-red pull-right"><i class="fa fa-trash-o"></i></a> <a href="javascript:void(0)" class="text-red pull-right"><i class="fa fa-trash-o"></i></a>
</label> </label>
</div> </div>
<!-- /.form-group --> <!-- /.form-group -->
</form> </form>
</div> </div>
<!-- /.tab-pane --> <!-- /.tab-pane -->
</div> </div>
</aside> </aside>
<!-- /.control-sidebar --> <!-- /.control-sidebar -->
<!-- Add the sidebar's background. This div must be placed <!-- Add the sidebar's background. This div must be placed
immediately after the control sidebar --> immediately after the control sidebar -->
<div class="control-sidebar-bg"></div> <div class="control-sidebar-bg"></div>
   
</div> </div>
<!-- ./wrapper --> <!-- ./wrapper -->
   
<script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="bower_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script> <script type="text/javascript" src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- AdminLTE App --> <!-- AdminLTE App -->
<script type="text/javascript"> <script type="text/javascript">
var AdminLTEOptions = { var AdminLTEOptions = {
sidebarExpandOnHover: true sidebarExpandOnHover: true
}; };
</script> </script>
<script type="text/javascript" src="bower_components/AdminLTE/dist/js/app.min.js"></script> <script type="text/javascript" src="bower_components/AdminLTE/dist/js/app.min.js"></script>
<!-- AdminLTE for demo purposes --> <!-- AdminLTE for demo purposes -->
<script type="text/javascript" src="bower_components/AdminLTE/dist/js/demo.js"></script> <script type="text/javascript" src="bower_components/AdminLTE/dist/js/demo.js"></script>
   
<script type="text/javascript" src="assets/js/mqtt.min.js"></script> <script type="text/javascript" src="assets/js/mqtt.min.js"></script>
<script type="text/javascript" src="config.js"></script> <script type="text/javascript" src="config.js"></script>
<script type="text/javascript" src="assets/js/iotcc.js"></script> <script type="text/javascript" src="assets/js/iotcc.js"></script>
   
</body> </body>
</html> </html>
   
<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}">  
<div class="info-box widget">  
<span class="info-box-icon {bgcolor}"><i class="ion {icon}"></i></span>  
<div class="info-box-content">  
<span class="info-box-text"><b>{title}</b></span>  
<span class="">  
{content}  
</span>  
<span class="info-box-text">{description}</span>  
</div>  
</div>  
</div>  
<div class="col-lg-3 col-xs-6 widgetcontainer" data-order="{order}">  
<div class="small-box {bgcolor}">  
<div class="inner">  
<h3>{title}</h3>  
<p>{content}</p>  
</div>  
<div class="icon">  
<i class="ion {icon}"></i>  
</div>  
</div>  
</div>  
<div class="col-md-3 col-sm-6 col-xs-12 widgetcontainer" data-order="{order}">  
<div class="info-box box {bgcolor}">  
<div class="box-header with-border">  
<span class="info-box-text"><b>{title}</b></span>  
<div class="box-tools pull-right">  
<div class="icon">  
<i class="ion {icon}"></i>  
</div>  
</div>  
</div>  
<div class="box-body">  
{content}  
</div>  
</div>  
</div>  
comments