visuddhinanda 2 лет назад
Родитель
Сommit
39e55f570d

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
public/assets/css/ananke/main.min.css


BIN
public/assets/images/hero.jpg


BIN
public/assets/solarize/81022c3314ffc605ad71a490c5d5ad15eb59ece2-person.png


+ 39 - 0
public/assets/solarize/animate.css

@@ -0,0 +1,39 @@
+#github-corner:hover .octo-arm {
+	animation: octocat-wave 560ms ease-in-out;
+}
+
+@keyframes octocat-wave {
+	0% {
+		transform: rotate(0deg);
+	}
+
+	20% {
+		transform: rotate(-25deg);
+	}
+
+	40% {
+		transform: rotate(10deg);
+	}
+
+	60% {
+		transform: rotate(-25deg);
+	}
+
+	80% {
+		transform: rotate(10deg);
+	}
+
+	100% {
+		transform: rotate(0deg);
+	}
+}
+
+@media (max-width: 500px) {
+	#github-corner:hover .octo-arm {
+		animation: none;
+	}
+
+	#github-corner .octo-arm {
+		animation: octocat-wave 560ms ease-in-out;
+	}
+}

+ 314 - 0
public/assets/solarize/debugbar.css

@@ -0,0 +1,314 @@
+/* Hide debugbar when printing a page */
+@media print {
+  div.phpdebugbar {
+    display: none;
+  }
+}
+
+div.phpdebugbar {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  border-top: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
+  background: #fff;
+  z-index: 10000;
+  font-size: 14px;
+  color: #000;
+  text-align: left;
+  line-height: 1;
+  letter-spacing: normal;
+  direction: ltr;
+}
+
+div.phpdebugbar a,
+div.phpdebugbar-openhandler {
+  cursor: pointer;
+}
+
+div.phpdebugbar-drag-capture {
+  position: fixed;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  z-index: 10001;
+  background: none;
+  display: none;
+  cursor: ns-resize;
+}
+
+div.phpdebugbar-closed {
+    width: auto;
+}
+
+div.phpdebugbar * {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  font-weight: normal;
+  text-decoration: none;
+  clear: initial;
+  width: auto;
+  -moz-box-sizing: content-box;
+       box-sizing: content-box;
+}
+
+div.phpdebugbar ol, div.phpdebugbar ul {
+  list-style: none;
+}
+
+div.phpdebugbar table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+div.phpdebugbar input[type='text'], div.phpdebugbar input[type='password'] {
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
+  background: #fff;
+  font-size: 14px;
+  color: #000;
+  border: 0;
+  padding: 0;
+  margin: 0;
+}
+
+div.phpdebugbar code, div.phpdebugbar pre, div.phpdebugbar samp {
+  background: none;
+  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+  font-size: 1em;
+  border: 0;
+  padding: 0;
+  margin: 0;
+}
+
+div.phpdebugbar code, div.phpdebugbar pre {
+  color: #000;
+}
+
+div.phpdebugbar pre.sf-dump {
+  color: #a0a000;
+  outline: 0;
+}
+
+a.phpdebugbar-restore-btn {
+  float: left;
+  padding: 5px 8px;
+  font-size: 14px;
+  color: #555;
+  text-decoration: none;
+  border-right: 1px solid #ddd;
+}
+
+div.phpdebugbar-resize-handle {
+  display: none;
+  height: 4px;
+  margin-top: -4px;
+  width: 100%;
+  background: none;
+  border-bottom: 1px solid #ccc;
+  cursor: ns-resize;
+}
+
+div.phpdebugbar-closed, div.phpdebugbar-minimized{
+  border-top: 1px solid #ccc;
+}
+/* -------------------------------------- */
+
+div.phpdebugbar-header, a.phpdebugbar-restore-btn {
+    background: #efefef url(data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2020%2020%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Ccircle%20fill%3D%22%23000%22%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%229%22%2F%3E%3Cpath%20d%3D%22M6.039%208.342c.463%200%20.772.084.927.251.154.168.191.455.11.862-.084.424-.247.727-.487.908-.241.182-.608.272-1.1.272h-.743l.456-2.293h.837zm-2.975%204.615h1.22l.29-1.457H5.62c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.13-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H4.153l-1.089%205.479zM9.235%206.02h1.21l-.289%201.458h1.079c.679%200%201.147.115%201.405.347.258.231.335.607.232%201.125l-.507%202.55h-1.23l.481-2.424c.055-.276.035-.464-.06-.565-.095-.1-.298-.15-.608-.15H9.98L9.356%2011.5h-1.21l1.089-5.48M15.566%208.342c.464%200%20.773.084.928.251.154.168.19.455.11.862-.084.424-.247.727-.488.908-.24.182-.607.272-1.1.272h-.742l.456-2.293h.836zm-2.974%204.615h1.22l.29-1.457h1.046c.461%200%20.84-.047%201.139-.142.298-.095.569-.254.812-.477.205-.184.37-.387.497-.608.127-.222.217-.466.27-.734.129-.65.032-1.155-.292-1.518-.324-.362-.84-.543-1.545-.543H13.68l-1.089%205.479z%22%20fill%3D%22%23FFF%22%2F%3E%3C%2Fsvg%3E)  no-repeat 5px 4px / 20px 20px;
+}
+div.phpdebugbar-header {
+  padding-left: 29px;
+  min-height: 26px;
+  line-height: 16px;
+}
+div.phpdebugbar-header:before, div.phpdebugbar-header:after {
+  display: table;
+  line-height: 0;
+  content: "";
+}
+div.phpdebugbar-header:after {
+  clear: both;
+}
+div.phpdebugbar-header-left {
+  float: left;
+}
+div.phpdebugbar-header-right {
+  float: right;
+}
+div.phpdebugbar-header > div > * {
+  padding: 5px 5px;
+  font-size: 14px;
+  color: #555;
+  text-decoration: none;
+}
+div.phpdebugbar-header-left > * {
+  float: left;
+}
+div.phpdebugbar-header-right > * {
+  float: right;
+}
+div.phpdebugbar-header-right > select {
+  padding: 0;
+}
+
+/* -------------------------------------- */
+
+span.phpdebugbar-indicator,
+a.phpdebugbar-indicator,
+a.phpdebugbar-close-btn {
+  border-right: 1px solid #ddd;
+}
+
+a.phpdebugbar-tab.phpdebugbar-active {
+  background: #ccc;
+  color: #444;
+  background-image: linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
+  background-image: -o-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
+  background-image: -moz-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
+  background-image: -webkit-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
+  background-image: -ms-linear-gradient(bottom, rgb(173,173,173) 41%, rgb(209,209,209) 71%);
+  background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.41, rgb(173,173,173)), color-stop(0.71, rgb(209,209,209)));
+}
+  a.phpdebugbar-tab span.phpdebugbar-badge {
+    display: none;
+    margin-left: 5px;
+    font-size: 11px;
+    line-height: 14px;
+    padding: 0 6px;
+    background: #ccc;
+    border-radius: 4px;
+    color: #555;
+    font-weight: normal;
+    text-shadow: none;
+    vertical-align: middle;
+  }
+  a.phpdebugbar-tab i {
+    display: none;
+    vertical-align: middle;
+  }
+  a.phpdebugbar-tab span.phpdebugbar-badge.phpdebugbar-visible {
+    display: inline;
+  }
+  a.phpdebugbar-tab span.phpdebugbar-badge.phpdebugbar-important {
+    background: #ed6868;
+    color: white;
+  }
+
+a.phpdebugbar-close-btn, a.phpdebugbar-open-btn, a.phpdebugbar-restore-btn, a.phpdebugbar-minimize-btn , a.phpdebugbar-maximize-btn {
+  width: 16px;
+  height: 16px;
+}
+
+a.phpdebugbar-minimize-btn , a.phpdebugbar-maximize-btn {
+  padding-right: 0 !important;
+}
+
+a.phpdebugbar-maximize-btn { display: none}
+
+a.phpdebugbar-minimize-btn { display: block}
+
+div.phpdebugbar-minimized a.phpdebugbar-maximize-btn { display: block}
+
+div.phpdebugbar-minimized a.phpdebugbar-minimize-btn { display: none}
+
+a.phpdebugbar-minimize-btn {
+  background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22chevron-down%22%3E%3Cpath%20d%3D%22M1683%20808l-742%20741q-19%2019-45%2019t-45-19l-742-741q-19-19-19-45.5t19-45.5l166-165q19-19%2045-19t45%2019l531%20531%20531-531q19-19%2045-19t45%2019l166%20165q19%2019%2019%2045.5t-19%2045.5z%22%2F%3E%3C%2Fsvg%3E) no-repeat 6px 6px / 14px 14px;
+}
+
+a.phpdebugbar-maximize-btn {
+  background:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22chevron-up%22%3E%3Cpath%20d%3D%22M1683%201331l-166%20165q-19%2019-45%2019t-45-19l-531-531-531%20531q-19%2019-45%2019t-45-19l-166-165q-19-19-19-45.5t19-45.5l742-741q19-19%2045-19t45%2019l742%20741q19%2019%2019%2045.5t-19%2045.5z%22%2F%3E%3C%2Fsvg%3E) no-repeat 6px 6px / 14px 14px;
+}
+
+a.phpdebugbar-close-btn {
+  background: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22close%22%3E%3Cpath%20d%3D%22M1490%201322q0%2040-28%2068l-136%20136q-28%2028-68%2028t-68-28l-294-294-294%20294q-28%2028-68%2028t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28%2068-28t68%2028l294%20294%20294-294q28-28%2068-28t68%2028l136%20136q28%2028%2028%2068t-28%2068l-294%20294%20294%20294q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) no-repeat 9px 6px / 14px 14px;
+}
+
+a.phpdebugbar-open-btn {
+  background: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201792%201792%22%20id%3D%22folder-open%22%3E%3Cpath%20d%3D%22M1815%20952q0%2031-31%2066l-336%20396q-43%2051-120.5%2086.5t-143.5%2035.5h-1088q-34%200-60.5-13t-26.5-43q0-31%2031-66l336-396q43-51%20120.5-86.5t143.5-35.5h1088q34%200%2060.5%2013t26.5%2043zm-343-344v160h-832q-94%200-197%2047.5t-164%20119.5l-337%20396-5%206q0-4-.5-12.5t-.5-12.5v-960q0-92%2066-158t158-66h320q92%200%20158%2066t66%20158v32h544q92%200%20158%2066t66%20158z%22%2F%3E%3C%2Fsvg%3E) no-repeat 8px 6px / 14px 14px;
+}
+
+.phpdebugbar-indicator {
+  position: relative;
+  cursor: pointer;
+}
+  .phpdebugbar-indicator span.phpdebugbar-text {
+    margin-left: 5px;
+  }
+  .phpdebugbar-indicator span.phpdebugbar-tooltip {
+    display: none;
+    position: absolute;
+    top: -30px;
+    background: #efefef;
+    opacity: .7;
+    border: 1px solid #ccc;
+    color: #555;
+    font-size: 11px;
+    padding: 2px 3px;
+    z-index: 1000;
+    text-align: center;
+    width: 200%;
+    right: 0;
+  }
+  .phpdebugbar-indicator:hover span.phpdebugbar-tooltip:not(.phpdebugbar-disabled) {
+    display: block;
+  }
+
+select.phpdebugbar-datasets-switcher {
+  float: right;
+  display: none;
+  margin: 2px 0 0 7px;
+  max-width: 200px;
+  max-height: 23px;
+  padding: 0;
+}
+
+/* -------------------------------------- */
+
+div.phpdebugbar-body {
+  border-top: 1px solid #ccc;
+  display: none;
+  position: relative;
+  height: 300px;
+}
+
+/* -------------------------------------- */
+
+div.phpdebugbar-panel {
+  display: none;
+  height: 100%;
+  overflow: auto;
+  width: 100%;
+}
+div.phpdebugbar-panel.phpdebugbar-active {
+  display: block;
+}
+
+/* -------------------------------------- */
+
+div.phpdebugbar-mini-design a.phpdebugbar-tab {
+  position: relative;
+  border-right: 1px solid #ddd;
+}
+  div.phpdebugbar-mini-design a.phpdebugbar-tab span.phpdebugbar-text {
+    display: none;
+  }
+  div.phpdebugbar-mini-design a.phpdebugbar-tab:hover span.phpdebugbar-text {
+    display: block;
+    position: absolute;
+    top: -30px;
+    background: #efefef;
+    opacity: .7;
+    border: 1px solid #ccc;
+    color: #555;
+    font-size: 11px;
+    padding: 2px 3px;
+    z-index: 1000;
+    text-align: center;
+    right: 0;
+  }
+  div.phpdebugbar-mini-design a.phpdebugbar-tab i {
+    display:inline-block;
+  }

+ 1216 - 0
public/assets/solarize/debugbar.js

@@ -0,0 +1,1216 @@
+if (typeof(PhpDebugBar) == 'undefined') {
+    // namespace
+    var PhpDebugBar = {};
+    PhpDebugBar.$ = jQuery;
+}
+
+(function($) {
+
+    if (typeof(localStorage) == 'undefined') {
+        // provide mock localStorage object for dumb browsers
+        localStorage = {
+            setItem: function(key, value) {},
+            getItem: function(key) { return null; }
+        };
+    }
+
+    if (typeof(PhpDebugBar.utils) == 'undefined') {
+        PhpDebugBar.utils = {};
+    }
+
+    /**
+     * Returns the value from an object property.
+     * Using dots in the key, it is possible to retrieve nested property values
+     *
+     * @param {Object} dict
+     * @param {String} key
+     * @param {Object} default_value
+     * @return {Object}
+     */
+    var getDictValue = PhpDebugBar.utils.getDictValue = function(dict, key, default_value) {
+        var d = dict, parts = key.split('.');
+        for (var i = 0; i < parts.length; i++) {
+            if (!d[parts[i]]) {
+                return default_value;
+            }
+            d = d[parts[i]];
+        }
+        return d;
+    }
+
+    /**
+     * Counts the number of properties in an object
+     *
+     * @param {Object} obj
+     * @return {Integer}
+     */
+    var getObjectSize = PhpDebugBar.utils.getObjectSize = function(obj) {
+        if (Object.keys) {
+            return Object.keys(obj).length;
+        }
+        var count = 0;
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                count++;
+            }
+        }
+        return count;
+    }
+
+    /**
+     * Returns a prefixed css class name
+     *
+     * @param {String} cls
+     * @return {String}
+     */
+    PhpDebugBar.utils.csscls = function(cls, prefix) {
+        if (cls.indexOf(' ') > -1) {
+            var clss = cls.split(' '), out = [];
+            for (var i = 0, c = clss.length; i < c; i++) {
+                out.push(PhpDebugBar.utils.csscls(clss[i], prefix));
+            }
+            return out.join(' ');
+        }
+        if (cls.indexOf('.') === 0) {
+            return '.' + prefix + cls.substr(1);
+        }
+        return prefix + cls;
+    };
+
+    /**
+     * Creates a partial function of csscls where the second
+     * argument is already defined
+     *
+     * @param  {string} prefix
+     * @return {Function}
+     */
+    PhpDebugBar.utils.makecsscls = function(prefix) {
+        var f = function(cls) {
+            return PhpDebugBar.utils.csscls(cls, prefix);
+        };
+        return f;
+    }
+
+    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-');
+
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Base class for all elements with a visual component
+     *
+     * @param {Object} options
+     * @constructor
+     */
+    var Widget = PhpDebugBar.Widget = function(options) {
+        this._attributes = $.extend({}, this.defaults);
+        this._boundAttributes = {};
+        this.$el = $('<' + this.tagName + ' />');
+        if (this.className) {
+            this.$el.addClass(this.className);
+        }
+        this.initialize.apply(this, [options || {}]);
+        this.render.apply(this);
+    };
+
+    $.extend(Widget.prototype, {
+
+        tagName: 'div',
+
+        className: null,
+
+        defaults: {},
+
+        /**
+         * Called after the constructor
+         *
+         * @param {Object} options
+         */
+        initialize: function(options) {
+            this.set(options);
+        },
+
+        /**
+         * Called after the constructor to render the element
+         */
+        render: function() {},
+
+        /**
+         * Sets the value of an attribute
+         *
+         * @param {String} attr Can also be an object to set multiple attributes at once
+         * @param {Object} value
+         */
+        set: function(attr, value) {
+            if (typeof(attr) != 'string') {
+                for (var k in attr) {
+                    this.set(k, attr[k]);
+                }
+                return;
+            }
+
+            this._attributes[attr] = value;
+            if (typeof(this._boundAttributes[attr]) !== 'undefined') {
+                for (var i = 0, c = this._boundAttributes[attr].length; i < c; i++) {
+                    this._boundAttributes[attr][i].apply(this, [value]);
+                }
+            }
+        },
+
+        /**
+         * Checks if an attribute exists and is not null
+         *
+         * @param {String} attr
+         * @return {[type]} [description]
+         */
+        has: function(attr) {
+            return typeof(this._attributes[attr]) !== 'undefined' && this._attributes[attr] !== null;
+        },
+
+        /**
+         * Returns the value of an attribute
+         *
+         * @param {String} attr
+         * @return {Object}
+         */
+        get: function(attr) {
+            return this._attributes[attr];
+        },
+
+        /**
+         * Registers a callback function that will be called whenever the value of the attribute changes
+         *
+         * If cb is a jQuery element, text() will be used to fill the element
+         *
+         * @param {String} attr
+         * @param {Function} cb
+         */
+        bindAttr: function(attr, cb) {
+            if ($.isArray(attr)) {
+                for (var i = 0, c = attr.length; i < c; i++) {
+                    this.bindAttr(attr[i], cb);
+                }
+                return;
+            }
+
+            if (typeof(this._boundAttributes[attr]) == 'undefined') {
+                this._boundAttributes[attr] = [];
+            }
+            if (typeof(cb) == 'object') {
+                var el = cb;
+                cb = function(value) { el.text(value || ''); };
+            }
+            this._boundAttributes[attr].push(cb);
+            if (this.has(attr)) {
+                cb.apply(this, [this._attributes[attr]]);
+            }
+        }
+
+    });
+
+
+    /**
+     * Creates a subclass
+     *
+     * Code from Backbone.js
+     *
+     * @param {Array} props Prototype properties
+     * @return {Function}
+     */
+    Widget.extend = function(props) {
+        var parent = this;
+
+        var child = function() { return parent.apply(this, arguments); };
+        $.extend(child, parent);
+
+        var Surrogate = function() { this.constructor = child; };
+        Surrogate.prototype = parent.prototype;
+        child.prototype = new Surrogate;
+        $.extend(child.prototype, props);
+
+        child.__super__ = parent.prototype;
+
+        return child;
+    };
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Tab
+     *
+     * A tab is composed of a tab label which is always visible and
+     * a tab panel which is visible only when the tab is active.
+     *
+     * The panel must contain a widget. A widget is an object which has
+     * an element property containing something appendable to a jQuery object.
+     *
+     * Options:
+     *  - title
+     *  - badge
+     *  - widget
+     *  - data: forward data to widget data
+     */
+    var Tab = Widget.extend({
+
+        className: csscls('panel'),
+
+        render: function() {
+            this.$tab = $('<a />').addClass(csscls('tab'));
+
+            this.$icon = $('<i />').appendTo(this.$tab);
+            this.bindAttr('icon', function(icon) {
+                if (icon) {
+                    this.$icon.attr('class', 'phpdebugbar-fa phpdebugbar-fa-' + icon);
+                } else {
+                    this.$icon.attr('class', '');
+                }
+            });
+
+            this.bindAttr('title', $('<span />').addClass(csscls('text')).appendTo(this.$tab));
+
+            this.$badge = $('<span />').addClass(csscls('badge')).appendTo(this.$tab);
+            this.bindAttr('badge', function(value) {
+                if (value !== null) {
+                    this.$badge.text(value);
+                    this.$badge.addClass(csscls('visible'));
+                } else {
+                    this.$badge.removeClass(csscls('visible'));
+                }
+            });
+
+            this.bindAttr('widget', function(widget) {
+                this.$el.empty().append(widget.$el);
+            });
+
+            this.bindAttr('data', function(data) {
+                if (this.has('widget')) {
+                    this.get('widget').set('data', data);
+                }
+            })
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Indicator
+     *
+     * An indicator is a text and an icon to display single value information
+     * right inside the always visible part of the debug bar
+     *
+     * Options:
+     *  - icon
+     *  - title
+     *  - tooltip
+     *  - data: alias of title
+     */
+    var Indicator = Widget.extend({
+
+        tagName: 'span',
+
+        className: csscls('indicator'),
+
+        render: function() {
+            this.$icon = $('<i />').appendTo(this.$el);
+            this.bindAttr('icon', function(icon) {
+                if (icon) {
+                    this.$icon.attr('class', 'phpdebugbar-fa phpdebugbar-fa-' + icon);
+                } else {
+                    this.$icon.attr('class', '');
+                }
+            });
+
+            this.bindAttr(['title', 'data'], $('<span />').addClass(csscls('text')).appendTo(this.$el));
+
+            this.$tooltip = $('<span />').addClass(csscls('tooltip disabled')).appendTo(this.$el);
+            this.bindAttr('tooltip', function(tooltip) {
+                if (tooltip) {
+                    this.$tooltip.text(tooltip).removeClass(csscls('disabled'));
+                } else {
+                    this.$tooltip.addClass(csscls('disabled'));
+                }
+            });
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Dataset title formater
+     *
+     * Formats the title of a dataset for the select box
+     */
+    var DatasetTitleFormater = PhpDebugBar.DatasetTitleFormater = function(debugbar) {
+        this.debugbar = debugbar;
+    };
+
+    $.extend(DatasetTitleFormater.prototype, {
+
+        /**
+         * Formats the title of a dataset
+         *
+         * @this {DatasetTitleFormater}
+         * @param {String} id
+         * @param {Object} data
+         * @param {String} suffix
+         * @return {String}
+         */
+        format: function(id, data, suffix) {
+            if (suffix) {
+                suffix = ' ' + suffix;
+            } else {
+                suffix = '';
+            }
+
+            var nb = getObjectSize(this.debugbar.datasets) + 1;
+
+            if (typeof(data['__meta']) === 'undefined') {
+                return "#" + nb + suffix;
+            }
+
+            var uri = data['__meta']['uri'], filename;
+            if (uri.length && uri.charAt(uri.length - 1) === '/') {
+                // URI ends in a trailing /: get the portion before then to avoid returning an empty string
+                filename = uri.substr(0, uri.length - 1); // strip trailing '/'
+                filename = filename.substr(filename.lastIndexOf('/') + 1); // get last path segment
+                filename += '/'; // add the trailing '/' back
+            } else {
+                filename = uri.substr(uri.lastIndexOf('/') + 1);
+            }
+
+            // truncate the filename in the label, if it's too long
+            var maxLength = 150;
+            if (filename.length > maxLength) {
+                filename = filename.substr(0, maxLength) + '...';
+            }
+
+            var label = "#" + nb + " " + filename + suffix + ' (' + data['__meta']['datetime'].split(' ')[1] + ')';
+            return label;
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+
+    /**
+     * DebugBar
+     *
+     * Creates a bar that appends itself to the body of your page
+     * and sticks to the bottom.
+     *
+     * The bar can be customized by adding tabs and indicators.
+     * A data map is used to fill those controls with data provided
+     * from datasets.
+     */
+    var DebugBar = PhpDebugBar.DebugBar = Widget.extend({
+
+        className: "phpdebugbar " + csscls('minimized'),
+
+        options: {
+            bodyMarginBottom: true,
+            bodyMarginBottomHeight: 0
+        },
+
+        initialize: function() {
+            this.controls = {};
+            this.dataMap = {};
+            this.datasets = {};
+            this.firstTabName = null;
+            this.activePanelName = null;
+            this.datesetTitleFormater = new DatasetTitleFormater(this);
+            this.options.bodyMarginBottomHeight = parseInt($('body').css('margin-bottom'));
+            this.registerResizeHandler();
+        },
+
+        /**
+         * Register resize event, for resize debugbar with reponsive css.
+         *
+         * @this {DebugBar}
+         */
+        registerResizeHandler: function() {
+            if (typeof this.resize.bind == 'undefined') return;
+
+            var f = this.resize.bind(this);
+            this.respCSSSize = 0;
+            $(window).resize(f);
+            setTimeout(f, 20);
+        },
+
+        /**
+         * Resizes the debugbar to fit the current browser window
+         */
+        resize: function() {
+            var contentSize = this.respCSSSize;
+            if (this.respCSSSize == 0) {
+                this.$header.find("> div > *:visible").each(function () {
+                    contentSize += $(this).outerWidth();
+                });
+            }
+
+            var currentSize = this.$header.width();
+            var cssClass = "phpdebugbar-mini-design";
+            var bool = this.$header.hasClass(cssClass);
+
+            if (currentSize <= contentSize && !bool) {
+                this.respCSSSize = contentSize;
+                this.$header.addClass(cssClass);
+            } else if (contentSize < currentSize && bool) {
+                this.respCSSSize = 0;
+                this.$header.removeClass(cssClass);
+            }
+
+            // Reset height to ensure bar is still visible
+            this.setHeight(this.$body.height());
+        },
+
+        /**
+         * Initialiazes the UI
+         *
+         * @this {DebugBar}
+         */
+        render: function() {
+            var self = this;
+            this.$el.appendTo('body');
+            this.$dragCapture = $('<div />').addClass(csscls('drag-capture')).appendTo(this.$el);
+            this.$resizehdle = $('<div />').addClass(csscls('resize-handle')).appendTo(this.$el);
+            this.$header = $('<div />').addClass(csscls('header')).appendTo(this.$el);
+            this.$headerLeft = $('<div />').addClass(csscls('header-left')).appendTo(this.$header);
+            this.$headerRight = $('<div />').addClass(csscls('header-right')).appendTo(this.$header);
+            var $body = this.$body = $('<div />').addClass(csscls('body')).appendTo(this.$el);
+            this.recomputeBottomOffset();
+
+            // dragging of resize handle
+            var pos_y, orig_h;
+            this.$resizehdle.on('mousedown', function(e) {
+                orig_h = $body.height(), pos_y = e.pageY;
+                $body.parents().on('mousemove', mousemove).on('mouseup', mouseup);
+                self.$dragCapture.show();
+                e.preventDefault();
+            });
+            var mousemove = function(e) {
+                var h = orig_h + (pos_y - e.pageY);
+                self.setHeight(h);
+            };
+            var mouseup = function() {
+                $body.parents().off('mousemove', mousemove).off('mouseup', mouseup);
+                self.$dragCapture.hide();
+            };
+
+            // close button
+            this.$closebtn = $('<a />').addClass(csscls('close-btn')).appendTo(this.$headerRight);
+            this.$closebtn.click(function() {
+                self.close();
+            });
+
+            // minimize button
+            this.$minimizebtn = $('<a />').addClass(csscls('minimize-btn') ).appendTo(this.$headerRight);
+            this.$minimizebtn.click(function() {
+                self.minimize();
+            });
+
+            // maximize button
+            this.$maximizebtn = $('<a />').addClass(csscls('maximize-btn') ).appendTo(this.$headerRight);
+            this.$maximizebtn.click(function() {
+                self.restore();
+            });
+
+            // restore button
+            this.$restorebtn = $('<a />').addClass(csscls('restore-btn')).hide().appendTo(this.$el);
+            this.$restorebtn.click(function() {
+                self.restore();
+            });
+
+            // open button
+            this.$openbtn = $('<a />').addClass(csscls('open-btn')).appendTo(this.$headerRight).hide();
+            this.$openbtn.click(function() {
+                self.openHandler.show(function(id, dataset) {
+                    self.addDataSet(dataset, id, "(opened)");
+                    self.showTab();
+                });
+            });
+
+            // select box for data sets
+            this.$datasets = $('<select />').addClass(csscls('datasets-switcher')).appendTo(this.$headerRight);
+            this.$datasets.change(function() {
+                self.dataChangeHandler(self.datasets[this.value]);
+                self.showTab();
+            });
+        },
+
+        /**
+         * Sets the height of the debugbar body section
+         * Forces the height to lie within a reasonable range
+         * Stores the height in local storage so it can be restored
+         * Resets the document body bottom offset
+         *
+         * @this {DebugBar}
+         */
+        setHeight: function(height) {
+          var min_h = 40;
+          var max_h = $(window).innerHeight() - this.$header.height() - 10;
+          height = Math.min(height, max_h);
+          height = Math.max(height, min_h);
+          this.$body.css('height', height);
+          localStorage.setItem('phpdebugbar-height', height);
+          this.recomputeBottomOffset();
+        },
+
+        /**
+         * Restores the state of the DebugBar using localStorage
+         * This is not called by default in the constructor and
+         * needs to be called by subclasses in their init() method
+         *
+         * @this {DebugBar}
+         */
+        restoreState: function() {
+            // bar height
+            var height = localStorage.getItem('phpdebugbar-height');
+            this.setHeight(height || this.$body.height());
+
+            // bar visibility
+            var open = localStorage.getItem('phpdebugbar-open');
+            if (open && open == '0') {
+                this.close();
+            } else {
+                var visible = localStorage.getItem('phpdebugbar-visible');
+                if (visible && visible == '1') {
+                    var tab = localStorage.getItem('phpdebugbar-tab');
+                    if (this.isTab(tab)) {
+                        this.showTab(tab);
+                    }
+                }
+            }
+        },
+
+        /**
+         * Creates and adds a new tab
+         *
+         * @this {DebugBar}
+         * @param {String} name Internal name
+         * @param {Object} widget A widget object with an element property
+         * @param {String} title The text in the tab, if not specified, name will be used
+         * @return {Tab}
+         */
+        createTab: function(name, widget, title) {
+            var tab = new Tab({
+                title: title || (name.replace(/[_\-]/g, ' ').charAt(0).toUpperCase() + name.slice(1)),
+                widget: widget
+            });
+            return this.addTab(name, tab);
+        },
+
+        /**
+         * Adds a new tab
+         *
+         * @this {DebugBar}
+         * @param {String} name Internal name
+         * @param {Tab} tab Tab object
+         * @return {Tab}
+         */
+        addTab: function(name, tab) {
+            if (this.isControl(name)) {
+                throw new Error(name + ' already exists');
+            }
+
+            var self = this;
+            tab.$tab.appendTo(this.$headerLeft).click(function() {
+                if (!self.isMinimized() && self.activePanelName == name) {
+                    self.minimize();
+                } else {
+                    self.showTab(name);
+                }
+            });
+            tab.$el.appendTo(this.$body);
+
+            this.controls[name] = tab;
+            if (this.firstTabName == null) {
+                this.firstTabName = name;
+            }
+            return tab;
+        },
+
+        /**
+         * Creates and adds an indicator
+         *
+         * @this {DebugBar}
+         * @param {String} name Internal name
+         * @param {String} icon
+         * @param {String} tooltip
+         * @param {String} position "right" or "left", default is "right"
+         * @return {Indicator}
+         */
+        createIndicator: function(name, icon, tooltip, position) {
+            var indicator = new Indicator({
+                icon: icon,
+                tooltip: tooltip
+            });
+            return this.addIndicator(name, indicator, position);
+        },
+
+        /**
+         * Adds an indicator
+         *
+         * @this {DebugBar}
+         * @param {String} name Internal name
+         * @param {Indicator} indicator Indicator object
+         * @return {Indicator}
+         */
+        addIndicator: function(name, indicator, position) {
+            if (this.isControl(name)) {
+                throw new Error(name + ' already exists');
+            }
+
+            if (position == 'left') {
+                indicator.$el.insertBefore(this.$headerLeft.children().first());
+            } else {
+                indicator.$el.appendTo(this.$headerRight);
+            }
+
+            this.controls[name] = indicator;
+            return indicator;
+        },
+
+        /**
+         * Returns a control
+         *
+         * @param {String} name
+         * @return {Object}
+         */
+        getControl: function(name) {
+            if (this.isControl(name)) {
+                return this.controls[name];
+            }
+        },
+
+        /**
+         * Checks if there's a control under the specified name
+         *
+         * @this {DebugBar}
+         * @param {String} name
+         * @return {Boolean}
+         */
+        isControl: function(name) {
+            return typeof(this.controls[name]) != 'undefined';
+        },
+
+        /**
+         * Checks if a tab with the specified name exists
+         *
+         * @this {DebugBar}
+         * @param {String} name
+         * @return {Boolean}
+         */
+        isTab: function(name) {
+            return this.isControl(name) && this.controls[name] instanceof Tab;
+        },
+
+        /**
+         * Checks if an indicator with the specified name exists
+         *
+         * @this {DebugBar}
+         * @param {String} name
+         * @return {Boolean}
+         */
+        isIndicator: function(name) {
+            return this.isControl(name) && this.controls[name] instanceof Indicator;
+        },
+
+        /**
+         * Removes all tabs and indicators from the debug bar and hides it
+         *
+         * @this {DebugBar}
+         */
+        reset: function() {
+            this.minimize();
+            var self = this;
+            $.each(this.controls, function(name, control) {
+                if (self.isTab(name)) {
+                    control.$tab.remove();
+                }
+                control.$el.remove();
+            });
+            this.controls = {};
+        },
+
+        /**
+         * Open the debug bar and display the specified tab
+         *
+         * @this {DebugBar}
+         * @param {String} name If not specified, display the first tab
+         */
+        showTab: function(name) {
+            if (!name) {
+                if (this.activePanelName) {
+                    name = this.activePanelName;
+                } else {
+                    name = this.firstTabName;
+                }
+            }
+
+            if (!this.isTab(name)) {
+                throw new Error("Unknown tab '" + name + "'");
+            }
+
+            this.$resizehdle.show();
+            this.$body.show();
+            this.recomputeBottomOffset();
+
+            $(this.$header).find('> div > .' + csscls('active')).removeClass(csscls('active'));
+            $(this.$body).find('> .' + csscls('active')).removeClass(csscls('active'));
+
+            this.controls[name].$tab.addClass(csscls('active'));
+            this.controls[name].$el.addClass(csscls('active'));
+            this.activePanelName = name;
+
+            this.$el.removeClass(csscls('minimized'));
+            localStorage.setItem('phpdebugbar-visible', '1');
+            localStorage.setItem('phpdebugbar-tab', name);
+            this.resize();
+        },
+
+        /**
+         * Hide panels and minimize the debug bar
+         *
+         * @this {DebugBar}
+         */
+        minimize: function() {
+            this.$header.find('> div > .' + csscls('active')).removeClass(csscls('active'));
+            this.$body.hide();
+            this.$resizehdle.hide();
+            this.recomputeBottomOffset();
+            localStorage.setItem('phpdebugbar-visible', '0');
+            this.$el.addClass(csscls('minimized'));
+            this.resize();
+        },
+
+        /**
+         * Checks if the panel is minimized
+         *
+         * @return {Boolean}
+         */
+        isMinimized: function() {
+            return this.$el.hasClass(csscls('minimized'));
+        },
+
+        /**
+         * Close the debug bar
+         *
+         * @this {DebugBar}
+         */
+        close: function() {
+            this.$resizehdle.hide();
+            this.$header.hide();
+            this.$body.hide();
+            this.$restorebtn.show();
+            localStorage.setItem('phpdebugbar-open', '0');
+            this.$el.addClass(csscls('closed'));
+            this.recomputeBottomOffset();
+        },
+
+        /**
+         * Checks if the panel is closed
+         *
+         * @return {Boolean}
+         */
+        isClosed: function() {
+            return this.$el.hasClass(csscls('closed'));
+        },
+
+        /**
+         * Restore the debug bar
+         *
+         * @this {DebugBar}
+         */
+        restore: function() {
+            this.$resizehdle.show();
+            this.$header.show();
+            this.$restorebtn.hide();
+            localStorage.setItem('phpdebugbar-open', '1');
+            var tab = localStorage.getItem('phpdebugbar-tab');
+            if (this.isTab(tab)) {
+                this.showTab(tab);
+            } else {
+                this.showTab();
+            }
+            this.$el.removeClass(csscls('closed'));
+            this.resize();
+        },
+
+        /**
+         * Recomputes the margin-bottom css property of the body so
+         * that the debug bar never hides any content
+         */
+        recomputeBottomOffset: function() {
+            if (this.options.bodyMarginBottom) {
+                if (this.isClosed()) {
+                    return $('body').css('margin-bottom', this.options.bodyMarginBottomHeight || '');
+                }
+
+                var offset = parseInt(this.$el.height()) + (this.options.bodyMarginBottomHeight || 0);
+                $('body').css('margin-bottom', offset);
+            }
+        },
+
+        /**
+         * Sets the data map used by dataChangeHandler to populate
+         * indicators and widgets
+         *
+         * A data map is an object where properties are control names.
+         * The value of each property should be an array where the first
+         * item is the name of a property from the data object (nested properties
+         * can be specified) and the second item the default value.
+         *
+         * Example:
+         *     {"memory": ["memory.peak_usage_str", "0B"]}
+         *
+         * @this {DebugBar}
+         * @param {Object} map
+         */
+        setDataMap: function(map) {
+            this.dataMap = map;
+        },
+
+        /**
+         * Same as setDataMap() but appends to the existing map
+         * rather than replacing it
+         *
+         * @this {DebugBar}
+         * @param {Object} map
+         */
+        addDataMap: function(map) {
+            $.extend(this.dataMap, map);
+        },
+
+        /**
+         * Resets datasets and add one set of data
+         *
+         * For this method to be usefull, you need to specify
+         * a dataMap using setDataMap()
+         *
+         * @this {DebugBar}
+         * @param {Object} data
+         * @return {String} Dataset's id
+         */
+        setData: function(data) {
+            this.datasets = {};
+            return this.addDataSet(data);
+        },
+
+        /**
+         * Adds a dataset
+         *
+         * If more than one dataset are added, the dataset selector
+         * will be displayed.
+         *
+         * For this method to be usefull, you need to specify
+         * a dataMap using setDataMap()
+         *
+         * @this {DebugBar}
+         * @param {Object} data
+         * @param {String} id The name of this set, optional
+         * @param {String} suffix
+         * @param {Bool} show Whether to show the new dataset, optional (default: true)
+         * @return {String} Dataset's id
+         */
+        addDataSet: function(data, id, suffix, show) {
+            var label = this.datesetTitleFormater.format(id, data, suffix);
+            id = id || (getObjectSize(this.datasets) + 1);
+            this.datasets[id] = data;
+
+            this.$datasets.append($('<option value="' + id + '">' + label + '</option>'));
+            if (this.$datasets.children().length > 1) {
+                this.$datasets.show();
+            }
+
+            if (typeof(show) == 'undefined' || show) {
+                this.showDataSet(id);
+            }
+            return id;
+        },
+
+        /**
+         * Loads a dataset using the open handler
+         *
+         * @param {String} id
+         * @param {Bool} show Whether to show the new dataset, optional (default: true)
+         */
+        loadDataSet: function(id, suffix, callback, show) {
+            if (!this.openHandler) {
+                throw new Error('loadDataSet() needs an open handler');
+            }
+            var self = this;
+            this.openHandler.load(id, function(data) {
+                self.addDataSet(data, id, suffix, show);
+                self.resize();
+                callback && callback(data);
+            });
+        },
+
+        /**
+         * Returns the data from a dataset
+         *
+         * @this {DebugBar}
+         * @param {String} id
+         * @return {Object}
+         */
+        getDataSet: function(id) {
+            return this.datasets[id];
+        },
+
+        /**
+         * Switch the currently displayed dataset
+         *
+         * @this {DebugBar}
+         * @param {String} id
+         */
+        showDataSet: function(id) {
+            this.dataChangeHandler(this.datasets[id]);
+            this.$datasets.val(id);
+        },
+
+        /**
+         * Called when the current dataset is modified.
+         *
+         * @this {DebugBar}
+         * @param {Object} data
+         */
+        dataChangeHandler: function(data) {
+            var self = this;
+            $.each(this.dataMap, function(key, def) {
+                var d = getDictValue(data, def[0], def[1]);
+                if (key.indexOf(':') != -1) {
+                    key = key.split(':');
+                    self.getControl(key[0]).set(key[1], d);
+                } else {
+                    self.getControl(key).set('data', d);
+                }
+            });
+        },
+
+        /**
+         * Sets the handler to open past dataset
+         *
+         * @this {DebugBar}
+         * @param {object} handler
+         */
+        setOpenHandler: function(handler) {
+            this.openHandler = handler;
+            if (handler !== null) {
+                this.$openbtn.show();
+            } else {
+                this.$openbtn.hide();
+            }
+        },
+
+        /**
+         * Returns the handler to open past dataset
+         *
+         * @this {DebugBar}
+         * @return {object}
+         */
+        getOpenHandler: function() {
+            return this.openHandler;
+        }
+
+    });
+
+    DebugBar.Tab = Tab;
+    DebugBar.Indicator = Indicator;
+
+    // ------------------------------------------------------------------
+
+    /**
+     * AjaxHandler
+     *
+     * Extract data from headers of an XMLHttpRequest and adds a new dataset
+     *
+     * @param {Bool} autoShow Whether to immediately show new datasets, optional (default: true)
+     */
+    var AjaxHandler = PhpDebugBar.AjaxHandler = function(debugbar, headerName, autoShow) {
+        this.debugbar = debugbar;
+        this.headerName = headerName || 'phpdebugbar';
+        this.autoShow = typeof(autoShow) == 'undefined' ? true : autoShow;
+    };
+
+    $.extend(AjaxHandler.prototype, {
+
+        /**
+         * Handles a Fetch API Response or an XMLHttpRequest
+         *
+         * @this {AjaxHandler}
+         * @param {Response|XMLHttpRequest} response
+         * @return {Bool}
+         */
+        handle: function(response) {
+            // Check if the debugbar header is available
+            if (this.isFetch(response) && !response.headers.has(this.headerName + '-id')) {
+                return true;
+            } else if (this.isXHR(response) && response.getAllResponseHeaders().indexOf(this.headerName) === -1) {
+                return true;
+            }
+            if (!this.loadFromId(response)) {
+                return this.loadFromData(response);
+            }
+            return true;
+        },
+
+        getHeader: function(response, header) {
+            if (this.isFetch(response)) {
+                return response.headers.get(header)
+            }
+
+            return response.getResponseHeader(header)
+        },
+
+        isFetch: function(response) {
+            return Object.prototype.toString.call(response) == '[object Response]'
+        },
+
+        isXHR: function(response) {
+            return Object.prototype.toString.call(response) == '[object XMLHttpRequest]'
+        },
+
+        /**
+         * Checks if the HEADER-id exists and loads the dataset using the open handler
+         *
+         * @param {Response|XMLHttpRequest} response
+         * @return {Bool}
+         */
+        loadFromId: function(response) {
+            var id = this.extractIdFromHeaders(response);
+            if (id && this.debugbar.openHandler) {
+                this.debugbar.loadDataSet(id, "(ajax)", undefined, this.autoShow);
+                return true;
+            }
+            return false;
+        },
+
+        /**
+         * Extracts the id from the HEADER-id
+         *
+         * @param {Response|XMLHttpRequest} response
+         * @return {String}
+         */
+        extractIdFromHeaders: function(response) {
+            return this.getHeader(response, this.headerName + '-id');
+        },
+
+        /**
+         * Checks if the HEADER exists and loads the dataset
+         *
+         * @param {Response|XMLHttpRequest} response
+         * @return {Bool}
+         */
+        loadFromData: function(response) {
+            var raw = this.extractDataFromHeaders(response);
+            if (!raw) {
+                return false;
+            }
+
+            var data = this.parseHeaders(raw);
+            if (data.error) {
+                throw new Error('Error loading debugbar data: ' + data.error);
+            } else if(data.data) {
+                this.debugbar.addDataSet(data.data, data.id, "(ajax)", this.autoShow);
+            }
+            return true;
+        },
+
+        /**
+         * Extract the data as a string from headers of an XMLHttpRequest
+         *
+         * @this {AjaxHandler}
+         * @param {Response|XMLHttpRequest} response
+         * @return {string}
+         */
+        extractDataFromHeaders: function(response) {
+            var data = this.getHeader(response, this.headerName);
+            if (!data) {
+                return;
+            }
+            for (var i = 1;; i++) {
+                var header = this.getHeader(response, this.headerName + '-' + i);
+                if (!header) {
+                    break;
+                }
+                data += header;
+            }
+            return decodeURIComponent(data);
+        },
+
+        /**
+         * Parses the string data into an object
+         *
+         * @this {AjaxHandler}
+         * @param {string} data
+         * @return {string}
+         */
+        parseHeaders: function(data) {
+            return JSON.parse(data);
+        },
+
+        /**
+         * Attaches an event listener to fetch
+         *
+         * @this {AjaxHandler}
+         */
+        bindToFetch: function() {
+            var self = this;
+            var proxied = window.fetch;
+
+            if (proxied !== undefined && proxied.polyfill !== undefined) {
+                return;
+            }
+
+            window.fetch = function () {
+                var promise = proxied.apply(this, arguments);
+
+                promise.then(function (response) {
+                    self.handle(response);
+                });
+
+                return promise;
+            };
+        },
+
+        /**
+         * Attaches an event listener to jQuery.ajaxComplete()
+         *
+         * @this {AjaxHandler}
+         * @param {jQuery} jq Optional
+         */
+        bindToJquery: function(jq) {
+            var self = this;
+            jq(document).ajaxComplete(function(e, xhr, settings) {
+                if (!settings.ignoreDebugBarAjaxHandler) {
+                    self.handle(xhr);
+                }
+            });
+        },
+
+        /**
+         * Attaches an event listener to XMLHttpRequest
+         *
+         * @this {AjaxHandler}
+         */
+        bindToXHR: function() {
+            var self = this;
+            var proxied = XMLHttpRequest.prototype.open;
+            XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
+                var xhr = this;
+                this.addEventListener("readystatechange", function() {
+                    var skipUrl = self.debugbar.openHandler ? self.debugbar.openHandler.get('url') : null;
+                    if (xhr.readyState == 4 && url.indexOf(skipUrl) !== 0) {
+                        self.handle(xhr);
+                    }
+                }, false);
+                proxied.apply(this, Array.prototype.slice.call(arguments));
+            };
+        }
+
+    });
+
+})(PhpDebugBar.$);

Разница между файлами не показана из-за своего большого размера
+ 70 - 0
public/assets/solarize/init.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
public/assets/solarize/jquery-3.x.min.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
public/assets/solarize/jquery.dropotron.min.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
public/assets/solarize/jquery.min.js


+ 32 - 0
public/assets/solarize/notices.css

@@ -0,0 +1,32 @@
+.notices {
+    padding: 1px 1px 1px 30px;
+    margin: 15px 0;
+}
+
+.notices p {
+
+}
+
+.notices.yellow {
+    border-left: 10px solid #f0ad4e;
+    background: #fcf8f2;
+    color: #df8a13;
+}
+
+.notices.red {
+    border-left: 10px solid #d9534f;
+    background: #fdf7f7;
+    color: #b52b27;
+}
+
+.notices.blue {
+    border-left: 10px solid #5bc0de;
+    background: #f4f8fa;
+    color: #28a1c5;
+}
+
+.notices.green {
+    border-left: 10px solid #5cb85c;
+    background: #f1f9f1;
+    color: #3d8b3d;
+}

Разница между файлами не показана из-за своего большого размера
+ 33 - 0
public/assets/solarize/openhandler.css


+ 202 - 0
public/assets/solarize/openhandler.js

@@ -0,0 +1,202 @@
+if (typeof(PhpDebugBar) == 'undefined') {
+    // namespace
+    var PhpDebugBar = {};
+    PhpDebugBar.$ = jQuery;
+}
+
+(function($) {
+
+    var csscls = function(cls) {
+        return PhpDebugBar.utils.csscls(cls, 'phpdebugbar-openhandler-');
+    };
+
+    PhpDebugBar.OpenHandler = PhpDebugBar.Widget.extend({
+
+        className: 'phpdebugbar-openhandler',
+
+        defaults: {
+            items_per_page: 20
+        },
+
+        render: function() {
+            var self = this;
+
+            this.$el.appendTo('body').hide();
+            this.$closebtn = $('<a><i class="phpdebugbar-fa phpdebugbar-fa-times"></i></a>');
+            this.$table = $('<tbody />');
+            $('<div>PHP DebugBar | Open</div>').addClass(csscls('header')).append(this.$closebtn).appendTo(this.$el);
+            $('<table><thead><tr><th width="150">Date</th><th width="55">Method</th><th>URL</th><th width="125">IP</th><th width="100">Filter data</th></tr></thead></table>').append(this.$table).appendTo(this.$el);
+            this.$actions = $('<div />').addClass(csscls('actions')).appendTo(this.$el);
+
+            this.$closebtn.on('click', function() {
+                self.hide();
+            });
+
+            this.$loadmorebtn = $('<a>Load more</a>')
+                .appendTo(this.$actions)
+                .on('click', function() {
+                    self.find(self.last_find_request, self.last_find_request.offset + self.get('items_per_page'), self.handleFind.bind(self));
+                });
+
+            this.$showonlycurrentbtn = $('<a>Show only current URL</a>')
+                .appendTo(this.$actions)
+                .on('click', function() {
+                    self.$table.empty();
+                    self.find({uri: window.location.pathname}, 0, self.handleFind.bind(self));
+                });
+
+            this.$showallbtn = $('<a>Show all</a>')
+                .appendTo(this.$actions)
+                .on('click', function() {
+                    self.refresh();
+                });
+
+            this.$clearbtn = $('<a>Delete all</a>')
+                .appendTo(this.$actions)
+                .on('click', function() {
+                    self.clear(function() {
+                        self.hide();
+                    });
+                });
+                
+            this.addSearch();
+
+            this.$overlay = $('<div />').addClass(csscls('overlay')).hide().appendTo('body');
+            this.$overlay.on('click', function() {
+                self.hide();
+            });
+        },
+
+        refresh: function() {
+            this.$table.empty();
+            this.$loadmorebtn.show();
+            this.find({}, 0, this.handleFind.bind(this));
+        },
+        
+        addSearch: function(){
+            var self = this;
+            var searchBtn = $('<button />')
+                .text('Search')
+                .attr('type', 'submit')
+                .on('click', function(e) {
+                    self.$table.empty();
+                    var search = {};
+                    var a = $(this).parent().serializeArray();
+                    $.each(a, function() {
+                        if(this.value){
+                            search[this.name] = this.value;
+                        }
+                    });
+
+                    self.find(search, 0, self.handleFind.bind(self));
+                    e.preventDefault();
+                });
+
+            $('<form />')
+                .append('<br/><b>Filter results</b><br/>')
+                .append('Method: <select name="method"><option></option><option>GET</option><option>POST</option><option>PUT</option><option>DELETE</option></select><br/>')
+                .append('Uri: <input type="text" name="uri"><br/>')
+                .append('IP: <input type="text" name="ip"><br/>')
+                .append(searchBtn)
+                .appendTo(this.$actions);
+        },
+
+        handleFind: function(data) {
+            var self = this;
+            $.each(data, function(i, meta) {
+               var a = $('<a />')
+                    .text('Load dataset')
+                    .on('click', function(e) {
+                       self.hide();
+                       self.load(meta['id'], function(data) {
+                           self.callback(meta['id'], data);
+                       });
+                       e.preventDefault();
+                    });
+                    
+                var method = $('<a />')
+                    .text(meta['method'])
+                    .on('click', function(e) {
+                        self.$table.empty();
+                        self.find({method: meta['method']}, 0, self.handleFind.bind(self));
+                        e.preventDefault();
+                    });
+
+                var uri = $('<a />')
+                    .text(meta['uri'])
+                    .on('click', function(e) {
+                        self.hide();
+                        self.load(meta['id'], function(data) {
+                            self.callback(meta['id'], data);
+                        });
+                        e.preventDefault();
+                    });
+
+                var ip = $('<a />')
+                    .text(meta['ip'])
+                    .on('click', function(e) {
+                        self.$table.empty();
+                        self.find({ip: meta['ip']}, 0, self.handleFind.bind(self));
+                        e.preventDefault();
+                    });
+
+                var search = $('<a />')
+                    .text('Show URL')
+                    .on('click', function(e) {
+                        self.$table.empty();
+                        self.find({uri: meta['uri']}, 0, self.handleFind.bind(self));
+                        e.preventDefault();
+                    });
+                    
+                $('<tr />')
+                    .append('<td>' + meta['datetime'] + '</td>')
+                    .append('<td>' + meta['method'] + '</td>')
+                    .append($('<td />').append(uri))
+                    .append($('<td />').append(ip))
+                    .append($('<td />').append(search))
+                    .appendTo(self.$table);
+            });
+            if (data.length < this.get('items_per_page')) {
+                this.$loadmorebtn.hide();
+            }
+        },
+
+        show: function(callback) {
+            this.callback = callback;
+            this.$el.show();
+            this.$overlay.show();
+            this.refresh();
+        },
+
+        hide: function() {
+            this.$el.hide();
+            this.$overlay.hide();
+        },
+
+        find: function(filters, offset, callback) {
+            var data = $.extend({}, filters, {max: this.get('items_per_page'), offset: offset || 0});
+            this.last_find_request = data;
+            this.ajax(data, callback);
+        },
+
+        load: function(id, callback) {
+            this.ajax({op: "get", id: id}, callback);
+        },
+
+        clear: function(callback) {
+            this.ajax({op: "clear"}, callback);
+        },
+
+        ajax: function(data, callback) {
+            $.ajax({
+                dataType: 'json',
+                url: this.get('url'),
+                data: data,
+                success: callback,
+                ignoreDebugBarAjaxHandler: true
+            });
+        }
+
+    });
+
+})(PhpDebugBar.$);

+ 1 - 0
public/assets/solarize/plausible.outbound-links.js

@@ -0,0 +1 @@
+!function(){"use strict";var a=window.location,r=window.document,t=window.localStorage,o=r.currentScript,s=o.getAttribute("data-api")||new URL(o.src).origin+"/api/event",l=t&&t.plausible_ignore;function p(t){console.warn("Ignoring Event: "+t)}function e(t,e){if(/^localhost$|^127(\.[0-9]+){0,2}\.[0-9]+$|^\[::1?\]$/.test(a.hostname)||"file:"===a.protocol)return p("localhost");if(!(window._phantom||window.__nightmare||window.navigator.webdriver||window.Cypress)){if("true"==l)return p("localStorage flag");var i={};i.n=t,i.u=a.href,i.d=o.getAttribute("data-domain"),i.r=r.referrer||null,i.w=window.innerWidth,e&&e.meta&&(i.m=JSON.stringify(e.meta)),e&&e.props&&(i.p=JSON.stringify(e.props));var n=new XMLHttpRequest;n.open("POST",s,!0),n.setRequestHeader("Content-Type","text/plain"),n.send(JSON.stringify(i)),n.onreadystatechange=function(){4==n.readyState&&e&&e.callback&&e.callback()}}}function i(t){for(var e=t.target,i="auxclick"==t.type&&2==t.which,n="click"==t.type;e&&(void 0===e.tagName||"a"!=e.tagName.toLowerCase()||!e.href);)e=e.parentNode;e&&e.href&&e.host&&e.host!==a.host&&((i||n)&&plausible("Outbound Link: Click",{props:{url:e.href}}),e.target&&!e.target.match(/^_(self|parent|top)$/i)||t.ctrlKey||t.metaKey||t.shiftKey||!n||(setTimeout(function(){a.href=e.href},150),t.preventDefault()))}r.addEventListener("click",i),r.addEventListener("auxclick",i);var n=window.plausible&&window.plausible.q||[];window.plausible=e;for(var c,d=0;d<n.length;d++)e.apply(this,n[d]);function u(){c!==a.pathname&&(c=a.pathname,e("pageview"))}var w,h=window.history;h.pushState&&(w=h.pushState,h.pushState=function(){w.apply(this,arguments),u()},window.addEventListener("popstate",u)),"prerender"===r.visibilityState?r.addEventListener("visibilitychange",function(){c||"visible"!==r.visibilityState||u()}):u()}();

+ 64 - 0
public/assets/solarize/sash-ribbon.css

@@ -0,0 +1,64 @@
+/* thanks to https://codepen.io/nxworld/pen/oLdoWb */
+.sash-box {
+  position: relative;
+  max-width: 225px;
+  /*width: 90%;
+  height: 400px;
+  background: #fff; */
+  box-shadow: 0 0 15px rgba(0,0,0,.1);
+  opacity: 0.85;
+  z-index: 999;
+}
+
+/* common */
+.ribbon {
+  width: 150px;
+  height: 150px;
+  overflow: hidden;
+  position: absolute;
+}
+.ribbon::before,
+.ribbon::after {
+  position: absolute;
+  z-index: -1;
+  content: '';
+  display: block;
+  border: 5px solid #2980b9;
+}
+.ribbon span {
+  position: absolute;
+  display: block;
+  width: 225px;
+  padding: 15px 0;
+  background-color: #3498db;
+  box-shadow: 0 5px 10px rgba(0,0,0,.1);
+  color: #fff;
+  font: 700 18px/1 'Lato', sans-serif;
+  text-shadow: 0 1px 1px rgba(0,0,0,.2);
+  text-transform: uppercase;
+  text-align: center;
+}
+
+/* top left*/
+.ribbon-top-left {
+  top: -10px;
+  left: -10px;
+}
+.ribbon-top-left::before,
+.ribbon-top-left::after {
+  border-top-color: transparent;
+  border-left-color: transparent;
+}
+.ribbon-top-left::before {
+  top: 10px;
+  right: 10px;
+}
+.ribbon-top-left::after {
+  bottom: 10px;
+  left: 10px;
+}
+.ribbon-top-left span {
+  right: -25px;
+  top: 30px;
+  transform: rotate(-45deg);
+}

Разница между файлами не показана из-за своего большого размера
+ 2 - 0
public/assets/solarize/saved_resource.html


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
public/assets/solarize/skel-layers.min.js


Разница между файлами не показана из-за своего большого размера
+ 1 - 0
public/assets/solarize/skel.min.js


+ 12 - 0
public/assets/solarize/style-wide.css

@@ -0,0 +1,12 @@
+/*
+	Solarize by TEMPLATED
+	templated.co @templatedco
+	Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
+*/
+
+/* Basic */
+
+	body, input, select, textarea {
+		font-size: 12pt;
+		line-height: 1.8em;
+	}

+ 811 - 0
public/assets/solarize/style.css

@@ -0,0 +1,811 @@
+@import url("font-awesome.min.css");
+@import url("//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800");
+
+/*
+	Solarize by TEMPLATED
+	templated.co @templatedco
+	Released for free under the Creative Commons Attribution 3.0 license (templated.co/license)
+*/
+
+/* Basic */
+
+	body {
+		background: #222222;
+	}
+
+		body.loading * {
+			-moz-transition: none !important;
+			-webkit-transition: none !important;
+			-o-transition: none !important;
+			-ms-transition: none !important;
+			transition: none !important;
+			-moz-animation: none !important;
+			-webkit-animation: none !important;
+			-o-animation: none !important;
+			-ms-animation: none !important;
+			animation: none !important;
+		}
+
+	body, input, select, textarea {
+		color: #555555;
+		font-family: 'Open Sans', sans-serif;
+		font-size: 12pt;
+		font-weight: 300;
+		line-height: 1.65em;
+	}
+
+	a {
+		color: #82b440;
+		text-decoration: underline;
+	}
+
+	strong, b {
+		font-weight: 700;
+	}
+
+	em, i {
+		font-style: italic;
+	}
+
+	p, ul, ol, dl, table, blockquote {
+		margin: 0 0 2em 0;
+	}
+
+	p {
+		line-height: 1.8em;
+	}
+
+		p.medium {
+			font-size: 1.4em;
+		}
+
+	h1, h2, h3, h4, h5, h6 {
+		color: inherit;
+		font-weight: 700;
+	}
+
+		h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
+			color: inherit;
+			text-decoration: none;
+		}
+
+	h2 {
+		font-size: 1.5em;
+	}
+
+	h3 {
+		font-size: 1.25em;
+	}
+
+	sub {
+		font-size: 0.8em;
+		position: relative;
+		top: 0.5em;
+	}
+
+	sup {
+		font-size: 0.8em;
+		position: relative;
+		top: -0.5em;
+	}
+
+	hr {
+		border-top: solid 1px #82b440;
+		border: 0;
+		margin-bottom: 1.5em;
+	}
+
+	blockquote {
+		border-left: solid 0.5em #82b440;
+		font-style: italic;
+		padding: 1em 0 1em 2em;
+	}
+
+	section.special, article.special {
+		text-align: center;
+	}
+
+	header.major {
+		padding-bottom: 3em;
+		text-align: center;
+		text-transform: uppercase;
+	}
+
+		header.major h2 {
+			font-size: 2.6em;
+			font-weight: 700;
+		}
+
+		header.major .byline {
+			display: block;
+			padding-top: 1em;
+			letter-spacing: 1px;
+			font-size: 1.4em;
+		}
+
+	footer > :last-child {
+		margin-bottom: 0;
+	}
+
+	footer.major {
+		padding-top: 3em;
+	}
+
+/* Form */
+
+	input[type="text"],
+	input[type="password"],
+	input[type="email"],
+	textarea {
+		-moz-appearance: none;
+		-webkit-appearance: none;
+		-o-appearance: none;
+		-ms-appearance: none;
+		appearance: none;
+		background: none;
+		border: solid 1px #82b440;
+		color: inherit;
+		display: block;
+		outline: 0;
+		padding: 0.75em;
+		text-decoration: none;
+		width: 100%;
+	}
+
+		input[type="text"]:focus,
+		input[type="password"]:focus,
+		input[type="email"]:focus,
+		textarea:focus {
+			border-color: #82b440;
+		}
+
+	input[type="text"],
+	input[type="password"],
+	input[type="email"] {
+		line-height: 1em;
+	}
+
+	::-webkit-input-placeholder {
+		color: inherit;
+		opacity: 0.5;
+		position: relative;
+		top: 3px;
+	}
+
+	:-moz-placeholder {
+		color: inherit;
+		opacity: 0.5;
+	}
+
+	::-moz-placeholder {
+		color: inherit;
+		opacity: 0.5;
+	}
+
+	:-ms-input-placeholder {
+		color: inherit;
+		opacity: 0.5;
+	}
+
+	.formerize-placeholder {
+		color: rgba(85, 85, 85, 0.5) !important;
+	}
+
+/* Image */
+
+	.image {
+		border: 0;
+		position: relative;
+	}
+
+		.image.fit {
+			display: block;
+		}
+
+			.image.fit img {
+				display: block;
+				width: 100%;
+			}
+
+		.image.feature {
+			display: block;
+			margin: 0 0 2em 0;
+		}
+
+			.image.feature img {
+				display: block;
+				width: 100%;
+			}
+
+/* Icon */
+
+	.icon {
+		position: relative;
+	}
+
+		.icon:before {
+			content: "";
+			-moz-osx-font-smoothing: grayscale;
+			-webkit-font-smoothing: antialiased;
+			font-family: FontAwesome;
+			font-style: normal;
+			font-weight: normal;
+			text-transform: none !important;
+		}
+
+		.icon > .label {
+			display: none;
+		}
+
+/* Lists */
+
+	ol.default {
+		list-style: decimal;
+		padding-left: 1.25em;
+	}
+
+		ol.default li {
+			padding-left: 0.25em;
+		}
+
+	ul.default {
+		margin: 0;
+		padding: 0;
+		list-style: none;
+	}
+
+		ul.default li {
+			padding: 0.40em 0em;
+		}
+
+	ul.icons {
+		cursor: default;
+		padding-bottom: 2em;
+	}
+
+		ul.icons li {
+			display: inline-block;
+			line-height: 1em;
+			padding: 0.5em 1em;
+		}
+
+			ul.icons li:first-child {
+				padding-left: 0;
+			}
+
+			ul.icons li span {
+				display: none;
+			}
+
+			ul.icons li a {
+				text-decoration: none;
+				font-size: 2em;
+				color: inherit;
+				opacity: 0.2;
+				-moz-transition: all 0.35s ease-in-out;
+				-webkit-transition: all 0.35s ease-in-out;
+				-o-transition: all 0.35s ease-in-out;
+				-ms-transition: all 0.35s ease-in-out;
+				transition: all 0.35s ease-in-out;
+			}
+
+			ul.icons li a:hover {
+				color: inherit;
+				opacity: 1;
+			}
+
+	ul.actions {
+		cursor: default;
+	}
+
+		ul.actions:last-child {
+			margin-bottom: 0;
+		}
+
+		ul.actions li {
+			display: inline-block;
+			padding: 0 0 0 1.5em;
+		}
+
+			ul.actions li:first-child {
+				padding: 0;
+			}
+
+		ul.actions.vertical li {
+			display: block;
+			padding: 1.5em 0 0 0;
+		}
+
+			ul.actions.vertical li:first-child {
+				padding: 0;
+			}
+
+	ul.special-icons {
+		margin: 0em;
+		padding: 0em;
+	}
+
+		ul.special-icons > li {
+			position: relative;
+			padding: 0.50em 0em 0.50em 0em;
+		}
+
+		ul.special-icons > li:before {
+			position: absolute;
+			left: 0;
+			top: 2em;
+			display: block;
+			background: none;
+			font-size: 2em;
+			border-radius: 5px;
+		}
+
+		ul.special-icons > li:first-child {
+			border-top: none;
+		}
+
+		ul.special-icons h3 {
+			margin-bottom: 0.80em;
+			line-height: 2em;
+			text-transform: uppercase;
+			font-weight: 700;
+			font-size: 1.2em;
+		}
+
+		ul.special-icons span {
+			line-height: 190%;
+		}
+
+		ul.special-icons .fa {
+			float: left;
+			display: inline-block;
+			padding-right: 1em;
+			font-size: 1.4em;
+			color: #82b440;
+		}
+
+		ul.special-icons p {
+			padding-left: 2.7em;
+		}
+
+/* Tables */
+
+	table {
+		width: 100%;
+	}
+
+		table.default {
+			width: 100%;
+		}
+
+			table.default tbody tr {
+				border-bottom: solid 1px #82b440;
+			}
+
+			table.default td {
+				padding: 0.5em 1em 0.5em 1em;
+			}
+
+			table.default th {
+				font-weight: 700;
+				padding: 0.5em 1em 0.5em 1em;
+				text-align: left;
+			}
+
+			table.default thead {
+				background: #555555;
+				color: #fff;
+			}
+
+/* Button */
+
+	input[type="submit"],
+	input[type="reset"],
+	input[type="button"],
+	.button {
+		-moz-appearance: none;
+		-webkit-appearance: none;
+		-o-appearance: none;
+		-ms-appearance: none;
+		appearance: none;
+		background: none;
+		border-radius: none;
+		border: 2px solid;
+		border-color: #82b440;
+		color: #82b440;
+		cursor: pointer;
+		display: inline-block;
+		padding: 0.90em 1.2em;
+		letter-spacing: 1px;
+		text-align: center;
+		text-decoration: none;
+		text-transform: uppercase;
+		font-size: 1.4em;
+		-moz-transition: all 0.35s ease-in-out;
+		-webkit-transition: all 0.35s ease-in-out;
+		-o-transition: all 0.35s ease-in-out;
+		-ms-transition: all 0.35s ease-in-out;
+		transition: all 0.35s ease-in-out;
+	}
+
+		input[type="submit"]:hover,
+		input[type="reset"]:hover,
+		input[type="button"]:hover,
+		.button:hover {
+			background: #82b440;
+			color: white;
+		}
+
+		input[type="submit"].alt,
+		input[type="reset"].alt,
+		input[type="button"].alt,
+		.button.alt {
+			border-color: inherit;
+			color: inherit;
+		}
+
+			input[type="submit"].alt:hover,
+			input[type="reset"].alt:hover,
+			input[type="button"].alt:hover,
+			.button.alt:hover {
+				background: white;
+				color: #82b440;
+			}
+
+		input[type="submit"].fit,
+		input[type="reset"].fit,
+		input[type="button"].fit,
+		.button.fit {
+			width: 100%;
+		}
+
+		input[type="submit"].small,
+		input[type="reset"].small,
+		input[type="button"].small,
+		.button.small {
+			font-size: 0.8em;
+		}
+
+/* Wrapper */
+
+	.wrapper {
+		padding: 6em 0em 4em 0em;
+	}
+
+		.wrapper.style1 {
+			padding: 0em;
+			background: #222222 url('images/banner.jpg') no-repeat;
+			background-size: cover;
+		}
+
+		.wrapper.style2,
+		.wrapper.evenpart {
+			background: #f2f2f2;
+		}
+
+			.wrapper.style2 .major,
+			.wrapper.evenpart .major {
+				text-align: left !important;
+			}
+
+				.wrapper.style2 .major h2,
+				.wrapper.evenpart .major h2 {
+					display: block;
+					margin-bottom: 0.70em;
+					letter-spacing: 1px;
+					line-height: 1.4em;
+					text-transform: uppercase;
+					font-size: 1.8em;
+					font-weight: 400;
+				}
+
+				.wrapper.style2 .major .byline,
+				.wrapper.evenpart .major .byline {
+					letter-spacing: normal;
+					line-height: 1.6em;
+					text-transform: capitalize;
+					font-size: 1.4em;
+				}
+
+			.wrapper.style2 h3,
+			.wrapper.evenpart h3 {
+				display: block;
+				margin-bottom: 1em;
+				letter-spacing: 1px;
+				line-height: 1.4em;
+				text-transform: uppercase;
+				font-size: 1.6em;
+				font-weight: 400;
+			}
+
+		.wrapper.style3,
+		.wrapper.cta {
+			padding-bottom: 6em;
+			background: #82b440;
+			text-align: center;
+			color: white;
+		}
+
+			.wrapper.style3 .container,
+			.wrapper.cta .container {
+				padding-left: 6em;
+				padding-right: 6em;
+			}
+
+			.wrapper.style3 p,
+			.wrapper.cta p {
+				font-size: 1.6em;
+			}
+
+		.wrapper.style4,
+		.wrapper.plain {
+			background: white;
+		}
+
+		.wrapper.style5,
+		.wrapper.portals {
+			background: #82b440;
+			text-align: center;
+			color: white;
+		}
+
+			.wrapper.style5 .image,
+			.wrapper.portals .image {
+				display: block;
+				width: 60%;
+				margin: 0em auto 2em auto;
+			}
+
+				.wrapper.style5 .image img,
+				.wrapper.portals .image img {
+					border-radius: 50%;
+					border: 10px solid;
+					border-color: white;
+				}
+
+/* Header */
+
+	#header {
+		color: white;
+		height: 4em;
+		background: rgba(0, 0, 0, 0.5);
+	}
+
+		#header .container {
+			position: relative;
+		}
+
+	.homepage #logo {
+		display: none;
+	}
+
+	.homepage #nav {
+		position: static;
+		right: none;
+		text-align: center;
+	}
+
+	#logo {
+		line-height: 2em;
+		letter-spacing: 2px;
+		text-transform: uppercase;
+		font-size: 2em;
+		font-weight: 400;
+	}
+
+		#logo h1 {
+			display: inline-block;
+			margin: 0;
+			padding: 0;
+		}
+
+		#logo a {
+			color: inherit;
+		}
+
+	#nav {
+		position: absolute;
+		top: 0;
+		right: 0;
+	}
+
+		#nav > ul {
+			margin: 0;
+		}
+
+			#nav > ul > li {
+				border-radius: 4px;
+				display: inline-block;
+				margin-left: 0.5em;
+				padding: 0 0.5em;
+			}
+
+				#nav > ul > li a {
+					color: inherit;
+					line-height: 4em;
+					letter-spacing: 2px;
+					text-decoration: none;
+					text-transform: uppercase;
+					font-weight: 400;
+					font-size: 1em;
+				}
+
+				#nav > ul > li:first-child {
+					margin-left: 0;
+				}
+
+				#nav > ul > li.active a {
+					color: white;
+				}
+
+				#nav > ul > li > ul {
+					display: none;
+				}
+
+/* Dropotron */
+
+	.dropotron {
+		top: 2em;
+		background: rgba(32, 32, 32, 0.75);
+		border-radius: 4px;
+		color: inherit;
+		min-width: 12em;
+		padding: 1em 0;
+		color: white;
+	}
+
+		.dropotron > li {
+			line-height: 2em;
+			padding: 0 1em;
+		}
+
+			.dropotron > li > a {
+				color: inherit;
+				letter-spacing: 2px;
+				text-decoration: none;
+				text-transform: uppercase;
+			}
+
+			.dropotron > li.active > a, .dropotron > li:hover > a {
+				color: inherit;
+			}
+
+		.dropotron.level-0 {
+			border-radius: 0 0 4px 4px;
+			font-size: 1em;
+			margin-left: -0.5em;
+		}
+
+/* Banner */
+
+	#banner {
+		padding: 6em 0em 3em 0em;
+		text-align: center;
+		text-transform: uppercase;
+		color: white;
+	}
+
+		#banner .container {
+			padding: 0em 8em;
+		}
+
+		#banner h2 {
+			display: inline-block;
+			padding: 0.50em 0.30em;
+			background: #82b440;
+			font-size: 3em;
+			font-weight: 400;
+		}
+
+		#banner span, #banner p {
+			display: block;
+			letter-spacing: 1px;
+			text-transform: uppercase;
+			font-size: 1.6em;
+			font-weight: 300;
+		}
+
+		#banner span {
+			padding: 1em 0em;
+		}
+
+/* Main */
+
+	#main {
+		padding: 4em 0;
+	}
+
+		#main #content .major, #main #sidebar .major {
+			text-align: left;
+		}
+
+		#main #sidebar section {
+			margin-top: 4em;
+		}
+
+			#main #sidebar section:first-child {
+				margin-top: 0;
+			}
+
+		#main #sidebar .major {
+			padding-bottom: 2em;
+		}
+
+			#main #sidebar .major h2 {
+				font-size: 1.8em;
+			}
+
+/* Footer */
+
+	#footer {
+		padding: 6em 0 2em 0;
+		text-align: center;
+		color: white;
+	}
+
+		#footer hr {
+			border-bottom: 1px solid;
+			border-color: inherit;
+			opacity: .05;
+		}
+
+		#footer .major h2 {
+			color: inherit;
+		}
+
+		#footer .major .byline {
+			color: inherit;
+			opacity: .4;
+		}
+
+		#footer .copyright {
+			margin-top: 3em;
+			text-align: center;
+		}
+
+/* Copyright */
+
+	#copyright {
+		position: relative;
+		text-transform: uppercase;
+		text-align: center;
+		padding: 3em 0em 3em 0em;
+		color: inherit;
+		opacity: .40;
+	}
+
+		#copyright a {
+			text-decoration: none;
+			color: inherit;
+		}
+
+/* Extra */
+
+	#extra1 h2 {
+		display: block;
+		margin-bottom: 1em;
+		letter-spacing: 1px;
+		line-height: 1.4em;
+		text-transform: uppercase;
+		font-size: 1.8em;
+		font-weight: 400;
+	}
+
+	#extra1 h3 {
+		display: block;
+		margin-bottom: 1em;
+		letter-spacing: 1px;
+		line-height: 1.4em;
+		text-transform: uppercase;
+		font-size: 1.6em;
+		font-weight: 400;
+	}
+
+/* Team */
+
+	#team h3 {
+		margin-bottom: 0.50em;
+		letter-spacing: 2px;
+		text-transform: uppercase;
+		font-weight: 700;
+	}

+ 261 - 0
public/assets/solarize/widgets.css

@@ -0,0 +1,261 @@
+pre.phpdebugbar-widgets-code-block {
+    white-space: pre;
+    word-wrap: normal;
+    overflow: hidden;
+}
+  pre.phpdebugbar-widgets-code-block code {
+    display: block;
+    overflow-x: auto;
+    overflow-y: hidden;
+  }
+  pre.phpdebugbar-widgets-code-block code.phpdebugbar-widgets-numbered-code {
+    padding: 5px;
+  }
+    pre.phpdebugbar-widgets-code-block code span.phpdebugbar-widgets-highlighted-line {
+      background: #800000;
+      color: #fff;
+      display: inline-block;
+      min-width: 100%;
+    }
+      pre.phpdebugbar-widgets-code-block code span.phpdebugbar-widgets-highlighted-line span {
+        background: none !important;
+        color: inherit !important;
+      }
+  pre.phpdebugbar-widgets-code-block ul {
+    float: left;
+    padding: 5px;
+    background: #cacaca;
+    border-right: 1px solid #aaa;
+    text-align: right;
+  }
+
+/* -------------------------------------- */
+
+ul.phpdebugbar-widgets-list {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+  ul.phpdebugbar-widgets-list li.phpdebugbar-widgets-list-item {
+    padding: 3px 6px;
+    border-bottom: 1px solid #eee;
+    position: relative;
+    overflow: hidden;
+  }
+  ul.phpdebugbar-widgets-list li.phpdebugbar-widgets-list-item:hover {
+    background: #fafafa;
+  }
+
+/* -------------------------------------- */
+
+div.phpdebugbar-widgets-messages {
+  position: relative;
+  height: 100%;
+}
+  div.phpdebugbar-widgets-messages ul.phpdebugbar-widgets-list {
+    padding-bottom: 20px;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-value.phpdebugbar-widgets-warning:before {
+    font-family: PhpDebugbarFontAwesome;
+    content: "\f071";
+    margin-right: 8px;
+    font-size: 11px;
+    color: #ecb03d;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-value.phpdebugbar-widgets-error {
+    color: red;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-value.phpdebugbar-widgets-error:before {
+    font-family: PhpDebugbarFontAwesome;
+    content: "\f057";
+    margin-right: 8px;
+    font-size: 11px;
+    color: red;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item pre.sf-dump {
+    display: inline;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-collector,
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-label {
+    float: right;
+    font-size: 12px;
+    padding: 2px 4px;
+    color: #888;
+    margin: 0 2px;
+    text-decoration: none;
+    text-shadow: none;
+    background: none;
+    font-weight: normal;
+  }
+  div.phpdebugbar-widgets-messages li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-collector {
+    color: #555;
+    font-style: italic;
+  }
+  div.phpdebugbar-widgets-messages div.phpdebugbar-widgets-toolbar {
+    position: fixed;
+    bottom: 0;
+    width: 100%;
+    background: #fff;
+  }
+    div.phpdebugbar-widgets-messages div.phpdebugbar-widgets-toolbar input {
+      border: 0;
+      margin: 0;
+      margin-left: 7px;
+      width: 50%;
+      box-shadow: none;
+    }
+    div.phpdebugbar-widgets-messages div.phpdebugbar-widgets-toolbar input:focus {
+      outline: none;
+    }
+      div.phpdebugbar-widgets-messages div.phpdebugbar-widgets-toolbar a.phpdebugbar-widgets-filter {
+        float: right;
+        font-size: 12px;
+        padding: 2px 4px;
+        background: #7cacd5;
+        margin: 0 2px;
+        border-radius: 4px;
+        color: #fff;
+        text-decoration: none;
+      }
+      div.phpdebugbar-widgets-messages div.phpdebugbar-widgets-toolbar a.phpdebugbar-widgets-filter.phpdebugbar-widgets-excluded {
+        background: #eee;
+        color: #888;
+      }
+
+/* -------------------------------------- */
+
+dl.phpdebugbar-widgets-kvlist {
+  margin: 0;
+}
+  dl.phpdebugbar-widgets-kvlist dt {
+    float: left;
+    width: 150px;
+    padding: 5px;
+    border-top: 1px solid #eee;
+    font-weight: bold;
+    clear: both;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+  dl.phpdebugbar-widgets-kvlist dd {
+    margin-left: 160px;
+    padding: 5px;
+    border-top: 1px solid #eee;
+    cursor: pointer;
+    min-height: 17px;
+  }
+
+/* -------------------------------------- */
+
+dl.phpdebugbar-widgets-varlist,
+dl.phpdebugbar-widgets-htmlvarlist {
+  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+  dl.phpdebugbar-widgets-htmlvarlist dd {
+    cursor: initial;
+  }
+
+/* -------------------------------------- */
+
+ul.phpdebugbar-widgets-timeline {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+  ul.phpdebugbar-widgets-timeline .phpdebugbar-widgets-measure {
+    height: 20px;
+    position: relative;
+    border-bottom: 1px solid #eee;
+    display: block;
+  }
+  ul.phpdebugbar-widgets-timeline li:hover {
+    background: #fafafa;
+  }
+    ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-label,
+    ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-collector {
+      position: absolute;
+      font-size: 12px;
+      font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+      color: #555;
+      top: 4px;
+      left: 5px;
+      background: none;
+      text-shadow: none;
+      font-weight: normal;
+      white-space: pre;
+    }
+    ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-collector {
+      left: initial;
+      right: 5px;
+    }
+    ul.phpdebugbar-widgets-timeline li span.phpdebugbar-widgets-value {
+      display: block;
+      position: absolute;
+      height: 10px;
+      background: #3db9ec;
+      top: 5px;
+      border-radius: 2px;
+      min-width: 1px;
+    }
+    ul.phpdebugbar-widgets-timeline table.phpdebugbar-widgets-params {
+      display: none;
+      width: 70%;
+      margin: 10px;
+      border: 1px solid #ddd;
+      font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+      border-collapse: collapse;
+    }
+      ul.phpdebugbar-widgets-timeline table.phpdebugbar-widgets-params td {
+        border: 1px solid #ddd;
+        padding: 0 5px;
+      }
+      ul.phpdebugbar-widgets-timeline table.phpdebugbar-widgets-params .phpdebugbar-widgets-name {
+        width: 20%;
+        font-weight: bold;
+      }
+
+/* -------------------------------------- */
+
+div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item {
+  cursor: pointer;
+}
+  div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-message {
+    display: block;
+    color: red;
+  }
+
+  div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-filename {
+    display: block;
+    font-style: italic;
+    color: #555;
+  }
+
+  div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item span.phpdebugbar-widgets-type {
+    display: block;
+    position: absolute;
+    right: 4px;
+    top: 4px;
+    font-weight: bold;
+  }
+
+  div.phpdebugbar-widgets-exceptions li.phpdebugbar-widgets-list-item pre.phpdebugbar-widgets-file {
+    display: none;
+    margin: 10px;
+    padding: 5px;
+    border: 1px solid #ddd;
+    font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+  }
+
+div.phpdebugbar-widgets-exceptions a.phpdebugbar-widgets-editor-link:before {
+  font-family: PhpDebugbarFontAwesome;
+  margin-right: 4px;
+  font-size: 12px;
+  font-style: normal;
+}
+
+div.phpdebugbar-widgets-exceptions a.phpdebugbar-widgets-editor-link:before {
+  content: "\f08e";
+  margin-left: 4px;
+}

+ 589 - 0
public/assets/solarize/widgets.js

@@ -0,0 +1,589 @@
+if (typeof(PhpDebugBar) == 'undefined') {
+    // namespace
+    var PhpDebugBar = {};
+    PhpDebugBar.$ = jQuery;
+}
+
+(function($) {
+
+    /**
+     * @namespace
+     */
+    PhpDebugBar.Widgets = {};
+
+    var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-widgets-');
+
+    /**
+     * Replaces spaces with &nbsp; and line breaks with <br>
+     *
+     * @param {String} text
+     * @return {String}
+     */
+    var htmlize = PhpDebugBar.Widgets.htmlize = function(text) {
+        return text.replace(/\n/g, '<br>').replace(/\s/g, "&nbsp;")
+    };
+
+    /**
+     * Returns a string representation of value, using JSON.stringify
+     * if it's an object.
+     *
+     * @param {Object} value
+     * @param {Boolean} prettify Uses htmlize() if true
+     * @return {String}
+     */
+    var renderValue = PhpDebugBar.Widgets.renderValue = function(value, prettify) {
+        if (typeof(value) !== 'string') {
+            if (prettify) {
+                return htmlize(JSON.stringify(value, undefined, 2));
+            }
+            return JSON.stringify(value);
+        }
+        return value;
+    };
+
+    /**
+     * Highlights a block of code
+     *
+     * @param  {String} code
+     * @param  {String} lang
+     * @return {String}
+     */
+    var highlight = PhpDebugBar.Widgets.highlight = function(code, lang) {
+        if (typeof(code) === 'string') {
+            if (typeof(hljs) === 'undefined') {
+                return htmlize(code);
+            }
+            if (lang) {
+                return hljs.highlight(lang, code).value;
+            }
+            return hljs.highlightAuto(code).value;
+        }
+
+        if (typeof(hljs) === 'object') {
+            code.each(function(i, e) { hljs.highlightBlock(e); });
+        }
+        return code;
+    };
+
+    /**
+     * Creates a <pre> element with a block of code
+     *
+     * @param  {String} code
+     * @param  {String} lang
+     * @param  {Number} [firstLineNumber] If provided, shows line numbers beginning with the given value.
+     * @param  {Number} [highlightedLine] If provided, the given line number will be highlighted.
+     * @return {String}
+     */
+    var createCodeBlock = PhpDebugBar.Widgets.createCodeBlock = function(code, lang, firstLineNumber, highlightedLine) {
+        var pre = $('<pre />').addClass(csscls('code-block'));
+        // Add a newline to prevent <code> element from vertically collapsing too far if the last
+        // code line was empty: that creates problems with the horizontal scrollbar being
+        // incorrectly positioned - most noticeable when line numbers are shown.
+        var codeElement = $('<code />').text(code + '\n').appendTo(pre);
+
+        // Add a span with a special class if we are supposed to highlight a line.  highlight.js will
+        // still correctly format code even with existing markup in it.
+        if ($.isNumeric(highlightedLine)) {
+            if ($.isNumeric(firstLineNumber)) {
+                highlightedLine = highlightedLine - firstLineNumber + 1;
+            }
+            codeElement.html(function (index, html) {
+                var currentLine = 1;
+                return html.replace(/^.*$/gm, function(line) {
+                    if (currentLine++ == highlightedLine) {
+                        return '<span class="' + csscls('highlighted-line') + '">' + line + '</span>';
+                    } else {
+                        return line;
+                    }
+                });
+            });
+        }
+
+        // Format the code
+        if (lang) {
+            pre.addClass("language-" + lang);
+        }
+        highlight(pre);
+
+        // Show line numbers in a list
+        if ($.isNumeric(firstLineNumber)) {
+            var lineCount = code.split('\n').length;
+            var $lineNumbers = $('<ul />').prependTo(pre);
+            pre.children().addClass(csscls('numbered-code'));
+            for (var i = firstLineNumber; i < firstLineNumber + lineCount; i++) {
+                $('<li />').text(i).appendTo($lineNumbers);
+            }
+        }
+
+        return pre;
+    };
+
+    // ------------------------------------------------------------------
+    // Generic widgets
+    // ------------------------------------------------------------------
+
+    /**
+     * Displays array element in a <ul> list
+     *
+     * Options:
+     *  - data
+     *  - itemRenderer: a function used to render list items (optional)
+     */
+    var ListWidget = PhpDebugBar.Widgets.ListWidget = PhpDebugBar.Widget.extend({
+
+        tagName: 'ul',
+
+        className: csscls('list'),
+
+        initialize: function(options) {
+            if (!options['itemRenderer']) {
+                options['itemRenderer'] = this.itemRenderer;
+            }
+            this.set(options);
+        },
+
+        render: function() {
+            this.bindAttr(['itemRenderer', 'data'], function() {
+                this.$el.empty();
+                if (!this.has('data')) {
+                    return;
+                }
+
+                var data = this.get('data');
+                for (var i = 0; i < data.length; i++) {
+                    var li = $('<li />').addClass(csscls('list-item')).appendTo(this.$el);
+                    this.get('itemRenderer')(li, data[i]);
+                }
+            });
+        },
+
+        /**
+         * Renders the content of a <li> element
+         *
+         * @param {jQuery} li The <li> element as a jQuery Object
+         * @param {Object} value An item from the data array
+         */
+        itemRenderer: function(li, value) {
+            li.html(renderValue(value));
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Displays object property/value paris in a <dl> list
+     *
+     * Options:
+     *  - data
+     *  - itemRenderer: a function used to render list items (optional)
+     */
+    var KVListWidget = PhpDebugBar.Widgets.KVListWidget = ListWidget.extend({
+
+        tagName: 'dl',
+
+        className: csscls('kvlist'),
+
+        render: function() {
+            this.bindAttr(['itemRenderer', 'data'], function() {
+                this.$el.empty();
+                if (!this.has('data')) {
+                    return;
+                }
+
+                var self = this;
+                $.each(this.get('data'), function(key, value) {
+                    var dt = $('<dt />').addClass(csscls('key')).appendTo(self.$el);
+                    var dd = $('<dd />').addClass(csscls('value')).appendTo(self.$el);
+                    self.get('itemRenderer')(dt, dd, key, value);
+                });
+            });
+        },
+
+        /**
+         * Renders the content of the <dt> and <dd> elements
+         *
+         * @param {jQuery} dt The <dt> element as a jQuery Object
+         * @param {jQuery} dd The <dd> element as a jQuery Object
+         * @param {String} key Property name
+         * @param {Object} value Property value
+         */
+        itemRenderer: function(dt, dd, key, value) {
+            dt.text(key);
+            dd.html(htmlize(value));
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * An extension of KVListWidget where the data represents a list
+     * of variables
+     *
+     * Options:
+     *  - data
+     */
+    var VariableListWidget = PhpDebugBar.Widgets.VariableListWidget = KVListWidget.extend({
+
+        className: csscls('kvlist varlist'),
+
+        itemRenderer: function(dt, dd, key, value) {
+            $('<span />').attr('title', key).text(key).appendTo(dt);
+
+            var v = value;
+            if (v && v.length > 100) {
+                v = v.substr(0, 100) + "...";
+            }
+            var prettyVal = null;
+            dd.text(v).click(function() {
+                if (dd.hasClass(csscls('pretty'))) {
+                    dd.text(v).removeClass(csscls('pretty'));
+                } else {
+                    prettyVal = prettyVal || createCodeBlock(value);
+                    dd.addClass(csscls('pretty')).empty().append(prettyVal);
+                }
+            });
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * An extension of KVListWidget where the data represents a list
+     * of variables whose contents are HTML; this is useful for showing
+     * variable output from VarDumper's HtmlDumper.
+     *
+     * Options:
+     *  - data
+     */
+    var HtmlVariableListWidget = PhpDebugBar.Widgets.HtmlVariableListWidget = KVListWidget.extend({
+
+        className: csscls('kvlist htmlvarlist'),
+
+        itemRenderer: function(dt, dd, key, value) {
+            $('<span />').attr('title', key).text(key).appendTo(dt);
+            dd.html(value);
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Iframe widget
+     *
+     * Options:
+     *  - data
+     */
+    var IFrameWidget = PhpDebugBar.Widgets.IFrameWidget = PhpDebugBar.Widget.extend({
+
+        tagName: 'iframe',
+
+        className: csscls('iframe'),
+
+        render: function() {
+            this.$el.attr({
+                seamless: "seamless",
+                border: "0",
+                width: "100%",
+                height: "100%"
+            });
+            this.bindAttr('data', function(url) { this.$el.attr('src', url); });
+        }
+
+    });
+
+
+    // ------------------------------------------------------------------
+    // Collector specific widgets
+    // ------------------------------------------------------------------
+
+    /**
+     * Widget for the MessagesCollector
+     *
+     * Uses ListWidget under the hood
+     *
+     * Options:
+     *  - data
+     */
+    var MessagesWidget = PhpDebugBar.Widgets.MessagesWidget = PhpDebugBar.Widget.extend({
+
+        className: csscls('messages'),
+
+        render: function() {
+            var self = this;
+
+            this.$list = new ListWidget({ itemRenderer: function(li, value) {
+                if (value.message_html) {
+                    var val = $('<span />').addClass(csscls('value')).html(value.message_html).appendTo(li);
+                } else {
+                    var m = value.message;
+                    if (m.length > 100) {
+                        m = m.substr(0, 100) + "...";
+                    }
+
+                    var val = $('<span />').addClass(csscls('value')).text(m).appendTo(li);
+                    if (!value.is_string || value.message.length > 100) {
+                        var prettyVal = value.message;
+                        if (!value.is_string) {
+                            prettyVal = null;
+                        }
+                        li.css('cursor', 'pointer').click(function () {
+                            if (val.hasClass(csscls('pretty'))) {
+                                val.text(m).removeClass(csscls('pretty'));
+                            } else {
+                                prettyVal = prettyVal || createCodeBlock(value.message, 'php');
+                                val.addClass(csscls('pretty')).empty().append(prettyVal);
+                            }
+                        });
+                    }
+                }
+
+                if (value.collector) {
+                    $('<span />').addClass(csscls('collector')).text(value.collector).prependTo(li);
+                }
+                if (value.label) {
+                    val.addClass(csscls(value.label));
+                    $('<span />').addClass(csscls('label')).text(value.label).prependTo(li);
+                }
+            }});
+
+            this.$list.$el.appendTo(this.$el);
+            this.$toolbar = $('<div><i class="phpdebugbar-fa phpdebugbar-fa-search"></i></div>').addClass(csscls('toolbar')).appendTo(this.$el);
+
+            $('<input type="text" />')
+                .on('change', function() { self.set('search', this.value); })
+                .appendTo(this.$toolbar);
+
+            this.bindAttr('data', function(data) {
+                this.set({ exclude: [], search: '' });
+                this.$toolbar.find(csscls('.filter')).remove();
+
+                var filters = [], self = this;
+                for (var i = 0; i < data.length; i++) {
+                    if (!data[i].label || $.inArray(data[i].label, filters) > -1) {
+                        continue;
+                    }
+                    filters.push(data[i].label);
+                    $('<a />')
+                        .addClass(csscls('filter'))
+                        .text(data[i].label)
+                        .attr('rel', data[i].label)
+                        .on('click', function() { self.onFilterClick(this); })
+                        .appendTo(this.$toolbar);
+                }
+            });
+
+            this.bindAttr(['exclude', 'search'], function() {
+                var data = this.get('data'),
+                    exclude = this.get('exclude'),
+                    search = this.get('search'),
+                    caseless = false,
+                    fdata = [];
+
+                if (search && search === search.toLowerCase()) {
+                    caseless = true;
+                }
+
+                for (var i = 0; i < data.length; i++) {
+                    var message = caseless ? data[i].message.toLowerCase() : data[i].message;
+
+                    if ((!data[i].label || $.inArray(data[i].label, exclude) === -1) && (!search || message.indexOf(search) > -1)) {
+                        fdata.push(data[i]);
+                    }
+                }
+
+                this.$list.set('data', fdata);
+            });
+        },
+
+        onFilterClick: function(el) {
+            $(el).toggleClass(csscls('excluded'));
+
+            var excludedLabels = [];
+            this.$toolbar.find(csscls('.filter') + csscls('.excluded')).each(function() {
+                excludedLabels.push(this.rel);
+            });
+
+            this.set('exclude', excludedLabels);
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Widget for the TimeDataCollector
+     *
+     * Options:
+     *  - data
+     */
+    var TimelineWidget = PhpDebugBar.Widgets.TimelineWidget = PhpDebugBar.Widget.extend({
+
+        tagName: 'ul',
+
+        className: csscls('timeline'),
+
+        render: function() {
+            this.bindAttr('data', function(data) {
+
+                // ported from php DataFormatter
+                var formatDuration = function(seconds) {
+                    if (seconds < 0.001)
+                        return (seconds * 1000000).toFixed() + 'μs';
+                    else if (seconds < 1)
+                        return (seconds * 1000).toFixed(2) + 'ms';
+                    return (seconds).toFixed(2) +  's';
+                };
+
+                this.$el.empty();
+                if (data.measures) {
+                    var aggregate = {};
+
+                    for (var i = 0; i < data.measures.length; i++) {
+                        var measure = data.measures[i];
+
+                        if(!aggregate[measure.label])
+                            aggregate[measure.label] = { count: 0, duration: 0 };
+
+                        aggregate[measure.label]['count'] += 1;
+                        aggregate[measure.label]['duration'] += measure.duration;
+
+                        var m = $('<div />').addClass(csscls('measure')),
+                            li = $('<li />'),
+                            left = (measure.relative_start * 100 / data.duration).toFixed(2),
+                            width = Math.min((measure.duration * 100 / data.duration).toFixed(2), 100 - left);
+
+                        m.append($('<span />').addClass(csscls('value')).css({
+                            left: left + "%",
+                            width: width + "%"
+                        }));
+                        m.append($('<span />').addClass(csscls('label')).text(measure.label + " (" + measure.duration_str + ")"));
+
+                        if (measure.collector) {
+                            $('<span />').addClass(csscls('collector')).text(measure.collector).appendTo(m);
+                        }
+
+                        m.appendTo(li);
+                        this.$el.append(li);
+
+                        if (measure.params && !$.isEmptyObject(measure.params)) {
+                            var table = $('<table><tr><th colspan="2">Params</th></tr></table>').addClass(csscls('params')).appendTo(li);
+                            for (var key in measure.params) {
+                                if (typeof measure.params[key] !== 'function') {
+                                    table.append('<tr><td class="' + csscls('name') + '">' + key + '</td><td class="' + csscls('value') +
+                                    '"><pre><code>' + measure.params[key] + '</code></pre></td></tr>');
+                                }
+                            }
+                            li.css('cursor', 'pointer').click(function() {
+                                var table = $(this).find('table');
+                                if (table.is(':visible')) {
+                                    table.hide();
+                                } else {
+                                    table.show();
+                                }
+                            });
+                        }
+                    }
+
+                    // convert to array and sort by duration
+                    aggregate = $.map(aggregate, function(data, label) {
+                       return {
+                           label: label,
+                           data: data
+                       }
+                    }).sort(function(a, b) {
+                        return b.data.duration - a.data.duration
+                    });
+
+                    // build table and add
+                    var aggregateTable = $('<table style="display: table; border: 0; width: 99%"></table>').addClass(csscls('params'));
+                    $.each(aggregate, function(i, aggregate) {
+                        width = Math.min((aggregate.data.duration * 100 / data.duration).toFixed(2), 100);
+
+                        aggregateTable.append('<tr><td class="' + csscls('name') + '">' + aggregate.data.count + ' x ' + aggregate.label + ' (' + width + '%)</td><td class="' + csscls('value') + '">' +
+                            '<div class="' + csscls('measure') +'">' +
+                                '<span class="' + csscls('value') + '" style="width:' + width + '%"></span>' +
+                                '<span class="' + csscls('label') + '">' + formatDuration(aggregate.data.duration) + '</span>' +
+                            '</div></td></tr>');
+                    });
+
+                    this.$el.append('<li/>').find('li:last').append(aggregateTable);
+                }
+            });
+        }
+
+    });
+
+    // ------------------------------------------------------------------
+
+    /**
+     * Widget for the displaying exceptions
+     *
+     * Options:
+     *  - data
+     */
+    var ExceptionsWidget = PhpDebugBar.Widgets.ExceptionsWidget = PhpDebugBar.Widget.extend({
+
+        className: csscls('exceptions'),
+
+        render: function() {
+            this.$list = new ListWidget({ itemRenderer: function(li, e) {
+                $('<span />').addClass(csscls('message')).text(e.message).appendTo(li);
+                if (e.file) {
+                    var header = $('<span />').addClass(csscls('filename')).text(e.file + "#" + e.line);
+                    if (e.xdebug_link) {
+                        if (e.xdebug_link.ajax) {
+                            $('<a title="' + e.xdebug_link.url + '"></a>').on('click', function () {
+                                $.ajax(e.xdebug_link.url);
+                            }).addClass(csscls('editor-link')).appendTo(header);
+                        } else {
+                            $('<a href="' + e.xdebug_link.url + '"></a>').addClass(csscls('editor-link')).appendTo(header);
+                        }
+                    }
+                    header.appendTo(li);
+                }
+                if (e.type) {
+                    $('<span />').addClass(csscls('type')).text(e.type).appendTo(li);
+                }
+                if (e.surrounding_lines) {
+                    var pre = createCodeBlock(e.surrounding_lines.join(""), 'php').addClass(csscls('file')).appendTo(li);
+                    if (!e.stack_trace_html) {
+                        // This click event makes the var-dumper hard to use.
+                        li.click(function () {
+                            if (pre.is(':visible')) {
+                                pre.hide();
+                            } else {
+                                pre.show();
+                            }
+                        });
+                    }
+                }
+                if (e.stack_trace_html) {
+                    var $trace = $('<span />').addClass(csscls('filename')).html(e.stack_trace_html);
+                    $trace.appendTo(li);
+                } else if (e.stack_trace) {
+                    e.stack_trace.split("\n").forEach(function (trace) {
+                        var $traceLine = $('<div />');
+                        $('<span />').addClass(csscls('filename')).text(trace).appendTo($traceLine);
+                        $traceLine.appendTo(li);
+                    });
+                }
+            }});
+            this.$list.$el.appendTo(this.$el);
+
+            this.bindAttr('data', function(data) {
+                this.$list.set('data', data);
+                if (data.length == 1) {
+                    this.$list.$el.children().first().find(csscls('.file')).show();
+                }
+            });
+
+        }
+
+    });
+
+
+})(PhpDebugBar.$);

+ 325 - 0
resources/views/index.blade.php

@@ -0,0 +1,325 @@
+<html lang="en-us">
+  <head>
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+
+    <title>Ananke: a Hugo Theme | Ananke</title>
+    <meta name="viewport" content="width=device-width,minimum-scale=1" />
+    <meta
+      name="description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta name="generator" content="Hugo 0.92.1" />
+
+    <meta name="robots" content="noindex, nofollow" />
+
+    <link rel="stylesheet" href="{{ URL::asset('assets/css/ananke/main.min.css') }}" />
+
+    <link
+      href="/index.xml"
+      rel="alternate"
+      type="application/rss+xml"
+      title="Ananke"
+    />
+    <link
+      href="/index.xml"
+      rel="feed"
+      type="application/rss+xml"
+      title="Ananke"
+    />
+
+    <meta property="og:title" content="Ananke: a Hugo Theme" />
+    <meta
+      property="og:description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta property="og:type" content="website" />
+    <meta
+      property="og:url"
+      content="https://gohugo-ananke-theme-demo.netlify.app/"
+    />
+    <meta property="og:site_name" content="Ananke" />
+
+    <meta itemprop="name" content="Ananke: a Hugo Theme" />
+    <meta
+      itemprop="description"
+      content="The last theme you'll ever need. Maybe."
+    />
+    <meta name="twitter:card" content="summary" />
+    <meta name="twitter:title" content="Ananke: a Hugo Theme" />
+    <meta
+      name="twitter:description"
+      content="The last theme you'll ever need. Maybe."
+    />
+  </head>
+
+  <body
+    class="ma0 avenir bg-near-white"
+  >
+    <header
+      class="cover bg-top"
+      style="background-image: url('{{ URL::asset('assets/images/hero.jpg') }}');"
+    >
+      <div class="bg-black-60">
+        <nav class="pv3 ph3 ph4-ns" role="navigation">
+          <div class="flex-l justify-between items-center center">
+            <a href="/" class="f3 fw2 hover-white no-underline white-90 dib">
+              wikipali
+            </a>
+            <div class="flex-l items-center">
+              <h4></h4>
+              <ul class="pl0 mr3">
+                @foreach ($nav as $item)
+                <li class="list f5 f4-ns fw4 dib pr3">
+                  <a
+                    class="hover-white no-underline white-90"
+                    href="/my/{{ $item['link'] }}"
+                    title="{{ $item['title'] }}"
+                  >
+                    {{ $item['title'] }}
+                  </a>
+                </li>
+                @endforeach
+              </ul>
+
+            </div>
+          </div>
+        </nav>
+
+        <div class="tc-l pv4 pv6-l ph3 ph4-ns">
+          <h1 class="f2 f-subheadline-l fw2 white-90 mb0 lh-title">
+            {{ $title }}
+          </h1>
+
+          <h2 class="fw1 f5 f3-l white-80 measure-wide-l center mt3">
+          {{ $subtitle }}
+          </h2>
+        </div>
+      </div>
+    </header>
+
+    <main class="pb7" role="main">
+      <article
+        class="cf ph3 ph5-l pv3 pv4-l f4 tc-l center measure-wide lh-copy mid-gray"
+      >
+        <p>
+          Welcome to my blog with some of my work in progress. I’ve been working
+          on this book idea. You can read some of the chapters below.
+        </p>
+      </article>
+
+      <div class="pa3 pa4-ns w-100 w-70-ns center">
+        <h1 class="flex-none">Recent Articles</h1>
+
+        <section class="w-100 mw8">
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="pr3-ns mb4 mb0-ns w-100 w-40-ns">
+                    <a href="/post/chapter-6/" class="db grow">
+                      <img
+                        src="https://gohugo-ananke-theme-demo.netlify.app/images/esmeralda.jpg"
+                        class="img"
+                        alt="image from Chapter VI: Esmeralda"
+                      />
+                    </a>
+                  </div>
+
+                  <div class="blah w-100 w-60-ns pl3-ns">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-6/" class="color-inherit dim link">
+                        Chapter VI: Esmeralda
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      We are delighted to be able to inform the reader, that
+                      during the whole of this scene, Gringoire and his piece
+                      had stood firm. His actors, spurred on by him, had not
+                      ceased to spout his comedy, and he had not ceased to
+                      listen to it. He had made up his mind about the tumult,
+                      and was determined to proceed to the end, not giving up
+                      the hope of a return of attention on the part of the
+                      public.
+                    </div>
+                    <a
+                      href="/post/chapter-6/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="blah w-100">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-5/" class="color-inherit dim link">
+                        Chapter V: Quasimodo
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      In the twinkling of an eye, all was ready to execute
+                      Coppenole’s idea. Bourgeois, scholars and law clerks all
+                      set to work. The little chapel situated opposite the
+                      marble table was selected for the scene of the grinning
+                      match. A pane broken in the pretty rose window above the
+                      door, left free a circle of stone through which it was
+                      agreed that the competitors should thrust their heads. In
+                      order to reach it, it was only necessary to mount upon a
+                      couple of hogsheads, which had been produced from I know
+                      not where, and perched one upon the other, after a
+                      fashion.
+                    </div>
+                    <a
+                      href="/post/chapter-5/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+
+          <div class="relative w-100 mb4">
+            <article class="bb b--black-10">
+              <div class="db pv4 ph3 ph0-l no-underline dark-gray">
+                <div class="flex flex-column flex-row-ns">
+                  <div class="blah w-100">
+                    <h1 class="f3 fw1 athelas mt0 lh-title">
+                      <a href="/post/chapter-4/" class="color-inherit dim link">
+                        Chapter IV: Master Jacques Coppenole
+                      </a>
+                    </h1>
+                    <div
+                      class="f6 f5-l lh-copy nested-copy-line-height nested-links"
+                    >
+                      While the pensioner of Ghent and his eminence were
+                      exchanging very low bows and a few words in voices still
+                      lower, a man of lofty stature, with a large face and broad
+                      shoulders, presented himself, in order to enter abreast
+                      with Guillaume Rym; one would have pronounced him a
+                      bull-dog by the side of a fox. His felt doublet and
+                      leather jerkin made a spot on the velvet and silk which
+                      surrounded him.
+                    </div>
+                    <a
+                      href="/post/chapter-4/"
+                      class="ba b--moon-gray bg-light-gray br2 color-inherit dib f7 hover-bg-moon-gray link mt2 ph2 pv1"
+                      >read more</a
+                    >
+                  </div>
+                </div>
+              </div>
+            </article>
+          </div>
+        </section>
+
+        <section class="w-100">
+          <h1 class="f3">More</h1>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-3/" class="link black dim">
+              Chapter III: Monsieur the Cardinal
+            </a>
+          </h2>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-2/" class="link black dim">
+              Chapter II: Pierre Gringoire
+            </a>
+          </h2>
+
+          <h2 class="f5 fw4 mb4 dib mr3">
+            <a href="/post/chapter-1/" class="link black dim">
+              Chapter I: The Grand Hall
+            </a>
+          </h2>
+
+          <a
+            href="/post/"
+            class="link db f6 pa2 br3 bg-mid-gray white dim w4 tc"
+            >All Articles</a
+          >
+        </section>
+      </div>
+    </main>
+    <footer class="bg-black bottom-0 w-100 pa3" role="contentinfo">
+      <div class="flex justify-between">
+        <a
+          class="f4 fw4 hover-white no-underline white-70 dn dib-ns pv2 ph3"
+          href="https://gohugo-ananke-theme-demo.netlify.app"
+        >
+          © Ananke 2022
+        </a>
+        <div>
+          <div class="ananke-socials">
+            <a
+              href="https://twitter.com/GoHugoIO"
+              target="_blank"
+              class="twitter ananke-social-link link-transition stackoverflow link dib z-999 pt3 pt0-l mr1"
+              title="Twitter link"
+              rel="noopener"
+              aria-label="follow on Twitter——Opens in a new window"
+            >
+              <span class="icon"
+                ><svg
+                  style="enable-background: new 0 0 67 67"
+                  version="1.1"
+                  viewBox="0 0 67 67"
+                  xml:space="preserve"
+                  xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink"
+                >
+                  <path
+                    d="M37.167,22.283c-2.619,0.953-4.274,3.411-4.086,6.101  l0.063,1.038l-1.048-0.127c-3.813-0.487-7.145-2.139-9.974-4.915l-1.383-1.377l-0.356,1.017c-0.754,2.267-0.272,4.661,1.299,6.271  c0.838,0.89,0.649,1.017-0.796,0.487c-0.503-0.169-0.943-0.296-0.985-0.233c-0.146,0.149,0.356,2.076,0.754,2.839  c0.545,1.06,1.655,2.097,2.871,2.712l1.027,0.487l-1.215,0.021c-1.173,0-1.215,0.021-1.089,0.467  c0.419,1.377,2.074,2.839,3.918,3.475l1.299,0.444l-1.131,0.678c-1.676,0.976-3.646,1.526-5.616,1.568  C19.775,43.256,19,43.341,19,43.405c0,0.211,2.557,1.397,4.044,1.864c4.463,1.377,9.765,0.783,13.746-1.568  c2.829-1.673,5.657-5,6.978-8.221c0.713-1.716,1.425-4.851,1.425-6.354c0-0.975,0.063-1.102,1.236-2.267  c0.692-0.678,1.341-1.419,1.467-1.631c0.21-0.403,0.188-0.403-0.88-0.043c-1.781,0.636-2.033,0.551-1.152-0.402  c0.649-0.678,1.425-1.907,1.425-2.267c0-0.063-0.314,0.042-0.671,0.233c-0.377,0.212-1.215,0.53-1.844,0.72l-1.131,0.361l-1.027-0.7  c-0.566-0.381-1.361-0.805-1.781-0.932C39.766,21.902,38.131,21.944,37.167,22.283z M33,64C16.432,64,3,50.569,3,34S16.432,4,33,4  s30,13.431,30,30S49.568,64,33,64z"
+                    style="fill-rule: evenodd; clip-rule: evenodd"
+                  ></path>
+                </svg>
+              </span>
+
+              <span class="new-window"
+                ><svg
+                  height="8px"
+                  style="enable-background: new 0 0 1000 1000"
+                  version="1.1"
+                  viewBox="0 0 1000 1000"
+                  xml:space="preserve"
+                  xmlns="http://www.w3.org/2000/svg"
+                  xmlns:xlink="http://www.w3.org/1999/xlink"
+                >
+                  <path
+                    d="M598 128h298v298h-86v-152l-418 418-60-60 418-418h-152v-86zM810 810v-298h86v298c0 46-40 86-86 86h-596c-48 0-86-40-86-86v-596c0-46 38-86 86-86h298v86h-298v596h596z"
+                    style="fill-rule: evenodd; clip-rule: evenodd"
+                  ></path>
+                </svg> </span
+            ></a>
+          </div>
+        </div>
+      </div>
+    </footer>
+
+    <iframe
+      frameborder="0"
+      scrolling="no"
+      style="background-color: transparent; border: 0px; display: none"
+    ></iframe>
+    <div
+      id="GOOGLE_INPUT_CHEXT_FLAG"
+      input=""
+      input_stat='{"tlang":true,"tsbc":true,"pun":true,"mk":true,"ss":true}'
+      style="display: none"
+    ></div>
+    <div id="monica-content-root" class="monica-widget"></div>
+  </body>
+</html>

Разница между файлами не показана из-за своего большого размера
+ 397 - 0
resources/views/solarize.blade.php


+ 30 - 0
tests/Feature/TaskMq.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Tests\Feature;
+
+use Illuminate\Foundation\Testing\RefreshDatabase;
+use Illuminate\Foundation\Testing\WithFaker;
+use Tests\TestCase;
+
+class TaskMq extends TestCase
+{
+    /**
+     * A basic feature test example.
+     *
+     * @return void
+     */
+    public function test_store()
+    {
+        $response = $this->withHeaders([
+            'Authorization' => env('TEST_USER_TOKEN'),
+        ])->json('POST', '/api/v2/task',
+                    [
+                        'name'=>'test:md.render',
+                        'param'=>[
+                            'item'=>'bold',
+                        ],
+                    ]);
+
+        $response->assertOk();
+    }
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов