UNPKG

domotz-remote-pawn

Version:

Domotz Agent

19 lines (18 loc) 40.5 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ !function(){"use strict";angular.module("agent",["ionic","ngResource","zxcvbn","domotzEntities","domotzAngularWidgets","agent.template","agent.nettools","angularMoment","ngLodash","ngDialog","agent.http"]).constant("ANGULAR_WIDGETS_PATH","../lib/domotz-angular-widgets/").constant("amTimeAgoConfig",{withoutSuffix:!0}).config(["$stateProvider","$urlRouterProvider",function(e,t){var n=["userService","$q","$state","$timeout",function(e,t,n,r){var a=t.defer();return null===e.data.info?(a.reject(),r(function(){n.go("restricted.signup")})):a.resolve(),a.promise}];t.otherwise("/agentinfo"),e.state("restricted",{url:"/restricted","abstract":!0,templateUrl:"partials/restricted/restricted.html",controller:"RestrictedController as ctrl",resolve:{agentStatus:["agentService","$state","$q",function(e,t,n){var r=n.defer();return e.getStatus()["finally"](function(){e.isRestricted()?r.resolve({isUpdating:e.isUpdating()}):(r.reject(),t.go("app.agentinfo"))}),r.promise}]}}).state("restricted.welcome",{url:"/welcome",views:{main:{templateUrl:"partials/restricted/welcome.html"}}}).state("restricted.login",{url:"/login",views:{main:{templateUrl:"partials/restricted/login.html"}}}).state("restricted.signup",{url:"/signup",views:{main:{templateUrl:"partials/restricted/signup.html"}}}).state("restricted.activation",{url:"/activation",views:{main:{templateUrl:"partials/restricted/activation.html"}},resolve:{isLoggedUser:n}}).state("restricted.configuring",{url:"/configuring",views:{main:{templateUrl:"partials/restricted/configuring.html"}},resolve:{isLoggedUser:n}}).state("app",{url:"","abstract":!0,templateUrl:"partials/layout/menu.html",controller:"MenuController as ctrl",resolve:{agentStatus:["agentService","$state","$q",function(e,t,n){var r=n.defer();return e.getStatus()["finally"](function(){e.isRestricted()?(r.reject(),t.go("restricted.welcome")):r.resolve()}),r.promise}]}}).state("app.agentinfo",{url:"/agentinfo",views:{menuContent:{templateUrl:"partials/agent/agentinfo.html",controller:"AgentController as agentCtrl"}}}).state("app.netinfo",{url:"/netinfo",views:{menuContent:{templateUrl:"partials/nettools/netinfo.html"}}}).state("app.netroute",{url:"/netroute",views:{menuContent:{templateUrl:"partials/nettools/netroute.html"}}}).state("app.netspeed",{url:"/netspeed",views:{menuContent:{templateUrl:"partials/nettools/netspeed.html",controller:"AgentController as agentCtrl"}}})}]).run(["flurryService",function(e){e.init(),e.startSession("agent")}]),angular.module("agent.template",[])}(),function(){"use strict";angular.module("agent.http",[]).config(["$httpProvider",function(e){e.interceptors.push("httpRequestHandlerService")}])}(),function(){"use strict";angular.module("agent.nettools",[])}(),function(){"use strict";var e="Reset in Progress...",t="Reset successfully performed. Wait for local server restart...",n=3e4;angular.module("agent").controller("AgentController",["agentService","geoLocationService","$state","$timeout","$interval",function(r,a,i,o,s){function c(){d.waitMessage=t,o(function(){window.location=window.location.origin},n)}function l(){r.data.error?d.errorMessage=r.data.error:d.errorMessage="Error",d.errorOccurred=!0,d.resetLoading=!1,r.data.error=null}var d=this;d.email={value:"",focus:!1},d.password={value:"",focus:!1},d.errorOccurred=!1,d.errorMessage="",d.waitMessage=e,d.resetLoading=!1,d.resetTimeout=null,d.resetAgent=function(){d.resetLoading=!0,r.resetAgent(d.email.value,d.password.value).then(c)["catch"](l)},d.getAgentName=function(){return r.getName()},d.getTimeZone=function(){return r.getTimeZone()},d.getAgentLocation=function(){return r.getLocation()},d.goToAgentInfo=function(){i.go("app.agentinfo")},d.goToAgentReset=function(){i.go("app.agentreset")},d.goToAgentResetConfirmation=function(){i.go("app.agentresetconfirm")},d.updateConnectivityInfo=function(){r.getConnectivityStatus().then(function(e){d.connectivity=e.status,"offline"==d.connectivity&&(d.offline_since=new Date((new Date).getTime()-1e3*e.offline_since).toISOString())})},function(){r.fetchInfo().then(function(){var e=r.getLocation();a.reverseGeocode(e.latitude,e.longitude).then(function(e){r.setAddress(e.address)})}),d.updateConnectivityInfo(),s(function(){d.updateConnectivityInfo()},3e4)}()}])}(),function(){"use strict";var e="Invalid e-mail or password",t="Cannot reset: Your Agent is expired",n="Reset Failed",r="Error on Server: Please contact our support";angular.module("agent").factory("agentService",["$resource",function(a){function i(){var e=a("/api/v1/status",{request_id:function(){return Math.floor(4503599627370496*(1+Math.random()))}},{read:{method:"GET"}}).read().$promise;return e.then(function(e){w.mac_address=e.mac_address,w.interfaces_list=e.interfaces_list,w.mode=e.mode},function(e){w.error=e.message}),e}function o(){var e=a("/api/v1/connectivity",{},{read:{method:"GET"}}).read().$promise;return e}function s(){var e=a("/api/v1/agent",{},{read:{method:"GET"}}).read().$promise;return e.then(function(e){w=e},function(e){w.error=e.message}),e}function c(i,o){var s=a("/api/v1/agent",{},{"delete":{method:"DELETE",headers:{"X-Forward-Password":o},params:{username:i}}})["delete"]().$promise;return s["catch"](function(a){401===a.status?w.error=e:404===a.status?w.error=t:400===a.status?w.error=n:500===a.status?w.error=r:w.error=a.message}),s}function l(){return w.display_name}function d(){return w.timezone}function u(){return w.location}function m(e){w.location.address=e}function g(){return w.mac_address}function p(){return w.interfaces_list}function f(){return"RESTRICTED"==w.mode||"UPDATING"==w.mode||w.mode===!0}function v(){return"UPDATING"==w.mode}var w={};return{fetchInfo:s,getName:l,getMacAddress:g,getInterfacesList:p,getStatus:i,getConnectivityStatus:o,isRestricted:f,isUpdating:v,getLocation:u,setAddress:m,getTimeZone:d,resetAgent:c,data:w}}])}(),function(){"use strict";angular.module("agent.http").factory("httpRequestHandlerService",[function(){function e(e){return 0!=e.url.indexOf("http")&&e.url.indexOf("/api/v1/")>-1&&(e.headers["X-API-Minor-Version"]="2"),e}return{request:e}}])}(),function(){"use strict";angular.module("agent").controller("MenuController",["userService","XORCipher","dmtTermsConditionsFactory",function(e,t,n){var r=this,a=e.data.password,i=e.data.username;r.randomString=Math.random().toString(36).substr(2,5),r.encodedPassword=t.encode(r.randomString,a),r.encodedUsername=t.encode(r.randomString,i),r.webapp=function(){window.open("https://portal.domotz.com/webapp/#/sso?u="+encodeURIComponent(r.encodedUsername)+"&p="+encodeURIComponent(r.encodedPassword)+"&k="+encodeURIComponent(r.randomString),"_blank")},r.showAgreement=function(){n.showAgreement()}}])}(),function(){"use strict";angular.module("agent").factory("netToolsService",["$resource",function(e){function t(){var e=i.read().$promise;return e}function n(e,t){var n=o.start({destination:e,count:t}).$promise;return n}function r(e){var t=s.start({"server-id":e}).$promise;return t}function a(){var e=c.read().$promise;return e}var i=e("/api/v1/net-info",{},{read:{method:"GET"}}),o=e("/api/v1/mtr",{},{start:{method:"GET"}}),s=e("/api/v1/network-speed",{},{start:{method:"GET"}}),c=e("/api/v1/ndt-server",{timeout:5,attempts:6},{read:{method:"GET"}});return{fetchNetworkInfo:t,startMtrTest:n,startSpeedTest:r,fetchSpeedTestServer:a}}])}(),function(){"use strict";var e="Impossible to retrieve agent coordinates, please restart the service";angular.module("agent").controller("RestrictedController",["$rootScope","userService","agentService","geoLocationService","$state","$timeout","agentStatus","dmtPopup","$scope","signupService","dmtTermsConditionsFactory","agreementService","$window",function(t,n,r,a,i,o,s,c,l,d,u,m,g){function p(){S.errorOccurred=!1,S.agreementDisabled=!0,S.agreementAccepted=!1,S.selectedCountry=""}function f(){n.data.error?S.errorMessage=n.data.error:S.errorMessage="Error",c.alert({scope:l,title:n.data.errorTitle||"Error",subTitle:S.errorMessage}),S.errorOccurred=!0,n.data.error=null}function v(){S.agentDisplayName="",S.agentContextSelected=null,delete r.data.id,delete r.data.name,S.isResumeProcedure=!1}function w(){v(),n.fetchAvailableLicences().then(function(){if(n.data.error)f();else{var e=n.getUser().getActivatedLicences(),t=r.getInterfacesList(),a=[];for(var i in t)a.push(t[i].mac);for(var o=0;o<e.length;o++)if(a.indexOf(e[o].bound_mac_address)>-1){var s=e[o].agent;void 0!==s.id&&(r.data.id=s.id,r.data.name=s.name,r.data.display_name=s.display_name,S.agentDisplayName=s.display_name,r.data.context=s.context,S.agentContextSelected=s.context,S.isResumeProcedure=!0);break}S.goToRestrictedState("activation")}})["catch"](f)}function h(){S.loading=!1}function b(){var e=n.fetchUser(S.email,S.password);return e.then(w)["catch"](f)["finally"](h),e}function y(){S.loading||r.getStatus()["finally"](function(){r.isUpdating()?A():(S.loading=!0,d.createUser(S.email,S.password,S.selectedCountry.iso_code).then(function(){b().then(function(){m.setUserAgreement(S.version)})})["catch"](function(e){console.error(JSON.stringify(e)),409===e.status?S.errorMessage="There was an error. This email might be already in use. Try to Log in.":S.errorMessage="There was an error. Please try again in a bit.",c.alert({scope:l,title:"Error",subTitle:S.errorMessage}),S.errorOccurred=!0,n.data.error=null})["finally"](h))})}function C(){n.data.error?f():(S.agentIsRestarting=!0,S.goToRestrictedState("configuring"),o(function(){S.agentIsRestarting=!1},3e4))}var A=function(){var e=["Checking for updates","Update found, downloading"],t=["Applying changes","Updating interface","Installing new features","Thank you for waiting","Patching bugs"],n="Restarting services";l.progressMsg=e[0];var a=e,i=0,s=function(){i>=a.length&&(a=t,i=0),a==t&&i>0&&i%2==0?r.getStatus()["finally"](function(){r.isUpdating()?o(s,7e3):(l.progressMsg=n,o(function(){l.closeCurrentPopup(),g.location.reload()},7e3))}):o(s,7e3),l.progressMsg=a[i],i++};c.custom({scope:l,title:"Updating Local Agent",preventClosing:!0,contentTemplate:'<div class="dmt-popup-subtitle">{{progressMsg}}</div><div class="dmt-spinner-wrapper"><ion-spinner icon="android" class="dmt-spinner"></ion-spinner></div>'}),s()};s&&s.isUpdating&&A();var S=this;S.loginForm={},S.signupForm={},S.activationForm={},S.errorMessage="",S.loading=!1,S.agentIsRestarting=!1,S.email="",S.password="",S.agentDisplayName="",S.geoLocation={data:null},S.agentContexts={home:"Home",office:"Office"},S.agentContextSelected=null,S.isResumeProcedure=!1,p(),S.goToRestrictedState=function(e){S.errorOccurred=!1,i.go("restricted."+e)},S.goToState=function(e){S.errorOccurred=!1,i.go(e)},S.login=function(){if(!S.loading)return S.loginForm.$valid?void r.getStatus()["finally"](function(){r.isUpdating()?A():(S.loading=!0,b())}):(l.formSubmitted=!0,S.errorOccurred=!0,!1)},S.signup=function(){return S.signupForm.$valid?void y():(l.formSubmitted=!0,S.errorOccurred=!0,!1)},S.getGeoLocation=function(){S.geoLocation={loading:!0,error:!1,data:null},a.getGeoLocation().then(function(e){S.geoLocation.data=e.location,a.reverseGeocode(e.location.latitude,e.location.longitude).then(function(e){S.geoLocation.address=e.address})},function(){S.geoLocation.data={},S.geoLocation.error=!0,S.errorMessage=e})["finally"](function(){S.geoLocation.loading=!1})},S.activate=function(){if(!S.loading){if(!S.activationForm.$valid)return l.formSubmitted=!0,S.errorOccurred=!0,!1;S.loading=!0,S.isResumeProcedure?n.updateAgent(r.data.id,r.data.name,S.geoLocation.data).then(C)["catch"](f)["finally"](h):n.createAgent(S.agentDisplayName,S.geoLocation.data,S.agentContextSelected).then(C)["catch"](f)["finally"](h)}},S.showAgreement=function(){S.version&&u.showAgreement(!0,S.version)},l.$watch("ctrl.selectedCountry",function(e){"object"==typeof e&&m.getUserRegion().then(function(t){var n=u.getCurrentVersion(e.region,t.regions);S.version=n.full,S.versionNumber=n.number,S.agreementDisabled=!1})["catch"](function(e){console.log(e)})}),t.$on("$stateChangeSuccess",function(){l.formSubmitted=!1,p()})}])}(),function(){"use strict";angular.module("agent").factory("geoLocationService",["$resource","$q",function(e,t){function n(){var e=i.read().$promise;return e.then(function(e){a.result=e},function(e){a.error=e.message}),e}function r(e,n){var r=t.defer();return o.get({latlng:e+","+n}).$promise.then(function(e){if(e.results.length>0){for(var t=e.results[0].address_components,n=0;n<t.length;n++)if(t[n].types.indexOf("administrative_area_level_3")>-1){r.resolve({address:t[n].long_name});break}}else r.resolve({address:"N/A"})},function(e){r.resolve({address:"N/A"})}),r.promise}var a={},i=e("/api/v1/location",{},{read:{method:"GET"}}),o=e("http://maps.googleapis.com/maps/api/geocode/json",{},{get:{method:"GET"}});return{getGeoLocation:n,reverseGeocode:r,data:a}}])}(),function(){"use strict";angular.module("agent").directive("scrollResize",["$window","$ionicScrollDelegate",function(e,t){return function(n,r,a){function i(){var e=t.getScrollView(r);e.resize();var n=r[0].offsetHeight,a=r.children()[0].offsetHeight;a>n?r.addClass("dmt-long-content"):r.removeClass("dmt-long-content")}var o=angular.element(e);o.bind("resize",function(){i()}),n.$on("scroll-resize",function(e,t){t.handler==a.delegateHandle&&setTimeout(i,100)}),setTimeout(i,100)}}])}(),function(){"use strict";angular.module("agent").factory("agreementService",["$resource","userService",function(e,t){function n(){return e("/api/v1/region",{},{read:{method:"GET"}}).read().$promise}function r(){return e("/api/v1/accepted-conditions",{},{get:{isArray:!0,method:"GET"},set:{method:"PUT"}})}function a(t){return e("https://portal.domotz.com/partials/static/terms-conditions/"+t+".html",{},{read:{method:"GET",timeout:3e3,transformResponse:function(e){return{html:e}}}}).read().$promise}function i(){return r().get({user_id:t.getUserId()}).$promise}function o(e){return r().set({user_id:t.getUserId(),version:e}).$promise}var s={version:""};return{getUserRegion:n,getAgreementHTML:a,getUserAgreements:i,setUserAgreement:o,data:s}}])}(),function(){"use strict";var e="Invalid e-mail or password",t="There was an error. This email might be already in use. Try to log in.";angular.module("agent").factory("signupService",["$resource",function(n){function r(){return n("/api/v1/country/",{},{read:{method:"GET"}}).read().$promise}function a(r,a,o){r=r.toLowerCase(),i.username=r,i.password=a;var s=n("/api/v1/user",{},{create:{method:"POST",url:"/api/v1/user",headers:{"X-Forward-Password":a},params:{username:r,country:o}}}).create().$promise;return s.then(function(e){},function(n){console.error(JSON.stringify(n)),404===n.status||401===n.status?i.error=e:409===n.status?i.error=t:i.error=n.message}),s}var i={error:null};return{createUser:a,getUserCountries:r,data:i}}])}(),function(){"use strict";var e="Invalid e-mail or password";angular.module("agent").factory("userService",["$resource","userFactory",function(t,n){function r(){return d}function a(){return d.id}function i(r,a){r=r.toLowerCase(),m.username=r,m.password=a;var i=t("/api/v1/user",{},{read:{method:"GET",url:"/api/v1/user",headers:{"X-Forward-Password":a},params:{username:r}}}).read().$promise;return i.then(function(e){m.info=e,d=n.createUser(e)},function(t){404===t.status||401===t.status?m.error=e:m.error="Error: "+c(t)}),i}function o(n,r,a){m.display_name=n;var i={display_name:m.display_name,location:r,context:a},o=t("/api/v1/user/:user_id/agent",{user_id:d.getRequestId()},{create:{method:"POST",headers:{"X-Forward-Password":m.password,"Content-Type":"application/json"},timeout:u}}).create({},i).$promise;return o.then(function(){console.info("Agent activated.")},function(t){404===t.status||401===t.status?m.error=e:403===t.status?(m.errorTitle="Cannot activate your Agent",m.error="Please check Agent status on Portal."):m.error="Error: "+c(t)}),o}function s(n,r,a){var i=t("/api/v1/user/:user_id/agent/:agent_id",{user_id:d.getRequestId(),agent_id:n},{update:{method:"PUT",headers:{"X-Forward-Password":m.password},params:{agent_name:r},timeout:u}}).update({},a).$promise;return i.then(function(e){m.info=e},function(t){404===t.status||401===t.status?m.error=e:400===t.status?m.error="Malformed request":m.error="Error: "+c(t)}),i}function c(e){return e.data?void 0!==e.data.error?e.data.error:JSON.stringify(e.data):0==e.status?"status 0 (cannot connect to agent)":JSON.stringify(e)}function l(){var e=t("/api/v1/available-licence",{user_id:d.getId(),ignore_no_licence:1},{get:{method:"GET",isArray:!0}}).get().$promise;return e.then(function(e){d.setLicences(e)},function(e){m.error="Error: "+c(e)}),e}var d=n.createUser(),u=18e4,m={info:null,username:null,password:null,agent_name:null,agent_id:null,display_name:null,is_configured:null,error:null};return{fetchUser:i,createAgent:o,updateAgent:s,data:m,getUser:r,getUserId:a,fetchAvailableLicences:l}}])}(),function(){"use strict";ionic.Platform.isIE=function(){return ionic.Platform.ua.toLowerCase().indexOf("trident")>-1},ionic.Platform.isIE()&&angular.module("ionic").factory("$ionicNgClick",["$parse","$timeout",function(e,t){return function(n,r,a){var i=angular.isFunction(a)?a:e(a);r.on("click",function(e){n.$apply(function(){n.clicktimer||(i(n,{$event:e}),n.clicktimer=t(function(){delete n.clicktimer},1,!1))})}),r.onclick=function(e){}}}])}(),angular.module("agent.template").run(["$templateCache",function(e){e.put("index.html",'<!DOCTYPE html>\n<html lang="en" class="no-js">\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">\n <title>Domotz Agent</title>\n\n <link href="lib/ionic/css/ionic.min.css" rel="stylesheet">\n <link href="css/agent.min.css" rel="stylesheet">\n <script src="https://cdn.flurry.com/js/flurry.js"></script>\n\n <!-- build:libs -->\n\n <!-- endbuild -->\n\n <!-- build:uglify -->\n\n <!-- endbuild -->\n\n </head>\n\n <body ng-app="agent">\n <ion-nav-view></ion-nav-view>\n </body>\n</html>'),e.put("partials/agent/agentinfo.html",'<ion-view view-title="Agent Info" ng-init="fetchNetworkInfo()">\n <ion-content class="has-header dmt-content-wrapper dmt-agentinfo" delegate-handle="agentinfo-scroll" scroll-resize>\n <h3>Agent Info</h3>\n <div class="dmt-rows">\n <div class="dmt-row-data">\n <span class="dmt-left">Status</span>\n <span class="dmt-right">\n <span class="dmt-status" ng-class="{\'dmt-online\': true, \'dmt-offline\': false}">\n <span>Active</span>\n <i class="icon icon-online"></i>\n </span>\n </span>\n </div>\n <div class="dmt-row-data">\n <span class="dmt-left">Connection</span>\n <span class="dmt-right">\n <span class="dmt-status dmt-offline" ng-if="agentCtrl.connectivity == \'offline\'">\n <span>Down for </span><span am-time-ago="agentCtrl.offline_since"></span>\n <i class="icon icon-offline"></i>\n </span>\n <span class="dmt-status dmt-online" ng-if="agentCtrl.connectivity == \'online\'">\n <span>Online</span>\n <i class="icon icon-online"></i>\n </span>\n </span>\n </div>\n <div class="dmt-row-divider"></div>\n <div class="dmt-row-data">\n <span class="dmt-left">Name</span>\n <span class="dmt-right">{{agentCtrl.getAgentName()}}</span>\n </div>\n <div class="dmt-row-data">\n <span class="dmt-left">Time Zone</span>\n <span class="dmt-right">{{agentCtrl.getTimeZone()}}</span>\n </div>\n <div class="dmt-row-data">\n <span class="dmt-left">Location</span>\n <span class="dmt-right">{{agentCtrl.getAgentLocation().address}}</span>\n <span class="dmt-right dmt-coordinates">{{agentCtrl.getAgentLocation().latitude}}, {{agentCtrl.getAgentLocation().longitude}}</span>\n </div>\n </div>\n\n <div class="dmt-map-wrapper">\n <img ng-src="http://maps.googleapis.com/maps/api/staticmap?center={{agentCtrl.getAgentLocation().latitude}},{{agentCtrl.getAgentLocation().longitude}}&markers={{agentCtrl.getAgentLocation().latitude}},{{agentCtrl.getAgentLocation().longitude}}&zoom=12&scale=false&size=420x280&maptype=roadmap&format=png" />\n </div>\n\n <!--\n <div class="dmt-section-divider">\n\n </div>\n\n <div class="dmt-action-button-wrapper">\n <button class="dmt-action-button dmt-reset-button" ng-click="agentCtrl.goToAgentReset()">Agent Reset</button>\n </div>\n\n <div class="dmt-info">\n This action cannot be undone!\n </div>\n -->\n\n </ion-content>\n</ion-view>'),e.put("partials/agent/agentreset.html",'<ion-view view-title="Agent Info" ng-init="fetchNetworkInfo()">\n <ion-content class="has-header dmt-content-wrapper dmt-agentinfo" delegate-handle="agentinfo-scroll" scroll-resize>\n <h3 class="dmt-warn-color">Agent Reset</h3>\n <div class="dmt-rows">\n <div class="dmt-row-data">\n Are you sure you want to RESET this agent?\n </div>\n <div class="dmt-row-data">\n This action cannot be undone! The devices, alerts and agent configuration\n will be <span class="dmt-warn-color">PERMANENTLY DELETED!</span>\n </div>\n <div class="dmt-row-data">\n If you still wish to delete all data, press the\n "Yes, reset this agent" button.\n </div>\n </div>\n\n <div class="dmt-row-divider"></div>\n\n <div class="dmt-action-button-wrapper">\n <button class="dmt-action-button dmt-back-button" ng-click="agentCtrl.goToAgentInfo()"><< Back</button>\n <button class="dmt-action-button dmt-reset-confirm-button" ng-click="agentCtrl.goToAgentResetConfirmation()">Yes, reset this agent</button>\n </div>\n\n </ion-content>\n</ion-view>'),e.put("partials/agent/agentresetconfirm.html",'<ion-view view-title="Agent Info" ng-init="fetchNetworkInfo()">\n <ion-content class="has-header dmt-spinner-wrapper" ng-show="agentCtrl.resetLoading">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n <div class="dmt-notice">{{agentCtrl.waitMessage}}</div>\n </ion-content>\n <ion-content class="has-header dmt-content-wrapper dmt-agentinfo" delegate-handle="agentinfo-scroll" scroll-resize ng-show="!agentCtrl.resetLoading">\n <h3 class="dmt-warn-color">{{agentCtrl.errorOccurred ? agentCtrl.errorMessage : \'To RESET this agent you have to be authenticated.\'}}</h3>\n <form name="credentials" ng-keyup="$event.keyCode == 13 && agentCtrl.resetAgent()">\n <div class="dmt-rows">\n\n <div class="dmt-field-wrapper">\n <div class="dmt-field-input" ng-class="{\'dmt-active\': agentCtrl.email.focus || agentCtrl.email.value.length > 0 || credentials.$error.email}">\n <input class="dmt-input" name="email" type="email" ng-model="agentCtrl.email.value" ng-focus="agentCtrl.email.focus = true" ng-blur="agentCtrl.email.focus = false" />\n <span class="dmt-input-label">Email</span>\n </div>\n </div>\n\n <div class="dmt-field-wrapper">\n <div class="dmt-field-input" ng-class="{\'dmt-active\': agentCtrl.password.focus || agentCtrl.password.value.length > 0}">\n <input class="dmt-input" type="password" ng-model="agentCtrl.password.value" ng-focus="agentCtrl.password.focus = true" ng-blur="agentCtrl.password.focus = false" />\n <span class="dmt-input-label">Password</span>\n </div>\n </div>\n\n </div>\n\n <div class="dmt-row-divider"></div>\n\n <div class="dmt-action-button-wrapper">\n <button class="dmt-action-button dmt-back-button" ng-click="agentCtrl.goToAgentReset()"><< Cancel</button>\n <button class="dmt-action-button dmt-reset-request-button"\n ng-class="{\'dmt-active\': agentCtrl.password.value.length > 0 || agentCtrl.email.value.length > 0}"\n ng-click="agentCtrl.resetAgent()">RESET</button>\n </div>\n </form>\n </ion-content>\n</ion-view>'),e.put("partials/layout/menu.html",'<ion-side-menus enable-menu-with-back-views="false">\n <ion-side-menu-content>\n <ion-nav-bar class="dmt-header-bar">\n <ion-nav-back-button>\n </ion-nav-back-button>\n\n <ion-nav-buttons side="left">\n <button class="button button-icon button-clear ion-navicon" menu-toggle="left">\n </button>\n </ion-nav-buttons>\n </ion-nav-bar>\n <ion-nav-view name="menuContent"></ion-nav-view>\n </ion-side-menu-content>\n\n <ion-side-menu side="left" expose-aside-when="large" width="320">\n\n <ion-content scroll="true" class="dmt-menu">\n\n <div class="dmt-logo-wrapper">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <!--\n <div class="dmt-status-wrapper" ng-show="agentCtrl.getAgentName().length > 0">\n <div class="dmt-agent-name">\n <span>{{agentCtrl.getAgentName()}}</span>\n </div>\n <div class="dmt-status">\n <i class="icon icon-online"></i>\n <span>is up and running.</span>\n </div>\n </div>\n -->\n\n <ion-list class="dmt-sections">\n <ion-item class="dmt-local-agent-label">\n <span>Local Agent</span>\n </ion-item>\n <ion-item menu-close ui-sref="app.agentinfo()" ui-sref-active="active">\n <i class="icon icon-generic"></i>\n <span>Agent Info</span>\n <i class="icon icon-arrow-right dmt-accessory-icon"></i>\n </ion-item>\n <ion-item menu-close ui-sref="app.netinfo()" ui-sref-active="active">\n <i class="icon icon-info"></i>\n <span>Network Info</span>\n <i class="icon icon-arrow-right dmt-accessory-icon"></i>\n </ion-item>\n <ion-item menu-close ui-sref="app.netroute()" ui-sref-active="active">\n <i class="icon icon-mtr"></i>\n <span>Route Analysis</span>\n <i class="icon icon-arrow-right dmt-accessory-icon"></i>\n </ion-item>\n <ion-item menu-close ui-sref="app.netspeed()" ui-sref-active="active">\n <i class="icon ion-speedometer"></i>\n <span>Speed Test</span>\n <i class="icon icon-arrow-right dmt-accessory-icon"></i>\n </ion-item>\n <ion-item class="dmt-webapp-item" menu-close ng-click="ctrl.webapp()" ui-sref-active="active">\n <i class="icon icon-pc-notebook"></i>\n <span>Web App</span>\n <i class="icon ion-android-open dmt-accessory-icon"></i>\n </ion-item>\n </ion-list>\n </ion-content>\n </ion-side-menu>\n\n <!--\n <div class="dmt-tc-button" ng-click="ctrl.showAgreement()">\n <span>Terms & Conditions</span>\n </div>\n -->\n</ion-side-menus>'),e.put("partials/nettools/netinfo.html",'<ion-view view-title="Network Info">\n <dmt-net-info-view></dmt-net-info-view>\n</ion-view>'),e.put("partials/nettools/netroute.html",'<ion-view view-title="Route Analysis">\n <dmt-net-route-view></dmt-net-route-view>\n</ion-view>'),e.put("partials/nettools/netspeed.html",'<ion-view view-title="Speed Test">\n <dmt-net-speed-view agent-name="agentCtrl.getAgentName()"></dmt-net-speed-view>\n</ion-view>'),e.put("partials/restricted/activation.html",'<ion-content scroll="true" class="dmt-restricted-wrapper dmt-dark-background">\n\n <div class="dmt-logo-wrapper" ui-sref="restricted.welcome">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <div class="dmt-title">{{ctrl.isResumeProcedure ? \'Resume configuration\' : \'Activate\'}}</div>\n\n <div class="dmt-form-wrapper dmt-activation">\n\n <form name="ctrl.activationForm" ng-keyup="$event.keyCode == 13 && ctrl.activate()" novalidate>\n\n <dmt-field ng-class="{\'dmt-disabled\': ctrl.isResumeProcedure}"\n ng-model="ctrl.agentDisplayName"\n field-label="{{ctrl.isResumeProcedure ? \'Your Domotz Agent\' : \'Give a name to your Network\'}}"\n field-name="agent-name"\n field-type="text"\n field-required="true"\n field-error-message="Name required"\n field-disabled="ctrl.isResumeProcedure"></dmt-field>\n\n <div class="dmt-map-wrapper" ng-if="!ctrl.geoLocation.error">\n <img ng-src="http://maps.googleapis.com/maps/api/staticmap?center={{ctrl.geoLocation.data.latitude}},{{ctrl.geoLocation.data.longitude}}&markers={{ctrl.geoLocation.data.latitude}},{{ctrl.geoLocation.data.longitude}}&zoom=12&scale=false&size=160x160&maptype=roadmap&format=png" />\n\n <div class="dmt-location-wrapper">\n <div class="dmt-label-wrapper" ng-show="ctrl.geoLocation.data">\n <span class="dmt-label-title">Location:</span>\n <span class="dmt-label-detail">{{ ctrl.geoLocation.address }} ({{ ctrl.geoLocation.data.latitude }}, {{ ctrl.geoLocation.data.longitude }})</span>\n </div>\n\n <div class="dmt-label-wrapper" ng-show="ctrl.geoLocation.data">\n <span class="dmt-label-title">Time Zone:</span>\n <span class="dmt-label-detail">{{ ctrl.geoLocation.data.time_zone }}</span>\n </div>\n </div>\n </div>\n\n <div class="dmt-agent-context" ng-hide="ctrl.isResumeProcedure && !ctrl.agentContextSelected"\n ng-class="{\'dmt-agent-context-error\': !ctrl.activationForm[\'agent_context\'].$valid && (ctrl.activationForm[\'agent_context\'].$dirty || formSubmitted)}">\n <span>This Agent is running in your:</span>\n <ul class="dmt-radio-list">\n <li ng-repeat="(k, p) in ctrl.agentContexts" ng-class="{\'dmt-radio-disabled\': ctrl.isResumeProcedure}">\n <label for="{{k}}">{{p}}</label>\n <div class="dmt-radio-button">\n <input id="{{k}}" type="radio" name="agent_context" value="{{k}}" ng-model="ctrl.agentContextSelected" ng-disabled="ctrl.isResumeProcedure" ng-required="!ctrl.isResumeProcedure">\n <label for="{{k}}"></label>\n </div>\n </li>\n </ul>\n <span ng-show="!ctrl.activationForm[\'agent_context\'].$valid && (ctrl.activationForm[\'agent_context\'].$dirty || formSubmitted)" class="dmt-field-error">Selection required</span>\n </div>\n\n <button class="dmt-btn-proceed dmt-btn-big dmt-btn-bubbly" ng-click="ctrl.activate()">{{(ctrl.isResumeProcedure ? \'Resume your Agent\' : \'Activate your Agent\')}}</button>\n\n </form>\n </div>\n\n</ion-content>\n\n<ion-content class="dmt-spinner-wrapper dmt-opaque-background dmt-activation-spinner" ng-show="ctrl.loading">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n <div class="dmt-activation-spinner-msg">Please be patient, this may take<br/>a couple of minutes.</div>\n</ion-content>'), e.put("partials/restricted/configuring.html",'<ion-content scroll="true" class="dmt-restricted-wrapper dmt-light-background">\n\n <div class="dmt-logo-wrapper" ui-sref="restricted.welcome">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <div class="dmt-title">Scanning for devices</div>\n\n <div class="dmt-form-wrapper dmt-configuring">\n\n <form name="configuring" ng-keyup="$event.keyCode == 13 && ctrl.goTo(\'netinfo\')">\n\n <div class="dmt-configuring-animation"></div>\n\n <div class="dmt-label-wrapper">It can take up to 15 minutes to discover all devices in your network.</div>\n\n <div class="dmt-label-wrapper">We use a continuous discovery procedure after the initial scan. Feel free to start using Domotz right away by downloading our App on:</div>\n\n <div class="dmt-label-wrapper"><a href="https://itunes.apple.com/us/app/domotz/id991773982?mt=8" target="_blank">iOS App Store</a></div>\n\n <div class="dmt-label-wrapper"><a href="https://play.google.com/store/apps/details?id=com.domotz.app" target="_blank">Google Play Store</a></div>\n\n <div class="dmt-spinner-wrapper" ng-show="ctrl.agentIsRestarting">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n </div>\n\n <button class="dmt-btn-proceed dmt-btn-big dmt-btn-bubbly" ng-click="!ctrl.agentIsRestarting && ctrl.goToState(\'app.agentinfo\')" ng-show="!ctrl.agentIsRestarting">Done</button>\n\n <div class="dmt-info" ng-show="ctrl.agentIsRestarting">\n Starting services, please wait, it will be ready to use in approximately 30 seconds.\n </div>\n\n </form>\n </div>\n\n</ion-content>'),e.put("partials/restricted/login.html",'<ion-content scroll="true" class="dmt-restricted-wrapper dmt-dark-background dmt-has-bottom-bar">\n\n <div class="dmt-logo-wrapper" ui-sref="restricted.welcome">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <div class="dmt-title">Login to Domotz local Agent</div>\n\n <div class="dmt-form-wrapper dmt-login">\n\n <form name="ctrl.loginForm" ng-keyup="$event.keyCode == 13 && ctrl.login()" novalidate>\n\n <dmt-field ng-model="ctrl.email"\n field-label="Domotz account email"\n field-name="email"\n field-type="email"\n field-required="true"\n field-error-message="Invalid email"></dmt-field>\n\n <dmt-field ng-model="ctrl.password"\n field-label="Password"\n field-name="password"\n field-type="password"\n field-required="true"\n field-error-message="Password required"></dmt-field>\n\n <button class="dmt-btn-proceed dmt-btn-big dmt-btn-bubbly" ng-click="ctrl.login()">Login</button>\n\n <a class="dmt-recover-password" href="https://portal.domotz.com/#/forgot-password" target="_blank">Forgot Password?</a>\n\n </form>\n </div>\n</ion-content>\n\n<div class="dmt-bottom-button dmt-create" ng-click="ctrl.goToRestrictedState(\'signup\')">\n <span>New to Domotz?</span> <span class="dmt-bottom-button-emph">Create an account</span>\n</div>\n\n<ion-content class="dmt-spinner-wrapper dmt-opaque-background" ng-show="ctrl.loading">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n</ion-content>'),e.put("partials/restricted/restricted.html",'<ion-view>\n <div class="dmt-splitted-views">\n <div ui-view="main" class="dmt-main-view" ng-init="ctrl.getGeoLocation()"></div>\n <div class="dmt-right-view">\n <div class="dmt-animated-background">\n <div class="dmt-background-overlay" ng-class="{\'dmt-error\': ctrl.errorOccurred}"></div>\n </div>\n </div>\n </div>\n</ion-view>'),e.put("partials/restricted/signup.html",'<ion-content scroll="true" class="dmt-restricted-wrapper dmt-dark-background dmt-has-bottom-bar">\n\n <div class="dmt-logo-wrapper" ui-sref="restricted.welcome">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <div class="dmt-title">Create a Domotz Account</div>\n\n <div class="dmt-form-wrapper dmt-signup">\n\n <form name="ctrl.signupForm" ng-keyup="$event.keyCode == 13 && ctrl.signup()" novalidate>\n\n <dmt-field ng-model="ctrl.email"\n field-label="Email address"\n field-name="email"\n field-type="email"\n field-required="true"\n field-error-message="Invalid email"></dmt-field>\n\n <dmt-field ng-model="ctrl.password"\n field-label="Password"\n field-name="password"\n field-type="password"\n field-required="true"\n field-error-message="Password required"\n display-pwd-strength="true"\n display-pwd-eye="true"></dmt-field>\n\n <dmt-country-select ng-model="ctrl.selectedCountry" display-importance-msg="true"></dmt-country-select>\n\n <dmt-agreement-checkbox\n field-id="tc-agreement"\n field-name="tc-agreement"\n ng-model="ctrl.agreementAccepted"\n label-text="I agree with "\n has-label-link="true"\n label-link="Terms and Conditions"\n on-click-fn="ctrl.showAgreement()"\n ng-required="true"\n ng-disabled="ctrl.agreementDisabled"\n field-error="Please accept Terms and Conditions"\n >\n </dmt-agreement-checkbox>\n\n <button class="dmt-btn-promote dmt-btn-big" ng-click="ctrl.signup()">Start Free Trial</button>\n\n </form>\n </div>\n\n</ion-content>\n\n<div class="dmt-bottom-button" ng-click="ctrl.goToRestrictedState(\'login\')">\n <span>Have an account? Log in</span>\n</div>\n\n<ion-content class="dmt-spinner-wrapper dmt-opaque-background" ng-show="ctrl.loading">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n</ion-content>'),e.put("partials/restricted/welcome.html",'<ion-content scroll="false" class="dmt-restricted-wrapper dmt-dark-background dmt-welcome">\n\n <div class="dmt-logo-wrapper" ui-sref="restricted.welcome">\n <i class="icon icon-domotz-logo"></i>\n </div>\n\n <div class="dmt-welcome-content-wrapper">\n <div class="dmt-title">\n Start Monitoring\n </br>Your Network\n </div>\n <div class="dmt-welcome-options">\n <div>\n <div class="dmt-welcome-option-text">Have an account?</div>\n <button class="dmt-btn-proceed dmt-btn-big dmt-btn-bubbly" ng-click="ctrl.goToRestrictedState(\'login\')">Login</button>\n </div>\n <div>\n <div>New to Domotz?</div>\n <button class="dmt-btn-promote dmt-btn-big" ng-click="ctrl.goToRestrictedState(\'signup\')">Create an account</button>\n </div>\n </div>\n </div>\n\n</ion-content>\n\n<ion-content class="dmt-spinner-wrapper dmt-opaque-background" ng-show="ctrl.loading">\n <ion-spinner icon="android" class="dmt-spinner"></ion-spinner>\n</ion-content>')}]);