diff --git a/css/components/json-tree.css b/css/components/json-tree.css new file mode 100644 index 0000000..232dbab --- /dev/null +++ b/css/components/json-tree.css @@ -0,0 +1,75 @@ + + +/* bat-json-tree */ + +bat-json-tree { + font-size: 11px !important; + font-family: Menlo, monospace; + display: block; + margin-left: 5px; +} + +bat-json-tree .name { + color: rgb(136, 19, 145); +} + +bat-json-tree .console-formatted-string { + color: rgb(196, 26, 22); +} + +bat-json-tree + .console-formatted-null, + .console-formatted-undefined { + color: rgb(128, 128, 128); + } + +bat-json-tree .console-formatted-number { + color: rgb(28, 0, 207); +} + +bat-json-tree + .console-formatted-object, + .console-formatted-node, + .console-formatted-array { + color: #222; + } + +bat-json-tree .properties-tree li { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + -webkit-user-select: text; + cursor: default; + padding-top: 2px; + line-height: 12px; + list-style: none; +} + +bat-json-tree .properties-tree li.parent { + margin-left: -15px; +} +bat-json-tree .properties-tree li.parent li { + padding-left: 28px; +} + +bat-json-tree .properties-tree li.parent::before { + -webkit-user-select: none; + background-image: url(../../img/statusbarButtonGlyphs.png); + background-size: 320px 120px; + opacity: 0.5; + content: "a"; + width: 8px; + float: left; + margin-right: 2px; + color: transparent; + text-shadow: none; + margin-top: -2px; +} + +bat-json-tree .properties-tree li.parent::before { + background-position: -4px -96px; +} + +bat-json-tree .properties-tree li.parent.expanded::before { + background-position: -20px -96px; +} diff --git a/css/components/scope-tree.css b/css/components/scope-tree.css new file mode 100644 index 0000000..72a6ba1 --- /dev/null +++ b/css/components/scope-tree.css @@ -0,0 +1,127 @@ + +/* Stolen from WebKit Inspector CSS */ + +.source-code { + font-size: 11px !important; + font-family: Menlo, monospace; +} + +.source-code li { + display: list-item; + text-align: -webkit-match-parent; +} + +.outline-disclosure, +.outline-disclosure ol { + list-style-type: none; + -webkit-padding-start: 12px; + margin: 0; +} + +.outline-disclosure ol.children.expanded { + display: block; +} + +.outline-disclosure > ol { + position: relative; + padding: 2px 6px !important; + margin: 0; + cursor: default; + min-width: 100%; +} + +.outline-disclosure li { + padding: 0 0 0 14px; + margin-top: 1px; + margin-left: -2px; + word-wrap: break-word; +} + +.outline-disclosure li.selected .selection { + display: block; + background-color: rgb(212, 212, 212); +} + +.elements-tree-outline li.parent::before { + top: 0 !important; +} +.outline-disclosure li.parent::before { + -webkit-mask-position: -4px -96px; + background-color: rgb(110, 110, 110); +} +.outline-disclosure li.parent::before { + -webkit-user-select: none; + -webkit-mask-image: url(../../img/statusbarButtonGlyphs.png); + -webkit-mask-size: 320px 120px; + content: "a"; + color: transparent; + text-shadow: none; + position: relative; + top: 2px; + margin-right: 1px; + height: 12px; +} +.outline-disclosure li.parent::before { + float: left; + width: 8px; + padding-right: 2px; +} + +.webkit-html-tag { + color: rgb(136, 18, 128); +} + +.webkit-html-attribute-name { + color: rgb(153, 69, 0); +} + +.webkit-html-attribute-value { + color: rgb(26, 26, 166); +} + +.webkit-html-doctype { + color: rgb(192, 192, 192); +} + +.webkit-html-comment { + color: rgb(35, 110, 37); +} + + +.outline-disclosure .selection { + display: none; + position: absolute; + left: 0; + right: 0; + height: 13px; + z-index: -1; +} + +.outline-disclosure .selection:not(.selected):hover { + display: block; + left: 3px; + right: 3px; + background-color: rgba(56, 121, 217, 0.1); + border-radius: 5px; +} + +.outline-disclosure .selection.selected { + display: block; + background-color: rgb(212, 212, 212); +} + + +:focus .sidebar-tree-item.selected { + border-top: 1px solid rgb(68, 128, 200); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170))); +} + +/* */ + +/* +bat-scope-tree .selected { + font-weight: bold; + text-decoration: underline; + color: #333; +} +*/ diff --git a/css/components/slider.css b/css/components/slider.css new file mode 100644 index 0000000..0292074 --- /dev/null +++ b/css/components/slider.css @@ -0,0 +1,63 @@ + +/* + * Slider widget style based on jquery-ui-bootstrap + * http://addyosmani.github.com/jquery-ui-bootstrap + */ + +.ui-slider { + position: relative; + text-align: left; + height: .8em; + + border-radius: 4px; + border: 1px solid #aaaaaa; + + background: #ffffff; +} + +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + top: -.3em; + margin-left: -.6em; + cursor: default; + border-radius: 4px; + + background-color: #e6e6e6; + background-repeat: no-repeat; + background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); + /*background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);*/ + + font-size: 13px; + line-height: normal; + + border: 1px solid #ccc; + border-bottom-color: #bbb; + + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + + -webkit-transition: 0.1s linear background-image; + transition: 0.1s linear background-image; + + overflow: visible; +} + +.ui-slider .ui-slider-range { + position: absolute; + top: 0; + height: 100%; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + + background-position: 0 0; + background-color: #0064cd; + background-repeat: repeat-x; + background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); + /*background-image: linear-gradient(top, #049cdb, #0064cd);*/ +} + diff --git a/css/components/watcher-list.css b/css/components/watcher-list.css new file mode 100644 index 0000000..efa77d1 --- /dev/null +++ b/css/components/watcher-list.css @@ -0,0 +1,75 @@ + + +/* watcher-list */ + +.watcher-list { + font-size: 11px !important; + font-family: Menlo, monospace; + display: block; + margin-left: 5px; +} + +.watcher-list .name { + color: rgb(136, 19, 145); +} + +.watcher-list .console-formatted-string { + color: rgb(196, 26, 22); +} + +.watcher-list + .console-formatted-null, + .console-formatted-undefined { + color: rgb(128, 128, 128); + } + +.watcher-list .console-formatted-number { + color: rgb(28, 0, 207); +} + +.watcher-list + .console-formatted-object, + .console-formatted-node, + .console-formatted-array { + color: #222; + } + +.watcher-list li { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + -webkit-user-select: text; + cursor: default; + padding-top: 2px; + line-height: 12px; + list-style: none; +} + +.watcher-list li.parent { + margin-left: -15px; +} +.watcher-list li.parent li { + padding-left: 28px; +} + +.watcher-list li.parent::before { + -webkit-user-select: none; + background-image: url(../../img/statusbarButtonGlyphs.png); + background-size: 320px 120px; + opacity: 0.5; + content: "a"; + width: 8px; + float: left; + margin-right: 2px; + color: transparent; + text-shadow: none; + margin-top: -2px; +} + +.watcher-list li.parent::before { + background-position: -4px -96px; +} + +.watcher-list li.parent.expanded::before { + background-position: -20px -96px; +} diff --git a/css/panel.css b/css/panel.css index a014d18..84ab74d 100644 --- a/css/panel.css +++ b/css/panel.css @@ -36,105 +36,7 @@ margin: 0; } -bat-scope-tree .selected { - font-weight: bold; - text-decoration: underline; - color: #333; -} - -/* - * Slider widget style based on jquery-ui-bootstrap - * http://addyosmani.github.com/jquery-ui-bootstrap - */ - -.ui-slider { - position: relative; - text-align: left; - height: .8em; - - border-radius: 4px; - border: 1px solid #aaaaaa; - - background: #ffffff; -} - -.ui-slider .ui-slider-handle { - position: absolute; - z-index: 2; - width: 1.2em; - height: 1.2em; - top: -.3em; - margin-left: -.6em; - cursor: default; - border-radius: 4px; - - background-color: #e6e6e6; - background-repeat: no-repeat; - background-image: -webkit-linear-gradient(#ffffff, #ffffff 25%, #e6e6e6); - /*background-image: linear-gradient(#ffffff, #ffffff 25%, #e6e6e6);*/ - - font-size: 13px; - line-height: normal; - - border: 1px solid #ccc; - border-bottom-color: #bbb; - - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); - - -webkit-transition: 0.1s linear background-image; - transition: 0.1s linear background-image; - - overflow: visible; -} - -.ui-slider .ui-slider-range { - position: absolute; - top: 0; - height: 100%; - z-index: 1; - font-size: .7em; - display: block; - border: 0; - - background-position: 0 0; - background-color: #0064cd; - background-repeat: repeat-x; - background-image: -webkit-linear-gradient(top, #049cdb, #0064cd); - /*background-image: linear-gradient(top, #049cdb, #0064cd);*/ -} - - - /* Mimic Chrome's Devtools */ - -/* reset */ - -* { - box-sizing: border-box; -} - -/* TODO: defaults for other platforms?? */ -body { - cursor: default; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - overflow: hidden; - font-size: 12px; - margin: 0; - tab-size: 4; - -webkit-user-select: none; - color: rgb(48, 57, 66); - font-family: 'Lucida Grande', sans-serif; -} - -img { - -webkit-user-drag: none; -} - /* split */ @@ -290,7 +192,7 @@ img { background-clip: padding-box; } -:focus .sidebar-tree-item.selected { +body:focus .sidebar-tree-item.selected { border-top: 1px solid rgb(68, 128, 200); background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(92, 147, 213)), to(rgb(21, 83, 170))); } @@ -343,161 +245,3 @@ li .status:empty { display: none; } - - -/* */ - -.source-code { - font-family: Menlo, monospace; - font-size: 11px; - /*white-space: pre-wrap;*/ -} - -.source-code li { - display: list-item; - text-align: -webkit-match-parent; -} - -.outline-disclosure, -.outline-disclosure ol { - list-style-type: none; - -webkit-padding-start: 12px; - margin: 0; -} - -.outline-disclosure ol.children.expanded { - display: block; -} - -.outline-disclosure > ol { - position: relative; - padding: 2px 6px !important; - margin: 0; - cursor: default; - min-width: 100%; -} - -.outline-disclosure li { - padding: 0 0 0 14px; - margin-top: 1px; - margin-left: -2px; - word-wrap: break-word; -} - -.outline-disclosure li.selected .selection { - display: block; - background-color: rgb(212, 212, 212); -} - -.elements-tree-outline li.parent::before { - top: 0 !important; -} -.outline-disclosure li.parent::before { - -webkit-mask-position: -4px -96px; - background-color: rgb(110, 110, 110); -} -.outline-disclosure li.parent::before { - -webkit-user-select: none; - -webkit-mask-image: url(../img/statusbarButtonGlyphs.png); - -webkit-mask-size: 320px 120px; - content: "a"; - color: transparent; - text-shadow: none; - position: relative; - top: 2px; - margin-right: 1px; - height: 12px; -} -.outline-disclosure li.parent::before { - float: left; - width: 8px; - padding-right: 2px; -} - -.webkit-html-tag { - color: rgb(136, 18, 128); -} - -.webkit-html-attribute-name { - color: rgb(153, 69, 0); -} - -.webkit-html-attribute-value { - color: rgb(26, 26, 166); -} - -.webkit-html-doctype { - color: rgb(192, 192, 192); -} - -.webkit-html-comment { - color: rgb(35, 110, 37); -} - - - - -/* bat-json-tree */ - -bat-json-tree { - font-size: 11px !important; - font-family: Menlo, monospace; -} - -bat-json-tree .name { - color: rgb(136, 19, 145); -} - -bat-json-tree .console-formatted-string { - color: rgb(196, 26, 22); -} - -bat-json-tree - .console-formatted-null, - .console-formatted-undefined { - color: rgb(128, 128, 128); - } - -bat-json-tree .console-formatted-number { - color: rgb(28, 0, 207); -} - -bat-json-tree - .console-formatted-object, - .console-formatted-node, - .console-formatted-array { - color: #222; - } - -bat-json-tree .properties-tree li { - margin-left: 12px; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - -webkit-user-select: text; - cursor: default; - padding-top: 2px; - line-height: 12px; - list-style: none; -} - -bat-json-tree .properties-tree li.parent::before { - -webkit-user-select: none; - background-image: url(../img/statusbarButtonGlyphs.png); - background-size: 320px 120px; - opacity: 0.5; - content: "a"; - width: 8px; - float: left; - margin-right: 4px; - color: transparent; - text-shadow: none; -} - -bat-json-tree .properties-tree li.parent::before { - background-position: -4px -96px; -} - -bat-json-tree .properties-tree li.parent.expanded::before { - background-position: -20px -96px; -} diff --git a/css/reset.css b/css/reset.css new file mode 100644 index 0000000..8847cfe --- /dev/null +++ b/css/reset.css @@ -0,0 +1,26 @@ +/* reset */ + +* { + box-sizing: border-box; +} + +/* TODO: defaults for other platforms?? */ +body { + cursor: default; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow: hidden; + font-size: 12px; + margin: 0; + tab-size: 4; + -webkit-user-select: none; + color: rgb(48, 57, 66); + font-family: 'Lucida Grande', sans-serif; +} + +img { + -webkit-user-drag: none; +} diff --git a/js/background.js b/js/background.js index 08759f2..c64b09a 100644 --- a/js/background.js +++ b/js/background.js @@ -18,7 +18,10 @@ chrome.extension.onConnect.addListener(function (port) { }); chrome.extension.onMessage.addListener(function (msg) { - if (msg.action === 'modelChange' || msg.action === 'scopeChange') { + if (msg.action === 'modelChange' || + msg.action === 'scopeChange' || + msg.action === 'watcherChange') { + port.postMessage(msg); } }); diff --git a/js/controllers/ModelCtrl.js b/js/controllers/ModelCtrl.js index c54330a..f4ae9e9 100644 --- a/js/controllers/ModelCtrl.js +++ b/js/controllers/ModelCtrl.js @@ -1,5 +1,8 @@ angular.module('panelApp').controller('ModelCtrl', function ModelCtrl($scope, appContext, appModel) { + $scope.modelsExpanded = true; + $scope.watchExpanded = true; + $scope.roots = appModel.getRootScopes; $scope.selectedRoot = null; $scope.$watch('roots()', function (newVal, oldVal) { @@ -21,7 +24,7 @@ angular.module('panelApp').controller('ModelCtrl', function ModelCtrl($scope, ap } return appModel.getScopeTree(select); }; - $scope.selectedScope = null; + $scope.selectedScopeId = null; $scope.watching = {}; @@ -32,10 +35,18 @@ angular.module('panelApp').controller('ModelCtrl', function ModelCtrl($scope, ap }); }); + appContext.watchWatcherChange(function (msg) { + $scope.watchers = msg.watchers; + }); + $scope.select = function () { - appModel.unwatchModel($scope.selectedScope); - $scope.selectedScope = this.val.id; - appModel.watchModel($scope.selectedScope); + if ($scope.selectedScopeId === this.val.id) { + return; + } + appModel.unwatchModel($scope.selectedScopeId); + delete $scope.watching[$scope.selectedScopeId]; + $scope.selectedScopeId = this.val.id; + appModel.watchModel($scope.selectedScopeId); }; $scope.expand = function (id, path) { diff --git a/js/directives/scopeTree.js b/js/directives/scopeTree.js index ba0240b..d8fcae9 100644 --- a/js/directives/scopeTree.js +++ b/js/directives/scopeTree.js @@ -26,7 +26,7 @@ angular.module('panelApp').directive('batScopeTree', function ($compile) { var name = function (name) { if (!name) { - return '???'; + return '$rootScope'; } if (name['ng-repeat']) { return name.lhs; @@ -52,10 +52,11 @@ angular.module('panelApp').directive('batScopeTree', function ($compile) { var template = '
    ' + - '' + - '{{c}} ' + - '{{name(val.name)}} ' + - '{{xc}}' + + '
    ' + + '' + + '<' + + '{{name(val.name)}}' + + '>' + '' + '
    ' + '<!-- {{repeat}} -->' + @@ -64,7 +65,7 @@ angular.module('panelApp').directive('batScopeTree', function ($compile) { 'val="child" ' + 'inspect="inspect" ' + 'select="select" ' + - 'selected-scope-id="selectedScope.id">' + + 'selected-scope-id="selectedScopeId">' + '' + '
    ' + '' + + 'selected-scope-id="selectedScopeId">' + '' + '
'; @@ -91,8 +92,6 @@ angular.module('panelApp').directive('batScopeTree', function ($compile) { element.append(template); scope.name = name; - scope.c = '{{'; - scope.xc = '}}'; var childScope = scope.$new(); @@ -110,14 +109,14 @@ angular.module('panelApp').directive('batScopeTree', function ($compile) { var repOver = child.name['ng-repeat']; grouped[repOver] = grouped[repOver] || []; grouped[repOver].push(child); - }, {}); + }); childScope.ungrouped = newChildren.filter(notRepeatedPredicate); }); childScope.select = scope.select; - //childScope.selectedScope = scope.selectedScope; + //childScope.selectedScopeId = scope.selectedScopeId; childScope.inspect = scope.inspect; $compile(element.contents())(childScope); diff --git a/js/directives/verticalSplit.js b/js/directives/verticalSplit.js index 4b9e742..a3c5590 100644 --- a/js/directives/verticalSplit.js +++ b/js/directives/verticalSplit.js @@ -8,6 +8,8 @@ directive('batVerticalSplit', function ($document, defaultSplit) { 'visible' ]; + var body = angular.element($document[0].body); + return { restrict: 'A', compile: function (element) { @@ -17,6 +19,7 @@ directive('batVerticalSplit', function ($document, defaultSplit) { var left = angular.element(children[0]); var right = angular.element(children[1]); + return function (scope, element, attr) { var slider = angular.element('
'); @@ -31,14 +34,14 @@ directive('batVerticalSplit', function ($document, defaultSplit) { slider.bind('mousedown', function (ev) { drag(ev); - oldCursor = $document.css('cursor'); - $document.css('cursor', 'ew-resize'); + oldCursor = body.css('cursor'); + body.css('cursor', 'ew-resize'); $document.bind('mousemove', drag); $document.bind('mouseup', stopDrag); }); var stopDrag = function () { - $document.css('cursor', oldCursor); + body.css('cursor', oldCursor); $document.unbind('mousemove', drag); $document.unbind('mouseup', stopDrag); }; diff --git a/js/inject/debug.js b/js/inject/debug.js index 3b76fed..972e081 100644 --- a/js/inject/debug.js +++ b/js/inject/debug.js @@ -3,7 +3,7 @@ // but injects an 'instrumentation' script tag into the app context // confusing, right? -var instument = function (window) { +var instument = function instument (window) { // Helper to determine if the root 'ng' module has been loaded // window.angular may be available if the app is bootstrapped asynchronously, but 'ng' might @@ -163,32 +163,6 @@ var instument = function (window) { // Utils // ===== - // this is silly - var getWatchTree = function (id) { - var traverse = function (sc) { - var tree = { - id: sc.$id, - watchers: debug.watchers[sc.$id], - children: [] - }; - - var child = sc.$$childHead; - if (child) { - do { - tree.children.push(traverse(child)); - } while (child !== sc.$$childTail && (child = child.$$nextSibling)); - } - - return tree; - }; - - var root = debug.rootScopes[id]; - var tree = traverse(root); - - return tree; - }; - - var getScopeTree = function (id) { var names = api.niceNames(); @@ -273,6 +247,16 @@ var instument = function (window) { }); }, 50), + watcherChange: throttle(function (id) { + if (debug.modelWatchers[id]) { + fireCustomEvent({ + action: 'watcherChange', + id: id, + watchers: debug.watchers[id] + }); + } + }, 50), + // might be worth limiting watchPerf: function () { throw new Error('Implement me :c'); @@ -447,6 +431,7 @@ var instument = function (window) { debug.modelWatchers[id] = debug.modelWatchers[id] || {}; debug.modelWatchers[id][path || ''] = true; emit.modelChange(id); + emit.watcherChange(id); }, // unwatches all children of the given path @@ -898,6 +883,7 @@ var instument = function (window) { debug.watchers[thatScope.$id] = []; } debug.watchers[thatScope.$id].push(watchStr); + emit.watcherChange(thatScope.$id); // patch watchExpression // --------------------- diff --git a/js/services/appContext.js b/js/services/appContext.js index 82e9854..a34e7ea 100644 --- a/js/services/appContext.js +++ b/js/services/appContext.js @@ -114,6 +114,16 @@ angular.module('panelApp').factory('appContext', function (chromeExtension, $roo }); } }); + }, + + watchWatcherChange: function (cb) { + port.onMessage.addListener(function (msg) { + if (msg.action === 'watcherChange') { + $rootScope.$apply(function () { + cb(msg); + }); + } + }); } }; diff --git a/panel.html b/panel.html index 9fe8ad8..afaf104 100644 --- a/panel.html +++ b/panel.html @@ -5,7 +5,12 @@ --> + + + + + diff --git a/panes/model.html b/panes/model.html index a10cf2a..509c8d8 100644 --- a/panes/model.html +++ b/panes/model.html @@ -1,7 +1,6 @@
-
-

Scopes

+
-
-      
-    
+
- -
-
    - -
  1. - <!DOCTYPE html> -
  2. -
  3. - <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7 ng-app: docsApp;" lang="en" ng-controller="DocsController"> <![endif]--> -
  4. -
  5. - <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8 ng-app: docsApp;" lang="en" ng-controller="DocsController"> <![endif]--> -
  6. -
  7. - <!--[if IE 8]> <html class="no-js lt-ie9 ng-app: docsApp;" lang="en" ng-controller="DocsController"> <![endif]--> -
  8. -
  9. - <!--[if gt IE 8]><!--> -
  10. -
  11. - <html class=​"no-js ng-app:​ docsApp;​ ng-scope" lang=​"en" ng-controller=​"DocsController"> -
  12. -
      -
    1. - <!--<![endif]--> -
    2. -
    3. - <head></head> -
    4. -
    5. - <body> -
    6. -
        -
      1. - <header class=​"header"> -
      2. -
          -
        1. - <div class=​"navbar navbar-fixed-top"></div> -
        2. -
        3. - </header> -
        4. -
        -
      3. - <div role=​"main" class=​"container"> -
      4. -
          -
        1. - <div class=​"row clear-navbar"></div> -
        2. -
        3. - <div class=​"row"></div> -
        4. -
            -
          1. - <div class=​"span12"></div> -
          2. -
              -
            1. -<!--[if lt IE 7]> -<p class="alert alert-error">Your browser is <em>ancient!</em> -<a href="http://browsehappy.com/">Upgrade to a different browser</a> or -<a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to -experience this site. -</p> -<![endif]--> -
            2. -
            3. - <!--[if lt IE 9]> -<div class="alert"> -You are using an old version of Internet Explorer. -For better and safer browsing experience please <a href="http://www.microsoft.com/IE9">upgrade IE</a> -or install <a href="http://google.com/chrome">Google Chrome browser</a>. -</div> -<![endif]--> -
            4. -
            5. - </div> -
            6. -
            -
          3. </div>
          4. -
          -
        5. - <div class=​"row"></div> -
        6. -
        7. - </div> -
        8. -
        -
      5. - <div id=​"fader" ng-show=​"subpage" style=​"display:​ none;​"></div> -
      6. -
      7. - <div id=​"subpage" ng-show=​"subpage" style=​"display:​ none;​"></div> -
      8. -
      9. - <footer class=​"footer"></footer> -
      10. -
      11. - <div id=​"__ngDebugElement" style=​"display:​ none;​"></div> -
      12. -
      13. - </body> -
      14. -
      -
    7. </html>
    8. -
    -
- - - - -