diff --git a/README.md b/README.md index aa86152..c6e4916 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,10 @@ Hand-picked registry of Node.js frameworks. 1. Fork it! 2. Create your feature branch: `git checkout -b my-new-feature` -3. Commit your changes: `git commit -am 'Add some feature'` -4. Push to the branch: `git push origin my-new-feature` -5. Submit a pull request :D +3. If you're adding a framework, add it to `./projects.js` +4. Commit your changes: `git commit -am 'Add some feature'` +5. Push to the branch: `git push origin my-new-feature` +6. Submit a pull request :D ## License [MIT License](https://github.com/azat-co/nodeframework/blob/master/LICENSE) © Azat Mardan diff --git a/assets/js/main.js b/assets/js/main.js index 1bb2abe..da529f8 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,4 +1,42 @@ $(document).ready(function() { + // Check if `projects.js` was loaded before this file. + // `projects` is defined in `projects.js`. + if (typeof projects !== 'undefined') { + // Loop over each project + projects.forEach(function (project) { + if (project.hasOwnProperty('tags')) { + // Project has tag(s), so add to every list that matches the tag. + project.tags.forEach(function (tag) { + addProjectToProjectList(tag, project); + }); + } else { + // The project doesn't have any tags, so add it to the "other" section. + addProjectToProjectList('other', project); + } + }); + } else { + // `projects.js` needs to be loaded before this file + console.error('Please load `projects.js` before `main.js`!'); + } + + function addProjectToProjectList(tag, project) { + var element = ''; + + element += '
  • '; + element += ' ' + project.name + ' '; + if (project.annotation) { element += '(' + project.annotation + ') '; } + element += ''; + element += ''; + element += ''; + element += ''; + element += ''; + element += '
  • '; + + return $('#project-list-' + tag).append(element); + } + $('[rel=tooltip]').tooltip(); // Add spin.js to lazy load container diff --git a/assets/js/main.min.js b/assets/js/main.min.js index 60375f6..867a36a 100644 --- a/assets/js/main.min.js +++ b/assets/js/main.min.js @@ -1,3 +1,3 @@ !function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()},e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")},e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=n,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},to:function(t){var n=this.$element.find(".item.active"),r=n.parent().children(),i=r.index(n),s=this;if(t>r.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){s.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",e(r[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0]});if(i.hasClass("active"))return;if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}},e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e(document).on("click.carousel.data-api","[data-slide]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data());i.carousel(s),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning)return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning)return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=typeof n=="object"&&n;i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;return n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=e(n),r.length||(r=t.parent()),r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||(s.toggleClass("open"),n.focus()),!1},keydown:function(t){var n,r,s,o,u,a;if(!/(38|40|27)/.test(t.keyCode))return;n=e(this),t.preventDefault(),t.stopPropagation();if(n.is(".disabled, :disabled"))return;o=i(n),u=o.hasClass("open");if(!u||u&&t.keyCode==27)return n.click();r=e("[role=menu] li:not(.divider) a",o);if(!r.length)return;a=r.index(r.filter(":focus")),t.keyCode==38&&a>0&&a--,t.keyCode==40&&a').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,e.proxy(this.removeBackdrop,this)):this.removeBackdrop()):t&&t()}},e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,this.options.trigger=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):this.options.trigger!="manual"&&(i=this.options.trigger=="hover"?"mouseenter":"focus",s=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this))),this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,t,this.$element.data()),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);if(!n.options.delay||!n.options.delay.show)return n.show();clearTimeout(this.timeout),n.hoverState="in",this.timeout=setTimeout(function(){n.hoverState=="in"&&n.show()},n.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var e,t,n,r,i,s,o;if(this.hasContent()&&this.enabled){e=this.tip(),this.setContent(),this.options.animation&&e.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,t=/in/.test(s),e.detach().css({top:0,left:0,display:"block"}).insertAfter(this.$element),n=this.getPosition(t),r=e[0].offsetWidth,i=e[0].offsetHeight;switch(t?s.split(" ")[1]:s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}e.offset(o).addClass(s).addClass("in")}},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function r(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip();return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?r():n.detach(),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(t){return e.extend({},t?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);n[n.tip().hasClass("in")?"hide":"show"]()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}},e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
    ',trigger:"hover",title:"",delay:0,html:!1}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content > *")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-content")||(typeof n.content=="function"?n.content.call(t[0]):n.content),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}}),e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'

    '})}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var t=e(this),n=t.data("target")||t.attr("href"),r=/^#\w/.test(n)&&e(n);return r&&r.length&&[[r.position().top,n]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}},e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}},e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=e(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:t.top+t.height,left:t.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length"+t+""})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=!~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(e){var t=this;setTimeout(function(){t.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(t){this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")}},e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
  • ',minLength:1},e.fn.typeahead.Constructor=t,e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;t.preventDefault(),n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))},e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery);(function($,window,undefined){"$:nomunge";var str_hashchange="hashchange",doc=document,fake_onhashchange,special=$.event.special,doc_mode=doc.documentMode,supports_onhashchange="on"+str_hashchange in window&&(doc_mode===undefined||doc_mode>7);function get_fragment(url){url=url||location.href;return"#"+url.replace(/^[^#]*#?(.*)$/,"$1")}$.fn[str_hashchange]=function(fn){return fn?this.bind(str_hashchange,fn):this.trigger(str_hashchange)};$.fn[str_hashchange].delay=50;special[str_hashchange]=$.extend(special[str_hashchange],{setup:function(){if(supports_onhashchange){return false}$(fake_onhashchange.start)},teardown:function(){if(supports_onhashchange){return false}$(fake_onhashchange.stop)}});fake_onhashchange=function(){var self={},timeout_id,last_hash=get_fragment(),fn_retval=function(val){return val},history_set=fn_retval,history_get=fn_retval;self.start=function(){timeout_id||poll()};self.stop=function(){timeout_id&&clearTimeout(timeout_id);timeout_id=undefined};function poll(){var hash=get_fragment(),history_hash=history_get(last_hash);if(hash!==last_hash){history_set(last_hash=hash,history_hash);$(window).trigger(str_hashchange)}else if(history_hash!==last_hash){location.href=location.href.replace(/#.*/,"")+history_hash}timeout_id=setTimeout(poll,$.fn[str_hashchange].delay)}return self}()})(jQuery,this);(function($,undefined){var Public=function(url){if(_type==="pathname"){if(_last!==url)window.history.pushState({},null,_last=url)}else if(_type==="hash"){if(_last!==url){_last=location.hash=url;if(_ie67){if(!$("#jQueryHistory").length)throw new Error("jQuery."+publicName+".push: iframe not found.");if(_firstTime){_firstTime=0;_iframe.contentWindow.document.open().close();_iframe.contentWindow.location.hash="/"}_iframe.contentWindow.document.open().close();_iframe.contentWindow.location.hash=url}}}else{throw new Error("jQuery."+publicName+".push: listener is not active.")}Public.context.trigger("push",[url,_type]);return Public},publicName="history";Public.context=$({});$.each(["on","off","trigger"],function(index,method){Public[method]=function(){Public.context[method].apply(Public.context,arguments);return Public}});Public.push=Public;Public.getListenType=function(){return _type};Public.listen=function(type,interval){Public.unlisten();var size=arguments.length;if(!size||type==="auto"){type=_pushState?"pathname":"hash";size=1}else if(type!=="pathname"&&type!=="hash"){throw new Error("jQuery."+publicName+".listen: type is not valid.")}if(type==="hash"){if(!_onhashchange&&size===1||interval===true){interval=Public.config.interval;size=2}if(size===2&&(isNaN(interval)||interval<1))throw new Error("jQuery."+publicName+".listen: interval delay is not valid.")}if((_type=type)==="pathname"){if(!_pushState)throw new Error("jQuery."+publicName+".listen: this browser has not support to pushState.");$(window).on("popstate.history",function(event){if(event.originalEvent&&event.originalEvent.state&&_last!==location.pathname)Public.trigger("change",[_last=location.pathname,"pathname"])});if(location.pathname.length>1)Public.trigger("load",[location.pathname+location.search+location.hash,"pathname"])}else{if(_onhashchange&&!interval){$(window).on("hashchange.history",function(event){var hash=location.hash.substr(1);if(_last!==hash)Public.trigger("change",[_last=hash,"hash"])})}else{if(_ie67===undefined)_ie67=Public.isIE67();if(_ie67){if(!(size=$("body")).length)throw new Error("jQuery."+publicName+".listen: document is not ready.");_iframe=$('',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){l.types.push(B),C(!0),u(b+"."+B,function(){C()})},getIframe:function(b,c){var d=b.src,e=l.st.iframe;a.each(e.patterns,function(){if(d.indexOf(this.index)>-1)return this.id&&(typeof this.id=="string"?d=d.substr(d.lastIndexOf(this.id)+this.id.length,d.length):d=this.id.call(this,d)),d=this.src.replace("%id%",d),!1});var f={};return e.srcAction&&(f[e.srcAction]=d),l._parseMarkup(c,f,b),l.updateStatus("ready"),c}}})})(window.jQuery||window.Zepto);var responsiveNav=function(window,document){var computed=!!window.getComputedStyle;if(!window.getComputedStyle){window.getComputedStyle=function(el){this.el=el;this.getPropertyValue=function(prop){var re=/(\-([a-z]){1})/g;if(prop==="float"){prop="styleFloat"}if(re.test(prop)){prop=prop.replace(re,function(){return arguments[2].toUpperCase()})}return el.currentStyle[prop]?el.currentStyle[prop]:null};return this}}var nav,opts,navToggle,docEl=document.documentElement,head=document.getElementsByTagName("head")[0],styleElement=document.createElement("style"),navOpen=false,addEvent=function(el,evt,fn,bubble){if("addEventListener"in el){try{el.addEventListener(evt,fn,bubble)}catch(e){if(typeof fn==="object"&&fn.handleEvent){el.addEventListener(evt,function(e){fn.handleEvent.call(fn,e)},bubble)}else{throw e}}}else if("attachEvent"in el){if(typeof fn==="object"&&fn.handleEvent){el.attachEvent("on"+evt,function(){fn.handleEvent.call(fn)})}else{el.attachEvent("on"+evt,fn)}}},removeEvent=function(el,evt,fn,bubble){if("removeEventListener"in el){try{el.removeEventListener(evt,fn,bubble)}catch(e){if(typeof fn==="object"&&fn.handleEvent){el.removeEventListener(evt,function(e){fn.handleEvent.call(fn,e)},bubble)}else{throw e}}}else if("detachEvent"in el){if(typeof fn==="object"&&fn.handleEvent){el.detachEvent("on"+evt,function(){fn.handleEvent.call(fn)})}else{el.detachEvent("on"+evt,fn)}}},getFirstChild=function(e){var firstChild=e.firstChild;while(firstChild!==null&&firstChild.nodeType!==1){firstChild=firstChild.nextSibling}return firstChild},setAttributes=function(el,attrs){for(var key in attrs){el.setAttribute(key,attrs[key])}},addClass=function(el,cls){el.className+=" "+cls;el.className=el.className.replace(/(^\s*)|(\s*$)/g,"")},removeClass=function(el,cls){var reg=new RegExp("(\\s|^)"+cls+"(\\s|$)");el.className=el.className.replace(reg," ").replace(/(^\s*)|(\s*$)/g,"")},ResponsiveNav=function(el,options){var i;this.options={animate:true,transition:400,label:"Menu",insert:"after",customToggle:"",openPos:"relative",jsClass:"js",init:function(){},open:function(){},close:function(){}};for(i in options){this.options[i]=options[i]}addClass(docEl,this.options.jsClass);this.wrapperEl=el.replace("#","");if(document.getElementById(this.wrapperEl)){this.wrapper=document.getElementById(this.wrapperEl)}else{throw new Error("The nav element you are trying to select doesn't exist")}this.wrapper.inner=getFirstChild(this.wrapper);opts=this.options;nav=this.wrapper;this._init(this)};ResponsiveNav.prototype={destroy:function(){this._removeStyles();removeClass(nav,"closed");removeClass(nav,"opened");nav.removeAttribute("style");nav.removeAttribute("aria-hidden");nav=null;_instance=null;removeEvent(window,"load",this,false);removeEvent(window,"resize",this,false);removeEvent(navToggle,"mousedown",this,false);removeEvent(navToggle,"touchstart",this,false);removeEvent(navToggle,"touchend",this,false);removeEvent(navToggle,"keyup",this,false);removeEvent(navToggle,"click",this,false);if(!opts.customToggle){navToggle.parentNode.removeChild(navToggle)}else{navToggle.removeAttribute("aria-hidden")}},toggle:function(){if(!navOpen){removeClass(nav,"closed");addClass(nav,"opened");nav.style.position=opts.openPos;setAttributes(nav,{"aria-hidden":"false"});navOpen=true;opts.open()}else{removeClass(nav,"opened");addClass(nav,"closed");setAttributes(nav,{"aria-hidden":"true"});if(opts.animate){setTimeout(function(){nav.style.position="absolute"},opts.transition+10)}else{nav.style.position="absolute"}navOpen=false;opts.close()}},handleEvent:function(e){var evt=e||window.event;switch(evt.type){case"mousedown":this._onmousedown(evt);break;case"touchstart":this._ontouchstart(evt);break;case"touchend":this._ontouchend(evt);break;case"keyup":this._onkeyup(evt);break;case"click":this._onclick(evt);break;case"load":this._transitions(evt);this._resize(evt);break;case"resize":this._resize(evt);break}},_init:function(){addClass(nav,"closed");this._createToggle();addEvent(window,"load",this,false);addEvent(window,"resize",this,false);addEvent(navToggle,"mousedown",this,false);addEvent(navToggle,"touchstart",this,false);addEvent(navToggle,"touchend",this,false);addEvent(navToggle,"keyup",this,false);addEvent(navToggle,"click",this,false)},_createStyles:function(){if(!styleElement.parentNode){head.appendChild(styleElement)}},_removeStyles:function(){if(styleElement.parentNode){styleElement.parentNode.removeChild(styleElement)}},_createToggle:function(){if(!opts.customToggle){var toggle=document.createElement("a");toggle.innerHTML=opts.label;setAttributes(toggle,{href:"#",id:"nav-toggle"});if(opts.insert==="after"){nav.parentNode.insertBefore(toggle,nav.nextSibling)}else{nav.parentNode.insertBefore(toggle,nav)}navToggle=document.getElementById("nav-toggle")}else{var toggleEl=opts.customToggle.replace("#","");if(document.getElementById(toggleEl)){navToggle=document.getElementById(toggleEl)}else{throw new Error("The custom nav toggle you are trying to select doesn't exist")}}},_preventDefault:function(e){if(e.preventDefault){e.preventDefault();e.stopPropagation()}else{e.returnValue=false}},_onmousedown:function(e){var evt=e||window.event;if(!(evt.which===3||evt.button===2)){this._preventDefault(e);this.toggle(e)}},_ontouchstart:function(e){navToggle.onmousedown=null;this._preventDefault(e);this.toggle(e)},_ontouchend:function(){var that=this;nav.addEventListener("click",that._preventDefault,true);setTimeout(function(){nav.removeEventListener("click",that._preventDefault,true)},opts.transition)},_onkeyup:function(e){var evt=e||window.event;if(evt.keyCode===13){this.toggle(e)}},_onclick:function(e){this._preventDefault(e)},_transitions:function(){if(opts.animate){var objStyle=nav.style,transition="max-height "+opts.transition+"ms";objStyle.WebkitTransition=transition;objStyle.MozTransition=transition;objStyle.OTransition=transition;objStyle.transition=transition}},_calcHeight:function(){var savedHeight=nav.inner.offsetHeight,innerStyles="#"+this.wrapperEl+".opened{max-height:"+savedHeight+"px}";if(computed){styleElement.innerHTML=innerStyles;innerStyles=""}},_resize:function(){if(window.getComputedStyle(navToggle,null).getPropertyValue("display")!=="none"){setAttributes(navToggle,{"aria-hidden":"false"});if(nav.className.match(/(^|\s)closed(\s|$)/)){setAttributes(nav,{"aria-hidden":"true"});nav.style.position="absolute"}this._createStyles();this._calcHeight()}else{setAttributes(navToggle,{"aria-hidden":"true"});setAttributes(nav,{"aria-hidden":"false"});nav.style.position=opts.openPos;this._removeStyles()}opts.init()}};var _instance;function rn(el,options){if(!_instance){_instance=new ResponsiveNav(el,options)}return _instance}return rn}(window,document);(function(root,factory){if(typeof exports=="object")module.exports=factory();else if(typeof define=="function"&&define.amd)define(factory);else root.Spinner=factory()})(this,function(){"use strict";var prefixes=["webkit","Moz","ms","O"],animations={},useCssAnimations;function createEl(tag,prop){var el=document.createElement(tag||"div"),n;for(n in prop)el[n]=prop[n];return el}function ins(parent){for(var i=1,n=arguments.length;i>1):parseInt(o.left,10)+mid)+"px",top:(o.top=="auto"?tp.y-ep.y+(target.offsetHeight>>1):parseInt(o.top,10)+mid)+"px"})}el.setAttribute("role","progressbar");self.lines(el,self.opts);if(!useCssAnimations){var i=0,start=(o.lines-1)*(1-o.direction)/2,alpha,fps=o.fps,f=fps/o.speed,ostep=(1-o.opacity)/(f*o.trail/100),astep=f/o.lines;(function anim(){i++;for(var j=0;j>1)+"px"})}for(;i',attr)}sheet.addRule(".spin-vml","behavior:url(#default#VML)");Spinner.prototype.lines=function(el,o){var r=o.length+o.width,s=2*r;function grp(){return css(vml("group",{coordsize:s+" "+s,coordorigin:-r+" "+-r}),{width:s,height:s})}var margin=-(o.width+o.length)*2+"px",g=css(grp(),{position:"absolute",top:margin,left:margin}),i;function seg(i,dx,filter){ins(g,ins(css(grp(),{rotation:360/o.lines*i+"deg",left:~~dx}),ins(css(vml("roundrect",{arcsize:o.corners}),{width:r,height:o.width,left:o.radius,top:-o.width>>1,filter:filter}),vml("fill",{color:o.color,opacity:o.opacity}),vml("stroke",{opacity:0}))))}if(o.shadow)for(i=1;i<=o.lines;i++)seg(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=o.lines;i++)seg(i);return ins(el,g)};Spinner.prototype.opacity=function(el,i,val,o){var c=el.firstChild;o=o.shadow&&o.lines||0;if(c&&i+o=mediaBreakpoints[i]["enter"]&&width<=mediaBreakpoints[i]["exit"]){foundBrkpt=true;break}}if(foundBrkpt&&curr!==mediaBreakpoints[i]["label"]){prev=curr;curr=mediaBreakpoints[i]["label"];cycleThrough()}else if(!foundBrkpt&&curr!==""){curr="";cycleThrough()}};var testForCurr=function(elm){if(typeof elm==="object"){if(elm.join().indexOf(curr)>=0){return true}}else if(elm==="*"){return true}else if(typeof elm==="string"){if(curr===elm){return true}}};var checkResize=function(){var w=winWidth();if(w!==resizeW){resizeTmrSpd=resizeTmrFast;returnBreakpoint(w)}else{resizeTmrSpd=resizeTmrSlow}resizeW=w;setTimeout(checkResize,resizeTmrSpd)};checkResize();return{addFunc:function(elm){addFunction(elm)},getBreakpoint:function(){return curr}}}})(this,this.document);(function($,window,document,undefined){var $window=$(window);$.fn.lazyload=function(options){var elements=this;var $container;var settings={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:window,data_attribute:"original",skip_invisible:true,appear:null,load:null};function update(){var counter=0;elements.each(function(){var $this=$(this);if(settings.skip_invisible&&!$this.is(":visible")){return}if($.abovethetop(this,settings)||$.leftofbegin(this,settings)){}else if(!$.belowthefold(this,settings)&&!$.rightoffold(this,settings)){$this.trigger("appear");counter=0}else{if(++counter>settings.failure_limit){return false}}})}if(options){if(undefined!==options.failurelimit){options.failure_limit=options.failurelimit;delete options.failurelimit}if(undefined!==options.effectspeed){options.effect_speed=options.effectspeed;delete options.effectspeed}$.extend(settings,options)}$container=settings.container===undefined||settings.container===window?$window:$(settings.container);if(0===settings.event.indexOf("scroll")){$container.bind(settings.event,function(event){return update()})}this.each(function(){var self=this;var $self=$(self);self.loaded=false;$self.one("appear",function(){if(!this.loaded){if(settings.appear){var elements_left=elements.length;settings.appear.call(self,elements_left,settings)}$("").bind("load",function(){$self.hide().attr("src",$self.data(settings.data_attribute))[settings.effect](settings.effect_speed);self.loaded=true;var temp=$.grep(elements,function(element){return!element.loaded});elements=$(temp);if(settings.load){var elements_left=elements.length;settings.load.call(self,elements_left,settings)}}).attr("src",$self.data(settings.data_attribute))}});if(0!==settings.event.indexOf("scroll")){$self.bind(settings.event,function(event){if(!self.loaded){$self.trigger("appear")}})}});$window.bind("resize",function(event){update()});if(/iphone|ipod|ipad.*os 5/gi.test(navigator.appVersion)){$window.bind("pageshow",function(event){if(event.originalEvent.persisted){elements.each(function(){$(this).trigger("appear")})}})}$(window).load(function(){update()});return this};$.belowthefold=function(element,settings){var fold;if(settings.container===undefined||settings.container===window){fold=$window.height()+$window.scrollTop()}else{fold=$(settings.container).offset().top+$(settings.container).height()}return fold<=$(element).offset().top-settings.threshold};$.rightoffold=function(element,settings){var fold;if(settings.container===undefined||settings.container===window){fold=$window.width()+$window.scrollLeft()}else{fold=$(settings.container).offset().left+$(settings.container).width()}return fold<=$(element).offset().left-settings.threshold};$.abovethetop=function(element,settings){var fold;if(settings.container===undefined||settings.container===window){fold=$window.scrollTop()}else{fold=$(settings.container).offset().top}return fold>=$(element).offset().top+settings.threshold+$(element).height()};$.leftofbegin=function(element,settings){var fold;if(settings.container===undefined||settings.container===window){fold=$window.scrollLeft()}else{fold=$(settings.container).offset().left}return fold>=$(element).offset().left+settings.threshold+$(element).width()};$.inviewport=function(element,settings){return!$.rightoffold(element,settings)&&!$.leftofbegin(element,settings)&&!$.belowthefold(element,settings)&&!$.abovethetop(element,settings)};$.extend($.expr[":"],{"below-the-fold":function(a){return $.belowthefold(a,{threshold:0})},"above-the-top":function(a){return!$.belowthefold(a,{threshold:0})},"right-of-screen":function(a){return $.rightoffold(a,{threshold:0})},"left-of-screen":function(a){return!$.rightoffold(a,{threshold:0})},"in-viewport":function(a){return $.inviewport(a,{threshold:0})},"above-the-fold":function(a){return!$.belowthefold(a,{threshold:0})},"right-of-fold":function(a){return $.rightoffold(a,{threshold:0})},"left-of-fold":function(a){return!$.rightoffold(a,{threshold:0})}})})(jQuery,window,document);(function(a){var b="Close",c="BeforeAppend",d="MarkupParse",e="Open",f="Change",g="mfp",h="."+g,i="mfp-ready",j="mfp-removing",k="mfp-prevent-close",l,m=function(){},n,o=a(window),p,q,r,s,t,u=function(a,b){l.ev.on(g+a+h,b)},v=function(b,c,d,e){var f=document.createElement("div");return f.className="mfp-"+b,d&&(f.innerHTML=d),e?c&&c.appendChild(f):(f=a(f),c&&f.appendTo(c)),f},w=function(b,c){l.ev.triggerHandler(g+b,c),l.st.callbacks&&(b=b.charAt(0).toLowerCase()+b.slice(1),l.st.callbacks[b]&&l.st.callbacks[b].apply(l,a.isArray(c)?c:[c]))},x=function(){(l.st.focus?l.content.find(l.st.focus).eq(0):l.wrap).focus()},y=function(b){if(b!==t||!l.currTemplate.closeBtn)l.currTemplate.closeBtn=a(l.st.closeMarkup.replace("%title%",l.st.tClose)),t=b;return l.currTemplate.closeBtn};m.prototype={constructor:m,init:function(){var b=navigator.appVersion;l.isIE7=b.indexOf("MSIE 7.")!==-1,l.isAndroid=/android/gi.test(b),l.isIOS=/iphone|ipad|ipod/gi.test(b),l.probablyMobile=l.isAndroid||l.isIOS||/(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent),p=a(document.body),q=a(document),l.popupsCache={}},open:function(b){if(l.isOpen)return;var c;l.types=[],s="",l.ev=b.el||q;if(b.isObj)l.index=b.index||0;else{l.index=0;var f=b.items,g;for(c=0;c(a||o.height())?!0:!1},_parseMarkup:function(b,c,e){var f;e.data&&(c=a.extend(e.data,c)),w(d,[b,c,e]),a.each(c,function(a,c){if(c===undefined||c===!1)return!0;f=a.split("_");if(f.length>1){var d=b.find(h+"-"+f[0]);if(d.length>0){var e=f[1];e==="replaceWith"?d[0]!==c[0]&&d.replaceWith(c):e==="img"?d.is("img")?d.attr("src",c):d.replaceWith(''):d.attr(f[1],c)}}else b.find(h+"-"+a).html(c)})},_getScrollbarSize:function(){if(l.scrollbarSize===undefined){var a=document.createElement("div");a.id="mfp-sbm",a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),l.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return l.scrollbarSize}},a.magnificPopup={instance:null,proto:m.prototype,modules:[],open:function(b,c){return a.magnificPopup.instance||(l=new m,l.init(),a.magnificPopup.instance=l),b||(b={}),b.isObj=!0,b.index=c===undefined?0:c,this.instance.open(b)},close:function(){return a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeBtnInside:!0,alignTop:!1,removalDelay:0,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading..."}},a.fn.magnificPopup=function(b){return a.magnificPopup.instance||(l=new m,l.init(),a.magnificPopup.instance=l),l.addGroup(a(this),b),a(this)};var z,A=function(b){if(b.data&&b.data.title!==undefined)return b.data.title;var c=l.st.image.titleSrc;if(c){if(a.isFunction(c))return c.call(l,b);if(b.el)return b.el.attr(c)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
    ',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var a=l.st.image,c=".image";l.types.push("image"),u(e+c,function(){l.currItem.type==="image"&&a.cursor&&p.addClass(a.cursor)}),u(b+c,function(){a.cursor&&p.removeClass(a.cursor),o.off("resize"+h)}),u("Resize"+c,function(){l.resizeImage()})},resizeImage:function(){var a=l.currItem;if(!a.img)return;l.st.image.verticalFit&&a.img.css("max-height",l.wH+"px")},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,z&&clearInterval(z),a.isCheckingImgSize=!1,w("ImageHasSize",a),a.imgHidden&&(l.content&&l.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var b=0,c=a.img[0],d=function(e){z&&clearInterval(z),z=setInterval(function(){if(c.naturalWidth>0){l._onImageHasSize(a);return}b>200&&clearInterval(z),b++,b===3?d(10):b===40?d(50):b===100&&d(500)},e)};d(1)},getImage:function(b,c){var d=0,e=function(){b&&(b.img[0].complete?(b.img.off(".mfploader"),b===l.currItem&&(l._onImageHasSize(b),l.updateStatus("ready")),b.hasSize=!0,b.loaded=!0):(d++,d<200?setTimeout(e,100):f()))},f=function(){b&&(b.img.off(".mfploader"),b===l.currItem&&(l._onImageHasSize(b),l.updateStatus("error",g.tError.replace("%url%",b.src))),b.hasSize=!0,b.loaded=!0,b.loadError=!0)},g=l.st.image,h=c.find(".mfp-img");if(h.length){var i=new Image;i.className="mfp-img",b.img=a(i).on("load.mfploader",e).on("error.mfploader",f),i.src=b.src,h.is("img")&&(b.img=b.img.clone())}return l._parseMarkup(c,{title:A(b),img_replaceWith:b.img},b),l.resizeImage(),b.hasSize?(z&&clearInterval(z),b.loadError?(c.addClass("mfp-loading"),l.updateStatus("error",g.tError.replace("%url%",b.src))):(c.removeClass("mfp-loading"),l.updateStatus("ready")),c):(l.updateStatus("loading"),b.loading=!0,b.hasSize||(b.imgHidden=!0,c.addClass("mfp-loading"),l.findImageSize(b)),c)}}});var B="iframe",C=function(a){if(l.isIE7&&l.currItem&&l.currItem.type===B){var b=l.content.find("iframe");b.length&&b.css("display",a?"block":"none")}};a.magnificPopup.registerModule(B,{options:{markup:'
    ',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){l.types.push(B),C(!0),u(b+"."+B,function(){C()})},getIframe:function(b,c){var d=b.src,e=l.st.iframe;a.each(e.patterns,function(){if(d.indexOf(this.index)>-1)return this.id&&(typeof this.id=="string"?d=d.substr(d.lastIndexOf(this.id)+this.id.length,d.length):d=this.id.call(this,d)),d=this.src.replace("%id%",d),!1});var f={};return e.srcAction&&(f[e.srcAction]=d),l._parseMarkup(c,f,b),l.updateStatus("ready"),c}}})})(window.jQuery||window.Zepto);var responsiveNav=function(window,document){var computed=!!window.getComputedStyle;if(!window.getComputedStyle){window.getComputedStyle=function(el){this.el=el;this.getPropertyValue=function(prop){var re=/(\-([a-z]){1})/g;if(prop==="float"){prop="styleFloat"}if(re.test(prop)){prop=prop.replace(re,function(){return arguments[2].toUpperCase()})}return el.currentStyle[prop]?el.currentStyle[prop]:null};return this}}var nav,opts,navToggle,docEl=document.documentElement,head=document.getElementsByTagName("head")[0],styleElement=document.createElement("style"),navOpen=false,addEvent=function(el,evt,fn,bubble){if("addEventListener"in el){try{el.addEventListener(evt,fn,bubble)}catch(e){if(typeof fn==="object"&&fn.handleEvent){el.addEventListener(evt,function(e){fn.handleEvent.call(fn,e)},bubble)}else{throw e}}}else if("attachEvent"in el){if(typeof fn==="object"&&fn.handleEvent){el.attachEvent("on"+evt,function(){fn.handleEvent.call(fn)})}else{el.attachEvent("on"+evt,fn)}}},removeEvent=function(el,evt,fn,bubble){if("removeEventListener"in el){try{el.removeEventListener(evt,fn,bubble)}catch(e){if(typeof fn==="object"&&fn.handleEvent){el.removeEventListener(evt,function(e){fn.handleEvent.call(fn,e)},bubble)}else{throw e}}}else if("detachEvent"in el){if(typeof fn==="object"&&fn.handleEvent){el.detachEvent("on"+evt,function(){fn.handleEvent.call(fn)})}else{el.detachEvent("on"+evt,fn)}}},getFirstChild=function(e){var firstChild=e.firstChild;while(firstChild!==null&&firstChild.nodeType!==1){firstChild=firstChild.nextSibling}return firstChild},setAttributes=function(el,attrs){for(var key in attrs){el.setAttribute(key,attrs[key])}},addClass=function(el,cls){el.className+=" "+cls;el.className=el.className.replace(/(^\s*)|(\s*$)/g,"")},removeClass=function(el,cls){var reg=new RegExp("(\\s|^)"+cls+"(\\s|$)");el.className=el.className.replace(reg," ").replace(/(^\s*)|(\s*$)/g,"")},ResponsiveNav=function(el,options){var i;this.options={animate:true,transition:400,label:"Menu",insert:"after",customToggle:"",openPos:"relative",jsClass:"js",init:function(){},open:function(){},close:function(){}};for(i in options){this.options[i]=options[i]}addClass(docEl,this.options.jsClass);this.wrapperEl=el.replace("#","");if(document.getElementById(this.wrapperEl)){this.wrapper=document.getElementById(this.wrapperEl)}else{throw new Error("The nav element you are trying to select doesn't exist")}this.wrapper.inner=getFirstChild(this.wrapper);opts=this.options;nav=this.wrapper;this._init(this)};ResponsiveNav.prototype={destroy:function(){this._removeStyles();removeClass(nav,"closed");removeClass(nav,"opened");nav.removeAttribute("style");nav.removeAttribute("aria-hidden");nav=null;_instance=null;removeEvent(window,"load",this,false);removeEvent(window,"resize",this,false);removeEvent(navToggle,"mousedown",this,false);removeEvent(navToggle,"touchstart",this,false);removeEvent(navToggle,"touchend",this,false);removeEvent(navToggle,"keyup",this,false);removeEvent(navToggle,"click",this,false);if(!opts.customToggle){navToggle.parentNode.removeChild(navToggle)}else{navToggle.removeAttribute("aria-hidden")}},toggle:function(){if(!navOpen){removeClass(nav,"closed");addClass(nav,"opened");nav.style.position=opts.openPos;setAttributes(nav,{"aria-hidden":"false"});navOpen=true;opts.open()}else{removeClass(nav,"opened");addClass(nav,"closed");setAttributes(nav,{"aria-hidden":"true"});if(opts.animate){setTimeout(function(){nav.style.position="absolute"},opts.transition+10)}else{nav.style.position="absolute"}navOpen=false;opts.close()}},handleEvent:function(e){var evt=e||window.event;switch(evt.type){case"mousedown":this._onmousedown(evt);break;case"touchstart":this._ontouchstart(evt);break;case"touchend":this._ontouchend(evt);break;case"keyup":this._onkeyup(evt);break;case"click":this._onclick(evt);break;case"load":this._transitions(evt);this._resize(evt);break;case"resize":this._resize(evt);break}},_init:function(){addClass(nav,"closed");this._createToggle();addEvent(window,"load",this,false);addEvent(window,"resize",this,false);addEvent(navToggle,"mousedown",this,false);addEvent(navToggle,"touchstart",this,false);addEvent(navToggle,"touchend",this,false);addEvent(navToggle,"keyup",this,false);addEvent(navToggle,"click",this,false)},_createStyles:function(){if(!styleElement.parentNode){head.appendChild(styleElement)}},_removeStyles:function(){if(styleElement.parentNode){styleElement.parentNode.removeChild(styleElement)}},_createToggle:function(){if(!opts.customToggle){var toggle=document.createElement("a");toggle.innerHTML=opts.label;setAttributes(toggle,{href:"#",id:"nav-toggle"});if(opts.insert==="after"){nav.parentNode.insertBefore(toggle,nav.nextSibling)}else{nav.parentNode.insertBefore(toggle,nav)}navToggle=document.getElementById("nav-toggle")}else{var toggleEl=opts.customToggle.replace("#","");if(document.getElementById(toggleEl)){navToggle=document.getElementById(toggleEl)}else{throw new Error("The custom nav toggle you are trying to select doesn't exist")}}},_preventDefault:function(e){if(e.preventDefault){e.preventDefault();e.stopPropagation()}else{e.returnValue=false}},_onmousedown:function(e){var evt=e||window.event;if(!(evt.which===3||evt.button===2)){this._preventDefault(e);this.toggle(e)}},_ontouchstart:function(e){navToggle.onmousedown=null;this._preventDefault(e);this.toggle(e)},_ontouchend:function(){var that=this;nav.addEventListener("click",that._preventDefault,true);setTimeout(function(){nav.removeEventListener("click",that._preventDefault,true)},opts.transition)},_onkeyup:function(e){var evt=e||window.event;if(evt.keyCode===13){this.toggle(e)}},_onclick:function(e){this._preventDefault(e)},_transitions:function(){if(opts.animate){var objStyle=nav.style,transition="max-height "+opts.transition+"ms";objStyle.WebkitTransition=transition;objStyle.MozTransition=transition;objStyle.OTransition=transition;objStyle.transition=transition}},_calcHeight:function(){var savedHeight=nav.inner.offsetHeight,innerStyles="#"+this.wrapperEl+".opened{max-height:"+savedHeight+"px}";if(computed){styleElement.innerHTML=innerStyles;innerStyles=""}},_resize:function(){if(window.getComputedStyle(navToggle,null).getPropertyValue("display")!=="none"){setAttributes(navToggle,{"aria-hidden":"false"});if(nav.className.match(/(^|\s)closed(\s|$)/)){setAttributes(nav,{"aria-hidden":"true"});nav.style.position="absolute"}this._createStyles();this._calcHeight()}else{setAttributes(navToggle,{"aria-hidden":"true"});setAttributes(nav,{"aria-hidden":"false"});nav.style.position=opts.openPos;this._removeStyles()}opts.init()}};var _instance;function rn(el,options){if(!_instance){_instance=new ResponsiveNav(el,options)}return _instance}return rn}(window,document);(function(root,factory){if(typeof exports=="object")module.exports=factory();else if(typeof define=="function"&&define.amd)define(factory);else root.Spinner=factory()})(this,function(){"use strict";var prefixes=["webkit","Moz","ms","O"],animations={},useCssAnimations;function createEl(tag,prop){var el=document.createElement(tag||"div"),n;for(n in prop)el[n]=prop[n];return el}function ins(parent){for(var i=1,n=arguments.length;i>1):parseInt(o.left,10)+mid)+"px",top:(o.top=="auto"?tp.y-ep.y+(target.offsetHeight>>1):parseInt(o.top,10)+mid)+"px"})}el.setAttribute("role","progressbar");self.lines(el,self.opts);if(!useCssAnimations){var i=0,start=(o.lines-1)*(1-o.direction)/2,alpha,fps=o.fps,f=fps/o.speed,ostep=(1-o.opacity)/(f*o.trail/100),astep=f/o.lines;(function anim(){i++;for(var j=0;j>1)+"px"})}for(;i',attr)}sheet.addRule(".spin-vml","behavior:url(#default#VML)");Spinner.prototype.lines=function(el,o){var r=o.length+o.width,s=2*r;function grp(){return css(vml("group",{coordsize:s+" "+s,coordorigin:-r+" "+-r}),{width:s,height:s})}var margin=-(o.width+o.length)*2+"px",g=css(grp(),{position:"absolute",top:margin,left:margin}),i;function seg(i,dx,filter){ins(g,ins(css(grp(),{rotation:360/o.lines*i+"deg",left:~~dx}),ins(css(vml("roundrect",{arcsize:o.corners}),{width:r,height:o.width,left:o.radius,top:-o.width>>1,filter:filter}),vml("fill",{color:o.color,opacity:o.opacity}),vml("stroke",{opacity:0}))))}if(o.shadow)for(i=1;i<=o.lines;i++)seg(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=o.lines;i++)seg(i);return ins(el,g)};Spinner.prototype.opacity=function(el,i,val,o){var c=el.firstChild;o=o.shadow&&o.lines||0;if(c&&i+o'+n.name+" ",n.annotation&&(a+="("+n.annotation+") "),a+='',a+='',a+='',a+="",a+='",a+="",$("#project-list-"+e).append(a)}"undefined"!=typeof projects?projects.forEach(function(n){n.hasOwnProperty("tags")?n.tags.forEach(function(a){e(a,n)}):e("other",n)}):console.error("Please load `projects.js` before `main.js`!"),$(".lazy-container").spin({color:"#000"});var navigation=responsiveNav("#nav",{insert:"before",customToggle:"#toggle",open:function(){$("#toggle").addClass("btn-highlite")},close:function(){$("#toggle").removeClass("btn-highlite")}});$("img.lazy").lazyload({threshold:200,effect:"fadeIn",effectspeed:600,load:function(elements_left,settings){$(".lazy-container").has(this).addClass("loaded");$(".loaded .spinner").remove();$('[data-spy="scroll"]').each(function(){var $spy=$(this).scrollspy("refresh")})}});$(".lightbox").magnificPopup({type:"image",disableOn:function(){if($(window).width()<500){return false}return true},preloader:true,tLoading:"Loading",removalDelay:300,mainClass:"mfp-fade",callbacks:{open:function(){$(".navbar").fadeOut("slow")},close:function(){$(".navbar").fadeIn("slow")}}});$(" .iframe").magnificPopup({type:"iframe",mainClass:"mfp-fad",disableOn:function(){if($(window).width()<500){return false}return true},preloader:true,callbacks:{open:function(){$(".navbar").fadeOut("slow")},close:function(){$(".navbar").fadeIn("slow")}}});$('.scroll[href^="#"]').bind("click.smoothscroll",function(e){e.preventDefault();var target=this.hash;$target=$(target);$("html, body").stop().animate({scrollTop:$target.offset().top},900,"swing",function(){window.location.hash=target})});$(".collapse").on("show",function(){$(this).parent().find(".icon-plus").removeClass("icon-plus").addClass("icon-minus");$(this).parent().find(".accordion-heading").addClass("active")}).on("hide",function(){$(this).parent().find(".icon-minus").removeClass("icon-minus").addClass("icon-plus");$(this).parent().find(".accordion-heading").removeClass("active")});$(".nav a").click(function(e){if($("#toggle").is(":visible"))navigation.toggle()});var jRes=jRespond([{label:"mobile",enter:0,exit:768}]);jRes.addFunc({breakpoint:"mobile",enter:function(){$("h1").fadeOut("slow")},exit:function(){$("h1").fadeIn("slow")}})});function iOSversion(){if(/iP(hone|od|ad)/.test(navigator.platform)){var v=navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/);return[parseInt(v[1],10),parseInt(v[2],10),parseInt(v[3]||0,10)] }else{return"0"}}ver=iOSversion();if(ver[0]>=5){$(".navbar-fixed-top").addClass("iphone");$(".btn-nav").addClass("iphone")} \ No newline at end of file diff --git a/index.html b/index.html index 3e8e6f9..36b7915 100644 --- a/index.html +++ b/index.html @@ -115,311 +115,12 @@

    MVC frameworks

    Sinatra-like

    These frameworks offer rich configuration and are less opinionated than Rails-like or full-stack.

    - +

      Rails-like

      Present your project properly. Create your own art from included templates

      - +
        @@ -431,366 +132,7 @@

        Full-stack frameworks

        That's where Node.js really shines. The full-stack MVC frameworks are bundled with scaffolding, template engines, websocket and persistence libraries to allow you build real-time scalable web apps.

        - +
          @@ -803,243 +145,7 @@

          REST API frameworks

          For those who use rich-client/front-end MVC frameworks (or not) and just need to spin up a fast Node.js REST API server.

          - +

            @@ -1050,230 +156,7 @@

            Other libraries

            Middleware, libraries and static site generators.

            - +
              Not enough? Okay, here is the laundry list from Joyent.
              diff --git a/projects.js b/projects.js new file mode 100644 index 0000000..c0cd934 --- /dev/null +++ b/projects.js @@ -0,0 +1,1719 @@ +var projects = [ + { + name: 'Express', + homepage: 'http://expressjs.com/', + github: { + user: 'expressjs', + repo: 'express' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/expressjs/express' + }, + { + title: 'NPM', + url: 'http://npmjs.org/express' + }, + { + title: 'todo', + url: 'http://github.com/azat-co/todo-express' + }, + { + title: 'rest api', + url: 'http://github.com/azat-co/rest-api-express' + } + ] + }, + { + name: 'hapi', + homepage: 'http://hapijs.com/', + github: { + user: 'hapijs', + repo: 'hapi' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'http://github.com/hapijs/hapi' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/hapi' + }, + { + title: 'rest api', + url: 'https://github.com/azat-co/practicalnode/tree/master/ch8' + } + ] + }, + { + name: 'flatiron', + homepage: 'http://flatironjs.org/', + github: { + user: 'flatiron', + repo: 'flatiron' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/flatiron/flatiron' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/flatiron' + } + ] + }, + { + name: 'locomotive', + homepage: 'http://locomotivejs.org/', + github: { + user: 'jaredhanson', + repo: 'locomotive' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/jaredhanson/locomotive' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/locomotive' + } + ] + }, + { + name: 'total.js', + homepage: 'http://www.totaljs.com', + github: { + user: 'totaljs', + repo: 'framework' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/totaljs/framework' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/total.js' + } + ] + }, + { + name: 'koa.js', + homepage: 'http://koajs.com/', + github: { + user: 'koajs', + repo: 'koa' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/koajs/koa' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/koa' + } + ] + }, + { + name: 'TWEE.IO', + homepage: 'http://twee.io/', + github: { + user: 'tweeio', + repo: 'twee-framework' + }, + tags: [ + 'sinatra', + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/tweeio/twee-framework' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/twee' + }, + { + title: 'Official Site', + url: 'http://twee.io' + } + ] + }, + { + name: 'diet.js', + homepage: 'http://dietjs.com/', + github: { + user: 'adamhalasz', + repo: 'diet' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/adamhalasz/diet' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/diet' + }, + { + title: 'Official Site', + url: 'http://dietjs.com' + } + ] + }, + { + name: 'Flicker.js', + homepage: 'https://flickerstudio.github.io/flickerjs', + github: { + user: 'FlickerStudio', + repo: 'flickerjs' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/FlickerStudio/flickerjs' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/flickerjs' + }, + { + title: 'Rest API Example', + url: 'https://github.com/FlickerStudio/api_rest_example' + } + ] + }, + { + name: 'ZinkyJS', + homepage: 'https://github.com/zinkyJS/zinky', + github: { + user: 'zinkyjs', + repo: 'zinky' + }, + tags: [ + 'sinatra' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/zinkyJS/zinky' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/zinky' + } + ] + }, + { + name: 'Nodal', + homepage: 'http://nodaljs.com/', + github: { + user: 'keithwhor', + repo: 'nodal' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/keithwhor/nodal' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/nodal' + } + ] + }, + { + name: 'Strapi', + homepage: 'http://strapi.io/', + github: { + user: 'strapi', + repo: 'strapi' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/wistityhq/strapi' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/strapi' + } + ] + }, + { + name: 'CompoundJS', + homepage: 'http://compoundjs.com/', + annotation: 'former railswayjs', + github: { + user: '1602', + repo: 'compound' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/1602/compound' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/compound' + } + ] + }, + { + name: 'geddy', + homepage: 'http://geddyjs.org/', + github: { + user: 'geddy', + repo: 'geddy' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/geddy/geddy' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/geddy' + } + ] + }, + { + name: 'Sails.js', + homepage: 'http://sailsjs.org/', + github: { + user: 'balderdashy', + repo: 'sails' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/balderdashy/sails/' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/sails' + } + ] + }, + { + name: 'Adonis', + homepage: 'http://adonisjs.com', + github: { + user: 'adonisjs', + repo: 'adonis-framework' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/adonisjs/adonis-framework/' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/adonis-framework' + } + ] + }, + { + name: 'RhapsodyJS', + homepage: 'http://rhapsodyjs.github.io/', + github: { + user: 'rhapsodyjs', + repo: 'RhapsodyJS' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/rhapsodyjs/RhapsodyJS' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/rhapsody' + }, + { + title: 'Examples', + url: 'https://github.com/rhapsodyjs/RhapsodyJS-examples' + } + ] + }, + { + name: 'ThinkJS', + homepage: 'https://thinkjs.org/', + github: { + user: 'thinkjs', + repo: 'thinkjs' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/thinkjs/thinkjs' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/thinkjs' + } + ] + }, + { + name: 'Trails', + homepage: 'http://www.trailsjs.io/', + github: { + user: 'trailsjs', + repo: 'trails' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/trailsjs/trails' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/trails' + } + ] + }, + { + name: 'KambojaJS', + homepage: 'http://kambojajs.com/', + github: { + user: 'kambojajs', + repo: 'kamboja' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/kambojajs/kamboja' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/kamboja' + } + ] + }, + { + name: 'JS-Web', + homepage: 'http://js-web-framework.com/', + github: { + user: 'simonsmadsen', + repo: 'js-web' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/simonsmadsen/js-web' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/js-web' + } + ] + }, + { + name: 'FoalTS', + homepage: 'https://foalts.org/', + annotation: 'TypeScript', + github: { + user: 'FoalTS', + repo: 'foal' + }, + tags: [ + 'rails' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/FoalTS/foal' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/@foal/core' + } + ] + }, + { + name: 'AllcountJS', + homepage: 'http://allcountjs.com', + github: { + user: 'allcount', + repo: 'allcountjs' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/allcount/allcountjs' + }, + { + title: 'NPM CLI', + url: 'https://www.npmjs.org/package/allcountjs-cli' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/allcountjs' + }, + { + title: 'Gitter', + url: 'https://gitter.im/allcount/allcountjs' + } + ] + }, + { + name: 'Derby', + homepage: 'http://derbyjs.com', + github: { + user: 'derbyjs', + repo: 'derby' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/derbyjs/derby' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/derby' + } + ] + }, + { + name: 'Feathers', + homepage: 'http://feathersjs.com/', + github: { + user: 'feathersjs', + repo: 'feathers' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/feathersjs/feathers' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/feathers' + } + ] + }, + { + name: 'SocketCluster', + homepage: 'http://socketcluster.io/', + github: { + user: 'socketcluster', + repo: 'socketcluster' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/socketcluster/socketcluster' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/socketcluster' + } + ] + }, + { + name: 'SocketStream', + homepage: 'http://socketstream.org', + github: { + user: 'socketstream', + repo: 'socketstream' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'http://github.com/socketstream/socketstream' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/socketstream' + } + ] + }, + { + name: 'MEAN.js', + homepage: 'http://meanjs.org/', + github: { + user: 'meanjs', + repo: 'mean' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/meanjs/mean' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/generator-meanjs' + } + ] + }, + { + name: 'MEAN.io', + homepage: 'http://mean.io/', + github: { + user: 'linnovate', + repo: 'mean' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/linnovate/mean' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/meanio' + } + ] + }, + { + name: 'Meteor', + homepage: 'http://meteor.com/', + github: { + user: 'meteor', + repo: 'meteor' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/meteor/meteor' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/meteor' + } + ] + }, + { + name: 'Meatier', + homepage: 'https://github.com/mattkrick/meatier', + github: { + user: 'mattkrick', + repo: 'meatier' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/mattkrick/meatier' + } + ] + }, + { + name: 'Mojito', + homepage: 'http://developer.yahoo.com/cocktails/mojito/', + github: { + user: 'yahoo', + repo: 'mojito' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/yahoo/mojito' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/mojito' + } + ] + }, + { + name: 'Seeds.js', + homepage: 'http://seedsjs.com/', + github: { + user: 'terminalvelocity', + repo: 'seeds.js' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/terminalvelocity/seeds.js' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/seeds' + }, + { + title: 'Docs', + url: 'http://docs.seedsjs.com' + }, + { + title: 'Gitter Chat', + url: 'https://gitter.im/terminalvelocity/seeds.js' + } + ] + }, + { + name: 'SANE', + homepage: 'http://sanestack.com/', + github: { + user: 'artificialio', + repo: 'sane' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/artificialio/sane' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/sane-cli' + } + ] + }, + { + name: 'COKE', + homepage: 'http://coke-js.org', + github: { + user: 'dreamerslab', + repo: 'coke' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/dreamerslab/coke' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/coke' + } + ] + }, + { + name: 'Sleekjs', + homepage: 'http://sleekjs.com/', + github: { + user: 'cubettech', + repo: 'sleekjs' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/cubettech/sleekjs' + }, + { + title: 'NPM', + url: 'https://npmjs.org/package/sleek.js' + } + ] + }, + { + name: 'Danf', + homepage: 'https://github.com/gnodi/danf', + github: { + user: 'gnodi', + repo: 'danf' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/gnodi/danf' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/danf' + } + ] + }, + { + name: 'Catberry', + homepage: 'http://catberry.org', + github: { + user: 'catberry', + repo: 'catberry' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/catberry/catberry' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/catberry' + } + ] + }, + { + name: 'Nuke.js', + homepage: 'http://nukejs.com/', + github: { + user: 'FREEZX', + repo: 'nuke.js' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/FREEZX/nuke.js' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/generator-nukejs' + } + ] + }, + { + name: 'We.js', + homepage: 'http://wejs.org', + github: { + user: 'wejs', + repo: 'we' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/wejs/we' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/we' + }, + { + title: 'Gitter', + url: 'https://gitter.im/wejs/we' + }, + { + title: 'Google groups', + url: 'https://groups.google.com/forum/#!forum/we-js' + } + ] + }, + { + name: 'seneca.js', + homepage: 'http://senecajs.org', + github: { + user: 'senecajs', + repo: 'seneca' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/senecajs/seneca' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/seneca' + }, + { + title: 'Getting started', + url: 'http://senecajs.org/get-started/' + }, + { + title: 'Gitter', + url: 'https://gitter.im/senecajs/seneca' + } + ] + }, + { + name: 'Keystone.js', + homepage: 'http://keystonejs.com/', + github: { + user: 'keystonejs', + repo: 'keystone' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'http://github.com/keystonejs/keystone' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/keystone' + }, + { + title: 'Getting started', + url: 'http://keystonejs.com/getting-started/' + }, + { + title: 'Gitter', + url: 'https://gitter.im/keystonejs/keystone' + } + ] + }, + { + name: 'Horizon', + homepage: 'http://horizon.io', + github: { + user: 'rethinkdb', + repo: 'horizon' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/rethinkdb/horizon' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/horizon' + }, + { + title: 'Getting started', + url: 'http://horizon.io/docs/getting-started/' + }, + { + title: 'Discuss', + url: 'https://discuss.horizon.io/' + } + ] + }, + { + name: 'Apogeu', + homepage: 'https://apogeu.github.io/', + github: { + user: 'apogeu', + repo: 'apogeu' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/apogeu/apogeu' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/apogeu' + }, + { + title: 'Getting started', + url: 'https://apogeu.github.io/get-started' + } + ] + }, + { + name: 'monument', + homepage: 'http://monumentjs.com/', + github: { + user: 'ansble', + repo: 'monument' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/ansble/monument/' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/monument' + } + ] + }, + { + name: 'x2node | Resources', + homepage: 'http://x2node.com/', + github: { + user: 'boylesoftware', + repo: 'x2node-ws-resources' + }, + tags: [ + 'full-stack' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/boylesoftware/x2node-ws-resources' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/x2node-ws-resources' + } + ] + }, + { + name: 'Ivy', + homepage: 'http://ivyframework.com', + github: { + user: 'ivyjs', + repo: 'framework' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/ivyjs/framework' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/ivyframework' + } + ] + }, + { + name: 'Restocat', + homepage: 'https://github.com/restocat/restocat', + github: { + user: 'restocat', + repo: 'restocat' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/restocat/restocat' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/restocat' + } + ] + }, + { + name: 'actionHero.js', + homepage: 'http://actionherojs.com/', + github: { + user: 'evantahler', + repo: 'actionhero' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/evantahler/actionhero' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/actionhero' + } + ] + }, + { + name: 'Frisby', + homepage: 'http://frisbyjs.com/', + github: { + user: 'vlucas', + repo: 'frisby' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/vlucas/frisby' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/frisby' + } + ] + }, + { + name: 'restling', + homepage: 'https://github.com/lucasfeliciano/restling', + github: { + user: 'lucasfeliciano', + repo: 'restling' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/lucasfeliciano/restling' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/restling' + } + ] + }, + { + name: 'restify', + homepage: 'http://mcavage.github.io/node-restify/', + github: { + user: 'mcavage', + repo: 'node-restify' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/mcavage/node-restify' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/restify' + } + ] + }, + { + name: 'restmvc', + homepage: 'https://github.com/keithnlarsen/restmvc.js', + github: { + user: 'keithnlarsen', + repo: 'restmvc.js' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/keithnlarsen/restmvc.js' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/restmvc.js' + } + ] + }, + { + name: 'percolator', + homepage: 'http://percolatorjs.com', + github: { + user: 'cainus', + repo: 'percolator' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/cainus/percolator' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/percolator' + } + ] + }, + { + name: 'LoopBack', + homepage: 'http://loopback.io/', + github: { + user: 'strongloop', + repo: 'loopback' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/strongloop/loopback' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/loopback' + } + ] + }, + { + name: 'Fortune.js', + homepage: 'http://fortunejs.com', + github: { + user: 'daliwali', + repo: 'fortune' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/daliwali/fortune' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/fortune' + } + ] + }, + { + name: 'facet', + homepage: 'http://facet.github.io', + github: { + user: 'facet', + repo: 'facet.github.io' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/facet' + } + ] + }, + { + name: 'Raddish', + homepage: 'http://getraddish.com', + github: { + user: 'getraddished', + repo: 'raddish' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/getraddished/raddish' + } + ] + }, + { + name: 'Restberry', + homepage: 'http://restberry.com', + github: { + user: 'materik', + repo: 'restberry' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/materik/restberry' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/restberry' + } + ] + }, + { + name: 'Gugamarket', + homepage: 'http://pliik.github.io/gugamarket/', + github: { + user: 'pliik', + repo: 'gugamarket' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/pliik/gugamarket' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/gugamarket' + } + ] + }, + { + name: 'Nest', + homepage: 'https://kamilmysliwiec.gitbooks.io/nest/', + github: { + user: 'kamilmysliwiec', + repo: 'nest' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/kamilmysliwiec/nest' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/nest.js' + } + ] + }, + { + name: 'microlet', + homepage: 'https://borislemke.gitbooks.io/microlet/', + github: { + user: 'borislemke', + repo: 'microlet' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/borislemke/microlet' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/microlet' + } + ] + }, + { + name: 'Moleculer', + homepage: 'https://moleculer.services/', + github: { + user: 'ice-services', + repo: 'moleculer' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/ice-services/moleculer' + }, + { + title: 'NPM', + url: 'https://www.npmjs.com/package/moleculer' + } + ] + }, + { + name: 'x2node | Web Services', + homepage: 'http://x2node.com/', + github: { + user: 'boylesoftware', + repo: 'x2node-ws' + }, + tags: [ + 'rest' + ], + links: [ + { + title: 'GitHub', + url: 'https://github.com/boylesoftware/x2node-ws' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/x2node-ws' + } + ] + }, + { + name: 'Connect', + homepage: 'http://www.senchalabs.org/connect/', + github: { + user: 'senchalabs', + repo: 'connect' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/senchalabs/connect' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/connect' + } + ] + }, + { + name: 'Kraken', + homepage: 'http://krakenjs.com/', + github: { + user: 'krakenjs', + repo: 'kraken-js' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/krakenjs/kraken-js' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/kraken-js' + } + ] + }, + { + name: 'ewdGateway2', + homepage: 'https://github.com/robtweed/ewdGateway2', + github: { + user: 'robtweed', + repo: 'ewdGateway2' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/robtweed/ewdGateway2' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/ewdgateway2' + } + ] + }, + { + name: 'Wintersmith', + homepage: 'https://github.com/jnordberg/wintersmith', + github: { + user: 'jnordberg', + repo: 'wintersmith' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/jnordberg/wintersmith' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/wintersmith' + } + ] + }, + { + name: 'docpad', + homepage: 'http://docpad.org', + github: { + user: 'docpad', + repo: 'docpad' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/docpad/docpad' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/docpad' + } + ] + }, + { + name: 'Blacksmith', + homepage: 'http://blacksmith.jit.su/', + github: { + user: 'flatiron', + repo: 'blacksmith' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/flatiron/blacksmith' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/blacksmith' + } + ] + }, + { + name: 'romulus', + homepage: 'https://github.com/felixge/node-romulus', + github: { + user: 'felixge', + repo: 'node-romulus' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/felixge/node-romulus' + } + ] + }, + { + name: 'Petrify', + homepage: 'https://github.com/caolan/petrify', + github: { + user: 'caolan', + repo: 'petrify' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/caolan/petrify' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/petrify' + } + ] + }, + { + name: 'Tower.js', + homepage: 'http://tower.github.io', + github: { + user: 'tower', + repo: 'tower' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/tower/tower' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/tower' + } + ] + }, + { + name: 'Impress', + homepage: 'https://github.com/tshemsedinov/impress', + github: { + user: 'tshemsedinov', + repo: 'impress' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/tshemsedinov/impress' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/impress' + } + ] + }, + { + name: 'Rendr', + homepage: 'https://github.com/rendrjs/rendr', + github: { + user: 'rendrjs', + repo: 'rendr' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/airbnb/rendr' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/rendr' + } + ] + }, + { + name: 'Backnode', + homepage: 'https://github.com/mklabs/backnode', + github: { + user: 'mklabs', + repo: 'backnode' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/mklabs/backnode' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/backnode' + } + ] + }, + { + name: 'Sequelize', + homepage: 'http://sequelizejs.com/', + github: { + user: 'sequelize', + repo: 'sequelize' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/sequelize/sequelize' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/sequelize' + } + ] + }, + { + name: 'Cylon.js', + homepage: 'http://cylonjs.com/', + github: { + user: 'hybridgroup', + repo: 'cylon' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/hybridgroup/cylon' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/cylon' + } + ] + }, + { + name: 'Virgilio.js', + homepage: 'http://icemobilelab.github.io/virgilio/', + github: { + user: 'icemobilelab', + repo: 'virgilio' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/icemobilelab/virgilio' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/virgilio' + } + ] + }, + { + name: 'SHPS', + homepage: 'https://shps.io', + github: { + user: 'Skellods-Network', + repo: 'SHPS4Node' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/Skellods-Network/SHPS4Node' + }, + { + title: 'Gitter', + url: 'https://gitter.im/Skellods-Network/SHPS4Node' + } + ] + }, + { + name: 'x2node | Database Operations', + homepage: 'http://x2node.com/', + github: { + user: 'boylesoftware', + repo: 'x2node-dbos' + }, + links: [ + { + title: 'GitHub', + url: 'https://github.com/boylesoftware/x2node-dbos' + }, + { + title: 'NPM', + url: 'https://www.npmjs.org/package/x2node-dbos' + } + ] + } +];