Updated readme and fixed linting errors

Change-Id: I185a961fcfbec37acadd3fc35d9cb6e71883c5ce
diff --git a/dist/ngXosHelpers.min.js b/dist/ngXosHelpers.min.js
index ea7fd2e..c365512 100644
--- a/dist/ngXosHelpers.min.js
+++ b/dist/ngXosHelpers.min.js
@@ -1,2 +1,2 @@
-"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var n=0,i=Array(e.length);n<e.length;n++)i[n]=e[n];return i}return Array.from(e)}!function(){angular.module("xos.uiComponents",["chart.js","RecursionHelper","dndLists"])}(),function(){angular.module("xos.uiComponents").component("xosSmartTable",{restrict:"E",bindings:{config:"="},template:'\n        <div class="row" ng-show="vm.data.length > 0">\n          <div class="col-xs-12 text-right">\n            <a href="" class="btn btn-success" ng-click="vm.createItem()">\n              Add\n            </a>\n          </div>\n        </div>\n        <div class="row">\n          <div class="col-xs-12 table-responsive">\n            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n          </div>\n        </div>\n        <div class="panel panel-default" ng-show="vm.detailedItem">\n          <div class="panel-heading">\n            <div class="row">\n              <div class="col-xs-11">\n                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n              </div>\n              <div class="col-xs-1">\n                <a href="" ng-click="vm.cleanForm()">\n                  <i class="glyphicon glyphicon-remove pull-right"></i>\n                </a>\n              </div>\n            </div>\n          </div>\n          <div class="panel-body">\n            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n          </div>\n        </div>\n        <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n        <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n      ',bindToController:!0,controllerAs:"vm",controller:["$injector","LabelFormatter","_","XosFormHelpers",function(e,n,i,o){var t=this;this.responseMsg=!1,this.responseErr=!1,this.tableConfig={columns:[],actions:[{label:"delete",icon:"remove",cb:function(e){t.Resource["delete"]({id:e.id}).$promise.then(function(){i.remove(t.data,function(n){return n.id===e.id}),t.responseMsg=t.config.resource+" with id "+e.id+" successfully deleted"})["catch"](function(n){t.responseErr=n.data.detail||"Error while deleting "+t.config.resource+" with id "+e.id})},color:"red"},{label:"details",icon:"search",cb:function(e){t.detailedItem=e}}],classes:"table table-striped table-bordered table-responsive",filter:"field",order:!0,pagination:{pageSize:10}},this.formConfig={exclude:this.config.hiddenFields,fields:{},formName:this.config.resource+"Form",actions:[{label:"Save",icon:"ok",cb:function(e){var n=void 0,i=!0;e.id?(n=e.$update(),i=!1):n=e.$save(),n.then(function(n){i&&t.data.push(angular.copy(n)),delete t.detailedItem,t.responseMsg=t.config.resource+" with id "+e.id+" successfully saved"})["catch"](function(n){t.responseErr=n.data.detail||"Error while saving "+t.config.resource+" with id "+e.id})},"class":"success"}]},this.cleanForm=function(){delete t.detailedItem},this.createItem=function(){t.detailedItem=new t.Resource},this.Resource=e.get(this.config.resource);var r=function(){t.Resource.query().$promise.then(function(e){if(!e[0])return void(t.data=e);var r=e[0],a=Object.keys(r);i.remove(a,function(e){return"id"===e||"validators"===e}),angular.isArray(t.config.hiddenFields)&&(a=i.difference(a,t.config.hiddenFields)),a.forEach(function(e){var i={label:n.format(e),prop:e};i.type=o._getFieldFormat(r[e]),t.tableConfig.columns.push(i)}),a.forEach(function(e,i){t.formConfig.fields[e]={label:n.format(e).replace(":",""),type:o._getFieldFormat(r[e])}}),t.data=e})};r()}]})}(),function(){angular.module("xos.uiComponents").component("xosSmartPie",{restrict:"E",bindings:{config:"="},template:'\n      <canvas\n        class="chart chart-pie {{vm.config.classes}}"\n        chart-data="vm.data" chart-labels="vm.labels"\n        chart-legend="{{vm.config.legend}}">\n      </canvas>\n    ',bindToController:!0,controllerAs:"vm",controller:["$injector","$interval","$scope","$timeout","_",function(e,n,i,o,t){var r=this;if(!this.config.resource&&!this.config.data)throw new Error("[xosSmartPie] Please provide a resource or an array of data in the configuration");var a=function(e){return t.groupBy(e,r.config.groupBy)},s=function(e){return t.reduce(Object.keys(e),function(n,i){return n.concat(e[i].length)},[])},l=function(e){return angular.isFunction(r.config.labelFormatter)?r.config.labelFormatter(Object.keys(e)):Object.keys(e)},c=function(e){var n=a(e);r.data=s(n),r.labels=l(n)};this.config.resource?!function(){r.Resource=e.get(r.config.resource);var i=function(){r.Resource.query().$promise.then(function(e){e[0]&&c(e)})};i(),r.config.poll&&n(function(){i()},1e3*r.config.poll)}():i.$watch(function(){return r.config.data},function(e){e&&c(r.config.data)},!0),i.$on("create",function(e,n){console.log("create: "+n.id)}),i.$on("destroy",function(e,n){console.log("destroy: "+n.id)})}]})}(),function(){angular.module("xos.uiComponents").component("xosValidation",{restrict:"E",bindings:{field:"=",form:"="},template:'\n      <div ng-cloak>\n        <xos-alert config="vm.config" show="vm.field.$error.required !== undefined && vm.field.$error.required !== false  && (vm.field.$touched || vm.form.$submitted)">\n          Field required\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.email !== undefined && vm.field.$error.email !== false && (vm.field.$touched || vm.form.$submitted)">\n          This is not a valid email\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.minlength !== undefined && vm.field.$error.minlength !== false && (vm.field.$touched || vm.form.$submitted)">\n          Too short\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.maxlength !== undefined && vm.field.$error.maxlength !== false && (vm.field.$touched || vm.form.$submitted)">\n          Too long\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.custom !== undefined && vm.field.$error.custom !== false && (vm.field.$touched || vm.form.$submitted)">\n          Field invalid\n        </xos-alert>\n      </div>\n    ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:function(){this.config={type:"danger"}}})}(),function(){angular.module("xos.uiComponents").component("xosTable",{restrict:"E",bindings:{data:"=",config:"="},template:'\n        <div ng-show="vm.data.length > 0 && vm.loader == false">\n          <div class="row" ng-if="vm.config.filter == \'fulltext\'">\n            <div class="col-xs-12">\n              <input\n                class="form-control"\n                placeholder="Type to search.."\n                type="text"\n                ng-model="vm.query"/>\n            </div>\n          </div>\n          <table ng-class="vm.classes" ng-hide="vm.data.length == 0">\n            <thead>\n              <tr>\n                <th ng-repeat="col in vm.columns">\n                  {{col.label}}\n                  <span ng-if="vm.config.order">\n                    <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">\n                      <i class="glyphicon glyphicon-chevron-up"></i>\n                    </a>\n                    <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">\n                      <i class="glyphicon glyphicon-chevron-down"></i>\n                    </a>\n                  </span>\n                </th>\n                <th ng-if="vm.config.actions">Actions:</th>\n              </tr>\n            </thead>\n            <tbody ng-if="vm.config.filter == \'field\'">\n              <tr>\n                <td ng-repeat="col in vm.columns">\n                  <input\n                    ng-if="col.type !== \'boolean\' && col.type !== \'array\' && col.type !== \'object\' && col.type !== \'custom\'"\n                    class="form-control"\n                    placeholder="Type to search by {{col.label}}"\n                    type="text"\n                    ng-model="vm.query[col.prop]"/>\n                  <select\n                    ng-if="col.type === \'boolean\'"\n                    class="form-control"\n                    ng-model="vm.query[col.prop]">\n                    <option value="">-</option>\n                    <option value="true">True</option>\n                    <option value="false">False</option>\n                  </select>\n                </td>\n                <td ng-if="vm.config.actions"></td>\n              </tr>\n            </tbody>\n            <tbody>\n              <tr ng-repeat="item in vm.data | filter:vm.query:vm.comparator | orderBy:vm.orderBy:vm.reverse | pagination:vm.currentPage * vm.config.pagination.pageSize | limitTo: (vm.config.pagination.pageSize || vm.data.length) track by $index">\n                <td ng-repeat="col in vm.columns" xos-link-wrapper>\n                  <span ng-if="!col.type || col.type === \'text\'">{{item[col.prop]}}</span>\n                  <span ng-if="col.type === \'boolean\'">\n                    <i class="glyphicon"\n                      ng-class="{\'glyphicon-ok\': item[col.prop], \'glyphicon-remove\': !item[col.prop]}">\n                    </i>\n                  </span>\n                  <span ng-if="col.type === \'date\'">\n                    {{item[col.prop] | date:\'H:mm MMM d, yyyy\'}}\n                  </span>\n                  <span ng-if="col.type === \'array\'">\n                    {{item[col.prop] | arrayToList}}\n                  </span>\n                  <span ng-if="col.type === \'object\'">\n                    <dl class="dl-horizontal">\n                      <span ng-repeat="(k,v) in item[col.prop]">\n                        <dt>{{k}}</dt>\n                        <dd>{{v}}</dd>\n                      </span>\n                    </dl>\n                  </span>\n                  <span ng-if="col.type === \'custom\'">\n                    {{col.formatter(item)}}\n                  </span>\n                  <span ng-if="col.type === \'icon\'">\n                    <i class="glyphicon glyphicon-{{col.formatter(item)}}">\n                    </i>\n                  </span>\n                </td>\n                <td ng-if="vm.config.actions">\n                  <a href=""\n                    ng-repeat="action in vm.config.actions"\n                    ng-click="action.cb(item)"\n                    title="{{action.label}}">\n                    <i\n                      class="glyphicon glyphicon-{{action.icon}}"\n                      style="color: {{action.color}};"></i>\n                  </a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <xos-pagination\n            ng-if="vm.config.pagination"\n            page-size="vm.config.pagination.pageSize"\n            total-elements="vm.data.length"\n            change="vm.goToPage">\n            </xos-pagination>\n        </div>\n        <div ng-show="(vm.data.length == 0 || !vm.data) && vm.loader == false">\n           <xos-alert config="{type: \'info\'}">\n            No data to show.\n          </xos-alert>\n        </div>\n        <div ng-show="vm.loader == true">\n          <div class="loader"></div>\n        </div>\n      ',bindToController:!0,controllerAs:"vm",controller:["_","$scope","Comparator",function(e,n,i){var o=this;if(this.comparator=i,this.loader=!0,n.$watch(function(){return o.data},function(e){angular.isDefined(e)&&(o.loader=!1)}),!this.config)throw new Error('[xosTable] Please provide a configuration via the "config" attribute');if(!this.config.columns)throw new Error("[xosTable] Please provide a columns list in the configuration");this.config.order&&angular.isObject(this.config.order)&&(this.reverse=this.config.order.reverse||!1,this.orderBy=this.config.order.field||"id");var t=e.filter(this.config.columns,{type:"custom"});angular.isArray(t)&&t.length>0&&e.forEach(t,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided a custom field type, a formatter function should provided too.")});var r=e.filter(this.config.columns,{type:"icon"});angular.isArray(r)&&r.length>0&&e.forEach(r,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided an icon field type, a formatter function should provided too.")});var a=e.filter(this.config.columns,function(e){return angular.isDefined(e.link)});angular.isArray(a)&&a.length>0&&e.forEach(a,function(e){if(!angular.isFunction(e.link))throw new Error("[xosTable] The link property should be a function.")}),this.columns=this.config.columns,this.classes=this.config.classes||"table table-striped table-bordered",this.config.actions,this.config.pagination&&(this.currentPage=0,this.goToPage=function(e){o.currentPage=e})}]}).filter("arrayToList",function(){return function(e){return angular.isArray(e)?e.join(", "):e}}).directive("xosLinkWrapper",function(){return{restrict:"A",transclude:!0,template:'\n          <a ng-if="col.link" href="{{col.link(item)}}">\n            <div ng-transclude></div>\n          </a>\n          <div ng-transclude ng-if="!col.link"></div>\n        '}})}(),function(){angular.module("xos.uiComponents").component("xosPagination",{restrict:"E",bindings:{pageSize:"=",totalElements:"=",change:"="},template:'\n      <div class="row" ng-if="vm.pageList.length > 1">\n        <div class="col-xs-12 text-center">\n          <ul class="pagination">\n            <li\n              ng-click="vm.goToPage(vm.currentPage - 1)"\n              ng-class="{disabled: vm.currentPage == 0}">\n              <a href="" aria-label="Previous">\n                  <span aria-hidden="true">&laquo;</span>\n              </a>\n            </li>\n            <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n              <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n            </li>\n            <li\n              ng-click="vm.goToPage(vm.currentPage + 1)"\n              ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n              <a href="" aria-label="Next">\n                  <span aria-hidden="true">&raquo;</span>\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n    ',bindToController:!0,controllerAs:"vm",controller:["$scope",function(e){var n=this;this.currentPage=0,this.goToPage=function(e){e<0||e===n.pages||(n.currentPage=e,n.change(e))},this.createPages=function(e){for(var n=[],i=0;i<e;i++)n.push(i);return n},e.$watch(function(){return n.totalElements},function(){n.totalElements&&(n.pages=Math.ceil(n.totalElements/n.pageSize),n.pageList=n.createPages(n.pages))})}]}).filter("pagination",function(){return function(e,n){return e&&angular.isArray(e)?(n=parseInt(n,10),e.slice(n)):e}})}(),function(){angular.module("xos.uiComponents").component("xosForm",{restrict:"E",bindings:{config:"=",ngModel:"="},template:'\n      <form name="vm.{{vm.config.formName || \'form\'}}" novalidate>\n        <div class="form-group" ng-repeat="(name, field) in vm.formField">\n          <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>\n          <xos-validation field="vm[vm.config.formName || \'form\'][name]" form = "vm[vm.config.formName || \'form\']"></xos-validation>\n          <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>\n        </div>\n        <div class="form-group" ng-if="vm.config.actions">\n        <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>\n\n          <button role="button" href=""\n            ng-repeat="action in vm.config.actions"\n            ng-click="action.cb(vm.ngModel, vm[vm.config.formName || \'form\'])"\n            class="btn btn-{{action.class}}"\n            title="{{action.label}}">\n            <i class="glyphicon glyphicon-{{action.icon}}"></i>\n            {{action.label}}\n          </button>\n        </div>\n      </form>\n    ',bindToController:!0,controllerAs:"vm",controller:["$scope","$log","_","XosFormHelpers",function(e,n,i,o){var t=this;if(!this.config)throw new Error('[xosForm] Please provide a configuration via the "config" attribute');if(!this.config.actions)throw new Error("[xosForm] Please provide an action list in the configuration");this.config.feedback||(this.config.feedback={show:!1,message:"Form submitted successfully !!!",type:"success"}),this.excludedField=["id","validators","created","updated","deleted","backend_status"],this.config&&this.config.exclude&&(this.excludedField=this.excludedField.concat(this.config.exclude)),this.formField=[],e.$watch(function(){return t.config},function(){if(t.ngModel){var e=i.difference(Object.keys(t.ngModel),t.excludedField),n=o.parseModelField(e);t.formField=o.buildFormStructure(n,t.config.fields,t.ngModel)}},!0),e.$watch(function(){return t.ngModel},function(e){if(t.formField={},e){var n=i.difference(Object.keys(e),t.excludedField),r=o.parseModelField(n);t.formField=o.buildFormStructure(r,t.config.fields,e)}})}]})}(),function(){angular.module("xos.uiComponents").component("xosField",{restrict:"E",bindings:{name:"=",field:"=",ngModel:"="},template:'\n      <label ng-if="vm.field.type !== \'object\' && vm.field.type !== \'array\'">{{vm.field.label}}</label>\n      <input\n        xos-custom-validator custom-validator="vm.field.validators.custom || null"\n        ng-if="vm.field.type !== \'boolean\' && vm.field.type !== \'object\' && vm.field.type !== \'select\' && vm.field.type !== \'array\'"\n        type="{{vm.field.type}}"\n        name="{{vm.name}}"\n        class="form-control"\n        ng-model="vm.ngModel"\n        ng-minlength="vm.field.validators.minlength || 0"\n        ng-maxlength="vm.field.validators.maxlength || 2000"\n        ng-required="vm.field.validators.required || false" />\n        <select class="form-control" ng-if ="vm.field.type === \'select\'"\n          name = "{{vm.name}}"\n          ng-options="item.id as item.label for item in vm.field.options"\n          ng-model="vm.ngModel"\n          ng-required="vm.field.validators.required || false">\n          </select>\n      <span class="boolean-field" ng-if="vm.field.type === \'boolean\'">\n        <a href="#"\n          class="btn btn-success"\n          ng-show="vm.ngModel"\n          ng-click="vm.ngModel = false">\n          <i class="glyphicon glyphicon-ok"></i>\n        </a>\n        <a href="#"\n          class="btn btn-danger"\n          ng-show="!vm.ngModel"\n          ng-click="vm.ngModel = true">\n          <i class="glyphicon glyphicon-remove"></i>\n        </a>\n      </span>\n      <div\n        class="panel panel-default object-field"\n        ng-if="vm.field.type == \'object\' && (!vm.isEmptyObject(vm.ngModel) || !vm.isEmptyObject(vm.field.properties))"\n        >\n        <div class="panel-heading">{{vm.field.label}}</div>\n        <div class="panel-body">\n          <div ng-if="!vm.field.properties" ng-repeat="(k, v) in vm.ngModel">\n            <xos-field\n              name="k"\n              field="{label: vm.formatLabel(k), type: vm.getType(v)}"\n              ng-model="v">\n            </xos-field>\n          </div>\n          <div ng-if="vm.field.properties" ng-repeat="(k, v) in vm.field.properties">\n            <xos-field\n              name="k"\n              field="{\n                label: v.label || vm.formatLabel(k),\n                type: v.type,\n                validators: v.validators\n              }"\n              ng-model="vm.ngModel[k]">\n            </xos-field>\n          </div>\n        </div>\n      </div>\n      <div\n        class="panel panel-default array-field"\n        ng-if="vm.field.type == \'array\'">\n        <div class="panel-heading">{{vm.field.label}}</div>\n        <div class="panel-body selected">\n          <ul class="draggable" dnd-list="vm.ngModel">\n            <li\n              class="array-element"\n              ng-repeat="item in vm.ngModel"\n              dnd-draggable="item"\n              dnd-moved="vm.ngModel.splice($index, 1)"\n              dnd-effect-allowed="move"\n              dnd-selected="models.selected = item"\n              >\n              <div class="well well-sm text-center">\n                {{item}}\n              </div>\n            </li>\n            <div class="clearfix"></div>\n          </ul>\n        </div>\n        <div class="panel-body unselected">\n          <ul class="draggable" dnd-list="vm.field.availableOptions">\n            <li\n              class="array-element"\n              ng-repeat="item in vm.field.availableOptions"\n              dnd-draggable="item"\n              dnd-moved="vm.field.availableOptions.splice($index, 1)"\n              dnd-effect-allowed="move"\n              dnd-selected="models.selected = item"\n              >\n              <div class="well well-sm text-center">\n                {{item}}\n              </div>\n            </li>\n            <div class="clearfix"></div>\n          </ul>\n        </div>\n      </div>\n    ',bindToController:!0,controllerAs:"vm",controller:["$attrs","$scope","XosFormHelpers","LabelFormatter","_",function(e,n,i,o,t){var r=this;if(!this.name)throw new Error("[xosField] Please provide a field name");if(!this.field)throw new Error("[xosField] Please provide a field definition");if(!this.field.type)throw new Error("[xosField] Please provide a type in the field definition");if(!e.ngModel)throw new Error("[xosField] Please provide an ng-model");this.getType=i._getFieldFormat,this.formatLabel=o.format,this.isEmptyObject=function(e){return!e||0===Object.keys(e).length},"array"===this.field.type&&n.$watch(function(){return r.ngModel.length},function(){r.field.availableOptions=t.difference(r.field.options,r.ngModel)})}]}).directive("xosCustomValidator",function(){return{restrict:"A",scope:{fn:"=customValidator"},require:"ngModel",link:function(e,n,i,o){function t(n){var i=e.fn(n);return angular.isArray(i)?o.$setValidity.apply(o,_toConsumableArray(i)):o.$setValidity("custom",i),n}angular.isFunction(e.fn)&&o.$parsers.push(t)}}})}(),function(){angular.module("xos.uiComponents").component("xosAlert",{restrict:"E",bindings:{config:"=",show:"=?"},template:'\n      <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n        <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n          <span aria-hidden="true">&times;</span>\n        </button>\n        <p ng-transclude></p>\n      </div>\n    ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:["$timeout",function(e){var n=this;if(!this.config)throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');this.show=this.show!==!1,this.dismiss=function(){n.show=!1},this.config.autoHide&&!function(){var i=e(function(){n.dismiss(),e.cancel(i)},n.config.autoHide)}()}]})}(),function(){function e(){var e=function(e){return e.split("_").join(" ").trim()},n=function(e){return e.split(/(?=[A-Z])/).map(function(e){return e.toLowerCase()}).join(" ")},i=function(e){return e.slice(0,1).toUpperCase()+e.slice(1)},o=function(o){return o=e(o),o=n(o),o=i(o).replace(/\s\s+/g," ")+":",o.replace("::",":")};return{_formatByUnderscore:e,_formatByUppercase:n,_capitalize:i,format:o}}angular.module("xos.uiComponents").factory("LabelFormatter",e)}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(){angular.module("xos.uiComponents").service("XosFormHelpers",["_","LabelFormatter",function(e,n){var i=this;this._isEmail=function(e){var n=/(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;return n.test(e)},this._getFieldFormat=function(e){return angular.isArray(e)?"array":angular.isDate(e)||!Number.isNaN(Date.parse(e))&&/^\d+-\d+-\d+\D\d+:\d+:\d+\.\d+\D/.test(e)?"date":"boolean"==typeof e?"boolean":i._isEmail(e)?"email":angular.isString(e)||null===e?"text":"undefined"==typeof e?"undefined":_typeof(e)},this.buildFormStructure=function(o,t,r){return o=angular.extend(o,t),t=t||{},e.reduce(Object.keys(o),function(e,o){return e[o]={label:t[o]&&t[o].label?t[o].label+":":n.format(o),type:t[o]&&t[o].type?t[o].type:i._getFieldFormat(r[o]),validators:t[o]&&t[o].validators?t[o].validators:{},hint:t[o]&&t[o].hint?t[o].hint:""},t[o]&&t[o].options&&(e[o].options=t[o].options),t[o]&&t[o].properties&&(e[o].properties=t[o].properties),"date"===e[o].type&&(r[o]=new Date(r[o])),"number"===e[o].type&&(r[o]=parseInt(r[o],10)),e},{})},this.parseModelField=function(n){return e.reduce(n,function(e,n){return e[n]={},e},{})}}])}(),function(){function e(e){return function(n,i){if(angular.isUndefined(n))return!1;if(null===n||null===i)return n===i;if(angular.isObject(i)||angular.isObject(n))return angular.equals(i,n);if(e.isBoolean(n)||e.isBoolean(i))return 0!==n&&1!==n||(n=!!n),angular.equals(i,n);if(!angular.isString(n)||!angular.isString(i)){if(!angular.isDefined(n.toString)||!angular.isDefined(i.toString))return n===i;n=n.toString(),i=i.toString()}return n=n.toLowerCase()+"",i=i.toLowerCase()+"",n.indexOf(i)!==-1}}e.$inject=["_"],angular.module("xos.uiComponents").factory("Comparator",e)}(),function(){function e(e,n,i){e.interceptors.push("SetCSRFToken"),i.defaults.stripTrailingSlashes=!1}e.$inject=["$httpProvider","$interpolateProvider","$resourceProvider"],angular.module("xos.helpers",["ngCookies","ngResource","ngAnimate","xos.uiComponents"]).config(e).factory("_",["$window",function(e){return e._}])}(),function(){angular.module("xos.helpers").service("vSG-Collection",["$resource",function(e){return e("/api/service/vsg/")}])}(),function(){angular.module("xos.helpers").service("vOLT-Collection",["$resource",function(e){return e("/api/tenant/cord/volt/:volt_id/",{volt_id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Login",["$resource",function(e){return e("/api/utility/login/")}]).service("Logout",["$resource",function(e){return e("/api/utility/logout/")}])}(),function(){angular.module("xos.helpers").service("Users",["$resource",function(e){return e("/api/core/users/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Truckroll",["$resource",function(e){return e("/api/tenant/truckroll/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Tenants",["$resource",function(e){return e("/api/core/tenants/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Subscribers",["$resource",function(e){return e("/api/tenant/cord/subscriber/:id/",{id:"@id"},{update:{method:"PUT"},"View-a-Subscriber-Features-Detail":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/"},"Read-Subscriber-uplink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Update-Subscriber-uplink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Read-Subscriber-downlink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Update-Subscriber-downlink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Read-Subscriber-cdn":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Update-Subscriber-cdn":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Read-Subscriber-uverse":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Update-Subscriber-uverse":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Read-Subscriber-status":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"},"Update-Subscriber-status":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"}})}])}(),function(){angular.module("xos.helpers").service("SlicesPlus",["$http","$q",function(e,n){this.query=function(i){var o=n.defer();return e.get("/api/utility/slicesplus/",{params:i}).then(function(e){o.resolve(e.data)})["catch"](function(e){o.reject(e.data)}),{$promise:o.promise}},this.get=function(i,o){var t=n.defer();return e.get("/api/utility/slicesplus/"+i,{params:o}).then(function(e){t.resolve(e.data)})["catch"](function(e){t.reject(e.data)}),{$promise:t.promise}}}])}(),function(){angular.module("xos.helpers").service("Slices",["$resource",function(e){return e("/api/core/slices/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Sites",["$resource",function(e){return e("/api/core/sites/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Services",["$resource",function(e){return e("/api/core/services/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("ONOS-Services-Collection",["$resource",function(e){return e("/api/service/onos/")}])}(),function(){angular.module("xos.helpers").service("ONOS-App-Collection",["$resource",function(e){return e("/api/tenant/onos/app/")}])}(),function(){angular.module("xos.helpers").service("Nodes",["$resource",function(e){return e("/api/core/nodes/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networkstemplates",["$resource",function(e){return e("/api/core/networktemplates/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networks",["$resource",function(e){return e("/api/core/networks/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Me",["$q","$http",function(e,n){this.get=function(){var i=e.defer();return n.get("/api/utility/me/").then(function(e){i.resolve(e.data)})["catch"](function(e){i.reject(e)}),i.promise}}])}(),function(){angular.module("xos.helpers").service("Instances",["$resource",function(e){return e("/api/core/instances/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Images",["$resource",function(e){return e("/api/core/images/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Flavors",["$resource",function(e){return e("/api/core/flavors/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Example-Services-Collection",["$resource",function(e){return e("/api/service/exampleservice/")}])}(),function(){angular.module("xos.helpers").service("Deployments",["$resource",function(e){return e("/api/core/deployments/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Dashboards",["$resource","$q","$http",function(e,n,i){var o=e("/api/core/dashboardviews/:id/",{id:"@id"},{update:{method:"PUT"}});return o.prototype.$save=function(){var e=n.defer();return i.put("/api/core/dashboardviews/"+this.id+"/",this).then(function(n){e.resolve(n.data)})["catch"](function(n){e.reject(n.data)}),e.promise},o}])}(),function(){angular.module("xos.helpers").service("XosUserPrefs",["$cookies","Me","$q",function(e,n,i){var o=this,t=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{};this.getAll=function(){return t=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{}},this.setAll=function(n){e.put("xosUserPrefs",angular.toJson(n))},this.getSynchronizerNotificationStatus=function(){var e=!(arguments.length<=0||void 0===arguments[0])&&arguments[0];return e?o.getAll().synchronizers.notification[e]:o.getAll().synchronizers.notification},this.getUserDetailsCookie=function(){var e=i.defer(),n=o.getAll();return n.userData?e.resolve(n.userData):o.setUserDetailsCookie().$promise.then(function(n){
+"use strict";function _toConsumableArray(e){if(Array.isArray(e)){for(var n=0,i=Array(e.length);n<e.length;n++)i[n]=e[n];return i}return Array.from(e)}!function(){angular.module("xos.uiComponents",["chart.js","RecursionHelper","dndLists"])}(),function(){angular.module("xos.uiComponents").component("xosSmartPie",{restrict:"E",bindings:{config:"="},template:'\n      <canvas\n        class="chart chart-pie {{vm.config.classes}}"\n        chart-data="vm.data" chart-labels="vm.labels"\n        chart-legend="{{vm.config.legend}}">\n      </canvas>\n    ',bindToController:!0,controllerAs:"vm",controller:["$injector","$interval","$scope","$timeout","_",function(e,n,i,o,t){var r=this;if(!this.config.resource&&!this.config.data)throw new Error("[xosSmartPie] Please provide a resource or an array of data in the configuration");var a=function(e){return t.groupBy(e,r.config.groupBy)},s=function(e){return t.reduce(Object.keys(e),function(n,i){return n.concat(e[i].length)},[])},l=function(e){return angular.isFunction(r.config.labelFormatter)?r.config.labelFormatter(Object.keys(e)):Object.keys(e)},c=function(e){var n=a(e);r.data=s(n),r.labels=l(n)};this.config.resource?!function(){r.Resource=e.get(r.config.resource);var i=function(){r.Resource.query().$promise.then(function(e){e[0]&&c(e)})};i(),r.config.poll&&n(function(){i()},1e3*r.config.poll)}():i.$watch(function(){return r.config.data},function(e){e&&c(r.config.data)},!0),i.$on("create",function(e,n){console.log("create: "+n.id)}),i.$on("destroy",function(e,n){console.log("destroy: "+n.id)})}]})}(),function(){angular.module("xos.uiComponents").component("xosSmartTable",{restrict:"E",bindings:{config:"="},template:'\n        <div class="row" ng-show="vm.data.length > 0">\n          <div class="col-xs-12 text-right">\n            <a href="" class="btn btn-success" ng-click="vm.createItem()">\n              Add\n            </a>\n          </div>\n        </div>\n        <div class="row">\n          <div class="col-xs-12 table-responsive">\n            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n          </div>\n        </div>\n        <div class="panel panel-default" ng-show="vm.detailedItem">\n          <div class="panel-heading">\n            <div class="row">\n              <div class="col-xs-11">\n                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n              </div>\n              <div class="col-xs-1">\n                <a href="" ng-click="vm.cleanForm()">\n                  <i class="glyphicon glyphicon-remove pull-right"></i>\n                </a>\n              </div>\n            </div>\n          </div>\n          <div class="panel-body">\n            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n          </div>\n        </div>\n        <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n        <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n      ',bindToController:!0,controllerAs:"vm",controller:["$injector","LabelFormatter","_","XosFormHelpers",function(e,n,i,o){var t=this;this.responseMsg=!1,this.responseErr=!1,this.tableConfig={columns:[],actions:[{label:"delete",icon:"remove",cb:function(e){t.Resource["delete"]({id:e.id}).$promise.then(function(){i.remove(t.data,function(n){return n.id===e.id}),t.responseMsg=t.config.resource+" with id "+e.id+" successfully deleted"})["catch"](function(n){t.responseErr=n.data.detail||"Error while deleting "+t.config.resource+" with id "+e.id})},color:"red"},{label:"details",icon:"search",cb:function(e){t.detailedItem=e}}],classes:"table table-striped table-bordered table-responsive",filter:"field",order:!0,pagination:{pageSize:10}},this.formConfig={exclude:this.config.hiddenFields,fields:{},formName:this.config.resource+"Form",actions:[{label:"Save",icon:"ok",cb:function(e){var n=void 0,i=!0;e.id?(n=e.$update(),i=!1):n=e.$save(),n.then(function(n){i&&t.data.push(angular.copy(n)),delete t.detailedItem,t.responseMsg=t.config.resource+" with id "+e.id+" successfully saved"})["catch"](function(n){t.responseErr=n.data.detail||"Error while saving "+t.config.resource+" with id "+e.id})},"class":"success"}]},this.cleanForm=function(){delete t.detailedItem},this.createItem=function(){t.detailedItem=new t.Resource},this.Resource=e.get(this.config.resource);var r=function(){t.Resource.query().$promise.then(function(e){if(!e[0])return void(t.data=e);var r=e[0],a=Object.keys(r);i.remove(a,function(e){return"id"===e||"validators"===e}),angular.isArray(t.config.hiddenFields)&&(a=i.difference(a,t.config.hiddenFields)),a.forEach(function(e){var i={label:n.format(e),prop:e};i.type=o._getFieldFormat(r[e]),t.tableConfig.columns.push(i)}),a.forEach(function(e){t.formConfig.fields[e]={label:n.format(e).replace(":",""),type:o._getFieldFormat(r[e])}}),t.data=e})};r()}]})}(),function(){angular.module("xos.uiComponents").component("xosValidation",{restrict:"E",bindings:{field:"=",form:"="},template:'\n      <div ng-cloak>\n        <xos-alert config="vm.config" show="vm.field.$error.required !== undefined && vm.field.$error.required !== false  && (vm.field.$touched || vm.form.$submitted)">\n          Field required\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.email !== undefined && vm.field.$error.email !== false && (vm.field.$touched || vm.form.$submitted)">\n          This is not a valid email\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.minlength !== undefined && vm.field.$error.minlength !== false && (vm.field.$touched || vm.form.$submitted)">\n          Too short\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.maxlength !== undefined && vm.field.$error.maxlength !== false && (vm.field.$touched || vm.form.$submitted)">\n          Too long\n        </xos-alert>\n        <xos-alert config="vm.config" show="vm.field.$error.custom !== undefined && vm.field.$error.custom !== false && (vm.field.$touched || vm.form.$submitted)">\n          Field invalid\n        </xos-alert>\n      </div>\n    ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:function(){this.config={type:"danger"}}})}(),function(){angular.module("xos.uiComponents").component("xosForm",{restrict:"E",bindings:{config:"=",ngModel:"="},template:'\n      <form name="vm.{{vm.config.formName || \'form\'}}" novalidate>\n        <div class="form-group" ng-repeat="(name, field) in vm.formField">\n          <xos-field name="name" field="field" ng-model="vm.ngModel[name]"></xos-field>\n          <xos-validation field="vm[vm.config.formName || \'form\'][name]" form = "vm[vm.config.formName || \'form\']"></xos-validation>\n          <div class="alert alert-info" ng-show="(field.hint).length >0" role="alert">{{field.hint}}</div>\n        </div>\n        <div class="form-group" ng-if="vm.config.actions">\n        <xos-alert config="vm.config.feedback" show="vm.config.feedback.show">{{vm.config.feedback.message}}</xos-alert>\n\n          <button role="button" href=""\n            ng-repeat="action in vm.config.actions"\n            ng-click="action.cb(vm.ngModel, vm[vm.config.formName || \'form\'])"\n            class="btn btn-{{action.class}}"\n            title="{{action.label}}">\n            <i class="glyphicon glyphicon-{{action.icon}}"></i>\n            {{action.label}}\n          </button>\n        </div>\n      </form>\n    ',bindToController:!0,controllerAs:"vm",controller:["$scope","$log","_","XosFormHelpers",function(e,n,i,o){var t=this;if(!this.config)throw new Error('[xosForm] Please provide a configuration via the "config" attribute');if(!this.config.actions)throw new Error("[xosForm] Please provide an action list in the configuration");this.config.feedback||(this.config.feedback={show:!1,message:"Form submitted successfully !!!",type:"success"}),this.excludedField=["id","validators","created","updated","deleted","backend_status"],this.config&&this.config.exclude&&(this.excludedField=this.excludedField.concat(this.config.exclude)),this.formField=[],e.$watch(function(){return t.config},function(){if(t.ngModel){var e=i.difference(Object.keys(t.ngModel),t.excludedField),n=o.parseModelField(e);t.formField=o.buildFormStructure(n,t.config.fields,t.ngModel)}},!0),e.$watch(function(){return t.ngModel},function(e){if(t.formField={},e){var n=i.difference(Object.keys(e),t.excludedField),r=o.parseModelField(n);t.formField=o.buildFormStructure(r,t.config.fields,e)}})}]})}(),function(){angular.module("xos.uiComponents").component("xosPagination",{restrict:"E",bindings:{pageSize:"=",totalElements:"=",change:"="},template:'\n      <div class="row" ng-if="vm.pageList.length > 1">\n        <div class="col-xs-12 text-center">\n          <ul class="pagination">\n            <li\n              ng-click="vm.goToPage(vm.currentPage - 1)"\n              ng-class="{disabled: vm.currentPage == 0}">\n              <a href="" aria-label="Previous">\n                  <span aria-hidden="true">&laquo;</span>\n              </a>\n            </li>\n            <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n              <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n            </li>\n            <li\n              ng-click="vm.goToPage(vm.currentPage + 1)"\n              ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n              <a href="" aria-label="Next">\n                  <span aria-hidden="true">&raquo;</span>\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n    ',bindToController:!0,controllerAs:"vm",controller:["$scope",function(e){var n=this;this.currentPage=0,this.goToPage=function(e){e<0||e===n.pages||(n.currentPage=e,n.change(e))},this.createPages=function(e){for(var n=[],i=0;i<e;i++)n.push(i);return n},e.$watch(function(){return n.totalElements},function(){n.totalElements&&(n.pages=Math.ceil(n.totalElements/n.pageSize),n.pageList=n.createPages(n.pages))})}]}).filter("pagination",function(){return function(e,n){return e&&angular.isArray(e)?(n=parseInt(n,10),e.slice(n)):e}})}(),function(){angular.module("xos.uiComponents").component("xosField",{restrict:"E",bindings:{name:"=",field:"=",ngModel:"="},template:'\n      <label ng-if="vm.field.type !== \'object\' && vm.field.type !== \'array\'">{{vm.field.label}}</label>\n      <input\n        xos-custom-validator custom-validator="vm.field.validators.custom || null"\n        ng-if="vm.field.type !== \'boolean\' && vm.field.type !== \'object\' && vm.field.type !== \'select\' && vm.field.type !== \'array\'"\n        type="{{vm.field.type}}"\n        name="{{vm.name}}"\n        class="form-control"\n        ng-model="vm.ngModel"\n        ng-minlength="vm.field.validators.minlength || 0"\n        ng-maxlength="vm.field.validators.maxlength || 2000"\n        ng-required="vm.field.validators.required || false" />\n        <select class="form-control" ng-if ="vm.field.type === \'select\'"\n          name = "{{vm.name}}"\n          ng-options="item.id as item.label for item in vm.field.options"\n          ng-model="vm.ngModel"\n          ng-required="vm.field.validators.required || false">\n          </select>\n      <span class="boolean-field" ng-if="vm.field.type === \'boolean\'">\n        <a href="#"\n          class="btn btn-success"\n          ng-show="vm.ngModel"\n          ng-click="vm.ngModel = false">\n          <i class="glyphicon glyphicon-ok"></i>\n        </a>\n        <a href="#"\n          class="btn btn-danger"\n          ng-show="!vm.ngModel"\n          ng-click="vm.ngModel = true">\n          <i class="glyphicon glyphicon-remove"></i>\n        </a>\n      </span>\n      <div\n        class="panel panel-default object-field"\n        ng-if="vm.field.type == \'object\' && (!vm.isEmptyObject(vm.ngModel) || !vm.isEmptyObject(vm.field.properties))"\n        >\n        <div class="panel-heading">{{vm.field.label}}</div>\n        <div class="panel-body">\n          <div ng-if="!vm.field.properties" ng-repeat="(k, v) in vm.ngModel">\n            <xos-field\n              name="k"\n              field="{label: vm.formatLabel(k), type: vm.getType(v)}"\n              ng-model="v">\n            </xos-field>\n          </div>\n          <div ng-if="vm.field.properties" ng-repeat="(k, v) in vm.field.properties">\n            <xos-field\n              name="k"\n              field="{\n                label: v.label || vm.formatLabel(k),\n                type: v.type,\n                validators: v.validators\n              }"\n              ng-model="vm.ngModel[k]">\n            </xos-field>\n          </div>\n        </div>\n      </div>\n      <div\n        class="panel panel-default array-field"\n        ng-if="vm.field.type == \'array\'">\n        <div class="panel-heading">{{vm.field.label}}</div>\n        <div class="panel-body selected">\n          <ul class="draggable" dnd-list="vm.ngModel">\n            <li\n              class="array-element"\n              ng-repeat="item in vm.ngModel"\n              dnd-draggable="item"\n              dnd-moved="vm.ngModel.splice($index, 1)"\n              dnd-effect-allowed="move"\n              dnd-selected="models.selected = item"\n              >\n              <div class="well well-sm text-center">\n                {{item}}\n              </div>\n            </li>\n            <div class="clearfix"></div>\n          </ul>\n        </div>\n        <div class="panel-body unselected">\n          <ul class="draggable" dnd-list="vm.field.availableOptions">\n            <li\n              class="array-element"\n              ng-repeat="item in vm.field.availableOptions"\n              dnd-draggable="item"\n              dnd-moved="vm.field.availableOptions.splice($index, 1)"\n              dnd-effect-allowed="move"\n              dnd-selected="models.selected = item"\n              >\n              <div class="well well-sm text-center">\n                {{item}}\n              </div>\n            </li>\n            <div class="clearfix"></div>\n          </ul>\n        </div>\n      </div>\n    ',bindToController:!0,controllerAs:"vm",controller:["$attrs","$scope","XosFormHelpers","LabelFormatter","_",function(e,n,i,o,t){var r=this;if(!this.name)throw new Error("[xosField] Please provide a field name");if(!this.field)throw new Error("[xosField] Please provide a field definition");if(!this.field.type)throw new Error("[xosField] Please provide a type in the field definition");if(!e.ngModel)throw new Error("[xosField] Please provide an ng-model");this.getType=i._getFieldFormat,this.formatLabel=o.format,this.isEmptyObject=function(e){return!e||0===Object.keys(e).length},"array"===this.field.type&&n.$watch(function(){return r.ngModel.length},function(){r.field.availableOptions=t.difference(r.field.options,r.ngModel)})}]}).directive("xosCustomValidator",function(){return{restrict:"A",scope:{fn:"=customValidator"},require:"ngModel",link:function(e,n,i,o){function t(n){var i=e.fn(n);return angular.isArray(i)?o.$setValidity.apply(o,_toConsumableArray(i)):o.$setValidity("custom",i),n}angular.isFunction(e.fn)&&o.$parsers.push(t)}}})}(),function(){angular.module("xos.uiComponents").component("xosTable",{restrict:"E",bindings:{data:"=",config:"="},template:'\n        <div ng-show="vm.data.length > 0 && vm.loader == false">\n          <div class="row" ng-if="vm.config.filter == \'fulltext\'">\n            <div class="col-xs-12">\n              <input\n                class="form-control"\n                placeholder="Type to search.."\n                type="text"\n                ng-model="vm.query"/>\n            </div>\n          </div>\n          <table ng-class="vm.classes" ng-hide="vm.data.length == 0">\n            <thead>\n              <tr>\n                <th ng-repeat="col in vm.columns">\n                  {{col.label}}\n                  <span ng-if="vm.config.order">\n                    <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = false">\n                      <i class="glyphicon glyphicon-chevron-up"></i>\n                    </a>\n                    <a href="" ng-click="vm.orderBy = col.prop; vm.reverse = true">\n                      <i class="glyphicon glyphicon-chevron-down"></i>\n                    </a>\n                  </span>\n                </th>\n                <th ng-if="vm.config.actions">Actions:</th>\n              </tr>\n            </thead>\n            <tbody ng-if="vm.config.filter == \'field\'">\n              <tr>\n                <td ng-repeat="col in vm.columns">\n                  <input\n                    ng-if="col.type !== \'boolean\' && col.type !== \'array\' && col.type !== \'object\' && col.type !== \'custom\'"\n                    class="form-control"\n                    placeholder="Type to search by {{col.label}}"\n                    type="text"\n                    ng-model="vm.query[col.prop]"/>\n                  <select\n                    ng-if="col.type === \'boolean\'"\n                    class="form-control"\n                    ng-model="vm.query[col.prop]">\n                    <option value="">-</option>\n                    <option value="true">True</option>\n                    <option value="false">False</option>\n                  </select>\n                </td>\n                <td ng-if="vm.config.actions"></td>\n              </tr>\n            </tbody>\n            <tbody>\n              <tr ng-repeat="item in vm.data | filter:vm.query:vm.comparator | orderBy:vm.orderBy:vm.reverse | pagination:vm.currentPage * vm.config.pagination.pageSize | limitTo: (vm.config.pagination.pageSize || vm.data.length) track by $index">\n                <td ng-repeat="col in vm.columns" xos-link-wrapper>\n                  <span ng-if="!col.type || col.type === \'text\'">{{item[col.prop]}}</span>\n                  <span ng-if="col.type === \'boolean\'">\n                    <i class="glyphicon"\n                      ng-class="{\'glyphicon-ok\': item[col.prop], \'glyphicon-remove\': !item[col.prop]}">\n                    </i>\n                  </span>\n                  <span ng-if="col.type === \'date\'">\n                    {{item[col.prop] | date:\'H:mm MMM d, yyyy\'}}\n                  </span>\n                  <span ng-if="col.type === \'array\'">\n                    {{item[col.prop] | arrayToList}}\n                  </span>\n                  <span ng-if="col.type === \'object\'">\n                    <dl class="dl-horizontal">\n                      <span ng-repeat="(k,v) in item[col.prop]">\n                        <dt>{{k}}</dt>\n                        <dd>{{v}}</dd>\n                      </span>\n                    </dl>\n                  </span>\n                  <span ng-if="col.type === \'custom\'">\n                    {{col.formatter(item)}}\n                  </span>\n                  <span ng-if="col.type === \'icon\'">\n                    <i class="glyphicon glyphicon-{{col.formatter(item)}}">\n                    </i>\n                  </span>\n                </td>\n                <td ng-if="vm.config.actions">\n                  <a href=""\n                    ng-repeat="action in vm.config.actions"\n                    ng-click="action.cb(item)"\n                    title="{{action.label}}">\n                    <i\n                      class="glyphicon glyphicon-{{action.icon}}"\n                      style="color: {{action.color}};"></i>\n                  </a>\n                </td>\n              </tr>\n            </tbody>\n          </table>\n          <xos-pagination\n            ng-if="vm.config.pagination"\n            page-size="vm.config.pagination.pageSize"\n            total-elements="vm.data.length"\n            change="vm.goToPage">\n            </xos-pagination>\n        </div>\n        <div ng-show="(vm.data.length == 0 || !vm.data) && vm.loader == false">\n           <xos-alert config="{type: \'info\'}">\n            No data to show.\n          </xos-alert>\n        </div>\n        <div ng-show="vm.loader == true">\n          <div class="loader"></div>\n        </div>\n      ',bindToController:!0,controllerAs:"vm",controller:["_","$scope","Comparator",function(e,n,i){var o=this;if(this.comparator=i,this.loader=!0,n.$watch(function(){return o.data},function(e){angular.isDefined(e)&&(o.loader=!1)}),!this.config)throw new Error('[xosTable] Please provide a configuration via the "config" attribute');if(!this.config.columns)throw new Error("[xosTable] Please provide a columns list in the configuration");this.config.order&&angular.isObject(this.config.order)&&(this.reverse=this.config.order.reverse||!1,this.orderBy=this.config.order.field||"id");var t=e.filter(this.config.columns,{type:"custom"});angular.isArray(t)&&t.length>0&&e.forEach(t,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided a custom field type, a formatter function should provided too.")});var r=e.filter(this.config.columns,{type:"icon"});angular.isArray(r)&&r.length>0&&e.forEach(r,function(e){if(!e.formatter||!angular.isFunction(e.formatter))throw new Error("[xosTable] You have provided an icon field type, a formatter function should provided too.")});var a=e.filter(this.config.columns,function(e){return angular.isDefined(e.link)});angular.isArray(a)&&a.length>0&&e.forEach(a,function(e){if(!angular.isFunction(e.link))throw new Error("[xosTable] The link property should be a function.")}),this.columns=this.config.columns,this.classes=this.config.classes||"table table-striped table-bordered",this.config.actions,this.config.pagination&&(this.currentPage=0,this.goToPage=function(e){o.currentPage=e})}]}).filter("arrayToList",function(){return function(e){return angular.isArray(e)?e.join(", "):e}}).directive("xosLinkWrapper",function(){return{restrict:"A",transclude:!0,template:'\n          <a ng-if="col.link" href="{{col.link(item)}}">\n            <div ng-transclude></div>\n          </a>\n          <div ng-transclude ng-if="!col.link"></div>\n        '}})}(),function(){angular.module("xos.uiComponents").component("xosAlert",{restrict:"E",bindings:{config:"=",show:"=?"},template:'\n      <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n        <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n          <span aria-hidden="true">&times;</span>\n        </button>\n        <p ng-transclude></p>\n      </div>\n    ',transclude:!0,bindToController:!0,controllerAs:"vm",controller:["$timeout",function(e){var n=this;if(!this.config)throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');this.show=this.show!==!1,this.dismiss=function(){n.show=!1},this.config.autoHide&&!function(){var i=e(function(){n.dismiss(),e.cancel(i)},n.config.autoHide)}()}]})}(),function(){function e(){var e=function(e){return e.split("_").join(" ").trim()},n=function(e){return e.split(/(?=[A-Z])/).map(function(e){return e.toLowerCase()}).join(" ")},i=function(e){return e.slice(0,1).toUpperCase()+e.slice(1)},o=function(o){return o=e(o),o=n(o),o=i(o).replace(/\s\s+/g," ")+":",o.replace("::",":")};return{_formatByUnderscore:e,_formatByUppercase:n,_capitalize:i,format:o}}angular.module("xos.uiComponents").factory("LabelFormatter",e)}();var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(){angular.module("xos.uiComponents").service("XosFormHelpers",["_","LabelFormatter",function(e,n){var i=this;this._isEmail=function(e){var n=/(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/;return n.test(e)},this._getFieldFormat=function(e){return angular.isArray(e)?"array":angular.isDate(e)||!Number.isNaN(Date.parse(e))&&/^\d+-\d+-\d+\D\d+:\d+:\d+\.\d+\D/.test(e)?"date":"boolean"==typeof e?"boolean":i._isEmail(e)?"email":angular.isString(e)||null===e?"text":"undefined"==typeof e?"undefined":_typeof(e)},this.buildFormStructure=function(o,t,r){return o=angular.extend(o,t),t=t||{},e.reduce(Object.keys(o),function(e,o){return e[o]={label:t[o]&&t[o].label?t[o].label+":":n.format(o),type:t[o]&&t[o].type?t[o].type:i._getFieldFormat(r[o]),validators:t[o]&&t[o].validators?t[o].validators:{},hint:t[o]&&t[o].hint?t[o].hint:""},t[o]&&t[o].options&&(e[o].options=t[o].options),t[o]&&t[o].properties&&(e[o].properties=t[o].properties),"date"===e[o].type&&(r[o]=new Date(r[o])),"number"===e[o].type&&(r[o]=parseInt(r[o],10)),e},{})},this.parseModelField=function(n){return e.reduce(n,function(e,n){return e[n]={},e},{})}}])}(),function(){function e(e){return function(n,i){if(angular.isUndefined(n))return!1;if(null===n||null===i)return n===i;if(angular.isObject(i)||angular.isObject(n))return angular.equals(i,n);if(e.isBoolean(n)||e.isBoolean(i))return 0!==n&&1!==n||(n=!!n),angular.equals(i,n);if(!angular.isString(n)||!angular.isString(i)){if(!angular.isDefined(n.toString)||!angular.isDefined(i.toString))return n===i;n=n.toString(),i=i.toString()}return n=n.toLowerCase()+"",i=i.toLowerCase()+"",n.indexOf(i)!==-1}}e.$inject=["_"],angular.module("xos.uiComponents").factory("Comparator",e)}(),function(){function e(e,n,i){e.interceptors.push("SetCSRFToken"),i.defaults.stripTrailingSlashes=!1}e.$inject=["$httpProvider","$interpolateProvider","$resourceProvider"],angular.module("xos.helpers",["ngCookies","ngResource","ngAnimate","xos.uiComponents"]).config(e).factory("_",["$window",function(e){return e._}])}(),function(){angular.module("xos.helpers").service("vSG-Collection",["$resource",function(e){return e("/api/service/vsg/")}])}(),function(){angular.module("xos.helpers").service("vOLT-Collection",["$resource",function(e){return e("/api/tenant/cord/volt/:volt_id/",{volt_id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Login",["$resource",function(e){return e("/api/utility/login/")}]).service("Logout",["$resource",function(e){return e("/api/utility/logout/")}])}(),function(){angular.module("xos.helpers").service("Users",["$resource",function(e){return e("/api/core/users/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Truckroll",["$resource",function(e){return e("/api/tenant/truckroll/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Tenants",["$resource",function(e){return e("/api/core/tenants/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Subscribers",["$resource",function(e){return e("/api/tenant/cord/subscriber/:id/",{id:"@id"},{update:{method:"PUT"},"View-a-Subscriber-Features-Detail":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/"},"Read-Subscriber-uplink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Update-Subscriber-uplink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uplink_speed/"},"Read-Subscriber-downlink_speed":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Update-Subscriber-downlink_speed":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/downlink_speed/"},"Read-Subscriber-cdn":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Update-Subscriber-cdn":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/cdn/"},"Read-Subscriber-uverse":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Update-Subscriber-uverse":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/uverse/"},"Read-Subscriber-status":{method:"GET",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"},"Update-Subscriber-status":{method:"PUT",isArray:!1,url:"/api/tenant/cord/subscriber/:id/features/status/"}})}])}(),function(){angular.module("xos.helpers").service("SlicesPlus",["$http","$q",function(e,n){this.query=function(i){var o=n.defer();return e.get("/api/utility/slicesplus/",{params:i}).then(function(e){o.resolve(e.data)})["catch"](function(e){o.reject(e.data)}),{$promise:o.promise}},this.get=function(i,o){var t=n.defer();return e.get("/api/utility/slicesplus/"+i,{params:o}).then(function(e){t.resolve(e.data)})["catch"](function(e){t.reject(e.data)}),{$promise:t.promise}}}])}(),function(){angular.module("xos.helpers").service("Slices",["$resource",function(e){return e("/api/core/slices/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Sites",["$resource",function(e){return e("/api/core/sites/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Services",["$resource",function(e){return e("/api/core/services/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("ONOS-Services-Collection",["$resource",function(e){return e("/api/service/onos/")}])}(),function(){angular.module("xos.helpers").service("ONOS-App-Collection",["$resource",function(e){return e("/api/tenant/onos/app/")}])}(),function(){angular.module("xos.helpers").service("Nodes",["$resource",function(e){return e("/api/core/nodes/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networkstemplates",["$resource",function(e){return e("/api/core/networktemplates/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Networks",["$resource",function(e){return e("/api/core/networks/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Me",["$q","$http",function(e,n){this.get=function(){var i=e.defer();return n.get("/api/utility/me/").then(function(e){i.resolve(e.data)})["catch"](function(e){i.reject(e)}),i.promise}}])}(),function(){angular.module("xos.helpers").service("Instances",["$resource",function(e){return e("/api/core/instances/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Images",["$resource",function(e){return e("/api/core/images/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Flavors",["$resource",function(e){return e("/api/core/flavors/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Example-Services-Collection",["$resource",function(e){return e("/api/service/exampleservice/")}])}(),function(){angular.module("xos.helpers").service("Deployments",["$resource",function(e){return e("/api/core/deployments/:id/",{id:"@id"},{update:{method:"PUT"}})}])}(),function(){angular.module("xos.helpers").service("Dashboards",["$resource","$q","$http",function(e,n,i){var o=e("/api/core/dashboardviews/:id/",{id:"@id"},{update:{method:"PUT"}});return o.prototype.$save=function(){var e=n.defer();return i.put("/api/core/dashboardviews/"+this.id+"/",this).then(function(n){e.resolve(n.data)})["catch"](function(n){e.reject(n.data)}),e.promise},o}])}(),function(){angular.module("xos.helpers").service("XosUserPrefs",["$cookies","Me","$q",function(e,n,i){var o=this,t=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{};this.getAll=function(){return t=e.get("xosUserPrefs")?angular.fromJson(e.get("xosUserPrefs")):{}},this.setAll=function(n){e.put("xosUserPrefs",angular.toJson(n))},this.getSynchronizerNotificationStatus=function(){var e=!(arguments.length<=0||void 0===arguments[0])&&arguments[0];return e?o.getAll().synchronizers.notification[e]:o.getAll().synchronizers.notification},this.getUserDetailsCookie=function(){var e=i.defer(),n=o.getAll();return n.userData?e.resolve(n.userData):o.setUserDetailsCookie().$promise.then(function(n){
 e.resolve(n)}),{$promise:e.promise}},this.setUserDetailsCookie=function(){var e=arguments.length<=0||void 0===arguments[0]?null:arguments[0],t=i.defer(),r=o.getAll();return e?(r.userData=e,o.setAll(r),t.resolve(e)):n.get().then(function(e){r.userData=e,o.setAll(r),t.resolve(e)})["catch"](function(e){t.reject(e)}),{$promise:t.promise}},this.setSynchronizerNotificationStatus=function(){var e=!(arguments.length<=0||void 0===arguments[0])&&arguments[0],n=arguments[1];if(!e)throw new Error("[XosUserPrefs] When updating a synchronizer is mandatory to provide a name.");var i=o.getAll();i.synchronizers||(i.synchronizers={notification:{}}),i.synchronizers.notification[e]=n,o.setAll(i)}}])}(),function(){angular.module("xos.helpers").service("GraphService",["$q","Tenants","Services",function(e,n,i){var o=this;this.loadCoarseData=function(){var o=void 0,t=e.defer();return i.query().$promise.then(function(e){return o=e,n.query({kind:"coarse"}).$promise}).then(function(e){t.resolve({tenants:e,services:o})}),t.promise},this.getCoarseGraph=function(){return o.loadCoarseData().then(function(e){console.log(e)}),"ciao"}}])}(),function(){angular.module("xos.helpers").factory("Notification",function(){return window.Notification}).service("xosNotification",["$q","$log","Notification",function(e,n,i){var o=this;this.checkPermission=function(){var n=e.defer();return i.requestPermission().then(function(e){"granted"===e?n.resolve(e):n.reject(e)}),n.promise},this.sendNotification=function(e,o){var t=new i(e,o);t.onerror=function(e){n.error(e)}},this.notify=function(e,t){"Notification"in window?"granted"!==i.permission?o.checkPermission().then(function(){return o.sendNotification(e,t)}):"granted"===i.permission&&o.sendNotification(e,t):n.info("This browser does not support desktop notification")}}])}(),function(){function e(){return{request:function(e){return e.url.indexOf(".html")===-1&&(e.url+="?no_hyperlinks=1"),e}}}angular.module("xos.helpers").factory("NoHyperlinks",e)}(),angular.module("xos.helpers").config(["$provide",function(e){e.decorator("$log",["$delegate",function(e){var n=function(){return window.location.href.indexOf("debug=true")>=0},i=e.log,o=e.info,t=e.warn,r=e.debug,a=function(i){return function(){if(n()){var o=[].slice.call(arguments),t=new Date;return o[0]="["+t.getHours()+":"+t.getMinutes()+":"+t.getSeconds()+"] "+o[0],!angular.isFunction(e.reset)||e.debug.logs instanceof Array||e.reset(),i.apply(null,o)}}};return e.info=a(o),e.log=a(i),e.warn=a(t),e.debug=a(r),e}])}]),function(){function e(e){return{request:function(n){return"GET"!==n.method&&(n.headers["X-CSRFToken"]=e.get("xoscsrftoken")),n}}}e.$inject=["$cookies"],angular.module("xos.helpers").factory("SetCSRFToken",e)}();
\ No newline at end of file
diff --git a/dist/xosUiComponents.js b/dist/xosUiComponents.js
index e6b9709..80de789 100644
--- a/dist/xosUiComponents.js
+++ b/dist/xosUiComponents.js
@@ -28,8 +28,470 @@
 
   angular.module('xos.uiComponents', ['chart.js', 'RecursionHelper', 'dndLists']);
 })();
-//# sourceMappingURL=../maps/ui_components/ui-components.module.js.map
+'use strict';
 
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 3/24/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+
+  /**
+  * @ngdoc directive
+  * @name xos.uiComponents.directive:xosSmartTable
+  * @link xos.uiComponents.directive:xosTable xosTable
+  * @link xos.uiComponents.directive:xosForm xosForm
+  * @restrict E
+  * @description The xos-table directive
+  * @param {Object} config The configuration for the component,
+  * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
+  * and an array of fields that shouldn't be printed.
+  * ```
+  * {
+      resource: 'Users',
+      hiddenFields: []
+    }
+  * ```
+  * @scope
+  * @example
+   <example module="sampleSmartTable">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl as vm">
+        <xos-smart-table config="vm.config"></xos-smart-table>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleSmartTable', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
+      // This is only for documentation purpose
+      .run(function($httpBackend, _){
+        let datas = [{id: 1, name: 'Jhon', surname: 'Doe'}];
+        let count = 1;
+         let paramsUrl = new RegExp(/\/test\/(.+)/);
+         $httpBackend.whenDELETE(paramsUrl, undefined, ['id']).respond((method, url, data, headers, params) => {
+          data = angular.fromJson(data);
+          let id = url.match(paramsUrl)[1];
+          _.remove(datas, (d) => {
+            return d.id === parseInt(id);
+          })
+          return [204];
+        });
+         $httpBackend.whenGET('/test').respond(200, datas)
+        $httpBackend.whenPOST('/test').respond((method, url, data) => {
+          data = angular.fromJson(data);
+          data.id = ++count;
+          datas.push(data);
+          return [201, data, {}];
+        });
+      })
+      .factory('_', function($window){
+        return $window._;
+      })
+      .service('SampleResource', function($resource){
+        return $resource('/test/:id', {id: '@id'});
+      })
+      // End of documentation purpose, example start
+      .controller('SampleCtrl', function(){
+        this.config = {
+          resource: 'SampleResource'
+        };
+      });
+    </file>
+  </example>
+  */
+
+  .component('xosSmartTable', {
+    restrict: 'E',
+    bindings: {
+      config: '='
+    },
+    template: '\n        <div class="row" ng-show="vm.data.length > 0">\n          <div class="col-xs-12 text-right">\n            <a href="" class="btn btn-success" ng-click="vm.createItem()">\n              Add\n            </a>\n          </div>\n        </div>\n        <div class="row">\n          <div class="col-xs-12 table-responsive">\n            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n          </div>\n        </div>\n        <div class="panel panel-default" ng-show="vm.detailedItem">\n          <div class="panel-heading">\n            <div class="row">\n              <div class="col-xs-11">\n                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n              </div>\n              <div class="col-xs-1">\n                <a href="" ng-click="vm.cleanForm()">\n                  <i class="glyphicon glyphicon-remove pull-right"></i>\n                </a>\n              </div>\n            </div>\n          </div>\n          <div class="panel-body">\n            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n          </div>\n        </div>\n        <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n        <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n      ',
+    bindToController: true,
+    controllerAs: 'vm',
+    controller: ["$injector", "LabelFormatter", "_", "XosFormHelpers", function controller($injector, LabelFormatter, _, XosFormHelpers) {
+      var _this = this;
+
+      // TODO
+      // - Validate the config (what if resource does not exist?)
+
+      // NOTE
+      // Corner case
+      // - if response is empty, how can we generate a form ?
+
+      this.responseMsg = false;
+      this.responseErr = false;
+
+      this.tableConfig = {
+        columns: [],
+        actions: [{
+          label: 'delete',
+          icon: 'remove',
+          cb: function cb(item) {
+            _this.Resource.delete({ id: item.id }).$promise.then(function () {
+              _.remove(_this.data, function (d) {
+                return d.id === item.id;
+              });
+              _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully deleted';
+            }).catch(function (err) {
+              _this.responseErr = err.data.detail || 'Error while deleting ' + _this.config.resource + ' with id ' + item.id;
+            });
+          },
+          color: 'red'
+        }, {
+          label: 'details',
+          icon: 'search',
+          cb: function cb(item) {
+            _this.detailedItem = item;
+          }
+        }],
+        classes: 'table table-striped table-bordered table-responsive',
+        filter: 'field',
+        order: true,
+        pagination: {
+          pageSize: 10
+        }
+      };
+
+      this.formConfig = {
+        exclude: this.config.hiddenFields,
+        fields: {},
+        formName: this.config.resource + 'Form',
+        actions: [{
+          label: 'Save',
+          icon: 'ok',
+          cb: function cb(item) {
+            var p = void 0;
+            var isNew = true;
+
+            if (item.id) {
+              p = item.$update();
+              isNew = false;
+            } else {
+              p = item.$save();
+            }
+
+            p.then(function (res) {
+              if (isNew) {
+                _this.data.push(angular.copy(res));
+              }
+              delete _this.detailedItem;
+              _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully saved';
+            }).catch(function (err) {
+              _this.responseErr = err.data.detail || 'Error while saving ' + _this.config.resource + ' with id ' + item.id;
+            });
+          },
+          class: 'success'
+        }]
+      };
+
+      this.cleanForm = function () {
+        delete _this.detailedItem;
+      };
+
+      this.createItem = function () {
+        _this.detailedItem = new _this.Resource();
+      };
+
+      this.Resource = $injector.get(this.config.resource);
+
+      var getData = function getData() {
+        _this.Resource.query().$promise.then(function (res) {
+
+          if (!res[0]) {
+            _this.data = res;
+            return;
+          }
+
+          var item = res[0];
+          var props = Object.keys(item);
+
+          _.remove(props, function (p) {
+            return p === 'id' || p === 'validators';
+          });
+
+          // TODO move out cb,  non sense triggering a lot of times
+          if (angular.isArray(_this.config.hiddenFields)) {
+            props = _.difference(props, _this.config.hiddenFields);
+          }
+
+          props.forEach(function (p) {
+            var fieldConfig = {
+              label: LabelFormatter.format(p),
+              prop: p
+            };
+
+            fieldConfig.type = XosFormHelpers._getFieldFormat(item[p]);
+
+            _this.tableConfig.columns.push(fieldConfig);
+          });
+
+          // build form structure
+          // TODO move in a pure function for testing purposes
+          props.forEach(function (p, i) {
+            _this.formConfig.fields[p] = {
+              label: LabelFormatter.format(p).replace(':', ''),
+              type: XosFormHelpers._getFieldFormat(item[p])
+            };
+          });
+          _this.data = res;
+        });
+      };
+
+      getData();
+    }]
+  });
+})();
+'use strict';
+
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 3/24/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+  /**
+    * @ngdoc directive
+    * @name xos.uiComponents.directive:xosSmartPie
+    * @restrict E
+    * @description The xos-table directive
+    * @param {Object} config The configuration for the component,
+    * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
+    * and a field name that is used to group the data.
+    * ```
+    * {
+        resource: 'Users',
+        groupBy: 'fieldName',
+        classes: 'my-custom-class',
+        labelFormatter: (labels) => {
+          // here you can format your label,
+          // you should return an array with the same order
+          return labels;
+        }
+      }
+    * ```
+    * @scope
+    * @example
+    
+    Displaying Local data
+     <example module="sampleSmartPieLocal">
+      <file name="index.html">
+        <div ng-controller="SampleCtrlLocal as vm">
+          <xos-smart-pie config="vm.configLocal"></xos-smart-pie>
+        </div>
+      </file>
+      <file name="script.js">
+        angular.module('sampleSmartPieLocal', ['xos.uiComponents'])
+        .factory('_', function($window){
+          return $window._;
+        })
+        .controller('SampleCtrlLocal', function($timeout){
+          
+          this.datas = [
+            {id: 1, first_name: 'Jon', last_name: 'aaa', category: 2},
+            {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 1},
+            {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2}
+          ];
+           this.configLocal = {
+            data: [],
+            groupBy: 'category',
+            classes: 'local',
+            labelFormatter: (labels) => {
+              return labels.map(l => l === '1' ? 'North' : 'Dragon');
+            }
+          };
+          
+          $timeout(() => {
+            // this need to be triggered in this way just because of ngDoc,
+            // otherwise you can assign data directly in the config
+            this.configLocal.data = this.datas;
+          }, 1)
+        });
+      </file>
+    </example>
+     Fetching data from API
+     <example module="sampleSmartPieResource">
+      <file name="index.html">
+        <div ng-controller="SampleCtrl as vm">
+          <xos-smart-pie config="vm.config"></xos-smart-pie>
+        </div>
+      </file>
+      <file name="script.js">
+        angular.module('sampleSmartPieResource', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
+        .controller('SampleCtrl', function(){
+          this.config = {
+            resource: 'SampleResource',
+            groupBy: 'category',
+            classes: 'resource',
+            labelFormatter: (labels) => {
+              return labels.map(l => l === '1' ? 'North' : 'Dragon');
+            }
+          };
+        });
+      </file>
+      <file name="backendPoll.js">
+        angular.module('sampleSmartPieResource')
+        .run(function($httpBackend, _){
+          let datas = [
+            {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
+            {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
+            {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1}
+          ];
+           $httpBackend.whenGET('/test').respond(200, datas)
+        })
+        .factory('_', function($window){
+          return $window._;
+        })
+        .service('SampleResource', function($resource){
+          return $resource('/test/:id', {id: '@id'});
+        })
+      </file>
+    </example>
+     Polling data from API
+     <example module="sampleSmartPiePoll">
+      <file name="index.html">
+        <div ng-controller="SampleCtrl as vm">
+          <xos-smart-pie config="vm.config"></xos-smart-pie>
+        </div>
+      </file>
+      <file name="script.js">
+        angular.module('sampleSmartPiePoll', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
+        .controller('SampleCtrl', function(){
+          this.config = {
+            resource: 'SampleResource',
+            groupBy: 'category',
+            poll: 2,
+            labelFormatter: (labels) => {
+              return labels.map(l => l === '1' ? 'Active' : 'Banned');
+            }
+          };
+        });
+      </file>
+      <file name="backend.js">
+        angular.module('sampleSmartPiePoll')
+        .run(function($httpBackend, _){
+          let mock = [
+            [
+              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
+              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
+              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
+              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 1}
+            ],
+             [
+              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
+              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
+              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2},
+              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
+            ],
+             [
+              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
+              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
+              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
+              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
+            ]
+          ];
+          $httpBackend.whenGET('/test').respond(function(method, url, data, headers, params) {
+            return [200, mock[Math.round(Math.random() * 3)]];
+          });
+        })
+        .factory('_', function($window){
+          return $window._;
+        })
+        .service('SampleResource', function($resource){
+          return $resource('/test/:id', {id: '@id'});
+        })
+      </file>
+    </example>
+    */
+  .component('xosSmartPie', {
+    restrict: 'E',
+    bindings: {
+      config: '='
+    },
+    template: '\n      <canvas\n        class="chart chart-pie {{vm.config.classes}}"\n        chart-data="vm.data" chart-labels="vm.labels"\n        chart-legend="{{vm.config.legend}}">\n      </canvas>\n    ',
+    bindToController: true,
+    controllerAs: 'vm',
+    controller: ["$injector", "$interval", "$scope", "$timeout", "_", function controller($injector, $interval, $scope, $timeout, _) {
+      var _this = this;
+
+      if (!this.config.resource && !this.config.data) {
+        throw new Error('[xosSmartPie] Please provide a resource or an array of data in the configuration');
+      }
+
+      var groupData = function groupData(data) {
+        return _.groupBy(data, _this.config.groupBy);
+      };
+      var formatData = function formatData(data) {
+        return _.reduce(Object.keys(data), function (list, group) {
+          return list.concat(data[group].length);
+        }, []);
+      };
+      var formatLabels = function formatLabels(data) {
+        return angular.isFunction(_this.config.labelFormatter) ? _this.config.labelFormatter(Object.keys(data)) : Object.keys(data);
+      };
+
+      var prepareData = function prepareData(data) {
+        // group data
+        var grouped = groupData(data);
+        _this.data = formatData(grouped);
+        // create labels
+        _this.labels = formatLabels(grouped);
+      };
+
+      if (this.config.resource) {
+        (function () {
+
+          _this.Resource = $injector.get(_this.config.resource);
+          var getData = function getData() {
+            _this.Resource.query().$promise.then(function (res) {
+
+              if (!res[0]) {
+                return;
+              }
+
+              prepareData(res);
+            });
+          };
+
+          getData();
+
+          if (_this.config.poll) {
+            $interval(function () {
+              getData();
+            }, _this.config.poll * 1000);
+          }
+        })();
+      } else {
+        $scope.$watch(function () {
+          return _this.config.data;
+        }, function (data) {
+          if (data) {
+            prepareData(_this.config.data);
+          }
+        }, true);
+      }
+
+      $scope.$on('create', function (event, chart) {
+        console.log('create: ' + chart.id);
+      });
+
+      $scope.$on('destroy', function (event, chart) {
+        console.log('destroy: ' + chart.id);
+      });
+    }]
+  });
+})();
 'use strict';
 
 /**
@@ -124,110 +586,6 @@
     }
   });
 })();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/validation/validation.component.js.map
-
-'use strict';
-
-/**
- * © OpenCORD
- *
- * Visit http://guide.xosproject.org/devguide/addview/ for more information
- *
- * Created by teone on 4/15/16.
- */
-
-(function () {
-  'use strict';
-
-  angular.module('xos.uiComponents')
-
-  /**
-    * @ngdoc directive
-    * @name xos.uiComponents.directive:xosPagination
-    * @restrict E
-    * @description The xos-table directive
-    * @param {Number} pageSize Number of elements per page
-    * @param {Number} totalElements Number of total elements in the collection
-    * @param {Function} change The callback to be triggered on page change.
-    * * @element ANY
-    * @scope
-    * @example
-  <example module="samplePagination">
-    <file name="index.html">
-      <div ng-controller="SampleCtrl1 as vm">
-        <xos-pagination
-          page-size="vm.pageSize"
-          total-elements="vm.totalElements"
-          change="vm.change">
-        </xos-pagination>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('samplePagination', ['xos.uiComponents'])
-      .controller('SampleCtrl1', function(){
-        this.pageSize = 10;
-        this.totalElements = 35;
-        this.change = (pageNumber) => {
-          console.log(pageNumber);
-        }
-      });
-    </file>
-  </example>
-  **/
-
-  .component('xosPagination', {
-    restrict: 'E',
-    bindings: {
-      pageSize: '=',
-      totalElements: '=',
-      change: '='
-    },
-    template: '\n      <div class="row" ng-if="vm.pageList.length > 1">\n        <div class="col-xs-12 text-center">\n          <ul class="pagination">\n            <li\n              ng-click="vm.goToPage(vm.currentPage - 1)"\n              ng-class="{disabled: vm.currentPage == 0}">\n              <a href="" aria-label="Previous">\n                  <span aria-hidden="true">&laquo;</span>\n              </a>\n            </li>\n            <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n              <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n            </li>\n            <li\n              ng-click="vm.goToPage(vm.currentPage + 1)"\n              ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n              <a href="" aria-label="Next">\n                  <span aria-hidden="true">&raquo;</span>\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n    ',
-    bindToController: true,
-    controllerAs: 'vm',
-    controller: ["$scope", function controller($scope) {
-      var _this = this;
-
-      this.currentPage = 0;
-
-      this.goToPage = function (n) {
-        if (n < 0 || n === _this.pages) {
-          return;
-        }
-        _this.currentPage = n;
-        _this.change(n);
-      };
-
-      this.createPages = function (pages) {
-        var arr = [];
-        for (var i = 0; i < pages; i++) {
-          arr.push(i);
-        }
-        return arr;
-      };
-
-      // watch for data changes
-      $scope.$watch(function () {
-        return _this.totalElements;
-      }, function () {
-        if (_this.totalElements) {
-          _this.pages = Math.ceil(_this.totalElements / _this.pageSize);
-          _this.pageList = _this.createPages(_this.pages);
-        }
-      });
-    }]
-  }).filter('pagination', function () {
-    return function (input, start) {
-      if (!input || !angular.isArray(input)) {
-        return input;
-      }
-      start = parseInt(start, 10);
-      return input.slice(start);
-    };
-  });
-})();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/pagination/pagination.component.js.map
-
 'use strict';
 
 /**
@@ -658,8 +1016,106 @@
     };
   });
 })();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/table/table.component.js.map
+'use strict';
 
+/**
+ * © OpenCORD
+ *
+ * Visit http://guide.xosproject.org/devguide/addview/ for more information
+ *
+ * Created by teone on 4/15/16.
+ */
+
+(function () {
+  'use strict';
+
+  angular.module('xos.uiComponents')
+
+  /**
+    * @ngdoc directive
+    * @name xos.uiComponents.directive:xosPagination
+    * @restrict E
+    * @description The xos-table directive
+    * @param {Number} pageSize Number of elements per page
+    * @param {Number} totalElements Number of total elements in the collection
+    * @param {Function} change The callback to be triggered on page change.
+    * * @element ANY
+    * @scope
+    * @example
+  <example module="samplePagination">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl1 as vm">
+        <xos-pagination
+          page-size="vm.pageSize"
+          total-elements="vm.totalElements"
+          change="vm.change">
+        </xos-pagination>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('samplePagination', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.pageSize = 10;
+        this.totalElements = 35;
+        this.change = (pageNumber) => {
+          console.log(pageNumber);
+        }
+      });
+    </file>
+  </example>
+  **/
+
+  .component('xosPagination', {
+    restrict: 'E',
+    bindings: {
+      pageSize: '=',
+      totalElements: '=',
+      change: '='
+    },
+    template: '\n      <div class="row" ng-if="vm.pageList.length > 1">\n        <div class="col-xs-12 text-center">\n          <ul class="pagination">\n            <li\n              ng-click="vm.goToPage(vm.currentPage - 1)"\n              ng-class="{disabled: vm.currentPage == 0}">\n              <a href="" aria-label="Previous">\n                  <span aria-hidden="true">&laquo;</span>\n              </a>\n            </li>\n            <li ng-repeat="i in vm.pageList" ng-class="{active: i === vm.currentPage}">\n              <a href="" ng-click="vm.goToPage(i)">{{i + 1}}</a>\n            </li>\n            <li\n              ng-click="vm.goToPage(vm.currentPage + 1)"\n              ng-class="{disabled: vm.currentPage == vm.pages - 1}">\n              <a href="" aria-label="Next">\n                  <span aria-hidden="true">&raquo;</span>\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n    ',
+    bindToController: true,
+    controllerAs: 'vm',
+    controller: ["$scope", function controller($scope) {
+      var _this = this;
+
+      this.currentPage = 0;
+
+      this.goToPage = function (n) {
+        if (n < 0 || n === _this.pages) {
+          return;
+        }
+        _this.currentPage = n;
+        _this.change(n);
+      };
+
+      this.createPages = function (pages) {
+        var arr = [];
+        for (var i = 0; i < pages; i++) {
+          arr.push(i);
+        }
+        return arr;
+      };
+
+      // watch for data changes
+      $scope.$watch(function () {
+        return _this.totalElements;
+      }, function () {
+        if (_this.totalElements) {
+          _this.pages = Math.ceil(_this.totalElements / _this.pageSize);
+          _this.pageList = _this.createPages(_this.pages);
+        }
+      });
+    }]
+  }).filter('pagination', function () {
+    return function (input, start) {
+      if (!input || !angular.isArray(input)) {
+        return input;
+      }
+      start = parseInt(start, 10);
+      return input.slice(start);
+    };
+  });
+})();
 'use strict';
 
 /**
@@ -917,145 +1373,6 @@
     }]
   });
 })();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/form/form.component.js.map
-
-'use strict';
-
-/**
- * © OpenCORD
- *
- * Visit http://guide.xosproject.org/devguide/addview/ for more information
- *
- * Created by teone on 4/15/16.
- */
-
-(function () {
-  'use strict';
-
-  angular.module('xos.uiComponents')
-
-  /**
-    * @ngdoc directive
-    * @name xos.uiComponents.directive:xosAlert
-    * @restrict E
-    * @description The xos-alert directive
-    * @param {Object} config The configuration object
-    * ```
-    * {
-    *   type: 'danger', //info, success, warning
-    *   closeBtn: true, //default false
-    *   autoHide: 3000 //delay to automatically hide the alert
-    * }
-    * ```
-    * @param {Boolean=} show Binding to show and hide the alert, default to true
-    * @element ANY
-    * @scope
-    * @example
-  <example module="sampleAlert1">
-    <file name="index.html">
-      <div ng-controller="SampleCtrl1 as vm">
-        <xos-alert config="vm.config1">
-          A sample alert message
-        </xos-alert>
-        <xos-alert config="vm.config2">
-          A sample alert message (with close button)
-        </xos-alert>
-        <xos-alert config="vm.config3">
-          A sample info message
-        </xos-alert>
-        <xos-alert config="vm.config4">
-          A sample success message
-        </xos-alert>
-        <xos-alert config="vm.config5">
-          A sample warning message
-        </xos-alert>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('sampleAlert1', ['xos.uiComponents'])
-      .controller('SampleCtrl1', function(){
-        this.config1 = {
-          type: 'danger'
-        };
-         this.config2 = {
-          type: 'danger',
-          closeBtn: true
-        };
-         this.config3 = {
-          type: 'info'
-        };
-         this.config4 = {
-          type: 'success'
-        };
-         this.config5 = {
-          type: 'warning'
-        };
-      });
-    </file>
-  </example>
-   <example module="sampleAlert2" animations="true">
-    <file name="index.html">
-      <div ng-controller="SampleCtrl as vm" class="row">
-        <div class="col-sm-4">
-          <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
-          <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
-        </div>
-        <div class="col-sm-8">
-          <xos-alert config="vm.config1" show="vm.show">
-            A sample alert message, not displayed by default.
-          </xos-alert>
-        </div>
-      </div>
-    </file>
-    <file name="script.js">
-      angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
-      .controller('SampleCtrl', function(){
-        this.config1 = {
-          type: 'success'
-        };
-         this.show = false;
-      });
-    </file>
-  </example>
-  **/
-
-  .component('xosAlert', {
-    restrict: 'E',
-    bindings: {
-      config: '=',
-      show: '=?'
-    },
-    template: '\n      <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n        <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n          <span aria-hidden="true">&times;</span>\n        </button>\n        <p ng-transclude></p>\n      </div>\n    ',
-    transclude: true,
-    bindToController: true,
-    controllerAs: 'vm',
-    controller: ["$timeout", function controller($timeout) {
-      var _this = this;
-
-      if (!this.config) {
-        throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
-      }
-
-      // default the value to true
-      this.show = this.show !== false;
-
-      this.dismiss = function () {
-        _this.show = false;
-      };
-
-      if (this.config.autoHide) {
-        (function () {
-          var to = $timeout(function () {
-            _this.dismiss();
-            $timeout.cancel(to);
-          }, _this.config.autoHide);
-        })();
-      }
-    }]
-  });
-})();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/alert/alert.component.js.map
-
 'use strict';
 
 function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
@@ -1289,8 +1606,6 @@
     };
   });
 })();
-//# sourceMappingURL=../../../maps/ui_components/dumbComponents/field/field.component.js.map
-
 'use strict';
 
 /**
@@ -1298,7 +1613,7 @@
  *
  * Visit http://guide.xosproject.org/devguide/addview/ for more information
  *
- * Created by teone on 3/24/16.
+ * Created by teone on 4/15/16.
  */
 
 (function () {
@@ -1307,458 +1622,125 @@
   angular.module('xos.uiComponents')
 
   /**
-  * @ngdoc directive
-  * @name xos.uiComponents.directive:xosSmartTable
-  * @link xos.uiComponents.directive:xosTable xosTable
-  * @link xos.uiComponents.directive:xosForm xosForm
-  * @restrict E
-  * @description The xos-table directive
-  * @param {Object} config The configuration for the component,
-  * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
-  * and an array of fields that shouldn't be printed.
-  * ```
-  * {
-      resource: 'Users',
-      hiddenFields: []
-    }
-  * ```
-  * @scope
-  * @example
-   <example module="sampleSmartTable">
+    * @ngdoc directive
+    * @name xos.uiComponents.directive:xosAlert
+    * @restrict E
+    * @description The xos-alert directive
+    * @param {Object} config The configuration object
+    * ```
+    * {
+    *   type: 'danger', //info, success, warning
+    *   closeBtn: true, //default false
+    *   autoHide: 3000 //delay to automatically hide the alert
+    * }
+    * ```
+    * @param {Boolean=} show Binding to show and hide the alert, default to true
+    * @element ANY
+    * @scope
+    * @example
+  <example module="sampleAlert1">
     <file name="index.html">
-      <div ng-controller="SampleCtrl as vm">
-        <xos-smart-table config="vm.config"></xos-smart-table>
+      <div ng-controller="SampleCtrl1 as vm">
+        <xos-alert config="vm.config1">
+          A sample alert message
+        </xos-alert>
+        <xos-alert config="vm.config2">
+          A sample alert message (with close button)
+        </xos-alert>
+        <xos-alert config="vm.config3">
+          A sample info message
+        </xos-alert>
+        <xos-alert config="vm.config4">
+          A sample success message
+        </xos-alert>
+        <xos-alert config="vm.config5">
+          A sample warning message
+        </xos-alert>
       </div>
     </file>
     <file name="script.js">
-      angular.module('sampleSmartTable', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
-      // This is only for documentation purpose
-      .run(function($httpBackend, _){
-        let datas = [{id: 1, name: 'Jhon', surname: 'Doe'}];
-        let count = 1;
-         let paramsUrl = new RegExp(/\/test\/(.+)/);
-         $httpBackend.whenDELETE(paramsUrl, undefined, ['id']).respond((method, url, data, headers, params) => {
-          data = angular.fromJson(data);
-          let id = url.match(paramsUrl)[1];
-          _.remove(datas, (d) => {
-            return d.id === parseInt(id);
-          })
-          return [204];
-        });
-         $httpBackend.whenGET('/test').respond(200, datas)
-        $httpBackend.whenPOST('/test').respond((method, url, data) => {
-          data = angular.fromJson(data);
-          data.id = ++count;
-          datas.push(data);
-          return [201, data, {}];
-        });
-      })
-      .factory('_', function($window){
-        return $window._;
-      })
-      .service('SampleResource', function($resource){
-        return $resource('/test/:id', {id: '@id'});
-      })
-      // End of documentation purpose, example start
-      .controller('SampleCtrl', function(){
-        this.config = {
-          resource: 'SampleResource'
+      angular.module('sampleAlert1', ['xos.uiComponents'])
+      .controller('SampleCtrl1', function(){
+        this.config1 = {
+          type: 'danger'
+        };
+         this.config2 = {
+          type: 'danger',
+          closeBtn: true
+        };
+         this.config3 = {
+          type: 'info'
+        };
+         this.config4 = {
+          type: 'success'
+        };
+         this.config5 = {
+          type: 'warning'
         };
       });
     </file>
   </example>
-  */
+   <example module="sampleAlert2" animations="true">
+    <file name="index.html">
+      <div ng-controller="SampleCtrl as vm" class="row">
+        <div class="col-sm-4">
+          <a class="btn btn-default btn-block" ng-show="!vm.show" ng-click="vm.show = true">Show Alert</a>
+          <a class="btn btn-default btn-block" ng-show="vm.show" ng-click="vm.show = false">Hide Alert</a>
+        </div>
+        <div class="col-sm-8">
+          <xos-alert config="vm.config1" show="vm.show">
+            A sample alert message, not displayed by default.
+          </xos-alert>
+        </div>
+      </div>
+    </file>
+    <file name="script.js">
+      angular.module('sampleAlert2', ['xos.uiComponents', 'ngAnimate'])
+      .controller('SampleCtrl', function(){
+        this.config1 = {
+          type: 'success'
+        };
+         this.show = false;
+      });
+    </file>
+  </example>
+  **/
 
-  .component('xosSmartTable', {
+  .component('xosAlert', {
     restrict: 'E',
     bindings: {
-      config: '='
+      config: '=',
+      show: '=?'
     },
-    template: '\n        <div class="row" ng-show="vm.data.length > 0">\n          <div class="col-xs-12 text-right">\n            <a href="" class="btn btn-success" ng-click="vm.createItem()">\n              Add\n            </a>\n          </div>\n        </div>\n        <div class="row">\n          <div class="col-xs-12 table-responsive">\n            <xos-table config="vm.tableConfig" data="vm.data"></xos-table>\n          </div>\n        </div>\n        <div class="panel panel-default" ng-show="vm.detailedItem">\n          <div class="panel-heading">\n            <div class="row">\n              <div class="col-xs-11">\n                <h3 class="panel-title" ng-show="vm.detailedItem.id">Update {{vm.config.resource}} {{vm.detailedItem.id}}</h3>\n                <h3 class="panel-title" ng-show="!vm.detailedItem.id">Create {{vm.config.resource}} item</h3>\n              </div>\n              <div class="col-xs-1">\n                <a href="" ng-click="vm.cleanForm()">\n                  <i class="glyphicon glyphicon-remove pull-right"></i>\n                </a>\n              </div>\n            </div>\n          </div>\n          <div class="panel-body">\n            <xos-form config="vm.formConfig" ng-model="vm.detailedItem"></xos-form>\n          </div>\n        </div>\n        <xos-alert config="{type: \'success\', closeBtn: true}" show="vm.responseMsg">{{vm.responseMsg}}</xos-alert>\n        <xos-alert config="{type: \'danger\', closeBtn: true}" show="vm.responseErr">{{vm.responseErr}}</xos-alert>\n      ',
+    template: '\n      <div ng-cloak class="alert alert-{{vm.config.type}}" ng-hide="!vm.show">\n        <button type="button" class="close" ng-if="vm.config.closeBtn" ng-click="vm.dismiss()">\n          <span aria-hidden="true">&times;</span>\n        </button>\n        <p ng-transclude></p>\n      </div>\n    ',
+    transclude: true,
     bindToController: true,
     controllerAs: 'vm',
-    controller: ["$injector", "LabelFormatter", "_", "XosFormHelpers", function controller($injector, LabelFormatter, _, XosFormHelpers) {
+    controller: ["$timeout", function controller($timeout) {
       var _this = this;
 
-      // TODO
-      // - Validate the config (what if resource does not exist?)
-
-      // NOTE
-      // Corner case
-      // - if response is empty, how can we generate a form ?
-
-      this.responseMsg = false;
-      this.responseErr = false;
-
-      this.tableConfig = {
-        columns: [],
-        actions: [{
-          label: 'delete',
-          icon: 'remove',
-          cb: function cb(item) {
-            _this.Resource.delete({ id: item.id }).$promise.then(function () {
-              _.remove(_this.data, function (d) {
-                return d.id === item.id;
-              });
-              _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully deleted';
-            }).catch(function (err) {
-              _this.responseErr = err.data.detail || 'Error while deleting ' + _this.config.resource + ' with id ' + item.id;
-            });
-          },
-          color: 'red'
-        }, {
-          label: 'details',
-          icon: 'search',
-          cb: function cb(item) {
-            _this.detailedItem = item;
-          }
-        }],
-        classes: 'table table-striped table-bordered table-responsive',
-        filter: 'field',
-        order: true,
-        pagination: {
-          pageSize: 10
-        }
-      };
-
-      this.formConfig = {
-        exclude: this.config.hiddenFields,
-        fields: {},
-        formName: this.config.resource + 'Form',
-        actions: [{
-          label: 'Save',
-          icon: 'ok',
-          cb: function cb(item) {
-            var p = void 0;
-            var isNew = true;
-
-            if (item.id) {
-              p = item.$update();
-              isNew = false;
-            } else {
-              p = item.$save();
-            }
-
-            p.then(function (res) {
-              if (isNew) {
-                _this.data.push(angular.copy(res));
-              }
-              delete _this.detailedItem;
-              _this.responseMsg = _this.config.resource + ' with id ' + item.id + ' successfully saved';
-            }).catch(function (err) {
-              _this.responseErr = err.data.detail || 'Error while saving ' + _this.config.resource + ' with id ' + item.id;
-            });
-          },
-          class: 'success'
-        }]
-      };
-
-      this.cleanForm = function () {
-        delete _this.detailedItem;
-      };
-
-      this.createItem = function () {
-        _this.detailedItem = new _this.Resource();
-      };
-
-      this.Resource = $injector.get(this.config.resource);
-
-      var getData = function getData() {
-        _this.Resource.query().$promise.then(function (res) {
-
-          if (!res[0]) {
-            _this.data = res;
-            return;
-          }
-
-          var item = res[0];
-          var props = Object.keys(item);
-
-          _.remove(props, function (p) {
-            return p === 'id' || p === 'validators';
-          });
-
-          // TODO move out cb,  non sense triggering a lot of times
-          if (angular.isArray(_this.config.hiddenFields)) {
-            props = _.difference(props, _this.config.hiddenFields);
-          }
-
-          props.forEach(function (p) {
-            var fieldConfig = {
-              label: LabelFormatter.format(p),
-              prop: p
-            };
-
-            fieldConfig.type = XosFormHelpers._getFieldFormat(item[p]);
-
-            _this.tableConfig.columns.push(fieldConfig);
-          });
-
-          // build form structure
-          // TODO move in a pure function for testing purposes
-          props.forEach(function (p, i) {
-            _this.formConfig.fields[p] = {
-              label: LabelFormatter.format(p).replace(':', ''),
-              type: XosFormHelpers._getFieldFormat(item[p])
-            };
-          });
-          _this.data = res;
-        });
-      };
-
-      getData();
-    }]
-  });
-})();
-//# sourceMappingURL=../../../maps/ui_components/smartComponents/smartTable/smartTable.component.js.map
-
-'use strict';
-
-/**
- * © OpenCORD
- *
- * Visit http://guide.xosproject.org/devguide/addview/ for more information
- *
- * Created by teone on 3/24/16.
- */
-
-(function () {
-  'use strict';
-
-  angular.module('xos.uiComponents')
-  /**
-    * @ngdoc directive
-    * @name xos.uiComponents.directive:xosSmartPie
-    * @restrict E
-    * @description The xos-table directive
-    * @param {Object} config The configuration for the component,
-    * it is composed by the name of an angular [$resource](https://docs.angularjs.org/api/ngResource/service/$resource)
-    * and a field name that is used to group the data.
-    * ```
-    * {
-        resource: 'Users',
-        groupBy: 'fieldName',
-        classes: 'my-custom-class',
-        labelFormatter: (labels) => {
-          // here you can format your label,
-          // you should return an array with the same order
-          return labels;
-        }
-      }
-    * ```
-    * @scope
-    * @example
-    
-    Displaying Local data
-     <example module="sampleSmartPieLocal">
-      <file name="index.html">
-        <div ng-controller="SampleCtrlLocal as vm">
-          <xos-smart-pie config="vm.configLocal"></xos-smart-pie>
-        </div>
-      </file>
-      <file name="script.js">
-        angular.module('sampleSmartPieLocal', ['xos.uiComponents'])
-        .factory('_', function($window){
-          return $window._;
-        })
-        .controller('SampleCtrlLocal', function($timeout){
-          
-          this.datas = [
-            {id: 1, first_name: 'Jon', last_name: 'aaa', category: 2},
-            {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 1},
-            {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2}
-          ];
-           this.configLocal = {
-            data: [],
-            groupBy: 'category',
-            classes: 'local',
-            labelFormatter: (labels) => {
-              return labels.map(l => l === '1' ? 'North' : 'Dragon');
-            }
-          };
-          
-          $timeout(() => {
-            // this need to be triggered in this way just because of ngDoc,
-            // otherwise you can assign data directly in the config
-            this.configLocal.data = this.datas;
-          }, 1)
-        });
-      </file>
-    </example>
-     Fetching data from API
-     <example module="sampleSmartPieResource">
-      <file name="index.html">
-        <div ng-controller="SampleCtrl as vm">
-          <xos-smart-pie config="vm.config"></xos-smart-pie>
-        </div>
-      </file>
-      <file name="script.js">
-        angular.module('sampleSmartPieResource', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
-        .controller('SampleCtrl', function(){
-          this.config = {
-            resource: 'SampleResource',
-            groupBy: 'category',
-            classes: 'resource',
-            labelFormatter: (labels) => {
-              return labels.map(l => l === '1' ? 'North' : 'Dragon');
-            }
-          };
-        });
-      </file>
-      <file name="backendPoll.js">
-        angular.module('sampleSmartPieResource')
-        .run(function($httpBackend, _){
-          let datas = [
-            {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
-            {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
-            {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1}
-          ];
-           $httpBackend.whenGET('/test').respond(200, datas)
-        })
-        .factory('_', function($window){
-          return $window._;
-        })
-        .service('SampleResource', function($resource){
-          return $resource('/test/:id', {id: '@id'});
-        })
-      </file>
-    </example>
-     Polling data from API
-     <example module="sampleSmartPiePoll">
-      <file name="index.html">
-        <div ng-controller="SampleCtrl as vm">
-          <xos-smart-pie config="vm.config"></xos-smart-pie>
-        </div>
-      </file>
-      <file name="script.js">
-        angular.module('sampleSmartPiePoll', ['xos.uiComponents', 'ngResource', 'ngMockE2E'])
-        .controller('SampleCtrl', function(){
-          this.config = {
-            resource: 'SampleResource',
-            groupBy: 'category',
-            poll: 2,
-            labelFormatter: (labels) => {
-              return labels.map(l => l === '1' ? 'Active' : 'Banned');
-            }
-          };
-        });
-      </file>
-      <file name="backend.js">
-        angular.module('sampleSmartPiePoll')
-        .run(function($httpBackend, _){
-          let mock = [
-            [
-              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
-              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
-              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
-              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 1}
-            ],
-             [
-              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
-              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
-              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 2},
-              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
-            ],
-             [
-              {id: 1, first_name: 'Jon', last_name: 'Snow', category: 1},
-              {id: 2, first_name: 'Danaerys', last_name: 'Targaryen', category: 2},
-              {id: 3, first_name: 'Aria', last_name: 'Stark', category: 1},
-              {id: 3, first_name: 'Tyrion', last_name: 'Lannister', category: 2}
-            ]
-          ];
-          $httpBackend.whenGET('/test').respond(function(method, url, data, headers, params) {
-            return [200, mock[Math.round(Math.random() * 3)]];
-          });
-        })
-        .factory('_', function($window){
-          return $window._;
-        })
-        .service('SampleResource', function($resource){
-          return $resource('/test/:id', {id: '@id'});
-        })
-      </file>
-    </example>
-    */
-  .component('xosSmartPie', {
-    restrict: 'E',
-    bindings: {
-      config: '='
-    },
-    template: '\n      <canvas\n        class="chart chart-pie {{vm.config.classes}}"\n        chart-data="vm.data" chart-labels="vm.labels"\n        chart-legend="{{vm.config.legend}}">\n      </canvas>\n    ',
-    bindToController: true,
-    controllerAs: 'vm',
-    controller: ["$injector", "$interval", "$scope", "$timeout", "_", function controller($injector, $interval, $scope, $timeout, _) {
-      var _this = this;
-
-      if (!this.config.resource && !this.config.data) {
-        throw new Error('[xosSmartPie] Please provide a resource or an array of data in the configuration');
+      if (!this.config) {
+        throw new Error('[xosAlert] Please provide a configuration via the "config" attribute');
       }
 
-      var groupData = function groupData(data) {
-        return _.groupBy(data, _this.config.groupBy);
-      };
-      var formatData = function formatData(data) {
-        return _.reduce(Object.keys(data), function (list, group) {
-          return list.concat(data[group].length);
-        }, []);
-      };
-      var formatLabels = function formatLabels(data) {
-        return angular.isFunction(_this.config.labelFormatter) ? _this.config.labelFormatter(Object.keys(data)) : Object.keys(data);
+      // default the value to true
+      this.show = this.show !== false;
+
+      this.dismiss = function () {
+        _this.show = false;
       };
 
-      var prepareData = function prepareData(data) {
-        // group data
-        var grouped = groupData(data);
-        _this.data = formatData(grouped);
-        // create labels
-        _this.labels = formatLabels(grouped);
-      };
-
-      if (this.config.resource) {
+      if (this.config.autoHide) {
         (function () {
-
-          _this.Resource = $injector.get(_this.config.resource);
-          var getData = function getData() {
-            _this.Resource.query().$promise.then(function (res) {
-
-              if (!res[0]) {
-                return;
-              }
-
-              prepareData(res);
-            });
-          };
-
-          getData();
-
-          if (_this.config.poll) {
-            $interval(function () {
-              getData();
-            }, _this.config.poll * 1000);
-          }
+          var to = $timeout(function () {
+            _this.dismiss();
+            $timeout.cancel(to);
+          }, _this.config.autoHide);
         })();
-      } else {
-        $scope.$watch(function () {
-          return _this.config.data;
-        }, function (data) {
-          if (data) {
-            prepareData(_this.config.data);
-          }
-        }, true);
       }
-
-      $scope.$on('create', function (event, chart) {
-        console.log('create: ' + chart.id);
-      });
-
-      $scope.$on('destroy', function (event, chart) {
-        console.log('destroy: ' + chart.id);
-      });
     }]
   });
 })();
-//# sourceMappingURL=../../../maps/ui_components/smartComponents/smartPie/smartPie.component.js.map
-
 'use strict';
 
 (function () {
@@ -1857,8 +1839,6 @@
     };
   }
 })();
-//# sourceMappingURL=../../../maps/services/helpers/ui/label_formatter.service.js.map
-
 'use strict';
 
 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
@@ -2017,8 +1997,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../../../maps/services/helpers/ui/form.helpers.js.map
-
 'use strict';
 
 (function () {
@@ -2115,8 +2093,6 @@
     };
   }
 })();
-//# sourceMappingURL=../../../maps/services/helpers/ui/comparator.service.js.map
-
 'use strict';
 
 (function () {
@@ -2158,8 +2134,6 @@
     $resourceProvider.defaults.stripTrailingSlashes = false;
   }
 })();
-//# sourceMappingURL=maps/xosHelpers.module.js.map
-
 'use strict';
 
 (function () {
@@ -2175,8 +2149,6 @@
     return $resource('/api/service/vsg/');
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/vSG.js.map
-
 'use strict';
 
 (function () {
@@ -2194,8 +2166,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/vOLT.js.map
-
 'use strict';
 
 (function () {
@@ -2219,8 +2189,6 @@
     return $resource('/api/utility/logout/');
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Utility.js.map
-
 'use strict';
 
 (function () {
@@ -2238,8 +2206,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Users.js.map
-
 'use strict';
 
 (function () {
@@ -2257,8 +2223,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Truckroll.js.map
-
 'use strict';
 
 (function () {
@@ -2276,8 +2240,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Tenant.js.map
-
 'use strict';
 
 (function () {
@@ -2427,8 +2389,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Subscribers.js.map
-
 'use strict';
 
 (function () {
@@ -2466,8 +2426,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Slices_plus.js.map
-
 'use strict';
 
 (function () {
@@ -2485,8 +2443,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Slices.js.map
-
 'use strict';
 
 (function () {
@@ -2504,8 +2460,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Sites.js.map
-
 'use strict';
 
 (function () {
@@ -2523,8 +2477,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Services.js.map
-
 'use strict';
 
 (function () {
@@ -2540,8 +2492,6 @@
     return $resource('/api/service/onos/');
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/ONOS-Services.js.map
-
 'use strict';
 
 (function () {
@@ -2557,8 +2507,6 @@
     return $resource('/api/tenant/onos/app/');
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/ONOS-Apps.js.map
-
 'use strict';
 
 (function () {
@@ -2576,8 +2524,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Nodes.js.map
-
 'use strict';
 
 (function () {
@@ -2595,8 +2541,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Networkstemplates.js.map
-
 'use strict';
 
 (function () {
@@ -2614,8 +2558,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Networks.js.map
-
 'use strict';
 
 (function () {
@@ -2641,8 +2583,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Me.js.map
-
 'use strict';
 
 (function () {
@@ -2660,8 +2600,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Instances.js.map
-
 'use strict';
 
 (function () {
@@ -2679,8 +2617,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Images.js.map
-
 'use strict';
 
 (function () {
@@ -2698,8 +2634,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Flavors.js.map
-
 'use strict';
 
 (function () {
@@ -2715,8 +2649,6 @@
     return $resource('/api/service/exampleservice/');
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Example.js.map
-
 'use strict';
 
 (function () {
@@ -2734,8 +2666,6 @@
     });
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Deployments.js.map
-
 'use strict';
 
 (function () {
@@ -2767,8 +2697,6 @@
     return r;
   }]);
 })();
-//# sourceMappingURL=../../maps/services/rest/Dashboards.js.map
-
 'use strict';
 
 (function () {
@@ -2929,8 +2857,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../../maps/services/helpers/user-prefs.service.js.map
-
 'use strict';
 
 (function () {
@@ -2972,8 +2898,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../maps/services/service_graph.service.js.map
-
 'use strict';
 
 /* eslint-disable  angular/ng_window_service*/
@@ -3033,8 +2957,6 @@
     };
   }]);
 })();
-//# sourceMappingURL=../maps/services/notification.service.js.map
-
 'use strict';
 
 (function () {
@@ -3059,8 +2981,6 @@
     };
   }
 })();
-//# sourceMappingURL=../maps/services/noHyperlinks.interceptor.js.map
-
 'use strict';
 
 // TODO write tests for log
@@ -3120,8 +3040,6 @@
     return $delegate;
   }]);
 }]);
-//# sourceMappingURL=../maps/services/log.decorator.js.map
-
 'use strict';
 
 (function () {
@@ -3147,8 +3065,6 @@
     };
   }
 })();
-//# sourceMappingURL=../maps/services/csrfToken.interceptor.js.map
-
 /**
 * @ngdoc overview
 * @name ngXosLib
@@ -3162,5 +3078,4 @@
 * ## Issues
 * Please report issues at https://jira.opencord.org
 **/
-"use strict";
-//# sourceMappingURL=maps/index.ngdoc.js.map
+"use strict";
\ No newline at end of file