Server : LiteSpeed
System : Linux server51.dnsbootclub.com 4.18.0-553.62.1.lve.el8.x86_64 #1 SMP Mon Jul 21 17:50:35 UTC 2025 x86_64
User : nandedex ( 1060)
PHP Version : 8.1.33
Disable Function : NONE
Directory :  /tmp/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]


Current File : //tmp/phpiTcDAM
!function(e,t,s){var i={model:{},collection:{},view:{},fn:{}},r=function(e,t){for(var s=[],i=SPECIFICITY.calculate(e),o=0;o<i.length;o++){var c=i[o];if(t)for(var a=0;a<c.parts.length;a++){var n=c.parts[a];s=s.concat(r(n.selector))}else s.push({selector:c.selector.trim(),specificity:parseInt(c.specificity.replace(/,/g,""))})}return s};i.view.inspector=Backbone.View.extend({active:!1,hl:!1,hoverEl:!1,pageSelectors:[],selectorTemplate:t.template('<div class="socss-selector"><%= selector %></div>'),importantClasses:["menu-item-","postid-","page-id-"],initialize:function(){var t=this;this.hl=new i.view.highlighter,this.hl.initialize(),this.pageSelectors=i.fn.pageSelectors(),e("body").on("mouseover","*",(function(s){if(!t.active)return!0;0===e(this).closest(".socss-element").length&&(s.stopPropagation(),t.setHoverEl(e(this)))}));var s=e(".single-product").length;e("body *").on("click",(function(i){if(!t.active||e(i.target).parent(".socss-link").length)return!0;var r=e(this);s&&r.parents(".wc-tabs").length||(i.preventDefault(),r.trigger("blur"),t.setActiveEl(t.hoverEl))})),this.$(".socss-enable-inspector").on("click",(function(){t.toggleActive()})),this.$el.on("mouseenter",(function(){t.hl.clear()}));try{parent.socss.mainEditor.setInspector(this)}catch(e){console.log("No editor to register this inspector with")}},setHoverEl:function(e){this.hoverEl=e,this.hl.highlight(e)},activate:function(){this.active=!0,e("body").addClass("socss-active"),e("body").removeClass("socss-inactive")},deactivate:function(){this.active=!1,e("body").addClass("socss-inactive"),e("body").removeClass("socss-active"),this.hl.clear(),this.$(".socss-hierarchy").empty()},toggleActive:function(){this.active?this.deactivate():this.activate()},setActiveEl:function(s){var r=this,o=this.$(".socss-hierarchy");if(o.empty(),s){if("body"!==s.prop("tagName").toLowerCase()){var c=e(s);do{var a=i.fn.elSelector(c);r.importantClasses.forEach((function(e){if(a.indexOf(e)>=0){var t=new RegExp("("+e+"\\d+)","g");a=a.replace(t,"<strong>$1</strong>")}})),e(this.selectorTemplate({selector:a})).prependTo(o).data("el",c),c=c.parent()}while("body"!==c.prop("tagName").toLowerCase());e(this.selectorTemplate({selector:"body"})).prependTo(o).data("el",e("body")),this.$(".socss-hierarchy .socss-selector").on("mouseenter",(function(){r.hl.highlight(e(this).data("el"))})).on("click",(function(t){t.preventDefault(),t.stopPropagation(),r.setActiveEl(e(this).data("el"))}))}o.scrollLeft(99999);var n=this.pageSelectors.filter((function(e){try{return s.is(e.selector)}catch(e){return!1}})),l=this.$(".socss-selectors-window").empty();t.each(n,(function(t){l.append(e(r.selectorTemplate(t)).data(t))})),l.find("> div").on("mouseenter",(function(){r.hl.highlight(e(this).data("selector"))})).on("click",(function(t){t.preventDefault(),t.stopPropagation(),r.trigger("click_selector",e(this).data("selector"))}));var h=i.fn.elementAttributes(s);l=this.$(".socss-properties-window").empty(),t.each(h,(function(t,s){l.append(e(r.selectorTemplate({selector:"<strong>"+s+"</strong>: "+t})).data("property",s+": "+t))})),l.find("> div").on("click",(function(t){t.preventDefault(),t.stopPropagation(),r.trigger("click_property",e(this).data("property"))}));var p=s.closest("a[href]"),f=this.$(".socss-link");p.length?f.show().find("a").html(p.attr("href").replace(/[\?&]*so_css_preview=1/,"")).attr("href",p.attr("href")):f.hide(),this.trigger("set_active_element",s,n)}}}),i.view.highlighter=Backbone.View.extend({template:t.template(e("#socss-template-hover").html().trim()),highlighted:[],highlight:function(t){this.clear();var s=this;e(t).each((function(t,i){if(!(i=e(i)).is(":visible"))return!0;var r,o=e(s.template());o.css({top:i.offset().top,left:i.offset().left,width:i.outerWidth(),height:i.outerHeight()}).appendTo("body");var c=i.padding();for(var a in c)parseInt(c[a])>0&&(r=o.find(".socss-guide-padding.socss-guide-"+a).show(),"top"===a||"bottom"===a?r.css("height",c[a]):(r.css("width",c[a]),r.css({width:c[a],top:c.top,bottom:c.bottom})));var n=i.margin();for(var a in n)parseInt(n[a])>0&&(r=o.find(".socss-guide-margin.socss-guide-"+a).show(),"top"===a||"bottom"===a?r.css("height",n[a]):r.css("width",n[a]));s.highlighted.push(o)}))},clear:function(){for(;this.highlighted.length;)this.highlighted.pop().remove()}}),i.parsedCss={},i.fn.getParsedCss=function(){if(0===Object.keys(i.parsedCss).length){var t=window.css;e(".socss-theme-styles").each((function(){var s=e(this),r=t.parse(s.html(),{silent:!0});i.parsedCss[s.attr("id")]=r}))}return i.parsedCss},i.fn.pageSelectors=function(){var s=[],o=i.fn.getParsedCss();for(var c in o)for(var a=o[c].stylesheet.rules,n=0;n<a.length;n++)if(void 0!==a[n].selectors)for(var l=0;l<a[n].selectors.length;l++)s=s.concat(r(a[n].selectors[l]));e("body *").each((function(){var t=e(this),o=i.fn.elSelector(t);s=s.concat(r(o))}));var h=e("body"),p=i.fn.elSelector(h);return s=s.concat(r(p,!0)),(s=t.uniq(s,!1,(function(e){return e.selector}))).sort((function(e,t){return e.specificity>t.specificity?-1:1})),s},i.fn.elementAttributes=function(e){if(!document.styleSheets)return[];var t=[],s=i.fn.getParsedCss(),r=function(e){switch(e){case"charset":case"custom-media":case"document":case"font-face":case"host":case"import":case"keyframes":case"keyframe":case"media":case"namespace":case"page":case"supports":return!0}return!1};for(var o in s)for(var c=s[o].stylesheet.rules,a=0;a<c.length;a++){var n=c[a];if(void 0!==n.selectors&&!r(n.type))for(var l=0;l<n.selectors.length;l++)for(var h=SPECIFICITY.calculate(n.selectors[l]),p=0;p<h.length;p++)try{if(e.is(h[p].selector)){var f=n.declarations;for(p=0;p<f.length;p++)t.push({name:f[p].property,value:f[p].value,specificity:parseInt(h[p].specificity.replace(/,/g,""))})}}catch(e){}}t.sort((function(e,t){return e.specificity>t.specificity?1:-1})).reverse();for(var d={},v=0;v<t.length;v++)void 0===d[t[v].name]&&(d[t[v].name]=t[v].value);return d},i.fn.elSelector=function(e){var t="";return void 0!==e.attr("id")&&(t+="#"+e.attr("id")),void 0!==e.attr("class")&&(t+="."+e.attr("class").replace(/\s+/g,".")),""===t&&(t=e.prop("tagName").toLowerCase()),t},window.socssInspector=i}(jQuery,_,socssOptions),jQuery((function(e){var t=new window.socssInspector.view.inspector({el:e("#socss-inspector-interface").get(0)});t.activate(),window.socssInspector.mainInspector=t}));!function(e,t,i){var s={model:{},collection:{},view:{},fn:{}};window.socss=s,s.model.CustomCssModel=Backbone.Model.extend({defaults:{postId:null,postTitle:null,css:null},urlRoot:i.postCssUrlRoot,url:function(){return this.urlRoot+"&postId="+this.get("postId")}}),s.model.CustomCssCollection=Backbone.Collection.extend({model:s.model.CustomCssModel,modelId:function(e){return e.postId}}),s.model.CSSEditorModel=Backbone.Model.extend({defaults:{customCssPosts:null}}),s.view.toolbar=Backbone.View.extend({button:t.template('<li><a href="#<%= action %>" class="toolbar-button socss-button"><%= text %></a></li>'),events:{"click .socss-button:not(.save)":"triggerEvent"},triggerEvent:function(t){t.preventDefault();var i=e(t.currentTarget);i.trigger("blur");var s=i.attr("href").replace("#","");this.$el.trigger("click_"+s)},addButton:function(t,i){return e(this.button({text:t,action:i})).appendTo(this.$(".toolbar-function-buttons .toolbar-buttons"))}}),s.view.editor=Backbone.View.extend({codeMirror:null,snippets:null,toolbar:null,visualProperties:null,inspector:null,cssSelectors:[],initValue:null,events:{"click_expand .custom-css-toolbar":"toggleExpand","click_visual .custom-css-toolbar":"showVisualEditor","click .socss-button.save":"save",submit:"onSubmit"},initialize:function(e){this.listenTo(this.model,"change:selectedPost",this.getSelectedPostCss),this.getSelectedPostCss().then(function(){e.openVisualEditor&&this.showVisualEditor()}.bind(this))},save:function(){s.save(this)},getSelectedPostCss:function(){var t=this.model.get("selectedPost");return(t&&!t.has("css")?t.fetch():(new e.Deferred).resolve()).then(this.render.bind(this))},render:function(){var t=this.model.get("selectedPost");return t&&!t.has("css")?this:(this.codeMirror||this.setupEditor(),this.toolbar||(this.toolbar=new s.view.toolbar({el:this.$(".custom-css-toolbar"),model:this.model}),this.toolbar.render()),this.visualProperties||(this.visualProperties=new s.view.properties({editor:this,el:e("#so-custom-css-properties")}),this.visualProperties.render()),this.preview||(this.preview=new s.view.preview({editor:this,model:this.model,el:this.$(".custom-css-preview"),initURL:i.homeURL}),this.preview.render()),t&&(this.codeMirror.setValue(t.get("css")),this.codeMirror.clearHistory()),this)},setupEditor:function(){var s=this.$("textarea.css-editor");this.initValue=s.val();var o=this.initValue.match(/\n/gm),r=(o&&o.length,this.initValue);s.val(r);var n={tabSize:2,lineNumbers:!0,mode:"css",theme:s.data("theme"),inputStyle:"contenteditable",gutters:["CodeMirror-lint-markers"],lint:!0,search:!0,dialog:!0,annotateScrollbar:!0,extraKeys:{"Ctrl-F":"findPersistent","Alt-G":"jumpToLine"}};void 0!==wp.codeEditor?(n=t.extend(wp.codeEditor.defaultSettings.codemirror,n),this.codeMirror=wp.codeEditor.initialize(s.get(0),n).codemirror):(this.registerCodeMirrorAutocomplete(),this.codeMirror=CodeMirror.fromTextArea(s.get(0),n),this.setupCodeMirrorExtensions());var l=this.codeMirror;e("#so_css_editor_theme").on("change",(function(){1==e(this).val()?l.setOption("theme","neat"):l.setOption("theme","ambiance")})),this.codeMirror.on("change",function(e,t){var i=this.model.get("selectedPost");i&&i.get("css")!==e.getValue().trim()&&i.set("css",e.getValue().trim())}.bind(this)),e(window).on("beforeunload",function(){if(this.codeMirror.getValue().trim()!==this.initValue)return i.loc.leave}.bind(this)),this.$el.find(".custom-css-container").css("overflow","visible"),this.scaleEditor(),e(window).on("resize",function(){this.scaleEditor()}.bind(this))},onSubmit:function(){this.initValue=this.codeMirror.getValue().trim()},registerCodeMirrorAutocomplete:function(){var e={link:1,visited:1,active:1,hover:1,focus:1,"first-letter":1,"first-line":1,"first-child":1,before:1,after:1,lang:1};CodeMirror.registerHelper("hint","css",function(t){var i=t.getCursor(),s=t.getTokenAt(i),o=CodeMirror.innerMode(t.getMode(),s.state);if("css"===o.mode.name){if("keyword"===s.type&&0==="!important".indexOf(s.string))return{list:["!important"],from:CodeMirror.Pos(i.line,s.start),to:CodeMirror.Pos(i.line,s.end)};var r=s.start,n=i.ch,l=s.string.slice(0,n-r);/[^\w$_-]/.test(l)&&(l="",r=n=i.ch);var a=CodeMirror.resolveMode("text/css"),c=[],d=o.state.state;if("top"===d){for(var p=t.getLine(i.line).trim(),h=this.cssSelectors,u=0;u<h.length;u++)-1!==h[u].selector.indexOf(p)&&c.push(h[u].selector);if(c.length)return{list:c,from:CodeMirror.Pos(i.line,0),to:CodeMirror.Pos(i.line,n)}}else if("pseudo"===d||"variable-3"===s.type?v(e):"block"===d||"maybeprop"===d?v(a.propertyKeywords):"prop"===d||"parens"===d||"at"===d||"params"===d?(v(a.valueKeywords),v(a.colorKeywords)):"media"!==d&&"media_parens"!==d||(v(a.mediaTypes),v(a.mediaFeatures)),c.length)return{list:c,from:CodeMirror.Pos(i.line,r),to:CodeMirror.Pos(i.line,n)}}function v(e){for(var t in e)l&&0!==t.lastIndexOf(l,0)||c.push(t)}}.bind(this))},setupCodeMirrorExtensions:function(){this.codeMirror.on("cursorActivity",function(e){var t=e.getCursor(),i=e.getTokenAt(t);CodeMirror.innerMode(e.getMode(),i.state);if("qualifier"===i.type||"tag"===i.type||"builtin"===i.type){var s=e.getLine(t.line).substring(0,i.end);this.preview.highlight(s)}else this.preview.clearHighlight()}.bind(this)),"function"==typeof CodeMirror.showHint&&this.codeMirror.on("keyup",(function(e,t){(t.keyCode>=65&&t.keyCode<=90||189===t.keyCode&&!t.shiftKey||190===t.keyCode&&!t.shiftKey||51===t.keyCode&&t.shiftKey||189===t.keyCode&&t.shiftKey)&&e.showHint({completeSingle:!1})}))},scaleEditor:function(){var t,i=e(window).outerHeight();if(this.$el.hasClass("expanded"))this.$el.find(".CodeMirror-scroll").css("max-height",""),t=i-this.$(".custom-css-toolbar").outerHeight(),this.codeMirror.setSize("100%",t),this.$el.find(".CodeMirror-scroll").css("height","100%");else{var s=e("#so-custom-css-form");(t=i-(e("#wpadminbar").outerHeight(!0)+e("#siteorigin-custom-css").find("> h2").outerHeight(!0)+s.find("> .custom-css-toolbar").outerHeight(!0)+s.find("> .so-css-footer").outerHeight(!0)+parseFloat(e("#wpbody-content").css("padding-bottom"))))<300&&(t=300),this.codeMirror.setSize("100%","auto"),this.$el.find(".CodeMirror-scroll").css("height",t+"px")}this.$el.find(".CodeMirror-code").css("height",t+"px")},isExpanded:function(){return this.$el.hasClass("expanded")},toggleExpand:function(t){e(".editor-expand").attr("title",e(".so-css-icon-"+(this.isExpanded()?"expand":"compress ")).attr("title")),this.$el.toggleClass("expanded"),this.scaleEditor()},setExpand:function(e){e?this.$el.addClass("expanded"):this.$el.removeClass("expanded"),this.scaleEditor()},showVisualEditor:function(){this.visualProperties.loadCSS(this.codeMirror.getValue().trim()),this.visualProperties.show()},setSnippets:function(e){t.isEmpty(e)||(this.snippets=new s.view.snippets({snippets:e}),this.snippets.editor=this,this.snippets.render(),this.toolbar.addButton("Snippets","snippets"),this.toolbar.on("click_snippets",function(){this.snippets.show()}.bind(this)))},addCode:function(e){var t=this.codeMirror,i="";i=1===t.doc.lineCount()&&0===t.doc.getLine(t.doc.lastLine()).length?"":0===t.doc.getLine(t.doc.lastLine()).length?"\n":"\n\n",t.doc.setCursor(t.doc.lastLine(),t.doc.getLine(t.doc.lastLine()).length),t.doc.replaceSelection(i+e)},addEmptySelector:function(e){this.addCode(e+" {\n  \n}")},setInspector:function(e){this.inspector=e,this.cssSelectors=e.pageSelectors,e.on("click_selector",function(e){this.visualProperties.isVisible()?this.visualProperties.addSelector(e):this.addEmptySelector(e)}.bind(this)),e.on("click_property",function(e){this.visualProperties.isVisible()||this.codeMirror.replaceSelection(e+";\n  ")}.bind(this)),e.on("set_active_element",function(e,t){this.visualProperties.isVisible()&&t.length&&this.visualProperties.addSelector(t[0].selector)}.bind(this))}}),s.view.preview=Backbone.View.extend({template:t.template(e("#template-preview-window").html()),editor:null,originalUri:null,currentUri:null,events:{"mouseleave #preview-iframe":"clearHighlight",'keydown #preview-navigator input[type="text"]':"reloadPreview"},initialize:function(e){this.editor=e.editor,this.listenTo(this.model,"change:selectedPost",this.render.bind(this)),this.originalUri=new URI(e.initURL),this.currentUri=new URI(e.initURL),this.editor.codeMirror.on("change",function(e,t){this.updatePreviewCss()}.bind(this))},render:function(){var e=this.model.get("selectedPost");if(e&&!e.has("postUrl"))return e.fetch().then(this.render.bind(this)),this;this.$el.html(this.template()),e&&(this.currentUri=new URI(e.get("postUrl"))),this.currentUri.removeQuery("so_css_preview",1),this.$("#preview-navigator input").val(this.currentUri.toString()),this.currentUri.addQuery("so_css_preview",1),this.$("#preview-iframe").attr("src",this.currentUri.toString()).on("load",this.initPreview.bind(this))},initPreview:function(){var t=this.$("#preview-iframe");this.currentUri=new URI(t.contents().get(0).location.href),this.currentUri.removeQuery("so_css_preview"),this.$("#preview-navigator input").val(this.currentUri.toString()),this.currentUri.addQuery("so_css_preview",1);var i=t.contents().find(".single-product").length;t.contents().find("a").each((function(){var t=e(this),s=t.attr("href");if(void 0===s||i&&t.parents(".wc-tabs").length)return!0;var o=-1===s.indexOf("?")?"?":"&";t.attr("href",s+o+"so_css_preview=1")})),this.updatePreviewCss()},reloadPreview:function(e){var t=this.$('#preview-navigator input[type="text"]');if(13===e.keyCode){e.preventDefault();var i=new URI(t.val());this.originalUri.host()!==i.host()||this.originalUri.protocol()!==i.protocol()?(t.trigger("blur"),alert(t.data("invalid-uri")),t.trigger("focus")):(i.addQuery("so_css_preview",1),this.$("#preview-iframe").attr("src",i.toString()))}},updatePreviewCss:function(){var e=this.$("#preview-iframe");if(0!==e.length){var t=e.contents().find("head");0===t.find("style.siteorigin-custom-css").length&&t.append('<style class="siteorigin-custom-css" type="text/css"></style>');var i=t.find("style.siteorigin-custom-css"),s=this.editor.codeMirror.getValue().trim();i.html(s)}},highlight:function(e){try{this.editor.inspector.hl.highlight(e)}catch(e){console.log("No inspector to highlight with")}},clearHighlight:function(){try{this.editor.inspector.hl.clear()}catch(e){console.log("No inspector to highlight with")}}}),s.view.snippets=Backbone.View.extend({template:t.template(e("#template-snippet-browser").html()),snippet:t.template('<li class="snippet"><%- name %></li>'),className:"css-editor-snippet-browser",snippets:null,editor:null,events:{"click .close":"hide","click .buttons .insert-snippet":"insertSnippet","click .snippet":"clickSnippet"},currentSnippet:null,initialize:function(e){this.snippets=e.snippets},render:function(){this.$el.html(this.template());for(var t=0;t<this.snippets.length;t++)e(this.snippet({name:this.snippets[t].Name})).data({description:this.snippets[t].Description,css:this.snippets[t].css}).appendTo(this.$("ul.snippets"));return this.$(".snippets li.snippet").eq(0).trigger("click"),this.attach(),this},clickSnippet:function(t){t.preventDefault();var i=e(t.currentTarget);this.$(".snippets li.snippet").removeClass("active"),e(this).addClass("active"),this.viewSnippet({name:i.html(),description:i.data("description"),css:i.data("css")})},viewSnippet:function(e){var t=this.$(".main .snippet-view");t.find(".snippet-title").html(e.name),t.find(".snippet-description").html(e.description),t.find(".snippet-code").html(e.css),this.currentSnippet=e},insertSnippet:function(){var e=this.editor.codeMirror,t=this.currentSnippet.css,i="";i=1===e.doc.lineCount()&&0===e.doc.getLine(e.doc.lastLine()).length?"":0===e.doc.getLine(e.doc.lastLine()).length?"\n":"\n\n",e.doc.setCursor(e.doc.lastLine(),e.doc.getLine(e.doc.lastLine()).length),e.doc.replaceSelection(i+t),this.hide()},attach:function(){this.$el.appendTo("body")},show:function(){this.$el.show()},hide:function(){this.$el.hide()}}),s.save=function(t){let s=e("#siteorigin-custom-css .save");var o;s.hasClass("button-primary-disabled")||(s.addClass("button-primary-disabled"),void 0!==t.editor?(o=t.editor.codeMirror.getValue().trim(),t.updateMainEditor(!0)):o=t.codeMirror.getValue().trim(),e.post(i.ajaxurl,{action:"socss_save_css",css:o},null,"html").done((function(t){t.length&&e(".custom-revisions-list").html(t)})).fail((function(e){alert(e.responseText)})).always((function(){s.removeClass("button-primary-disabled")})))},s.view.properties=Backbone.View.extend({tabTemplate:t.template('<li data-section="<%- id %>"><span class="so-css-icon so-css-icon-<%- icon %>"></span> <%- title %></li>'),sectionTemplate:t.template('<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>'),controllerTemplate:t.template('<tr><th scope="row"><%- title %></th><td></td></tr>'),propertyControllers:[],editor:null,css:"",parsed:{},activeSelector:"",editorExpandedBefore:!1,events:{"click .close":"hide","click .save":"save","click .section-tabs li":"onTabClick","change .toolbar select":"onToolbarSelectChange"},initialize:function(e){this.parser=window.css,this.editor=e.editor},render:function(){this.$(".section-tabs").empty(),this.$(".sections").empty(),this.$(".toolbar select").off(),this.propertyControllers=[];var o=i.propertyControllers;for(var r in o){e(this.tabTemplate({id:r,icon:o[r].icon,title:o[r].title})).appendTo(this.$(".section-tabs"));var n=e(this.sectionTemplate({id:r})).appendTo(this.$(".sections"));if(!t.isEmpty(o[r].controllers))for(var l=0;l<o[r].controllers.length;l++){var a,c=e(this.controllerTemplate({title:o[r].controllers[l].title})).appendTo(n.find("tbody")),d=o[r].controllers[l];a=void 0===s.view.properties.controllers[d.type]?new s.view.propertyController({el:c.find("td"),propertiesView:this,args:void 0===d.args?{}:d.args}):new s.view.properties.controllers[d.type]({el:c.find("td"),propertiesView:this,args:void 0===d.args?{}:d.args}),this.propertyControllers.push(a),a.render()}}this.$(".section-tabs li").eq(0).trigger("click")},onTabClick:function(t){var i=e(t.currentTarget),s=this.$('.sections .section[data-section="'+i.data("section")+'"]');this.$(".sections .section").not(s).hide().removeClass("active"),s.show().addClass("active"),this.$(".section-tabs li").not(i).removeClass("active"),i.addClass("active")},onToolbarSelectChange:function(t){this.setActiveSelector(e(t.currentTarget).find(":selected").data("selector"))},setRuleValue:function(e,i){if(void 0!==this.activeSelector&&void 0!==this.activeSelector.declarations){for(var s=this.activeSelector.declarations,o=!0,r=!1,n=0;n<s.length;n++)if(s[n].property===e){o=!1;var l=s[n];l.value!==i&&(l.value=i,r=!0),t.isEmpty(l.value)&&s.splice(s.indexOf(l));break}o&&!t.isEmpty(i)&&(s.push({property:e,value:i,type:"declaration"}),r=!0),r&&this.updateMainEditor(!1)}},addImport:function(e){var i=t.filter(this.parsed.stylesheet.rules,(function(e){return"import"===e.type}));t.any(i,(function(t){return t.import===e.import}))||(this.parsed.stylesheet.rules.unshift(e),this.updateMainEditor(!1))},findImport:function(e){return t.find(this.parsed.stylesheet.rules,(function(t){return"import"===t.type&&t.import.indexOf(e)>-1}))},updateImport:function(e,t){var i=this.findImport(e);i.import!==t.import&&(i.import=t.import,this.updateMainEditor(!1))},removeImport:function(e){var i=t.findIndex(this.parsed.stylesheet.rules,(function(t){return"import"===t.type&&t.import.indexOf(e)>-1}));i>-1&&this.parsed.stylesheet.rules.splice(i,1)},getRuleValue:function(e){if(void 0===this.activeSelector||void 0===this.activeSelector.declarations)return"";for(var t=this.activeSelector.declarations,i=0;i<t.length;i++)if(t[i].property===e)return t[i].value;return""},updateMainEditor:function(e){this.editor.codeMirror.setValue(this.parser.stringify(this.parsed))},show:function(){this.editorExpandedBefore=this.editor.isExpanded(),this.editor.setExpand(!0),this.$el.show().animate({left:0},"fast")},hide:function(){this.editor.setExpand(this.editorExpandedBefore),this.$el.animate({left:-338},"fast",(function(){e(this).hide()})),this.updateMainEditor(!0)},save:function(){s.save(this)},isVisible:function(){return this.$el.is(":visible")},loadCSS:function(i,s){this.css=i,this.parsed=this.parser.parse(i,{silent:!0});for(var o=this.parsed.stylesheet.rules,r=this.$(".toolbar select").empty(),n=0;n<o.length;n++){var l=o[n];if(t.contains(["rule","media"],l.type))if("media"===l.type)for(var a=0;a<l.rules.length;a++){var c="@media "+l.media,d=l.rules[a];"rule"==d.type&&r.append(e("<option>").html(c+": "+d.selectors.join(",")).attr("val",c+": "+d.selectors.join(",")).data("selector",d))}else r.append(e("<option>").html(l.selectors.join(",")).attr("val",l.selectors.join(",")).data("selector",l))}void 0===s&&(s=r.find("option").eq(0).attr("val")),t.isEmpty(s)||r.val(s).trigger("change")},setActiveSelector:function(e){this.activeSelector=e;for(var t=0;t<this.propertyControllers.length;t++)this.propertyControllers[t].refreshFromRule()},addSelector:function(e){var t=this.$(".toolbar select");t.val(e),t.val()===e?t.trigger("change"):(this.editor.addEmptySelector(e),this.loadCSS(this.editor.codeMirror.getValue().trim(),e)),t.addClass("highlighted"),setTimeout((function(){t.removeClass("highlighted")}),2e3)}}),s.view.propertyController=Backbone.View.extend({template:t.template('<input type="text" value="" class="socss-property-controller-input"/>'),activeRule:null,args:null,propertiesView:null,events:{"change .socss-property-controller-input":"onChange","keyup input.socss-property-controller-input":"onChange"},initialize:function(e){this.args=e.args,this.propertiesView=e.propertiesView,this.events=t.extend(s.view.propertyController.prototype.events,this.events),this.delegateEvents(this.events),this.on("set_value",this.updateRule,this),this.on("change",this.updateRule,this)},render:function(){this.$el.append(e(this.template({}))),this.field=this.$("input.socss-property-controller-input")},onChange:function(){this.trigger("change",this.field.val())},updateRule:function(){this.propertiesView.setRuleValue(this.args.property,this.getValue())},refreshFromRule:function(){var e=this.propertiesView.getRuleValue(this.args.property);this.setValue(e,{silent:!0})},getValue:function(){return this.field.val()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),i.silent||this.trigger("set_value",e)},reset:function(e){e=t.extend({silent:!1},e),this.setValue("",e)}}),s.view.properties.controllers={},s.view.properties.controllers.color=s.view.propertyController.extend({render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.field.minicolors({})},onChange:function(){this.trigger("change",this.field.minicolors("value"))},getValue:function(){return this.field.minicolors("value").trim()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.minicolors("value",e),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.select=s.view.propertyController.extend({template:t.template('<select class="socss-property-controller-input"></select>'),events:{"click .select-tab":"onSelect"},render:function(){for(var t in this.$el.append(e(this.template({}))),this.field=this.$("select"),this.field.append(e('<option value=""></option>').html("")),this.args.options)this.field.append(e("<option></option>").attr("value",t).html(this.args.options[t]));void 0!==this.args.option_icons&&this.setupVisualSelect()},setupVisualSelect:function(){this.field.hide();var t=e('<div class="select-tabs"></div>').appendTo(this.$el);for(var i in e('<div class="select-tab" data-value=""><span class="so-css-icon so-css-icon-circle"></span></div>').appendTo(t),this.args.option_icons)e('<div class="select-tab"></div>').appendTo(t).append(e('<span class="so-css-icon"></span>').addClass("so-css-icon-"+this.args.option_icons[i])).attr("data-value",i);t.find(".select-tab").css("width",100/t.find(">div").length+"%")},onSelect:function(t){this.$(".select-tab").removeClass("active");var i=e(t.currentTarget);i.addClass("active"),this.field.val(i.data("value")).trigger("change")},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e),this.$(".select-tabs .select-tab").removeClass("active").filter('[data-value="'+e+'"]').addClass("active"),i.silent||this.trigger("set_value",e)}}),s.view.properties.controllers.image=s.view.propertyController.extend({template:t.template('<input type="text" value="" /> <span class="select socss-button"><span class="so-css-icon so-css-icon-upload"></span></span>'),events:{"click .select":"openMedia"},render:function(){this.media=wp.media({title:i.loc.select_image,library:{type:"image"},button:{text:i.loc.select,close:!1}}),this.$el.append(e(this.template({select:i.loc.select}))),this.field=this.$el.find("input"),this.media.on("select",function(){var e=this.media.state().get("selection").first().attributes,t=this.args.value.replace("{{url}}",e.url);this.field.val(t).trigger("change"),this.trigger("set_value",t),this.media.close()}.bind(this))},openMedia:function(){this.media.open()}}),s.view.properties.controllers.measurement=s.view.propertyController.extend({wrapperClass:"socss-field-measurement",events:{"click .toggle-dropdown":"toggleUnitDropdown","click .dropdown li":"onSelectUnit","keydown .socss-field-input":"onInputKeyPress","keyup .socss-field-input":"onInputKeyUp"},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.setupMeasurementField()},setValue:function(e,i){i=t.extend({silent:!1},i),this.field.val(e).trigger("measurement_refresh"),i.silent||this.trigger("set_value",e)},units:["px","%","em","cm","mm","in","pt","pc","ex","ch","rem","vw","vh","vmin","vmax"],parseUnits:function(e){var t=this.units.map((function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")})),i=new RegExp("([0-9\\.\\-]+)("+t.join("|")+")?","i").exec(e);return null===i?{value:"",unit:""}:{value:i[1],unit:void 0===i[2]?"":i[2]}},setupMeasurementField:function(){this.field.hide(),this.$el.addClass(this.wrapperClass).data("unit","px");var t=e('<input type="text" class="socss-field-input"/>').appendTo(this.$el);e('<span class="toggle-dropdown dashicons dashicons-arrow-down"></span>').appendTo(this.$el);for(var i=e('<ul class="dropdown"></ul>').appendTo(this.$el),s=e('<span class="units"></span>').html("px").appendTo(this.$el),o=0;o<this.units.length;o++){var r=e("<li></li>").html(this.units[o]).data("unit",this.units[o]);"px"===this.units[o]&&r.addClass("active"),i.append(r)}this.field.on("measurement_refresh",function(){var i=this.parseUnits(this.field.val());t.val(i.value);var o=""===i.unit?"px":i.unit;this.$el.data("unit",o),s.html(o);var r=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(i.value).appendTo("body"),n=r.width();n=Math.min(n,63),r.remove(),s.css("left",n+12)}.bind(this));var n=e('<div class="socss-diw"></div>').appendTo(this.$el),l=e('<div class="dec-button socss-button"><span class="so-css-icon so-css-icon-minus"></span></div>').appendTo(n),a=e('<div class="inc-button socss-button"><span class="so-css-icon so-css-icon-plus"></span></div>').appendTo(n);this.setupStepButton(l),this.setupStepButton(a)},updateValue:function(){var e=this.$(".socss-field-input"),t=this.parseUnits(e.val());""!==t.unit&&t.unit!==this.$el.data("unit")&&(e.val(t.value),this.setUnit(t.unit)),""===t.value?this.field.val(""):this.field.val(t.value+this.$el.data("unit")),this.field.trigger("change")},setUnit:function(e){this.$(".units").html(e),this.$el.data("unit",e),this.$(".socss-field-input").trigger("keydown")},toggleUnitDropdown:function(){this.$(".dropdown").toggle()},onSelectUnit:function(t){this.toggleUnitDropdown(),this.setUnit(e(t.currentTarget).data("unit")),this.updateValue()},onInputKeyUp:function(e){this.onInputKeyPress(e),this.updateValue()},onInputKeyPress:function(t){var i=this.$(".socss-field-input"),s="";"keydown"===t.type&&(t.keyCode>=48&&t.keyCode<=57?s=String.fromCharCode(t.keyCode):189===t.keyCode?s="-":190===t.keyCode&&(s="."));var o=e('<span class="socss-hidden-placeholder"></span>').css({"font-size":"14px"}).html(i.val()+s).appendTo("body"),r=o.width();r=Math.min(r,63),o.remove(),this.$(".units").css("left",r+12)},stepValue:function(e){var t=Number.parseInt(this.parseUnits(this.field.val()).value);Number.isNaN(t)&&(t=0);var i=t+e;this.$(".socss-field-input").val(i),this.updateValue(),this.field.trigger("measurement_refresh")},setupStepButton:function(e){var t,i,s=e.is(".dec-button")?-1:1;e.on("mousedown",function(){this.stepValue(s),i=setTimeout(function(){t=setInterval(function(){this.stepValue(s)}.bind(this),50)}.bind(this),500)}.bind(this)).on("mouseup mouseout",(function(){i&&(clearTimeout(i),i=null),t&&(clearInterval(t),t=null)}))}}),s.view.properties.controllers.number=s.view.propertyController.extend({initialize:function(e){s.view.propertyController.prototype.initialize.apply(this,arguments),this.args=t.extend({change:null,default:0,increment:1,decrement:-1,max:null,min:null},e.args)},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.setupNumberField()},setupNumberField:function(){this.$el.addClass("socss-field-number");var t=e('<div class="socss-diw"></div>').appendTo(this.$el),i=e('<div class="dec-button socss-button"><span class="so-css-icon so-css-icon-minus"></span></div>').appendTo(t),s=e('<div class="inc-button socss-button"><span class="so-css-icon so-css-icon-plus"></span></div>').appendTo(t);return this.setupStepButton(i),this.setupStepButton(s),this},stepValue:function(e){var t=Number.parseFloat(this.field.val());Number.isNaN(t)&&(t=this.args.default);var i=t+e;i=Math.round(100*i)/100,null!==this.args.max&&(i=Math.min(this.args.max,i)),null!==this.args.min&&(i=Math.max(this.args.min,i)),this.field.val(i),this.field.trigger("change")},setupStepButton:function(e){var t,i,s=e.is(".dec-button")?this.args.decrement:this.args.increment;e.on("mousedown",function(){this.stepValue(s),i=setTimeout(function(){t=setInterval(function(){this.stepValue(s)}.bind(this),50)}.bind(this),500)}.bind(this)).on("mouseup mouseout",(function(){i&&(clearTimeout(i),i=null),t&&(clearInterval(t),t=null)}))}}),s.view.properties.controllers.sides=s.view.propertyController.extend({template:t.template(e("#template-sides-field").html().trim()),controllers:[],events:{"click .select-tab":"onTabClick"},render:function(){s.view.propertyController.prototype.render.apply(this,arguments),this.args.hasAll||(this.$(".select-tab").eq(0).remove(),this.$(".select-tab").css("width","25%")),this.args.isRadius?this.$('.select-tabs[data-type="box"]').remove():this.$('.select-tabs[data-type="radius"]').remove(),this.$(".select-tab").each(function(i,o){for(var r=e(o).data("direction"),n=e('<li class="side">').appendTo(this.$(".sides")).hide(),l=0;l<this.args.controllers.length;l++){var a=this.args.controllers[l];s.view.properties.controllers[a.type];var c="";c="all"===r?a.args.propertyAll:a.args.property.replace("{dir}",r);var d=t.extend({},a.args,{property:c}),p=new s.view.properties.controllers[a.type]({el:e("<div>").appendTo(n),propertiesView:this.propertiesView,args:d});p.render(),this.propertiesView.propertyControllers.push(p)}}.bind(this)),this.$(".select-tab").eq(0).click()},onTabClick:function(t){var i=this.$(".select-tab");i.removeClass("active");var s=e(t.currentTarget);s.addClass("active");var o=this.$(".sides .side");o.hide(),o.eq(i.index(s)).show()}}),s.view.properties.controllers.font_select=s.view.propertyController.extend({template:t.template(e("#template-webfont-teaser").html().trim())})}(jQuery,_,socssOptions),jQuery((function(e){var t=window.socss,i=new t.model.CSSEditorModel({customCssPosts:socssOptions.customCssPosts}),s=new t.view.editor({el:e("#so-custom-css-form").get(0),model:i,openVisualEditor:socssOptions.openVisualEditor});s.setSnippets(socssOptions.snippets),e("#so-custom-css-getting-started a.hide").on("click",(function(t){t.preventDefault(),e("#so-custom-css-getting-started").slideUp(),e.get(e(this).attr("href"))})),window.socss.mainEditor=s,e(t).trigger("initialized"),e('.button-primary[name="siteorigin_custom_css_save"]').on("click",(function(){e("#so-custom-css-form").trigger("submit")})),e(".installer-link").on("click",(function(t){t.preventDefault(),e(this).hide(),e(".installer-container").slideDown("fast")})),e(".installer_status").on("change",(function(){var t=e(this);t.prop("disabled",!0),jQuery.post(ajaxurl,{action:"so_installer_status",nonce:t.data("nonce"),status:t.is(":checked")},(function(){t.prop("disabled",!1)}))}))}));
/* globals jQuery, Backbone, _, socssOptions, SPECIFICITY, console */

( function( $, _, socssOptions ){

    var socss = {
        model : { },
        collection : { },
        view : { },
        fn : {}
    };
    
    var getSelectorSpecificity = function(selector, useParts) {
        var specificities = [];
        var ruleSpecificity = SPECIFICITY.calculate( selector );
        for (var i = 0; i < ruleSpecificity.length; i++) {
            var specificity = ruleSpecificity[ i ];
            if ( useParts ) {
                for ( var j = 0; j < specificity.parts.length; j++ ) {
                    var specificityPart = specificity.parts[ j ];
                    // Recursive call to add specificities for parts.
                    specificities = specificities.concat(getSelectorSpecificity(specificityPart.selector));
                }
            } else {
                specificities.push({
                    'selector': specificity.selector.trim(),
                    'specificity': parseInt(specificity.specificity.replace(/,/g, ''))
                });
            }
        }
        return specificities;
    };

    /**
     * This is the main view for the app
     */
    socss.view.inspector = Backbone.View.extend( {

        active: false,
        hl: false,
        hoverEl: false,
        pageSelectors: [],

        selectorTemplate: _.template('<div class="socss-selector"><%= selector %></div>'),
        importantClasses: [
            'menu-item-',
            'postid-',
            'page-id-',
        ],

        initialize: function(){
            var thisView = this;

            this.hl = new socss.view.highlighter();
            this.hl.initialize();

            this.pageSelectors = socss.fn.pageSelectors();

            // Setup hovering
            $('body').on('mouseover', '*', function(e){
                if( !thisView.active ) {
                    return true;
                }

                var $$ = $(this);
                if( $$.closest('.socss-element').length === 0 ) {
                    e.stopPropagation();
                    thisView.setHoverEl( $(this) );
                }
            });

            // Setup the click event
            var wcCheck = $( '.single-product' ).length;
            $('body *').on( 'click', function( e ) {
                if ( ! thisView.active || $( e.target ).parent( '.socss-link' ).length ) {
                    return true;
                }

                var $$ = $( this );
                if ( ! wcCheck || ! $$.parents( '.wc-tabs' ).length ) {
                    e.preventDefault();

                    $$.trigger( 'blur' );
                    thisView.setActiveEl( thisView.hoverEl );
                }
            });

            this.$('.socss-enable-inspector').on( 'click', function(){
                thisView.toggleActive();
            } );

            this.$el.on( 'mouseenter', function() {
                thisView.hl.clear();
            } );

            // Try register this inspector with the parent editor
            try {
                parent.socss.mainEditor.setInspector( this );
            }
            catch( err ){
                console.log( 'No editor to register this inspector with' );
            }

        },

        /**
         * Set the element that's currently being hovered
         *
         * @param hoverEl
         */
        setHoverEl: function( hoverEl ){
            this.hoverEl = hoverEl;
            this.hl.highlight( hoverEl );
        },

        activate: function(){
            this.active = true;
            $('body').addClass('socss-active');
            $('body').removeClass('socss-inactive');
        },

        deactivate: function(){
            this.active = false;
            $('body').addClass('socss-inactive');
            $('body').removeClass('socss-active');
            this.hl.clear();
            this.$('.socss-hierarchy').empty();
        },

        /**
         * Toggle the active status
         */
        toggleActive: function(){
            if( this.active ) {
                this.deactivate();
            }
            else {
                this.activate();
            }
        },

        /**
         * Set the element that we're busy inspecting
         * @param el
         */
        setActiveEl: function( el ) {
            var thisView = this;

            var $h = this.$('.socss-hierarchy');
            $h.empty();
    
            if ( !el ) {
                return;
            }

            if (el.prop('tagName').toLowerCase() !== 'body') {
                var cel = $(el);
                do {
                    var selector = socss.fn.elSelector( cel );
                    thisView.importantClasses.forEach( function( importantClass ) {
                        if ( selector.indexOf( importantClass ) >= 0 ) {
                            var selectorRegex = new RegExp( '(' + importantClass + '\\d+)', 'g' );
                            selector = selector.replace( selectorRegex, "<strong>$1</strong>");
                        }
                    } );

                    $( this.selectorTemplate( { selector: selector } ) )
                        .prependTo($h)
                        .data('el', cel);
                    cel = cel.parent();
                } while (cel.prop('tagName').toLowerCase() !== 'body');

                $(this.selectorTemplate({selector: 'body'}))
                    .prependTo($h)
                    .data('el', $('body'));

                this.$('.socss-hierarchy .socss-selector')
                    .on( 'mouseenter', function () {
                        thisView.hl.highlight($(this).data('el'));
                    })
                    .on( 'click', function(e) {
                        e.preventDefault();
                        e.stopPropagation();
                        thisView.setActiveEl($(this).data('el'));
                    });
            }

            // Scroll all the way left...
            $h.scrollLeft( 99999 );

            // Now lets add all the CSS selectors
            var selectors = this.pageSelectors.filter( function(a){
                // Use try to catch any malformed selectors
                try {
                    return el.is( a.selector );
                }
                catch(err) {
                    return false;
                }
            } );

            var container = this.$('.socss-selectors-window').empty();

            _.each( selectors, function( selector ){
                container.append(
                    $( thisView.selectorTemplate( selector ) )
                        .data( selector )
                );
            } );
            container.find('> div')
                .on( 'mouseenter', function() {
                    thisView.hl.highlight( $(this).data('selector') );
                } )
                .on( 'click', function( e ) {
                    e.preventDefault();
                    e.stopPropagation();

                    thisView.trigger( 'click_selector', $(this).data('selector') );
                } );

            // And the CSS attributes
            var attributes = socss.fn.elementAttributes(el);
            container = this.$('.socss-properties-window').empty();

            _.each( attributes, function(v, k){
                container.append(
                    $( thisView.selectorTemplate( { selector: '<strong>' + k + '</strong>: ' + v } ) )
                        .data( 'property', k + ': ' + v )
                );
            } );

            container.find('> div')
                .on( 'click', function( e ) {
                    e.preventDefault();
                    e.stopPropagation();

                    thisView.trigger( 'click_property', $(this).data('property') );
                });

            // Display the link
            var link = el.closest('a[href]');
            var linkContainer = this.$('.socss-link');
            if( link.length ) {
                linkContainer.show().find('a')
                    .html( link.attr('href').replace(/[\?&]*so_css_preview=1/, '') )
                    .attr('href', link.attr('href') );
            }
            else {
                linkContainer.hide();
            }

            this.trigger('set_active_element', el, selectors);
        }

    } );

    socss.view.highlighter = Backbone.View.extend( {
        template: _.template( $('#socss-template-hover').html().trim() ),
        highlighted: [ ],

        highlight: function( els ){
            this.clear();
            var thisView = this;

            $(els).each(function(i, el){
                el = $(el);

                if( !el.is(':visible') ) {
                    // Skip over invisible elements
                    return true;
                }

                var hl = $( thisView.template() );
                hl.css({
                    'top' : el.offset().top,
                    'left' : el.offset().left,
                    'width' : el.outerWidth(),
                    'height' : el.outerHeight()
                }).appendTo( 'body' );

                var g;

                var padding = el.padding();
                for( var k in padding ) {
                    if( parseInt( padding[k] ) > 0 ) {
                        g = hl.find( '.socss-guide-padding.socss-guide-' + k ).show();
                        if( k === 'top' || k === 'bottom' ) {
                            g.css('height', padding[k]);
                        }
                        else {
                            g.css('width', padding[k]);
                            g.css({
                                'width': padding[k],
                                'top' : padding.top,
                                'bottom' : padding.bottom
                            });
                        }
                    }
                }

                var margin = el.margin();
                for( var k in margin ) {
                    if( parseInt( margin[k] ) > 0 ) {
                        g = hl.find( '.socss-guide-margin.socss-guide-' + k ).show();
                        if( k === 'top' || k === 'bottom' ) {
                            g.css('height', margin[k]);
                        }
                        else {
                            g.css('width', margin[k]);
                        }
                    }
                }

                thisView.highlighted.push( hl );
            } );
        },

        clear: function(){
            while( this.highlighted.length ) {
                this.highlighted.pop().remove();
            }
        }
    } );

    socss.parsedCss = {};
    socss.fn.getParsedCss = function(){
        // Load all the parsed CSS
        if( Object.keys(socss.parsedCss).length === 0 ) {
            var parser = window.css;
            $('.socss-theme-styles').each(function(){
                var $$ = $(this);
                var p = parser.parse( $$.html(), {
                    silent: true
                } );
                socss.parsedCss[ $$.attr('id') ] = p;
            });
        }
        return socss.parsedCss;
    };

    /**
     * Function to get all the available page selectors
     */
    socss.fn.pageSelectors = function(){
        var selectors = [];
        var parsedCss = socss.fn.getParsedCss();

        for( var k in parsedCss ) {
            var rules = parsedCss[k].stylesheet.rules;
            for( var i = 0; i < rules.length; i++ ) {
                if (typeof rules[i].selectors === 'undefined') {
                    continue;
                }
    
                for(var j = 0; j < rules[i].selectors.length; j++) {
                    selectors = selectors.concat( getSelectorSpecificity( rules[i].selectors[j] ) );
                }
            }
        }

        // Also add selectors for all the elements in the
        $('body *').each(function(){
            var $$ = $(this);
            var elName = socss.fn.elSelector( $$ );
            
            selectors = selectors.concat(getSelectorSpecificity(elName));
        });
    
        var $body = $('body');
        var bName = socss.fn.elSelector($body);
        selectors = selectors.concat(getSelectorSpecificity(bName, true));

        selectors = _.uniq( selectors, false, function( a ){
            return a.selector;
        } );

        selectors.sort(function(a, b){
            return a.specificity > b.specificity ? -1 : 1;
        });

        return selectors;
    };

    socss.fn.elementAttributes = function( el ) {
        if( !document.styleSheets ) {
            return [];
        }

        var elProperties = [];

        var trimFunc = function(e) {
            return e.trim();
        };

        var filterFunc = function(e){
            return e !== '';
        };

        var splitFunc = function(e) {
            return e.split(':').map( trimFunc );
        };

        var parsedCss = socss.fn.getParsedCss();

        var isAtRule = function (ruleType) {
            switch(ruleType) {
                case 'charset':
                case 'custom-media':
                case 'document':
                case 'font-face':
                case 'host':
                case 'import':
                case 'keyframes':
                case 'keyframe':
                case 'media':
                case 'namespace':
                case 'page':
                case 'supports':
                    return true;
                  
            }
            return false;
        };

        for( var k in parsedCss ) {
            var rules = parsedCss[k].stylesheet.rules;
            for( var i = 0; i < rules.length; i++ ) {
                var rule = rules[i];
                if (
                    typeof rule.selectors === 'undefined' || isAtRule(rule.type)
                ) {
                    continue;
                }
                
                for(var j = 0; j < rule.selectors.length; j++) {
                    var ruleSpecificity = SPECIFICITY.calculate( rule.selectors[j] );
                    for (var l = 0; l < ruleSpecificity.length; l++) {
                        try {
                            if ( el.is( ruleSpecificity[l].selector ) ) {
                                var declarations = rule.declarations;
                                for (var l = 0; l < declarations.length; l++) {
                                    elProperties.push({
                                        'name': declarations[l].property,
                                        'value': declarations[l].value,
                                        'specificity': parseInt( ruleSpecificity[l].specificity.replace( /,/g, '' ) )
                                    });
                                }
                            }
                        }
                        catch (e) {
                            // For now, we're just going to ignore rules that trigger errors
                        }
                    }
                }

            }
        }

        elProperties.sort( function(a,b) {
            return a.specificity > b.specificity ? 1 : -1;
        }).reverse();

        var returnProperties = {};
        for( var pi = 0; pi < elProperties.length; pi++ ) {
            if( typeof returnProperties[elProperties[pi].name] === 'undefined' ) {
                returnProperties[elProperties[pi].name] = elProperties[pi].value;
            }
        }

        return returnProperties;
    };

    socss.fn.elSelector = function( el ){
        var elName = '';
        if( el.attr('id') !== undefined ) {
            elName += '#' + el.attr('id');
        }
        if( el.attr('class') !== undefined ) {
            elName += '.' + el.attr('class').replace(/\s+/g, '.');
        }

        if( elName === '' ) {
            elName = el.prop('tagName').toLowerCase();
        }

        return elName;
    };

    window.socssInspector = socss;

} ) ( jQuery, _, socssOptions );

jQuery( function($){
    var socss = window.socssInspector;

    // Setup the editor
    var inspector = new socss.view.inspector( {
        el : $('#socss-inspector-interface').get(0)
    } );
    inspector.activate();

    window.socssInspector.mainInspector = inspector;
} );
/*!
CSSLint v1.0.3
Copyright (c) 2016 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

var CSSLint = (function(){
  var module = module || {},
      exports = exports || {};

/*!
Parser-Lib
Copyright (c) 2009-2016 Nicholas C. Zakas. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* Version v1.0.0, Build time: 15-July-2016 12:36:10 */
var parserlib = (function () {
var require;
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";

/* exported Colors */

var Colors = module.exports = {
    __proto__       :null,
    aliceblue       :"#f0f8ff",
    antiquewhite    :"#faebd7",
    aqua            :"#00ffff",
    aquamarine      :"#7fffd4",
    azure           :"#f0ffff",
    beige           :"#f5f5dc",
    bisque          :"#ffe4c4",
    black           :"#000000",
    blanchedalmond  :"#ffebcd",
    blue            :"#0000ff",
    blueviolet      :"#8a2be2",
    brown           :"#a52a2a",
    burlywood       :"#deb887",
    cadetblue       :"#5f9ea0",
    chartreuse      :"#7fff00",
    chocolate       :"#d2691e",
    coral           :"#ff7f50",
    cornflowerblue  :"#6495ed",
    cornsilk        :"#fff8dc",
    crimson         :"#dc143c",
    cyan            :"#00ffff",
    darkblue        :"#00008b",
    darkcyan        :"#008b8b",
    darkgoldenrod   :"#b8860b",
    darkgray        :"#a9a9a9",
    darkgrey        :"#a9a9a9",
    darkgreen       :"#006400",
    darkkhaki       :"#bdb76b",
    darkmagenta     :"#8b008b",
    darkolivegreen  :"#556b2f",
    darkorange      :"#ff8c00",
    darkorchid      :"#9932cc",
    darkred         :"#8b0000",
    darksalmon      :"#e9967a",
    darkseagreen    :"#8fbc8f",
    darkslateblue   :"#483d8b",
    darkslategray   :"#2f4f4f",
    darkslategrey   :"#2f4f4f",
    darkturquoise   :"#00ced1",
    darkviolet      :"#9400d3",
    deeppink        :"#ff1493",
    deepskyblue     :"#00bfff",
    dimgray         :"#696969",
    dimgrey         :"#696969",
    dodgerblue      :"#1e90ff",
    firebrick       :"#b22222",
    floralwhite     :"#fffaf0",
    forestgreen     :"#228b22",
    fuchsia         :"#ff00ff",
    gainsboro       :"#dcdcdc",
    ghostwhite      :"#f8f8ff",
    gold            :"#ffd700",
    goldenrod       :"#daa520",
    gray            :"#808080",
    grey            :"#808080",
    green           :"#008000",
    greenyellow     :"#adff2f",
    honeydew        :"#f0fff0",
    hotpink         :"#ff69b4",
    indianred       :"#cd5c5c",
    indigo          :"#4b0082",
    ivory           :"#fffff0",
    khaki           :"#f0e68c",
    lavender        :"#e6e6fa",
    lavenderblush   :"#fff0f5",
    lawngreen       :"#7cfc00",
    lemonchiffon    :"#fffacd",
    lightblue       :"#add8e6",
    lightcoral      :"#f08080",
    lightcyan       :"#e0ffff",
    lightgoldenrodyellow  :"#fafad2",
    lightgray       :"#d3d3d3",
    lightgrey       :"#d3d3d3",
    lightgreen      :"#90ee90",
    lightpink       :"#ffb6c1",
    lightsalmon     :"#ffa07a",
    lightseagreen   :"#20b2aa",
    lightskyblue    :"#87cefa",
    lightslategray  :"#778899",
    lightslategrey  :"#778899",
    lightsteelblue  :"#b0c4de",
    lightyellow     :"#ffffe0",
    lime            :"#00ff00",
    limegreen       :"#32cd32",
    linen           :"#faf0e6",
    magenta         :"#ff00ff",
    maroon          :"#800000",
    mediumaquamarine:"#66cdaa",
    mediumblue      :"#0000cd",
    mediumorchid    :"#ba55d3",
    mediumpurple    :"#9370d8",
    mediumseagreen  :"#3cb371",
    mediumslateblue :"#7b68ee",
    mediumspringgreen   :"#00fa9a",
    mediumturquoise :"#48d1cc",
    mediumvioletred :"#c71585",
    midnightblue    :"#191970",
    mintcream       :"#f5fffa",
    mistyrose       :"#ffe4e1",
    moccasin        :"#ffe4b5",
    navajowhite     :"#ffdead",
    navy            :"#000080",
    oldlace         :"#fdf5e6",
    olive           :"#808000",
    olivedrab       :"#6b8e23",
    orange          :"#ffa500",
    orangered       :"#ff4500",
    orchid          :"#da70d6",
    palegoldenrod   :"#eee8aa",
    palegreen       :"#98fb98",
    paleturquoise   :"#afeeee",
    palevioletred   :"#d87093",
    papayawhip      :"#ffefd5",
    peachpuff       :"#ffdab9",
    peru            :"#cd853f",
    pink            :"#ffc0cb",
    plum            :"#dda0dd",
    powderblue      :"#b0e0e6",
    purple          :"#800080",
    red             :"#ff0000",
    rosybrown       :"#bc8f8f",
    royalblue       :"#4169e1",
    saddlebrown     :"#8b4513",
    salmon          :"#fa8072",
    sandybrown      :"#f4a460",
    seagreen        :"#2e8b57",
    seashell        :"#fff5ee",
    sienna          :"#a0522d",
    silver          :"#c0c0c0",
    skyblue         :"#87ceeb",
    slateblue       :"#6a5acd",
    slategray       :"#708090",
    slategrey       :"#708090",
    snow            :"#fffafa",
    springgreen     :"#00ff7f",
    steelblue       :"#4682b4",
    tan             :"#d2b48c",
    teal            :"#008080",
    thistle         :"#d8bfd8",
    tomato          :"#ff6347",
    turquoise       :"#40e0d0",
    violet          :"#ee82ee",
    wheat           :"#f5deb3",
    white           :"#ffffff",
    whitesmoke      :"#f5f5f5",
    yellow          :"#ffff00",
    yellowgreen     :"#9acd32",
    //'currentColor' color keyword https://www.w3.org/TR/css3-color/#currentcolor
    currentColor        :"The value of the 'color' property.",
    //CSS2 system colors https://www.w3.org/TR/css3-color/#css2-system
    activeBorder        :"Active window border.",
    activecaption       :"Active window caption.",
    appworkspace        :"Background color of multiple document interface.",
    background          :"Desktop background.",
    buttonface          :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",
    buttonhighlight     :"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",
    buttonshadow        :"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",
    buttontext          :"Text on push buttons.",
    captiontext         :"Text in caption, size box, and scrollbar arrow box.",
    graytext            :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",
    greytext            :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",
    highlight           :"Item(s) selected in a control.",
    highlighttext       :"Text of item(s) selected in a control.",
    inactiveborder      :"Inactive window border.",
    inactivecaption     :"Inactive window caption.",
    inactivecaptiontext :"Color of text in an inactive caption.",
    infobackground      :"Background color for tooltip controls.",
    infotext            :"Text color for tooltip controls.",
    menu                :"Menu background.",
    menutext            :"Text in menus.",
    scrollbar           :"Scroll bar gray area.",
    threeddarkshadow    :"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
    threedface          :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
    threedhighlight     :"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
    threedlightshadow   :"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
    threedshadow        :"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
    window              :"Window background.",
    windowframe         :"Window frame.",
    windowtext          :"Text in windows."
};

},{}],2:[function(require,module,exports){
"use strict";

module.exports = Combinator;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a selector combinator (whitespace, +, >).
 * @namespace parserlib.css
 * @class Combinator
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {String} text The text representation of the unit.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function Combinator(text, line, col) {

    SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE);

    /**
     * The type of modifier.
     * @type String
     * @property type
     */
    this.type = "unknown";

    //pretty simple
    if (/^\s+$/.test(text)) {
        this.type = "descendant";
    } else if (text === ">") {
        this.type = "child";
    } else if (text === "+") {
        this.type = "adjacent-sibling";
    } else if (text === "~") {
        this.type = "sibling";
    }

}

Combinator.prototype = new SyntaxUnit();
Combinator.prototype.constructor = Combinator;


},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(require,module,exports){
"use strict";

module.exports = Matcher;

var StringReader = require("../util/StringReader");
var SyntaxError = require("../util/SyntaxError");

/**
 * This class implements a combinator library for matcher functions.
 * The combinators are described at:
 * https://developer.mozilla.org/en-US/docs/Web/CSS/Value_definition_syntax#Component_value_combinators
 */
function Matcher(matchFunc, toString) {
    this.match = function(expression) {
        // Save/restore marks to ensure that failed matches always restore
        // the original location in the expression.
        var result;
        expression.mark();
        result = matchFunc(expression);
        if (result) {
            expression.drop();
        } else {
            expression.restore();
        }
        return result;
    };
    this.toString = typeof toString === "function" ? toString : function() {
        return toString;
    };
}

/** Precedence table of combinators. */
Matcher.prec = {
    MOD:    5,
    SEQ:    4,
    ANDAND: 3,
    OROR:   2,
    ALT:    1
};

/** Simple recursive-descent grammar to build matchers from strings. */
Matcher.parse = function(str) {
    var reader, eat, expr, oror, andand, seq, mod, term, result;
    reader = new StringReader(str);
    eat = function(matcher) {
        var result = reader.readMatch(matcher);
        if (result === null) {
            throw new SyntaxError(
                "Expected "+matcher, reader.getLine(), reader.getCol());
        }
        return result;
    };
    expr = function() {
        // expr = oror (" | " oror)*
        var m = [ oror() ];
        while (reader.readMatch(" | ") !== null) {
            m.push(oror());
        }
        return m.length === 1 ? m[0] : Matcher.alt.apply(Matcher, m);
    };
    oror = function() {
        // oror = andand ( " || " andand)*
        var m = [ andand() ];
        while (reader.readMatch(" || ") !== null) {
            m.push(andand());
        }
        return m.length === 1 ? m[0] : Matcher.oror.apply(Matcher, m);
    };
    andand = function() {
        // andand = seq ( " && " seq)*
        var m = [ seq() ];
        while (reader.readMatch(" && ") !== null) {
            m.push(seq());
        }
        return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m);
    };
    seq = function() {
        // seq = mod ( " " mod)*
        var m = [ mod() ];
        while (reader.readMatch(/^ (?![&|\]])/) !== null) {
            m.push(mod());
        }
        return m.length === 1 ? m[0] : Matcher.seq.apply(Matcher, m);
    };
    mod = function() {
        // mod = term ( "?" | "*" | "+" | "#" | "{<num>,<num>}" )?
        var m = term();
        if (reader.readMatch("?") !== null) {
            return m.question();
        } else if (reader.readMatch("*") !== null) {
            return m.star();
        } else if (reader.readMatch("+") !== null) {
            return m.plus();
        } else if (reader.readMatch("#") !== null) {
            return m.hash();
        } else if (reader.readMatch(/^\{\s*/) !== null) {
            var min = eat(/^\d+/);
            eat(/^\s*,\s*/);
            var max = eat(/^\d+/);
            eat(/^\s*\}/);
            return m.braces(+min, +max);
        }
        return m;
    };
    term = function() {
        // term = <nt> | literal | "[ " expression " ]"
        if (reader.readMatch("[ ") !== null) {
            var m = expr();
            eat(" ]");
            return m;
        }
        return Matcher.fromType(eat(/^[^ ?*+#{]+/));
    };
    result = expr();
    if (!reader.eof()) {
        throw new SyntaxError(
            "Expected end of string", reader.getLine(), reader.getCol());
    }
    return result;
};

/**
 * Convert a string to a matcher (parsing simple alternations),
 * or do nothing if the argument is already a matcher.
 */
Matcher.cast = function(m) {
    if (m instanceof Matcher) {
        return m;
    }
    return Matcher.parse(m);
};

/**
 * Create a matcher for a single type.
 */
Matcher.fromType = function(type) {
    // Late require of ValidationTypes to break a dependency cycle.
    var ValidationTypes = require("./ValidationTypes");
    return new Matcher(function(expression) {
        return expression.hasNext() && ValidationTypes.isType(expression, type);
    }, type);
};

/**
 * Create a matcher for one or more juxtaposed words, which all must
 * occur, in the given order.
 */
Matcher.seq = function() {
    var ms = Array.prototype.slice.call(arguments).map(Matcher.cast);
    if (ms.length === 1) {
        return ms[0];
    }
    return new Matcher(function(expression) {
        var i, result = true;
        for (i = 0; result && i < ms.length; i++) {
            result = ms[i].match(expression);
        }
        return result;
    }, function(prec) {
        var p = Matcher.prec.SEQ;
        var s = ms.map(function(m) {
            return m.toString(p);
        }).join(" ");
        if (prec > p) {
            s = "[ " + s + " ]";
        }
        return s;
    });
};

/**
 * Create a matcher for one or more alternatives, where exactly one
 * must occur.
 */
Matcher.alt = function() {
    var ms = Array.prototype.slice.call(arguments).map(Matcher.cast);
    if (ms.length === 1) {
        return ms[0];
    }
    return new Matcher(function(expression) {
        var i, result = false;
        for (i = 0; !result && i < ms.length; i++) {
            result = ms[i].match(expression);
        }
        return result;
    }, function(prec) {
        var p = Matcher.prec.ALT;
        var s = ms.map(function(m) {
            return m.toString(p);
        }).join(" | ");
        if (prec > p) {
            s = "[ " + s + " ]";
        }
        return s;
    });
};

/**
 * Create a matcher for two or more options.  This implements the
 * double bar (||) and double ampersand (&&) operators, as well as
 * variants of && where some of the alternatives are optional.
 * This will backtrack through even successful matches to try to
 * maximize the number of items matched.
 */
Matcher.many = function(required) {
    var ms = Array.prototype.slice.call(arguments, 1).reduce(function(acc, v) {
        if (v.expand) {
            // Insert all of the options for the given complex rule as
            // individual options.
            var ValidationTypes = require("./ValidationTypes");
            acc.push.apply(acc, ValidationTypes.complex[v.expand].options);
        } else {
            acc.push(Matcher.cast(v));
        }
        return acc;
    }, []);

    if (required === true) {
        required = ms.map(function() {
            return true;
        });
    }

    var result = new Matcher(function(expression) {
        var seen = [], max = 0, pass = 0;
        var success = function(matchCount) {
            if (pass === 0) {
                max = Math.max(matchCount, max);
                return matchCount === ms.length;
            } else {
                return matchCount === max;
            }
        };
        var tryMatch = function(matchCount) {
            for (var i = 0; i < ms.length; i++) {
                if (seen[i]) {
                    continue;
                }
                expression.mark();
                if (ms[i].match(expression)) {
                    seen[i] = true;
                    // Increase matchCount iff this was a required element
                    // (or if all the elements are optional)
                    if (tryMatch(matchCount + ((required === false || required[i]) ? 1 : 0))) {
                        expression.drop();
                        return true;
                    }
                    // Backtrack: try *not* matching using this rule, and
                    // let's see if it leads to a better overall match.
                    expression.restore();
                    seen[i] = false;
                } else {
                    expression.drop();
                }
            }
            return success(matchCount);
        };
        if (!tryMatch(0)) {
            // Couldn't get a complete match, retrace our steps to make the
            // match with the maximum # of required elements.
            pass++;
            tryMatch(0);
        }

        if (required === false) {
            return max > 0;
        }
        // Use finer-grained specification of which matchers are required.
        for (var i = 0; i < ms.length; i++) {
            if (required[i] && !seen[i]) {
                return false;
            }
        }
        return true;
    }, function(prec) {
        var p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND;
        var s = ms.map(function(m, i) {
            if (required !== false && !required[i]) {
                return m.toString(Matcher.prec.MOD) + "?";
            }
            return m.toString(p);
        }).join(required === false ? " || " : " && ");
        if (prec > p) {
            s = "[ " + s + " ]";
        }
        return s;
    });
    result.options = ms;
    return result;
};

/**
 * Create a matcher for two or more options, where all options are
 * mandatory but they may appear in any order.
 */
Matcher.andand = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(true);
    return Matcher.many.apply(Matcher, args);
};

/**
 * Create a matcher for two or more options, where options are
 * optional and may appear in any order, but at least one must be
 * present.
 */
Matcher.oror = function() {
    var args = Array.prototype.slice.call(arguments);
    args.unshift(false);
    return Matcher.many.apply(Matcher, args);
};

/** Instance methods on Matchers. */
Matcher.prototype = {
    constructor: Matcher,
    // These are expected to be overridden in every instance.
    match: function() { throw new Error("unimplemented"); },
    toString: function() { throw new Error("unimplemented"); },
    // This returns a standalone function to do the matching.
    func: function() { return this.match.bind(this); },
    // Basic combinators
    then: function(m) { return Matcher.seq(this, m); },
    or: function(m) { return Matcher.alt(this, m); },
    andand: function(m) { return Matcher.many(true, this, m); },
    oror: function(m) { return Matcher.many(false, this, m); },
    // Component value multipliers
    star: function() { return this.braces(0, Infinity, "*"); },
    plus: function() { return this.braces(1, Infinity, "+"); },
    question: function() { return this.braces(0, 1, "?"); },
    hash: function() {
        return this.braces(1, Infinity, "#", Matcher.cast(","));
    },
    braces: function(min, max, marker, optSep) {
        var m1 = this, m2 = optSep ? optSep.then(this) : this;
        if (!marker) {
            marker = "{" + min + "," + max + "}";
        }
        return new Matcher(function(expression) {
            var result = true, i;
            for (i = 0; i < max; i++) {
                if (i > 0 && optSep) {
                    result = m2.match(expression);
                } else {
                    result = m1.match(expression);
                }
                if (!result) {
                    break;
                }
            }
            return i >= min;
        }, function() {
            return m1.toString(Matcher.prec.MOD) + marker;
        });
    }
};

},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(require,module,exports){
"use strict";

module.exports = MediaFeature;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a media feature, such as max-width:500.
 * @namespace parserlib.css
 * @class MediaFeature
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {SyntaxUnit} name The name of the feature.
 * @param {SyntaxUnit} value The value of the feature or null if none.
 */
function MediaFeature(name, value) {

    SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE);

    /**
     * The name of the media feature
     * @type String
     * @property name
     */
    this.name = name;

    /**
     * The value for the feature or null if there is none.
     * @type SyntaxUnit
     * @property value
     */
    this.value = value;
}

MediaFeature.prototype = new SyntaxUnit();
MediaFeature.prototype.constructor = MediaFeature;


},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(require,module,exports){
"use strict";

module.exports = MediaQuery;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents an individual media query.
 * @namespace parserlib.css
 * @class MediaQuery
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {String} modifier The modifier "not" or "only" (or null).
 * @param {String} mediaType The type of media (i.e., "print").
 * @param {Array} parts Array of selectors parts making up this selector.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function MediaQuery(modifier, mediaType, features, line, col) {

    SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE);

    /**
     * The media modifier ("not" or "only")
     * @type String
     * @property modifier
     */
    this.modifier = modifier;

    /**
     * The mediaType (i.e., "print")
     * @type String
     * @property mediaType
     */
    this.mediaType = mediaType;

    /**
     * The parts that make up the selector.
     * @type Array
     * @property features
     */
    this.features = features;

}

MediaQuery.prototype = new SyntaxUnit();
MediaQuery.prototype.constructor = MediaQuery;


},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(require,module,exports){
"use strict";

module.exports = Parser;

var EventTarget = require("../util/EventTarget");
var SyntaxError = require("../util/SyntaxError");
var SyntaxUnit = require("../util/SyntaxUnit");

var Combinator = require("./Combinator");
var MediaFeature = require("./MediaFeature");
var MediaQuery = require("./MediaQuery");
var PropertyName = require("./PropertyName");
var PropertyValue = require("./PropertyValue");
var PropertyValuePart = require("./PropertyValuePart");
var Selector = require("./Selector");
var SelectorPart = require("./SelectorPart");
var SelectorSubPart = require("./SelectorSubPart");
var TokenStream = require("./TokenStream");
var Tokens = require("./Tokens");
var Validation = require("./Validation");

/**
 * A CSS3 parser.
 * @namespace parserlib.css
 * @class Parser
 * @constructor
 * @param {Object} options (Optional) Various options for the parser:
 *      starHack (true|false) to allow IE6 star hack as valid,
 *      underscoreHack (true|false) to interpret leading underscores
 *      as IE6-7 targeting for known properties, ieFilters (true|false)
 *      to indicate that IE < 8 filters should be accepted and not throw
 *      syntax errors.
 */
function Parser(options) {

    //inherit event functionality
    EventTarget.call(this);


    this.options = options || {};

    this._tokenStream = null;
}

//Static constants
Parser.DEFAULT_TYPE = 0;
Parser.COMBINATOR_TYPE = 1;
Parser.MEDIA_FEATURE_TYPE = 2;
Parser.MEDIA_QUERY_TYPE = 3;
Parser.PROPERTY_NAME_TYPE = 4;
Parser.PROPERTY_VALUE_TYPE = 5;
Parser.PROPERTY_VALUE_PART_TYPE = 6;
Parser.SELECTOR_TYPE = 7;
Parser.SELECTOR_PART_TYPE = 8;
Parser.SELECTOR_SUB_PART_TYPE = 9;

Parser.prototype = function() {

    var proto = new EventTarget(),  //new prototype
        prop,
        additions =  {
            __proto__: null,

            //restore constructor
            constructor: Parser,

            //instance constants - yuck
            DEFAULT_TYPE : 0,
            COMBINATOR_TYPE : 1,
            MEDIA_FEATURE_TYPE : 2,
            MEDIA_QUERY_TYPE : 3,
            PROPERTY_NAME_TYPE : 4,
            PROPERTY_VALUE_TYPE : 5,
            PROPERTY_VALUE_PART_TYPE : 6,
            SELECTOR_TYPE : 7,
            SELECTOR_PART_TYPE : 8,
            SELECTOR_SUB_PART_TYPE : 9,

            //-----------------------------------------------------------------
            // Grammar
            //-----------------------------------------------------------------

            _stylesheet: function() {

                /*
                 * stylesheet
                 *  : [ CHARSET_SYM S* STRING S* ';' ]?
                 *    [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
                 *    [ namespace [S|CDO|CDC]* ]*
                 *    [ [ ruleset | media | page | font_face | keyframes_rule | supports_rule ] [S|CDO|CDC]* ]*
                 *  ;
                 */

                var tokenStream = this._tokenStream,
                    count,
                    token,
                    tt;

                this.fire("startstylesheet");

                //try to read character set
                this._charset();

                this._skipCruft();

                //try to read imports - may be more than one
                while (tokenStream.peek() === Tokens.IMPORT_SYM) {
                    this._import();
                    this._skipCruft();
                }

                //try to read namespaces - may be more than one
                while (tokenStream.peek() === Tokens.NAMESPACE_SYM) {
                    this._namespace();
                    this._skipCruft();
                }

                //get the next token
                tt = tokenStream.peek();

                //try to read the rest
                while (tt > Tokens.EOF) {

                    try {

                        switch (tt) {
                            case Tokens.MEDIA_SYM:
                                this._media();
                                this._skipCruft();
                                break;
                            case Tokens.PAGE_SYM:
                                this._page();
                                this._skipCruft();
                                break;
                            case Tokens.FONT_FACE_SYM:
                                this._font_face();
                                this._skipCruft();
                                break;
                            case Tokens.KEYFRAMES_SYM:
                                this._keyframes();
                                this._skipCruft();
                                break;
                            case Tokens.VIEWPORT_SYM:
                                this._viewport();
                                this._skipCruft();
                                break;
                            case Tokens.DOCUMENT_SYM:
                                this._document();
                                this._skipCruft();
                                break;
                            case Tokens.SUPPORTS_SYM:
                                this._supports();
                                this._skipCruft();
                                break;
                            case Tokens.UNKNOWN_SYM:  //unknown @ rule
                                tokenStream.get();
                                if (!this.options.strict) {

                                    //fire error event
                                    this.fire({
                                        type:       "error",
                                        error:      null,
                                        message:    "Unknown @ rule: " + tokenStream.LT(0).value + ".",
                                        line:       tokenStream.LT(0).startLine,
                                        col:        tokenStream.LT(0).startCol
                                    });

                                    //skip braces
                                    count=0;
                                    while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE) {
                                        count++;    //keep track of nesting depth
                                    }

                                    while (count) {
                                        tokenStream.advance([Tokens.RBRACE]);
                                        count--;
                                    }

                                } else {
                                    //not a syntax error, rethrow it
                                    throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
                                }
                                break;
                            case Tokens.S:
                                this._readWhitespace();
                                break;
                            default:
                                if (!this._ruleset()) {

                                    //error handling for known issues
                                    switch (tt) {
                                        case Tokens.CHARSET_SYM:
                                            token = tokenStream.LT(1);
                                            this._charset(false);
                                            throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol);
                                        case Tokens.IMPORT_SYM:
                                            token = tokenStream.LT(1);
                                            this._import(false);
                                            throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol);
                                        case Tokens.NAMESPACE_SYM:
                                            token = tokenStream.LT(1);
                                            this._namespace(false);
                                            throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol);
                                        default:
                                            tokenStream.get();  //get the last token
                                            this._unexpectedToken(tokenStream.token());
                                    }

                                }
                        }
                    } catch (ex) {
                        if (ex instanceof SyntaxError && !this.options.strict) {
                            this.fire({
                                type:       "error",
                                error:      ex,
                                message:    ex.message,
                                line:       ex.line,
                                col:        ex.col
                            });
                        } else {
                            throw ex;
                        }
                    }

                    tt = tokenStream.peek();
                }

                if (tt !== Tokens.EOF) {
                    this._unexpectedToken(tokenStream.token());
                }

                this.fire("endstylesheet");
            },

            _charset: function(emit) {
                var tokenStream = this._tokenStream,
                    charset,
                    token,
                    line,
                    col;

                if (tokenStream.match(Tokens.CHARSET_SYM)) {
                    line = tokenStream.token().startLine;
                    col = tokenStream.token().startCol;

                    this._readWhitespace();
                    tokenStream.mustMatch(Tokens.STRING);

                    token = tokenStream.token();
                    charset = token.value;

                    this._readWhitespace();
                    tokenStream.mustMatch(Tokens.SEMICOLON);

                    if (emit !== false) {
                        this.fire({
                            type:   "charset",
                            charset:charset,
                            line:   line,
                            col:    col
                        });
                    }
                }
            },

            _import: function(emit) {
                /*
                 * import
                 *   : IMPORT_SYM S*
                 *    [STRING|URI] S* media_query_list? ';' S*
                 */

                var tokenStream = this._tokenStream,
                    uri,
                    importToken,
                    mediaList   = [];

                //read import symbol
                tokenStream.mustMatch(Tokens.IMPORT_SYM);
                importToken = tokenStream.token();
                this._readWhitespace();

                tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);

                //grab the URI value
                uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1");

                this._readWhitespace();

                mediaList = this._media_query_list();

                //must end with a semicolon
                tokenStream.mustMatch(Tokens.SEMICOLON);
                this._readWhitespace();

                if (emit !== false) {
                    this.fire({
                        type:   "import",
                        uri:    uri,
                        media:  mediaList,
                        line:   importToken.startLine,
                        col:    importToken.startCol
                    });
                }

            },

            _namespace: function(emit) {
                /*
                 * namespace
                 *   : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
                 */

                var tokenStream = this._tokenStream,
                    line,
                    col,
                    prefix,
                    uri;

                //read import symbol
                tokenStream.mustMatch(Tokens.NAMESPACE_SYM);
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;
                this._readWhitespace();

                //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT
                if (tokenStream.match(Tokens.IDENT)) {
                    prefix = tokenStream.token().value;
                    this._readWhitespace();
                }

                tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
                /*if (!tokenStream.match(Tokens.STRING)){
                    tokenStream.mustMatch(Tokens.URI);
                }*/

                //grab the URI value
                uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");

                this._readWhitespace();

                //must end with a semicolon
                tokenStream.mustMatch(Tokens.SEMICOLON);
                this._readWhitespace();

                if (emit !== false) {
                    this.fire({
                        type:   "namespace",
                        prefix: prefix,
                        uri:    uri,
                        line:   line,
                        col:    col
                    });
                }

            },

            _supports: function(emit) {
                /*
                 * supports_rule
                 *  : SUPPORTS_SYM S* supports_condition S* group_rule_body
                 *  ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col;

                if (tokenStream.match(Tokens.SUPPORTS_SYM)) {
                    line = tokenStream.token().startLine;
                    col = tokenStream.token().startCol;

                    this._readWhitespace();
                    this._supports_condition();
                    this._readWhitespace();

                    tokenStream.mustMatch(Tokens.LBRACE);
                    this._readWhitespace();

                    if (emit !== false) {
                        this.fire({
                            type:   "startsupports",
                            line:   line,
                            col:    col
                        });
                    }

                    while (true) {
                        if (!this._ruleset()) {
                            break;
                        }
                    }

                    tokenStream.mustMatch(Tokens.RBRACE);
                    this._readWhitespace();

                    this.fire({
                        type:   "endsupports",
                        line:   line,
                        col:    col
                    });
                }
            },

            _supports_condition: function() {
                /*
                 * supports_condition
                 *  : supports_negation | supports_conjunction | supports_disjunction |
                 *    supports_condition_in_parens
                 *  ;
                 */
                var tokenStream = this._tokenStream,
                    ident;

                if (tokenStream.match(Tokens.IDENT)) {
                    ident = tokenStream.token().value.toLowerCase();

                    if (ident === "not") {
                        tokenStream.mustMatch(Tokens.S);
                        this._supports_condition_in_parens();
                    } else {
                        tokenStream.unget();
                    }
                } else {
                    this._supports_condition_in_parens();
                    this._readWhitespace();

                    while (tokenStream.peek() === Tokens.IDENT) {
                        ident = tokenStream.LT(1).value.toLowerCase();
                        if (ident === "and" || ident === "or") {
                            tokenStream.mustMatch(Tokens.IDENT);
                            this._readWhitespace();
                            this._supports_condition_in_parens();
                            this._readWhitespace();
                        }
                    }
                }
            },

            _supports_condition_in_parens: function() {
                /*
                 * supports_condition_in_parens
                 *  : ( '(' S* supports_condition S* ')' ) | supports_declaration_condition |
                 *    general_enclosed
                 *  ;
                 */
                var tokenStream = this._tokenStream,
                    ident;

                if (tokenStream.match(Tokens.LPAREN)) {
                    this._readWhitespace();
                    if (tokenStream.match(Tokens.IDENT)) {
                        // look ahead for not keyword, if not given, continue with declaration condition.
                        ident = tokenStream.token().value.toLowerCase();
                        if (ident === "not") {
                            this._readWhitespace();
                            this._supports_condition();
                            this._readWhitespace();
                            tokenStream.mustMatch(Tokens.RPAREN);
                        } else {
                            tokenStream.unget();
                            this._supports_declaration_condition(false);
                        }
                    } else {
                        this._supports_condition();
                        this._readWhitespace();
                        tokenStream.mustMatch(Tokens.RPAREN);
                    }
                } else {
                    this._supports_declaration_condition();
                }
            },

            _supports_declaration_condition: function(requireStartParen) {
                /*
                 * supports_declaration_condition
                 *  : '(' S* declaration ')'
                 *  ;
                 */
                var tokenStream = this._tokenStream;

                if (requireStartParen !== false) {
                    tokenStream.mustMatch(Tokens.LPAREN);
                }
                this._readWhitespace();
                this._declaration();
                tokenStream.mustMatch(Tokens.RPAREN);
            },

            _media: function() {
                /*
                 * media
                 *   : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S*
                 *   ;
                 */
                var tokenStream     = this._tokenStream,
                    line,
                    col,
                    mediaList;//       = [];

                //look for @media
                tokenStream.mustMatch(Tokens.MEDIA_SYM);
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;

                this._readWhitespace();

                mediaList = this._media_query_list();

                tokenStream.mustMatch(Tokens.LBRACE);
                this._readWhitespace();

                this.fire({
                    type:   "startmedia",
                    media:  mediaList,
                    line:   line,
                    col:    col
                });

                while (true) {
                    if (tokenStream.peek() === Tokens.PAGE_SYM) {
                        this._page();
                    } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM) {
                        this._font_face();
                    } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM) {
                        this._viewport();
                    } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM) {
                        this._document();
                    } else if (tokenStream.peek() === Tokens.SUPPORTS_SYM) {
                        this._supports();
                    } else if (!this._ruleset()) {
                        break;
                    }
                }

                tokenStream.mustMatch(Tokens.RBRACE);
                this._readWhitespace();

                this.fire({
                    type:   "endmedia",
                    media:  mediaList,
                    line:   line,
                    col:    col
                });
            },


            //CSS3 Media Queries
            _media_query_list: function() {
                /*
                 * media_query_list
                 *   : S* [media_query [ ',' S* media_query ]* ]?
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    mediaList   = [];


                this._readWhitespace();

                if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN) {
                    mediaList.push(this._media_query());
                }

                while (tokenStream.match(Tokens.COMMA)) {
                    this._readWhitespace();
                    mediaList.push(this._media_query());
                }

                return mediaList;
            },

            /*
             * Note: "expression" in the grammar maps to the _media_expression
             * method.

             */
            _media_query: function() {
                /*
                 * media_query
                 *   : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
                 *   | expression [ AND S* expression ]*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    type        = null,
                    ident       = null,
                    token       = null,
                    expressions = [];

                if (tokenStream.match(Tokens.IDENT)) {
                    ident = tokenStream.token().value.toLowerCase();

                    //since there's no custom tokens for these, need to manually check
                    if (ident !== "only" && ident !== "not") {
                        tokenStream.unget();
                        ident = null;
                    } else {
                        token = tokenStream.token();
                    }
                }

                this._readWhitespace();

                if (tokenStream.peek() === Tokens.IDENT) {
                    type = this._media_type();
                    if (token === null) {
                        token = tokenStream.token();
                    }
                } else if (tokenStream.peek() === Tokens.LPAREN) {
                    if (token === null) {
                        token = tokenStream.LT(1);
                    }
                    expressions.push(this._media_expression());
                }

                if (type === null && expressions.length === 0) {
                    return null;
                } else {
                    this._readWhitespace();
                    while (tokenStream.match(Tokens.IDENT)) {
                        if (tokenStream.token().value.toLowerCase() !== "and") {
                            this._unexpectedToken(tokenStream.token());
                        }

                        this._readWhitespace();
                        expressions.push(this._media_expression());
                    }
                }

                return new MediaQuery(ident, type, expressions, token.startLine, token.startCol);
            },

            //CSS3 Media Queries
            _media_type: function() {
                /*
                 * media_type
                 *   : IDENT
                 *   ;
                 */
                return this._media_feature();
            },

            /**
             * Note: in CSS3 Media Queries, this is called "expression".
             * Renamed here to avoid conflict with CSS3 Selectors
             * definition of "expression". Also note that "expr" in the
             * grammar now maps to "expression" from CSS3 selectors.
             * @method _media_expression
             * @private
             */
            _media_expression: function() {
                /*
                 * expression
                 *  : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
                 *  ;
                 */
                var tokenStream = this._tokenStream,
                    feature     = null,
                    token,
                    expression  = null;

                tokenStream.mustMatch(Tokens.LPAREN);

                feature = this._media_feature();
                this._readWhitespace();

                if (tokenStream.match(Tokens.COLON)) {
                    this._readWhitespace();
                    token = tokenStream.LT(1);
                    expression = this._expression();
                }

                tokenStream.mustMatch(Tokens.RPAREN);
                this._readWhitespace();

                return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null);
            },

            //CSS3 Media Queries
            _media_feature: function() {
                /*
                 * media_feature
                 *   : IDENT
                 *   ;
                 */
                var tokenStream = this._tokenStream;

                this._readWhitespace();

                tokenStream.mustMatch(Tokens.IDENT);

                return SyntaxUnit.fromToken(tokenStream.token());
            },

            //CSS3 Paged Media
            _page: function() {
                /*
                 * page:
                 *    PAGE_SYM S* IDENT? pseudo_page? S*
                 *    '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
                 *    ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col,
                    identifier  = null,
                    pseudoPage  = null;

                //look for @page
                tokenStream.mustMatch(Tokens.PAGE_SYM);
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;

                this._readWhitespace();

                if (tokenStream.match(Tokens.IDENT)) {
                    identifier = tokenStream.token().value;

                    //The value 'auto' may not be used as a page name and MUST be treated as a syntax error.
                    if (identifier.toLowerCase() === "auto") {
                        this._unexpectedToken(tokenStream.token());
                    }
                }

                //see if there's a colon upcoming
                if (tokenStream.peek() === Tokens.COLON) {
                    pseudoPage = this._pseudo_page();
                }

                this._readWhitespace();

                this.fire({
                    type:   "startpage",
                    id:     identifier,
                    pseudo: pseudoPage,
                    line:   line,
                    col:    col
                });

                this._readDeclarations(true, true);

                this.fire({
                    type:   "endpage",
                    id:     identifier,
                    pseudo: pseudoPage,
                    line:   line,
                    col:    col
                });

            },

            //CSS3 Paged Media
            _margin: function() {
                /*
                 * margin :
                 *    margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*
                 *    ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col,
                    marginSym   = this._margin_sym();

                if (marginSym) {
                    line = tokenStream.token().startLine;
                    col = tokenStream.token().startCol;

                    this.fire({
                        type: "startpagemargin",
                        margin: marginSym,
                        line:   line,
                        col:    col
                    });

                    this._readDeclarations(true);

                    this.fire({
                        type: "endpagemargin",
                        margin: marginSym,
                        line:   line,
                        col:    col
                    });
                    return true;
                } else {
                    return false;
                }
            },

            //CSS3 Paged Media
            _margin_sym: function() {

                /*
                 * margin_sym :
                 *    TOPLEFTCORNER_SYM |
                 *    TOPLEFT_SYM |
                 *    TOPCENTER_SYM |
                 *    TOPRIGHT_SYM |
                 *    TOPRIGHTCORNER_SYM |
                 *    BOTTOMLEFTCORNER_SYM |
                 *    BOTTOMLEFT_SYM |
                 *    BOTTOMCENTER_SYM |
                 *    BOTTOMRIGHT_SYM |
                 *    BOTTOMRIGHTCORNER_SYM |
                 *    LEFTTOP_SYM |
                 *    LEFTMIDDLE_SYM |
                 *    LEFTBOTTOM_SYM |
                 *    RIGHTTOP_SYM |
                 *    RIGHTMIDDLE_SYM |
                 *    RIGHTBOTTOM_SYM
                 *    ;
                 */

                var tokenStream = this._tokenStream;

                if (tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM,
                        Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM,
                        Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM,
                        Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,
                        Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM,
                        Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM,
                        Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM])) {
                    return SyntaxUnit.fromToken(tokenStream.token());
                } else {
                    return null;
                }

            },

            _pseudo_page: function() {
                /*
                 * pseudo_page
                 *   : ':' IDENT
                 *   ;
                 */

                var tokenStream = this._tokenStream;

                tokenStream.mustMatch(Tokens.COLON);
                tokenStream.mustMatch(Tokens.IDENT);

                //TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed

                return tokenStream.token().value;
            },

            _font_face: function() {
                /*
                 * font_face
                 *   : FONT_FACE_SYM S*
                 *     '{' S* declaration [ ';' S* declaration ]* '}' S*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col;

                //look for @page
                tokenStream.mustMatch(Tokens.FONT_FACE_SYM);
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;

                this._readWhitespace();

                this.fire({
                    type:   "startfontface",
                    line:   line,
                    col:    col
                });

                this._readDeclarations(true);

                this.fire({
                    type:   "endfontface",
                    line:   line,
                    col:    col
                });
            },

            _viewport: function() {
                /*
                 * viewport
                 *   : VIEWPORT_SYM S*
                 *     '{' S* declaration? [ ';' S* declaration? ]* '}' S*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    line,
                    col;

                tokenStream.mustMatch(Tokens.VIEWPORT_SYM);
                line = tokenStream.token().startLine;
                col = tokenStream.token().startCol;

                this._readWhitespace();

                this.fire({
                    type:   "startviewport",
                    line:   line,
                    col:    col
                });

                this._readDeclarations(true);

                this.fire({
                    type:   "endviewport",
                    line:   line,
                    col:    col
                });

            },

            _document: function() {
                /*
                 * document
                 *   : DOCUMENT_SYM S*
                 *     _document_function [ ',' S* _document_function ]* S*
                 *     '{' S* ruleset* '}'
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    token,
                    functions = [],
                    prefix = "";

                tokenStream.mustMatch(Tokens.DOCUMENT_SYM);
                token = tokenStream.token();
                if (/^@\-([^\-]+)\-/.test(token.value)) {
                    prefix = RegExp.$1;
                }

                this._readWhitespace();
                functions.push(this._document_function());

                while (tokenStream.match(Tokens.COMMA)) {
                    this._readWhitespace();
                    functions.push(this._document_function());
                }

                tokenStream.mustMatch(Tokens.LBRACE);
                this._readWhitespace();

                this.fire({
                    type:      "startdocument",
                    functions: functions,
                    prefix:    prefix,
                    line:      token.startLine,
                    col:       token.startCol
                });

                var ok = true;
                while (ok) {
                    switch (tokenStream.peek()) {
                        case Tokens.PAGE_SYM:
                            this._page();
                            break;
                        case Tokens.FONT_FACE_SYM:
                            this._font_face();
                            break;
                        case Tokens.VIEWPORT_SYM:
                            this._viewport();
                            break;
                        case Tokens.MEDIA_SYM:
                            this._media();
                            break;
                        case Tokens.KEYFRAMES_SYM:
                            this._keyframes();
                            break;
                        case Tokens.DOCUMENT_SYM:
                            this._document();
                            break;
                        default:
                            ok = Boolean(this._ruleset());
                    }
                }

                tokenStream.mustMatch(Tokens.RBRACE);
                token = tokenStream.token();
                this._readWhitespace();

                this.fire({
                    type:      "enddocument",
                    functions: functions,
                    prefix:    prefix,
                    line:      token.startLine,
                    col:       token.startCol
                });
            },

            _document_function: function() {
                /*
                 * document_function
                 *   : function | URI S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    value;

                if (tokenStream.match(Tokens.URI)) {
                    value = tokenStream.token().value;
                    this._readWhitespace();
                } else {
                    value = this._function();
                }

                return value;
            },

            _operator: function(inFunction) {

                /*
                 * operator (outside function)
                 *  : '/' S* | ',' S* | /( empty )/
                 * operator (inside function)
                 *  : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/
                 *  ;
                 */

                var tokenStream = this._tokenStream,
                    token       = null;

                if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) ||
                    (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))) {
                    token =  tokenStream.token();
                    this._readWhitespace();
                }
                return token ? PropertyValuePart.fromToken(token) : null;

            },

            _combinator: function() {

                /*
                 * combinator
                 *  : PLUS S* | GREATER S* | TILDE S* | S+
                 *  ;
                 */

                var tokenStream = this._tokenStream,
                    value       = null,
                    token;

                if (tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])) {
                    token = tokenStream.token();
                    value = new Combinator(token.value, token.startLine, token.startCol);
                    this._readWhitespace();
                }

                return value;
            },

            _unary_operator: function() {

                /*
                 * unary_operator
                 *  : '-' | '+'
                 *  ;
                 */

                var tokenStream = this._tokenStream;

                if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])) {
                    return tokenStream.token().value;
                } else {
                    return null;
                }
            },

            _property: function() {

                /*
                 * property
                 *   : IDENT S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    value       = null,
                    hack        = null,
                    tokenValue,
                    token,
                    line,
                    col;

                //check for star hack - throws error if not allowed
                if (tokenStream.peek() === Tokens.STAR && this.options.starHack) {
                    tokenStream.get();
                    token = tokenStream.token();
                    hack = token.value;
                    line = token.startLine;
                    col = token.startCol;
                }

                if (tokenStream.match(Tokens.IDENT)) {
                    token = tokenStream.token();
                    tokenValue = token.value;

                    //check for underscore hack - no error if not allowed because it's valid CSS syntax
                    if (tokenValue.charAt(0) === "_" && this.options.underscoreHack) {
                        hack = "_";
                        tokenValue = tokenValue.substring(1);
                    }

                    value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));
                    this._readWhitespace();
                }

                return value;
            },

            //Augmented with CSS3 Selectors
            _ruleset: function() {
                /*
                 * ruleset
                 *   : selectors_group
                 *     '{' S* declaration? [ ';' S* declaration? ]* '}' S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    tt,
                    selectors;


                /*
                 * Error Recovery: If even a single selector fails to parse,
                 * then the entire ruleset should be thrown away.
                 */
                try {
                    selectors = this._selectors_group();
                } catch (ex) {
                    if (ex instanceof SyntaxError && !this.options.strict) {

                        //fire error event
                        this.fire({
                            type:       "error",
                            error:      ex,
                            message:    ex.message,
                            line:       ex.line,
                            col:        ex.col
                        });

                        //skip over everything until closing brace
                        tt = tokenStream.advance([Tokens.RBRACE]);
                        if (tt === Tokens.RBRACE) {
                            //if there's a right brace, the rule is finished so don't do anything
                        } else {
                            //otherwise, rethrow the error because it wasn't handled properly
                            throw ex;
                        }

                    } else {
                        //not a syntax error, rethrow it
                        throw ex;
                    }

                    //trigger parser to continue
                    return true;
                }

                //if it got here, all selectors parsed
                if (selectors) {

                    this.fire({
                        type:       "startrule",
                        selectors:  selectors,
                        line:       selectors[0].line,
                        col:        selectors[0].col
                    });

                    this._readDeclarations(true);

                    this.fire({
                        type:       "endrule",
                        selectors:  selectors,
                        line:       selectors[0].line,
                        col:        selectors[0].col
                    });

                }

                return selectors;

            },

            //CSS3 Selectors
            _selectors_group: function() {

                /*
                 * selectors_group
                 *   : selector [ COMMA S* selector ]*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    selectors   = [],
                    selector;

                selector = this._selector();
                if (selector !== null) {

                    selectors.push(selector);
                    while (tokenStream.match(Tokens.COMMA)) {
                        this._readWhitespace();
                        selector = this._selector();
                        if (selector !== null) {
                            selectors.push(selector);
                        } else {
                            this._unexpectedToken(tokenStream.LT(1));
                        }
                    }
                }

                return selectors.length ? selectors : null;
            },

            //CSS3 Selectors
            _selector: function() {
                /*
                 * selector
                 *   : simple_selector_sequence [ combinator simple_selector_sequence ]*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    selector    = [],
                    nextSelector = null,
                    combinator  = null,
                    ws          = null;

                //if there's no simple selector, then there's no selector
                nextSelector = this._simple_selector_sequence();
                if (nextSelector === null) {
                    return null;
                }

                selector.push(nextSelector);

                do {

                    //look for a combinator
                    combinator = this._combinator();

                    if (combinator !== null) {
                        selector.push(combinator);
                        nextSelector = this._simple_selector_sequence();

                        //there must be a next selector
                        if (nextSelector === null) {
                            this._unexpectedToken(tokenStream.LT(1));
                        } else {

                            //nextSelector is an instance of SelectorPart
                            selector.push(nextSelector);
                        }
                    } else {

                        //if there's not whitespace, we're done
                        if (this._readWhitespace()) {

                            //add whitespace separator
                            ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol);

                            //combinator is not required
                            combinator = this._combinator();

                            //selector is required if there's a combinator
                            nextSelector = this._simple_selector_sequence();
                            if (nextSelector === null) {
                                if (combinator !== null) {
                                    this._unexpectedToken(tokenStream.LT(1));
                                }
                            } else {

                                if (combinator !== null) {
                                    selector.push(combinator);
                                } else {
                                    selector.push(ws);
                                }

                                selector.push(nextSelector);
                            }
                        } else {
                            break;
                        }

                    }
                } while (true);

                return new Selector(selector, selector[0].line, selector[0].col);
            },

            //CSS3 Selectors
            _simple_selector_sequence: function() {
                /*
                 * simple_selector_sequence
                 *   : [ type_selector | universal ]
                 *     [ HASH | class | attrib | pseudo | negation ]*
                 *   | [ HASH | class | attrib | pseudo | negation ]+
                 *   ;
                 */

                var tokenStream = this._tokenStream,

                    //parts of a simple selector
                    elementName = null,
                    modifiers   = [],

                    //complete selector text
                    selectorText= "",

                    //the different parts after the element name to search for
                    components  = [
                        //HASH
                        function() {
                            return tokenStream.match(Tokens.HASH) ?
                                    new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
                                    null;
                        },
                        this._class,
                        this._attrib,
                        this._pseudo,
                        this._negation
                    ],
                    i           = 0,
                    len         = components.length,
                    component   = null,
                    line,
                    col;


                //get starting line and column for the selector
                line = tokenStream.LT(1).startLine;
                col = tokenStream.LT(1).startCol;

                elementName = this._type_selector();
                if (!elementName) {
                    elementName = this._universal();
                }

                if (elementName !== null) {
                    selectorText += elementName;
                }

                while (true) {

                    //whitespace means we're done
                    if (tokenStream.peek() === Tokens.S) {
                        break;
                    }

                    //check for each component
                    while (i < len && component === null) {
                        component = components[i++].call(this);
                    }

                    if (component === null) {

                        //we don't have a selector
                        if (selectorText === "") {
                            return null;
                        } else {
                            break;
                        }
                    } else {
                        i = 0;
                        modifiers.push(component);
                        selectorText += component.toString();
                        component = null;
                    }
                }


                return selectorText !== "" ?
                        new SelectorPart(elementName, modifiers, selectorText, line, col) :
                        null;
            },

            //CSS3 Selectors
            _type_selector: function() {
                /*
                 * type_selector
                 *   : [ namespace_prefix ]? element_name
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    ns          = this._namespace_prefix(),
                    elementName = this._element_name();

                if (!elementName) {
                    /*
                     * Need to back out the namespace that was read due to both
                     * type_selector and universal reading namespace_prefix
                     * first. Kind of hacky, but only way I can figure out
                     * right now how to not change the grammar.
                     */
                    if (ns) {
                        tokenStream.unget();
                        if (ns.length > 1) {
                            tokenStream.unget();
                        }
                    }

                    return null;
                } else {
                    if (ns) {
                        elementName.text = ns + elementName.text;
                        elementName.col -= ns.length;
                    }
                    return elementName;
                }
            },

            //CSS3 Selectors
            _class: function() {
                /*
                 * class
                 *   : '.' IDENT
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    token;

                if (tokenStream.match(Tokens.DOT)) {
                    tokenStream.mustMatch(Tokens.IDENT);
                    token = tokenStream.token();
                    return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
                } else {
                    return null;
                }

            },

            //CSS3 Selectors
            _element_name: function() {
                /*
                 * element_name
                 *   : IDENT
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    token;

                if (tokenStream.match(Tokens.IDENT)) {
                    token = tokenStream.token();
                    return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);

                } else {
                    return null;
                }
            },

            //CSS3 Selectors
            _namespace_prefix: function() {
                /*
                 * namespace_prefix
                 *   : [ IDENT | '*' ]? '|'
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    value       = "";

                //verify that this is a namespace prefix
                if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE) {

                    if (tokenStream.match([Tokens.IDENT, Tokens.STAR])) {
                        value += tokenStream.token().value;
                    }

                    tokenStream.mustMatch(Tokens.PIPE);
                    value += "|";

                }

                return value.length ? value : null;
            },

            //CSS3 Selectors
            _universal: function() {
                /*
                 * universal
                 *   : [ namespace_prefix ]? '*'
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    value       = "",
                    ns;

                ns = this._namespace_prefix();
                if (ns) {
                    value += ns;
                }

                if (tokenStream.match(Tokens.STAR)) {
                    value += "*";
                }

                return value.length ? value : null;

            },

            //CSS3 Selectors
            _attrib: function() {
                /*
                 * attrib
                 *   : '[' S* [ namespace_prefix ]? IDENT S*
                 *         [ [ PREFIXMATCH |
                 *             SUFFIXMATCH |
                 *             SUBSTRINGMATCH |
                 *             '=' |
                 *             INCLUDES |
                 *             DASHMATCH ] S* [ IDENT | STRING ] S*
                 *         ]? ']'
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    value       = null,
                    ns,
                    token;

                if (tokenStream.match(Tokens.LBRACKET)) {
                    token = tokenStream.token();
                    value = token.value;
                    value += this._readWhitespace();

                    ns = this._namespace_prefix();

                    if (ns) {
                        value += ns;
                    }

                    tokenStream.mustMatch(Tokens.IDENT);
                    value += tokenStream.token().value;
                    value += this._readWhitespace();

                    if (tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,
                            Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])) {

                        value += tokenStream.token().value;
                        value += this._readWhitespace();

                        tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
                        value += tokenStream.token().value;
                        value += this._readWhitespace();
                    }

                    tokenStream.mustMatch(Tokens.RBRACKET);

                    return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol);
                } else {
                    return null;
                }
            },

            //CSS3 Selectors
            _pseudo: function() {

                /*
                 * pseudo
                 *   : ':' ':'? [ IDENT | functional_pseudo ]
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    pseudo      = null,
                    colons      = ":",
                    line,
                    col;

                if (tokenStream.match(Tokens.COLON)) {

                    if (tokenStream.match(Tokens.COLON)) {
                        colons += ":";
                    }

                    if (tokenStream.match(Tokens.IDENT)) {
                        pseudo = tokenStream.token().value;
                        line = tokenStream.token().startLine;
                        col = tokenStream.token().startCol - colons.length;
                    } else if (tokenStream.peek() === Tokens.FUNCTION) {
                        line = tokenStream.LT(1).startLine;
                        col = tokenStream.LT(1).startCol - colons.length;
                        pseudo = this._functional_pseudo();
                    }

                    if (pseudo) {
                        pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col);
                    } else {
                        var startLine = tokenStream.LT(1).startLine,
                            startCol  = tokenStream.LT(0).startCol;
                        throw new SyntaxError("Expected a `FUNCTION` or `IDENT` after colon at line " + startLine + ", col " + startCol + ".", startLine, startCol);
                    }
                }

                return pseudo;
            },

            //CSS3 Selectors
            _functional_pseudo: function() {
                /*
                 * functional_pseudo
                 *   : FUNCTION S* expression ')'
                 *   ;
                */

                var tokenStream = this._tokenStream,
                    value = null;

                if (tokenStream.match(Tokens.FUNCTION)) {
                    value = tokenStream.token().value;
                    value += this._readWhitespace();
                    value += this._expression();
                    tokenStream.mustMatch(Tokens.RPAREN);
                    value += ")";
                }

                return value;
            },

            //CSS3 Selectors
            _expression: function() {
                /*
                 * expression
                 *   : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    value       = "";

                while (tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION,
                        Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH,
                        Tokens.FREQ, Tokens.ANGLE, Tokens.TIME,
                        Tokens.RESOLUTION, Tokens.SLASH])) {

                    value += tokenStream.token().value;
                    value += this._readWhitespace();
                }

                return value.length ? value : null;

            },

            //CSS3 Selectors
            _negation: function() {
                /*
                 * negation
                 *   : NOT S* negation_arg S* ')'
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    line,
                    col,
                    value       = "",
                    arg,
                    subpart     = null;

                if (tokenStream.match(Tokens.NOT)) {
                    value = tokenStream.token().value;
                    line = tokenStream.token().startLine;
                    col = tokenStream.token().startCol;
                    value += this._readWhitespace();
                    arg = this._negation_arg();
                    value += arg;
                    value += this._readWhitespace();
                    tokenStream.match(Tokens.RPAREN);
                    value += tokenStream.token().value;

                    subpart = new SelectorSubPart(value, "not", line, col);
                    subpart.args.push(arg);
                }

                return subpart;
            },

            //CSS3 Selectors
            _negation_arg: function() {
                /*
                 * negation_arg
                 *   : type_selector | universal | HASH | class | attrib | pseudo
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    args        = [
                        this._type_selector,
                        this._universal,
                        function() {
                            return tokenStream.match(Tokens.HASH) ?
                                    new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
                                    null;
                        },
                        this._class,
                        this._attrib,
                        this._pseudo
                    ],
                    arg         = null,
                    i           = 0,
                    len         = args.length,
                    line,
                    col,
                    part;

                line = tokenStream.LT(1).startLine;
                col = tokenStream.LT(1).startCol;

                while (i < len && arg === null) {

                    arg = args[i].call(this);
                    i++;
                }

                //must be a negation arg
                if (arg === null) {
                    this._unexpectedToken(tokenStream.LT(1));
                }

                //it's an element name
                if (arg.type === "elementName") {
                    part = new SelectorPart(arg, [], arg.toString(), line, col);
                } else {
                    part = new SelectorPart(null, [arg], arg.toString(), line, col);
                }

                return part;
            },

            _declaration: function() {

                /*
                 * declaration
                 *   : property ':' S* expr prio?
                 *   | /( empty )/
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    property    = null,
                    expr        = null,
                    prio        = null,
                    invalid     = null,
                    propertyName= "";

                property = this._property();
                if (property !== null) {

                    tokenStream.mustMatch(Tokens.COLON);
                    this._readWhitespace();

                    expr = this._expr();

                    //if there's no parts for the value, it's an error
                    if (!expr || expr.length === 0) {
                        this._unexpectedToken(tokenStream.LT(1));
                    }

                    prio = this._prio();

                    /*
                     * If hacks should be allowed, then only check the root
                     * property. If hacks should not be allowed, treat
                     * _property or *property as invalid properties.
                     */
                    propertyName = property.toString();
                    if (this.options.starHack && property.hack === "*" ||
                            this.options.underscoreHack && property.hack === "_") {

                        propertyName = property.text;
                    }

                    try {
                        this._validateProperty(propertyName, expr);
                    } catch (ex) {
                        invalid = ex;
                    }

                    this.fire({
                        type:       "property",
                        property:   property,
                        value:      expr,
                        important:  prio,
                        line:       property.line,
                        col:        property.col,
                        invalid:    invalid
                    });

                    return true;
                } else {
                    return false;
                }
            },

            _prio: function() {
                /*
                 * prio
                 *   : IMPORTANT_SYM S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    result      = tokenStream.match(Tokens.IMPORTANT_SYM);

                this._readWhitespace();
                return result;
            },

            _expr: function(inFunction) {
                /*
                 * expr
                 *   : term [ operator term ]*
                 *   ;
                 */

                var values      = [],
                    //valueParts    = [],
                    value       = null,
                    operator    = null;

                value = this._term(inFunction);
                if (value !== null) {

                    values.push(value);

                    do {
                        operator = this._operator(inFunction);

                        //if there's an operator, keep building up the value parts
                        if (operator) {
                            values.push(operator);
                        } /*else {
                            //if there's not an operator, you have a full value
                            values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
                            valueParts = [];
                        }*/

                        value = this._term(inFunction);

                        if (value === null) {
                            break;
                        } else {
                            values.push(value);
                        }
                    } while (true);
                }

                //cleanup
                /*if (valueParts.length) {
                    values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
                }*/

                return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null;
            },

            _term: function(inFunction) {

                /*
                 * term
                 *   : unary_operator?
                 *     [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* |
                 *       TIME S* | FREQ S* | function | ie_function ]
                 *   | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    unary       = null,
                    value       = null,
                    endChar     = null,
                    part        = null,
                    token,
                    line,
                    col;

                //returns the operator or null
                unary = this._unary_operator();
                if (unary !== null) {
                    line = tokenStream.token().startLine;
                    col = tokenStream.token().startCol;
                }

                //exception for IE filters
                if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters) {

                    value = this._ie_function();
                    if (unary === null) {
                        line = tokenStream.token().startLine;
                        col = tokenStream.token().startCol;
                    }

                //see if it's a simple block
                } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])) {

                    token = tokenStream.token();
                    endChar = token.endChar;
                    value = token.value + this._expr(inFunction).text;
                    if (unary === null) {
                        line = tokenStream.token().startLine;
                        col = tokenStream.token().startCol;
                    }
                    tokenStream.mustMatch(Tokens.type(endChar));
                    value += endChar;
                    this._readWhitespace();

                //see if there's a simple match
                } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH,
                        Tokens.ANGLE, Tokens.TIME,
                        Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])) {

                    value = tokenStream.token().value;
                    if (unary === null) {
                        line = tokenStream.token().startLine;
                        col = tokenStream.token().startCol;
                        // Correct potentially-inaccurate IDENT parsing in
                        // PropertyValuePart constructor.
                        part = PropertyValuePart.fromToken(tokenStream.token());
                    }
                    this._readWhitespace();
                } else {

                    //see if it's a color
                    token = this._hexcolor();
                    if (token === null) {

                        //if there's no unary, get the start of the next token for line/col info
                        if (unary === null) {
                            line = tokenStream.LT(1).startLine;
                            col = tokenStream.LT(1).startCol;
                        }

                        //has to be a function
                        if (value === null) {

                            /*
                             * This checks for alpha(opacity=0) style of IE
                             * functions. IE_FUNCTION only presents progid: style.
                             */
                            if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters) {
                                value = this._ie_function();
                            } else {
                                value = this._function();
                            }
                        }

                        /*if (value === null) {
                            return null;
                            //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " +  tokenStream.token().startCol + ".");
                        }*/

                    } else {
                        value = token.value;
                        if (unary === null) {
                            line = token.startLine;
                            col = token.startCol;
                        }
                    }

                }

                return part !== null ? part : value !== null ?
                        new PropertyValuePart(unary !== null ? unary + value : value, line, col) :
                        null;

            },

            _function: function() {

                /*
                 * function
                 *   : FUNCTION S* expr ')' S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    functionText = null,
                    expr        = null,
                    lt;

                if (tokenStream.match(Tokens.FUNCTION)) {
                    functionText = tokenStream.token().value;
                    this._readWhitespace();
                    expr = this._expr(true);
                    functionText += expr;

                    //START: Horrible hack in case it's an IE filter
                    if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS) {
                        do {

                            if (this._readWhitespace()) {
                                functionText += tokenStream.token().value;
                            }

                            //might be second time in the loop
                            if (tokenStream.LA(0) === Tokens.COMMA) {
                                functionText += tokenStream.token().value;
                            }

                            tokenStream.match(Tokens.IDENT);
                            functionText += tokenStream.token().value;

                            tokenStream.match(Tokens.EQUALS);
                            functionText += tokenStream.token().value;

                            //functionText += this._term();
                            lt = tokenStream.peek();
                            while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) {
                                tokenStream.get();
                                functionText += tokenStream.token().value;
                                lt = tokenStream.peek();
                            }
                        } while (tokenStream.match([Tokens.COMMA, Tokens.S]));
                    }

                    //END: Horrible Hack

                    tokenStream.match(Tokens.RPAREN);
                    functionText += ")";
                    this._readWhitespace();
                }

                return functionText;
            },

            _ie_function: function() {

                /* (My own extension)
                 * ie_function
                 *   : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    functionText = null,
                    lt;

                //IE function can begin like a regular function, too
                if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])) {
                    functionText = tokenStream.token().value;

                    do {

                        if (this._readWhitespace()) {
                            functionText += tokenStream.token().value;
                        }

                        //might be second time in the loop
                        if (tokenStream.LA(0) === Tokens.COMMA) {
                            functionText += tokenStream.token().value;
                        }

                        tokenStream.match(Tokens.IDENT);
                        functionText += tokenStream.token().value;

                        tokenStream.match(Tokens.EQUALS);
                        functionText += tokenStream.token().value;

                        //functionText += this._term();
                        lt = tokenStream.peek();
                        while (lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN) {
                            tokenStream.get();
                            functionText += tokenStream.token().value;
                            lt = tokenStream.peek();
                        }
                    } while (tokenStream.match([Tokens.COMMA, Tokens.S]));

                    tokenStream.match(Tokens.RPAREN);
                    functionText += ")";
                    this._readWhitespace();
                }

                return functionText;
            },

            _hexcolor: function() {
                /*
                 * There is a constraint on the color that it must
                 * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
                 * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
                 *
                 * hexcolor
                 *   : HASH S*
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    token = null,
                    color;

                if (tokenStream.match(Tokens.HASH)) {

                    //need to do some validation here

                    token = tokenStream.token();
                    color = token.value;
                    if (!/#[a-f0-9]{3,6}/i.test(color)) {
                        throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
                    }
                    this._readWhitespace();
                }

                return token;
            },

            //-----------------------------------------------------------------
            // Animations methods
            //-----------------------------------------------------------------

            _keyframes: function() {

                /*
                 * keyframes:
                 *   : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' {
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    token,
                    tt,
                    name,
                    prefix = "";

                tokenStream.mustMatch(Tokens.KEYFRAMES_SYM);
                token = tokenStream.token();
                if (/^@\-([^\-]+)\-/.test(token.value)) {
                    prefix = RegExp.$1;
                }

                this._readWhitespace();
                name = this._keyframe_name();

                this._readWhitespace();
                tokenStream.mustMatch(Tokens.LBRACE);

                this.fire({
                    type:   "startkeyframes",
                    name:   name,
                    prefix: prefix,
                    line:   token.startLine,
                    col:    token.startCol
                });

                this._readWhitespace();
                tt = tokenStream.peek();

                //check for key
                while (tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) {
                    this._keyframe_rule();
                    this._readWhitespace();
                    tt = tokenStream.peek();
                }

                this.fire({
                    type:   "endkeyframes",
                    name:   name,
                    prefix: prefix,
                    line:   token.startLine,
                    col:    token.startCol
                });

                this._readWhitespace();
                tokenStream.mustMatch(Tokens.RBRACE);
                this._readWhitespace();

            },

            _keyframe_name: function() {

                /*
                 * keyframe_name:
                 *   : IDENT
                 *   | STRING
                 *   ;
                 */
                var tokenStream = this._tokenStream;

                tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
                return SyntaxUnit.fromToken(tokenStream.token());
            },

            _keyframe_rule: function() {

                /*
                 * keyframe_rule:
                 *   : key_list S*
                 *     '{' S* declaration [ ';' S* declaration ]* '}' S*
                 *   ;
                 */
                var keyList = this._key_list();

                this.fire({
                    type:   "startkeyframerule",
                    keys:   keyList,
                    line:   keyList[0].line,
                    col:    keyList[0].col
                });

                this._readDeclarations(true);

                this.fire({
                    type:   "endkeyframerule",
                    keys:   keyList,
                    line:   keyList[0].line,
                    col:    keyList[0].col
                });

            },

            _key_list: function() {

                /*
                 * key_list:
                 *   : key [ S* ',' S* key]*
                 *   ;
                 */
                var tokenStream = this._tokenStream,
                    keyList = [];

                //must be least one key
                keyList.push(this._key());

                this._readWhitespace();

                while (tokenStream.match(Tokens.COMMA)) {
                    this._readWhitespace();
                    keyList.push(this._key());
                    this._readWhitespace();
                }

                return keyList;
            },

            _key: function() {
                /*
                 * There is a restriction that IDENT can be only "from" or "to".
                 *
                 * key
                 *   : PERCENTAGE
                 *   | IDENT
                 *   ;
                 */

                var tokenStream = this._tokenStream,
                    token;

                if (tokenStream.match(Tokens.PERCENTAGE)) {
                    return SyntaxUnit.fromToken(tokenStream.token());
                } else if (tokenStream.match(Tokens.IDENT)) {
                    token = tokenStream.token();

                    if (/from|to/i.test(token.value)) {
                        return SyntaxUnit.fromToken(token);
                    }

                    tokenStream.unget();
                }

                //if it gets here, there wasn't a valid token, so time to explode
                this._unexpectedToken(tokenStream.LT(1));
            },

            //-----------------------------------------------------------------
            // Helper methods
            //-----------------------------------------------------------------

            /**
             * Not part of CSS grammar, but useful for skipping over
             * combination of white space and HTML-style comments.
             * @return {void}
             * @method _skipCruft
             * @private
             */
            _skipCruft: function() {
                while (this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])) {
                    //noop
                }
            },

            /**
             * Not part of CSS grammar, but this pattern occurs frequently
             * in the official CSS grammar. Split out here to eliminate
             * duplicate code.
             * @param {Boolean} checkStart Indicates if the rule should check
             *      for the left brace at the beginning.
             * @param {Boolean} readMargins Indicates if the rule should check
             *      for margin patterns.
             * @return {void}
             * @method _readDeclarations
             * @private
             */
            _readDeclarations: function(checkStart, readMargins) {
                /*
                 * Reads the pattern
                 * S* '{' S* declaration [ ';' S* declaration ]* '}' S*
                 * or
                 * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
                 * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect.
                 * A semicolon is only necessary following a declaration if there's another declaration
                 * or margin afterwards.
                 */
                var tokenStream = this._tokenStream,
                    tt;


                this._readWhitespace();

                if (checkStart) {
                    tokenStream.mustMatch(Tokens.LBRACE);
                }

                this._readWhitespace();

                try {

                    while (true) {

                        if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())) {
                            //noop
                        } else if (this._declaration()) {
                            if (!tokenStream.match(Tokens.SEMICOLON)) {
                                break;
                            }
                        } else {
                            break;
                        }

                        //if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)){
                        //    break;
                        //}
                        this._readWhitespace();
                    }

                    tokenStream.mustMatch(Tokens.RBRACE);
                    this._readWhitespace();

                } catch (ex) {
                    if (ex instanceof SyntaxError && !this.options.strict) {

                        //fire error event
                        this.fire({
                            type:       "error",
                            error:      ex,
                            message:    ex.message,
                            line:       ex.line,
                            col:        ex.col
                        });

                        //see if there's another declaration
                        tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]);
                        if (tt === Tokens.SEMICOLON) {
                            //if there's a semicolon, then there might be another declaration
                            this._readDeclarations(false, readMargins);
                        } else if (tt !== Tokens.RBRACE) {
                            //if there's a right brace, the rule is finished so don't do anything
                            //otherwise, rethrow the error because it wasn't handled properly
                            throw ex;
                        }

                    } else {
                        //not a syntax error, rethrow it
                        throw ex;
                    }
                }

            },

            /**
             * In some cases, you can end up with two white space tokens in a
             * row. Instead of making a change in every function that looks for
             * white space, this function is used to match as much white space
             * as necessary.
             * @method _readWhitespace
             * @return {String} The white space if found, empty string if not.
             * @private
             */
            _readWhitespace: function() {

                var tokenStream = this._tokenStream,
                    ws = "";

                while (tokenStream.match(Tokens.S)) {
                    ws += tokenStream.token().value;
                }

                return ws;
            },


            /**
             * Throws an error when an unexpected token is found.
             * @param {Object} token The token that was found.
             * @method _unexpectedToken
             * @return {void}
             * @private
             */
            _unexpectedToken: function(token) {
                throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
            },

            /**
             * Helper method used for parsing subparts of a style sheet.
             * @return {void}
             * @method _verifyEnd
             * @private
             */
            _verifyEnd: function() {
                if (this._tokenStream.LA(1) !== Tokens.EOF) {
                    this._unexpectedToken(this._tokenStream.LT(1));
                }
            },

            //-----------------------------------------------------------------
            // Validation methods
            //-----------------------------------------------------------------
            _validateProperty: function(property, value) {
                Validation.validate(property, value);
            },

            //-----------------------------------------------------------------
            // Parsing methods
            //-----------------------------------------------------------------

            parse: function(input) {
                this._tokenStream = new TokenStream(input, Tokens);
                this._stylesheet();
            },

            parseStyleSheet: function(input) {
                //just passthrough
                return this.parse(input);
            },

            parseMediaQuery: function(input) {
                this._tokenStream = new TokenStream(input, Tokens);
                var result = this._media_query();

                //if there's anything more, then it's an invalid selector
                this._verifyEnd();

                //otherwise return result
                return result;
            },

            /**
             * Parses a property value (everything after the semicolon).
             * @return {parserlib.css.PropertyValue} The property value.
             * @throws parserlib.util.SyntaxError If an unexpected token is found.
             * @method parserPropertyValue
             */
            parsePropertyValue: function(input) {

                this._tokenStream = new TokenStream(input, Tokens);
                this._readWhitespace();

                var result = this._expr();

                //okay to have a trailing white space
                this._readWhitespace();

                //if there's anything more, then it's an invalid selector
                this._verifyEnd();

                //otherwise return result
                return result;
            },

            /**
             * Parses a complete CSS rule, including selectors and
             * properties.
             * @param {String} input The text to parser.
             * @return {Boolean} True if the parse completed successfully, false if not.
             * @method parseRule
             */
            parseRule: function(input) {
                this._tokenStream = new TokenStream(input, Tokens);

                //skip any leading white space
                this._readWhitespace();

                var result = this._ruleset();

                //skip any trailing white space
                this._readWhitespace();

                //if there's anything more, then it's an invalid selector
                this._verifyEnd();

                //otherwise return result
                return result;
            },

            /**
             * Parses a single CSS selector (no comma)
             * @param {String} input The text to parse as a CSS selector.
             * @return {Selector} An object representing the selector.
             * @throws parserlib.util.SyntaxError If an unexpected token is found.
             * @method parseSelector
             */
            parseSelector: function(input) {

                this._tokenStream = new TokenStream(input, Tokens);

                //skip any leading white space
                this._readWhitespace();

                var result = this._selector();

                //skip any trailing white space
                this._readWhitespace();

                //if there's anything more, then it's an invalid selector
                this._verifyEnd();

                //otherwise return result
                return result;
            },

            /**
             * Parses an HTML style attribute: a set of CSS declarations
             * separated by semicolons.
             * @param {String} input The text to parse as a style attribute
             * @return {void}
             * @method parseStyleAttribute
             */
            parseStyleAttribute: function(input) {
                input += "}"; // for error recovery in _readDeclarations()
                this._tokenStream = new TokenStream(input, Tokens);
                this._readDeclarations();
            }
        };

    //copy over onto prototype
    for (prop in additions) {
        if (Object.prototype.hasOwnProperty.call(additions, prop)) {
            proto[prop] = additions[prop];
        }
    }

    return proto;
}();


/*
nth
  : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
         ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
  ;
*/

},{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(require,module,exports){
"use strict";

/* exported Properties */

var Properties = module.exports = {
    __proto__: null,

    //A
    "align-items"                   : "flex-start | flex-end | center | baseline | stretch",
    "align-content"                 : "flex-start | flex-end | center | space-between | space-around | stretch",
    "align-self"                    : "auto | flex-start | flex-end | center | baseline | stretch",
    "-webkit-align-items"           : "flex-start | flex-end | center | baseline | stretch",
    "-webkit-align-content"         : "flex-start | flex-end | center | space-between | space-around | stretch",
    "-webkit-align-self"            : "auto | flex-start | flex-end | center | baseline | stretch",
    "alignment-adjust"              : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>",
    "alignment-baseline"            : "auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
    "animation"                     : 1,
    "animation-delay"               : "<time>#",
    "animation-direction"           : "<single-animation-direction>#",
    "animation-duration"            : "<time>#",
    "animation-fill-mode"           : "[ none | forwards | backwards | both ]#",
    "animation-iteration-count"     : "[ <number> | infinite ]#",
    "animation-name"                : "[ none | <single-animation-name> ]#",
    "animation-play-state"          : "[ running | paused ]#",
    "animation-timing-function"     : 1,

    //vendor prefixed
    "-moz-animation-delay"               : "<time>#",
    "-moz-animation-direction"           : "[ normal | alternate ]#",
    "-moz-animation-duration"            : "<time>#",
    "-moz-animation-iteration-count"     : "[ <number> | infinite ]#",
    "-moz-animation-name"                : "[ none | <single-animation-name> ]#",
    "-moz-animation-play-state"          : "[ running | paused ]#",

    "-ms-animation-delay"               : "<time>#",
    "-ms-animation-direction"           : "[ normal | alternate ]#",
    "-ms-animation-duration"            : "<time>#",
    "-ms-animation-iteration-count"     : "[ <number> | infinite ]#",
    "-ms-animation-name"                : "[ none | <single-animation-name> ]#",
    "-ms-animation-play-state"          : "[ running | paused ]#",

    "-webkit-animation-delay"               : "<time>#",
    "-webkit-animation-direction"           : "[ normal | alternate ]#",
    "-webkit-animation-duration"            : "<time>#",
    "-webkit-animation-fill-mode"           : "[ none | forwards | backwards | both ]#",
    "-webkit-animation-iteration-count"     : "[ <number> | infinite ]#",
    "-webkit-animation-name"                : "[ none | <single-animation-name> ]#",
    "-webkit-animation-play-state"          : "[ running | paused ]#",

    "-o-animation-delay"               : "<time>#",
    "-o-animation-direction"           : "[ normal | alternate ]#",
    "-o-animation-duration"            : "<time>#",
    "-o-animation-iteration-count"     : "[ <number> | infinite ]#",
    "-o-animation-name"                : "[ none | <single-animation-name> ]#",
    "-o-animation-play-state"          : "[ running | paused ]#",

    "appearance"                    : "icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none",
    "azimuth"                       : "<azimuth>",

    //B
    "backface-visibility"           : "visible | hidden",
    "background"                    : 1,
    "background-attachment"         : "<attachment>#",
    "background-clip"               : "<box>#",
    "background-color"              : "<color>",
    "background-image"              : "<bg-image>#",
    "background-origin"             : "<box>#",
    "background-position"           : "<bg-position>",
    "background-repeat"             : "<repeat-style>#",
    "background-size"               : "<bg-size>#",
    "baseline-shift"                : "baseline | sub | super | <percentage> | <length>",
    "behavior"                      : 1,
    "binding"                       : 1,
    "bleed"                         : "<length>",
    "bookmark-label"                : "<content> | <attr> | <string>",
    "bookmark-level"                : "none | <integer>",
    "bookmark-state"                : "open | closed",
    "bookmark-target"               : "none | <uri> | <attr>",
    "border"                        : "<border-width> || <border-style> || <color>",
    "border-bottom"                 : "<border-width> || <border-style> || <color>",
    "border-bottom-color"           : "<color>",
    "border-bottom-left-radius"     :  "<x-one-radius>",
    "border-bottom-right-radius"    :  "<x-one-radius>",
    "border-bottom-style"           : "<border-style>",
    "border-bottom-width"           : "<border-width>",
    "border-collapse"               : "collapse | separate",
    "border-color"                  : "<color>{1,4}",
    "border-image"                  : 1,
    "border-image-outset"           : "[ <length> | <number> ]{1,4}",
    "border-image-repeat"           : "[ stretch | repeat | round ]{1,2}",
    "border-image-slice"            : "<border-image-slice>",
    "border-image-source"           : "<image> | none",
    "border-image-width"            : "[ <length> | <percentage> | <number> | auto ]{1,4}",
    "border-left"                   : "<border-width> || <border-style> || <color>",
    "border-left-color"             : "<color>",
    "border-left-style"             : "<border-style>",
    "border-left-width"             : "<border-width>",
    "border-radius"                 : "<border-radius>",
    "border-right"                  : "<border-width> || <border-style> || <color>",
    "border-right-color"            : "<color>",
    "border-right-style"            : "<border-style>",
    "border-right-width"            : "<border-width>",
    "border-spacing"                : "<length>{1,2}",
    "border-style"                  : "<border-style>{1,4}",
    "border-top"                    : "<border-width> || <border-style> || <color>",
    "border-top-color"              : "<color>",
    "border-top-left-radius"        : "<x-one-radius>",
    "border-top-right-radius"       : "<x-one-radius>",
    "border-top-style"              : "<border-style>",
    "border-top-width"              : "<border-width>",
    "border-width"                  : "<border-width>{1,4}",
    "bottom"                        : "<margin-width>",
    "-moz-box-align"                : "start | end | center | baseline | stretch",
    "-moz-box-decoration-break"     : "slice | clone",
    "-moz-box-direction"            : "normal | reverse",
    "-moz-box-flex"                 : "<number>",
    "-moz-box-flex-group"           : "<integer>",
    "-moz-box-lines"                : "single | multiple",
    "-moz-box-ordinal-group"        : "<integer>",
    "-moz-box-orient"               : "horizontal | vertical | inline-axis | block-axis",
    "-moz-box-pack"                 : "start | end | center | justify",
    "-o-box-decoration-break"       : "slice | clone",
    "-webkit-box-align"             : "start | end | center | baseline | stretch",
    "-webkit-box-decoration-break"  : "slice | clone",
    "-webkit-box-direction"         : "normal | reverse",
    "-webkit-box-flex"              : "<number>",
    "-webkit-box-flex-group"        : "<integer>",
    "-webkit-box-lines"             : "single | multiple",
    "-webkit-box-ordinal-group"     : "<integer>",
    "-webkit-box-orient"            : "horizontal | vertical | inline-axis | block-axis",
    "-webkit-box-pack"              : "start | end | center | justify",
    "box-decoration-break"          : "slice | clone",
    "box-shadow"                    : "<box-shadow>",
    "box-sizing"                    : "content-box | border-box",
    "break-after"                   : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
    "break-before"                  : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
    "break-inside"                  : "auto | avoid | avoid-page | avoid-column",

    //C
    "caption-side"                  : "top | bottom",
    "clear"                         : "none | right | left | both",
    "clip"                          : "<shape> | auto",
    "-webkit-clip-path"             : "<clip-source> | <clip-path> | none",
    "clip-path"                     : "<clip-source> | <clip-path> | none",
    "clip-rule"                     : "nonzero | evenodd",
    "color"                         : "<color>",
    "color-interpolation"           : "auto | sRGB | linearRGB",
    "color-interpolation-filters"   : "auto | sRGB | linearRGB",
    "color-profile"                 : 1,
    "color-rendering"               : "auto | optimizeSpeed | optimizeQuality",
    "column-count"                  : "<integer> | auto",                      //https://www.w3.org/TR/css3-multicol/
    "column-fill"                   : "auto | balance",
    "column-gap"                    : "<length> | normal",
    "column-rule"                   : "<border-width> || <border-style> || <color>",
    "column-rule-color"             : "<color>",
    "column-rule-style"             : "<border-style>",
    "column-rule-width"             : "<border-width>",
    "column-span"                   : "none | all",
    "column-width"                  : "<length> | auto",
    "columns"                       : 1,
    "content"                       : 1,
    "counter-increment"             : 1,
    "counter-reset"                 : 1,
    "crop"                          : "<shape> | auto",
    "cue"                           : "cue-after | cue-before",
    "cue-after"                     : 1,
    "cue-before"                    : 1,
    "cursor"                        : 1,

    //D
    "direction"                     : "ltr | rtl",
    "display"                       : "inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | run-in | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | contents | none | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex",
    "dominant-baseline"             : "auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge",
    "drop-initial-after-adjust"     : "central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>",
    "drop-initial-after-align"      : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
    "drop-initial-before-adjust"    : "before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>",
    "drop-initial-before-align"     : "caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
    "drop-initial-size"             : "auto | line | <length> | <percentage>",
    "drop-initial-value"            : "<integer>",

    //E
    "elevation"                     : "<angle> | below | level | above | higher | lower",
    "empty-cells"                   : "show | hide",
    "enable-background"             : 1,

    //F
    "fill"                          : "<paint>",
    "fill-opacity"                  : "<opacity-value>",
    "fill-rule"                     : "nonzero | evenodd",
    "filter"                        : "<filter-function-list> | none",
    "fit"                           : "fill | hidden | meet | slice",
    "fit-position"                  : 1,
    "flex"                          : "<flex>",
    "flex-basis"                    : "<width>",
    "flex-direction"                : "row | row-reverse | column | column-reverse",
    "flex-flow"                     : "<flex-direction> || <flex-wrap>",
    "flex-grow"                     : "<number>",
    "flex-shrink"                   : "<number>",
    "flex-wrap"                     : "nowrap | wrap | wrap-reverse",
    "-webkit-flex"                  : "<flex>",
    "-webkit-flex-basis"            : "<width>",
    "-webkit-flex-direction"        : "row | row-reverse | column | column-reverse",
    "-webkit-flex-flow"             : "<flex-direction> || <flex-wrap>",
    "-webkit-flex-grow"             : "<number>",
    "-webkit-flex-shrink"           : "<number>",
    "-webkit-flex-wrap"             : "nowrap | wrap | wrap-reverse",
    "-ms-flex"                      : "<flex>",
    "-ms-flex-align"                : "start | end | center | stretch | baseline",
    "-ms-flex-direction"            : "row | row-reverse | column | column-reverse",
    "-ms-flex-order"                : "<number>",
    "-ms-flex-pack"                 : "start | end | center | justify",
    "-ms-flex-wrap"                 : "nowrap | wrap | wrap-reverse",
    "float"                         : "left | right | none",
    "float-offset"                  : 1,
    "flood-color"                   : 1,
    "flood-opacity"                 : "<opacity-value>",
    "font"                          : "<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar",
    "font-family"                   : "<font-family>",
    "font-feature-settings"         : "<feature-tag-value> | normal",
    "font-kerning"                  : "auto | normal | none",
    "font-size"                     : "<font-size>",
    "font-size-adjust"              : "<number> | none",
    "font-stretch"                  : "<font-stretch>",
    "font-style"                    : "<font-style>",
    "font-variant"                  : "<font-variant> | normal | none",
    "font-variant-alternates"       : "<font-variant-alternates> | normal",
    "font-variant-caps"             : "<font-variant-caps> | normal",
    "font-variant-east-asian"       : "<font-variant-east-asian> | normal",
    "font-variant-ligatures"        : "<font-variant-ligatures> | normal | none",
    "font-variant-numeric"          : "<font-variant-numeric> | normal",
    "font-variant-position"         : "normal | sub | super",
    "font-weight"                   : "<font-weight>",

    //G
    "glyph-orientation-horizontal"  : "<glyph-angle>",
    "glyph-orientation-vertical"    : "auto | <glyph-angle>",
    "grid"                          : 1,
    "grid-area"                     : 1,
    "grid-auto-columns"             : 1,
    "grid-auto-flow"                : 1,
    "grid-auto-position"            : 1,
    "grid-auto-rows"                : 1,
    "grid-cell-stacking"            : "columns | rows | layer",
    "grid-column"                   : 1,
    "grid-columns"                  : 1,
    "grid-column-align"             : "start | end | center | stretch",
    "grid-column-sizing"            : 1,
    "grid-column-start"             : 1,
    "grid-column-end"               : 1,
    "grid-column-span"              : "<integer>",
    "grid-flow"                     : "none | rows | columns",
    "grid-layer"                    : "<integer>",
    "grid-row"                      : 1,
    "grid-rows"                     : 1,
    "grid-row-align"                : "start | end | center | stretch",
    "grid-row-start"                : 1,
    "grid-row-end"                  : 1,
    "grid-row-span"                 : "<integer>",
    "grid-row-sizing"               : 1,
    "grid-template"                 : 1,
    "grid-template-areas"           : 1,
    "grid-template-columns"         : 1,
    "grid-template-rows"            : 1,

    //H
    "hanging-punctuation"           : 1,
    "height"                        : "<margin-width> | <content-sizing>",
    "hyphenate-after"               : "<integer> | auto",
    "hyphenate-before"              : "<integer> | auto",
    "hyphenate-character"           : "<string> | auto",
    "hyphenate-lines"               : "no-limit | <integer>",
    "hyphenate-resource"            : 1,
    "hyphens"                       : "none | manual | auto",

    //I
    "icon"                          : 1,
    "image-orientation"             : "angle | auto",
    "image-rendering"               : "auto | optimizeSpeed | optimizeQuality",
    "image-resolution"              : 1,
    "ime-mode"                      : "auto | normal | active | inactive | disabled",
    "inline-box-align"              : "last | <integer>",

    //J
    "justify-content"               : "flex-start | flex-end | center | space-between | space-around",
    "-webkit-justify-content"       : "flex-start | flex-end | center | space-between | space-around",

    //K
    "kerning"                       : "auto | <length>",

    //L
    "left"                          : "<margin-width>",
    "letter-spacing"                : "<length> | normal",
    "line-height"                   : "<line-height>",
    "line-break"                    : "auto | loose | normal | strict",
    "line-stacking"                 : 1,
    "line-stacking-ruby"            : "exclude-ruby | include-ruby",
    "line-stacking-shift"           : "consider-shifts | disregard-shifts",
    "line-stacking-strategy"        : "inline-line-height | block-line-height | max-height | grid-height",
    "list-style"                    : 1,
    "list-style-image"              : "<uri> | none",
    "list-style-position"           : "inside | outside",
    "list-style-type"               : "disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none",

    //M
    "margin"                        : "<margin-width>{1,4}",
    "margin-bottom"                 : "<margin-width>",
    "margin-left"                   : "<margin-width>",
    "margin-right"                  : "<margin-width>",
    "margin-top"                    : "<margin-width>",
    "mark"                          : 1,
    "mark-after"                    : 1,
    "mark-before"                   : 1,
    "marker"                        : 1,
    "marker-end"                    : 1,
    "marker-mid"                    : 1,
    "marker-start"                  : 1,
    "marks"                         : 1,
    "marquee-direction"             : 1,
    "marquee-play-count"            : 1,
    "marquee-speed"                 : 1,
    "marquee-style"                 : 1,
    "mask"                          : 1,
    "max-height"                    : "<length> | <percentage> | <content-sizing> | none",
    "max-width"                     : "<length> | <percentage> | <content-sizing> | none",
    "min-height"                    : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats",
    "min-width"                     : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats",
    "move-to"                       : 1,

    //N
    "nav-down"                      : 1,
    "nav-index"                     : 1,
    "nav-left"                      : 1,
    "nav-right"                     : 1,
    "nav-up"                        : 1,

    //O
    "object-fit"                    : "fill | contain | cover | none | scale-down",
    "object-position"               : "<position>",
    "opacity"                       : "<opacity-value>",
    "order"                         : "<integer>",
    "-webkit-order"                 : "<integer>",
    "orphans"                       : "<integer>",
    "outline"                       : 1,
    "outline-color"                 : "<color> | invert",
    "outline-offset"                : 1,
    "outline-style"                 : "<border-style>",
    "outline-width"                 : "<border-width>",
    "overflow"                      : "visible | hidden | scroll | auto",
    "overflow-style"                : 1,
    "overflow-wrap"                 : "normal | break-word",
    "overflow-x"                    : 1,
    "overflow-y"                    : 1,

    //P
    "padding"                       : "<padding-width>{1,4}",
    "padding-bottom"                : "<padding-width>",
    "padding-left"                  : "<padding-width>",
    "padding-right"                 : "<padding-width>",
    "padding-top"                   : "<padding-width>",
    "page"                          : 1,
    "page-break-after"              : "auto | always | avoid | left | right",
    "page-break-before"             : "auto | always | avoid | left | right",
    "page-break-inside"             : "auto | avoid",
    "page-policy"                   : 1,
    "pause"                         : 1,
    "pause-after"                   : 1,
    "pause-before"                  : 1,
    "perspective"                   : 1,
    "perspective-origin"            : 1,
    "phonemes"                      : 1,
    "pitch"                         : 1,
    "pitch-range"                   : 1,
    "play-during"                   : 1,
    "pointer-events"                : "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all",
    "position"                      : "static | relative | absolute | fixed",
    "presentation-level"            : 1,
    "punctuation-trim"              : 1,

    //Q
    "quotes"                        : 1,

    //R
    "rendering-intent"              : 1,
    "resize"                        : 1,
    "rest"                          : 1,
    "rest-after"                    : 1,
    "rest-before"                   : 1,
    "richness"                      : 1,
    "right"                         : "<margin-width>",
    "rotation"                      : 1,
    "rotation-point"                : 1,
    "ruby-align"                    : 1,
    "ruby-overhang"                 : 1,
    "ruby-position"                 : 1,
    "ruby-span"                     : 1,

    //S
    "shape-rendering"               : "auto | optimizeSpeed | crispEdges | geometricPrecision",
    "size"                          : 1,
    "speak"                         : "normal | none | spell-out",
    "speak-header"                  : "once | always",
    "speak-numeral"                 : "digits | continuous",
    "speak-punctuation"             : "code | none",
    "speech-rate"                   : 1,
    "src"                           : 1,
    "stop-color"                    : 1,
    "stop-opacity"                  : "<opacity-value>",
    "stress"                        : 1,
    "string-set"                    : 1,
    "stroke"                        : "<paint>",
    "stroke-dasharray"              : "none | <dasharray>",
    "stroke-dashoffset"             : "<percentage> | <length>",
    "stroke-linecap"                : "butt | round | square",
    "stroke-linejoin"               : "miter | round | bevel",
    "stroke-miterlimit"             : "<miterlimit>",
    "stroke-opacity"                : "<opacity-value>",
    "stroke-width"                  : "<percentage> | <length>",

    "table-layout"                  : "auto | fixed",
    "tab-size"                      : "<integer> | <length>",
    "target"                        : 1,
    "target-name"                   : 1,
    "target-new"                    : 1,
    "target-position"               : 1,
    "text-align"                    : "left | right | center | justify | match-parent | start | end",
    "text-align-last"               : 1,
    "text-anchor"                   : "start | middle | end",
    "text-decoration"               : "<text-decoration>",
    "text-emphasis"                 : 1,
    "text-height"                   : 1,
    "text-indent"                   : "<length> | <percentage>",
    "text-justify"                  : "auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida",
    "text-outline"                  : 1,
    "text-overflow"                 : 1,
    "text-rendering"                : "auto | optimizeSpeed | optimizeLegibility | geometricPrecision",
    "text-shadow"                   : 1,
    "text-transform"                : "capitalize | uppercase | lowercase | none",
    "text-wrap"                     : "normal | none | avoid",
    "top"                           : "<margin-width>",
    "-ms-touch-action"              : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation",
    "touch-action"                  : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation",
    "transform"                     : 1,
    "transform-origin"              : 1,
    "transform-style"               : 1,
    "transition"                    : 1,
    "transition-delay"              : 1,
    "transition-duration"           : 1,
    "transition-property"           : 1,
    "transition-timing-function"    : 1,

    //U
    "unicode-bidi"                  : "normal | embed | isolate | bidi-override | isolate-override | plaintext",
    "user-modify"                   : "read-only | read-write | write-only",
    "user-select"                   : "none | text | toggle | element | elements | all",

    //V
    "vertical-align"                : "auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length>",
    "visibility"                    : "visible | hidden | collapse",
    "voice-balance"                 : 1,
    "voice-duration"                : 1,
    "voice-family"                  : 1,
    "voice-pitch"                   : 1,
    "voice-pitch-range"             : 1,
    "voice-rate"                    : 1,
    "voice-stress"                  : 1,
    "voice-volume"                  : 1,
    "volume"                        : 1,

    //W
    "white-space"                   : "normal | pre | nowrap | pre-wrap | pre-line | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap",   // https://perishablepress.com/wrapping-content/
    "white-space-collapse"          : 1,
    "widows"                        : "<integer>",
    "width"                         : "<length> | <percentage> | <content-sizing> | auto",
    "will-change"                   : "<will-change>",
    "word-break"                    : "normal | keep-all | break-all",
    "word-spacing"                  : "<length> | normal",
    "word-wrap"                     : "normal | break-word",
    "writing-mode"                  : "horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb",

    //Z
    "z-index"                       : "<integer> | auto",
    "zoom"                          : "<number> | <percentage> | normal"
};

},{}],8:[function(require,module,exports){
"use strict";

module.exports = PropertyName;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a selector combinator (whitespace, +, >).
 * @namespace parserlib.css
 * @class PropertyName
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {String} text The text representation of the unit.
 * @param {String} hack The type of IE hack applied ("*", "_", or null).
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function PropertyName(text, hack, line, col) {

    SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_NAME_TYPE);

    /**
     * The type of IE hack applied ("*", "_", or null).
     * @type String
     * @property hack
     */
    this.hack = hack;

}

PropertyName.prototype = new SyntaxUnit();
PropertyName.prototype.constructor = PropertyName;
PropertyName.prototype.toString = function() {
    return (this.hack ? this.hack : "") + this.text;
};

},{"../util/SyntaxUnit":26,"./Parser":6}],9:[function(require,module,exports){
"use strict";

module.exports = PropertyValue;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a single part of a CSS property value, meaning that it represents
 * just everything single part between ":" and ";". If there are multiple values
 * separated by commas, this type represents just one of the values.
 * @param {String[]} parts An array of value parts making up this value.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 * @namespace parserlib.css
 * @class PropertyValue
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 */
function PropertyValue(parts, line, col) {

    SyntaxUnit.call(this, parts.join(" "), line, col, Parser.PROPERTY_VALUE_TYPE);

    /**
     * The parts that make up the selector.
     * @type Array
     * @property parts
     */
    this.parts = parts;

}

PropertyValue.prototype = new SyntaxUnit();
PropertyValue.prototype.constructor = PropertyValue;


},{"../util/SyntaxUnit":26,"./Parser":6}],10:[function(require,module,exports){
"use strict";

module.exports = PropertyValueIterator;

/**
 * A utility class that allows for easy iteration over the various parts of a
 * property value.
 * @param {parserlib.css.PropertyValue} value The property value to iterate over.
 * @namespace parserlib.css
 * @class PropertyValueIterator
 * @constructor
 */
function PropertyValueIterator(value) {

    /**
     * Iterator value
     * @type int
     * @property _i
     * @private
     */
    this._i = 0;

    /**
     * The parts that make up the value.
     * @type Array
     * @property _parts
     * @private
     */
    this._parts = value.parts;

    /**
     * Keeps track of bookmarks along the way.
     * @type Array
     * @property _marks
     * @private
     */
    this._marks = [];

    /**
     * Holds the original property value.
     * @type parserlib.css.PropertyValue
     * @property value
     */
    this.value = value;

}

/**
 * Returns the total number of parts in the value.
 * @return {int} The total number of parts in the value.
 * @method count
 */
PropertyValueIterator.prototype.count = function() {
    return this._parts.length;
};

/**
 * Indicates if the iterator is positioned at the first item.
 * @return {Boolean} True if positioned at first item, false if not.
 * @method isFirst
 */
PropertyValueIterator.prototype.isFirst = function() {
    return this._i === 0;
};

/**
 * Indicates if there are more parts of the property value.
 * @return {Boolean} True if there are more parts, false if not.
 * @method hasNext
 */
PropertyValueIterator.prototype.hasNext = function() {
    return this._i < this._parts.length;
};

/**
 * Marks the current spot in the iteration so it can be restored to
 * later on.
 * @return {void}
 * @method mark
 */
PropertyValueIterator.prototype.mark = function() {
    this._marks.push(this._i);
};

/**
 * Returns the next part of the property value or null if there is no next
 * part. Does not move the internal counter forward.
 * @return {parserlib.css.PropertyValuePart} The next part of the property value or null if there is no next
 * part.
 * @method peek
 */
PropertyValueIterator.prototype.peek = function(count) {
    return this.hasNext() ? this._parts[this._i + (count || 0)] : null;
};

/**
 * Returns the next part of the property value or null if there is no next
 * part.
 * @return {parserlib.css.PropertyValuePart} The next part of the property value or null if there is no next
 * part.
 * @method next
 */
PropertyValueIterator.prototype.next = function() {
    return this.hasNext() ? this._parts[this._i++] : null;
};

/**
 * Returns the previous part of the property value or null if there is no
 * previous part.
 * @return {parserlib.css.PropertyValuePart} The previous part of the
 * property value or null if there is no previous part.
 * @method previous
 */
PropertyValueIterator.prototype.previous = function() {
    return this._i > 0 ? this._parts[--this._i] : null;
};

/**
 * Restores the last saved bookmark.
 * @return {void}
 * @method restore
 */
PropertyValueIterator.prototype.restore = function() {
    if (this._marks.length) {
        this._i = this._marks.pop();
    }
};

/**
 * Drops the last saved bookmark.
 * @return {void}
 * @method drop
 */
PropertyValueIterator.prototype.drop = function() {
    this._marks.pop();
};

},{}],11:[function(require,module,exports){
"use strict";

module.exports = PropertyValuePart;

var SyntaxUnit = require("../util/SyntaxUnit");

var Colors = require("./Colors");
var Parser = require("./Parser");
var Tokens = require("./Tokens");

/**
 * Represents a single part of a CSS property value, meaning that it represents
 * just one part of the data between ":" and ";".
 * @param {String} text The text representation of the unit.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 * @namespace parserlib.css
 * @class PropertyValuePart
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 */
function PropertyValuePart(text, line, col, optionalHint) {
    var hint = optionalHint || {};

    SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_VALUE_PART_TYPE);

    /**
     * Indicates the type of value unit.
     * @type String
     * @property type
     */
    this.type = "unknown";

    //figure out what type of data it is

    var temp;

    //it is a measurement?
    if (/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)) {  //dimension
        this.type = "dimension";
        this.value = +RegExp.$1;
        this.units = RegExp.$2;

        //try to narrow down
        switch (this.units.toLowerCase()) {

            case "em":
            case "rem":
            case "ex":
            case "px":
            case "cm":
            case "mm":
            case "in":
            case "pt":
            case "pc":
            case "ch":
            case "vh":
            case "vw":
            case "vmax":
            case "vmin":
                this.type = "length";
                break;

            case "fr":
                this.type = "grid";
                break;

            case "deg":
            case "rad":
            case "grad":
                this.type = "angle";
                break;

            case "ms":
            case "s":
                this.type = "time";
                break;

            case "hz":
            case "khz":
                this.type = "frequency";
                break;

            case "dpi":
            case "dpcm":
                this.type = "resolution";
                break;

            //default

        }

    } else if (/^([+\-]?[\d\.]+)%$/i.test(text)) {  //percentage
        this.type = "percentage";
        this.value = +RegExp.$1;
    } else if (/^([+\-]?\d+)$/i.test(text)) {  //integer
        this.type = "integer";
        this.value = +RegExp.$1;
    } else if (/^([+\-]?[\d\.]+)$/i.test(text)) {  //number
        this.type = "number";
        this.value = +RegExp.$1;

    } else if (/^#([a-f0-9]{3,6})/i.test(text)) {  //hexcolor
        this.type = "color";
        temp = RegExp.$1;
        if (temp.length === 3) {
            this.red    = parseInt(temp.charAt(0)+temp.charAt(0), 16);
            this.green  = parseInt(temp.charAt(1)+temp.charAt(1), 16);
            this.blue   = parseInt(temp.charAt(2)+temp.charAt(2), 16);
        } else {
            this.red    = parseInt(temp.substring(0, 2), 16);
            this.green  = parseInt(temp.substring(2, 4), 16);
            this.blue   = parseInt(temp.substring(4, 6), 16);
        }
    } else if (/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)) { //rgb() color with absolute numbers
        this.type   = "color";
        this.red    = +RegExp.$1;
        this.green  = +RegExp.$2;
        this.blue   = +RegExp.$3;
    } else if (/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { //rgb() color with percentages
        this.type   = "color";
        this.red    = +RegExp.$1 * 255 / 100;
        this.green  = +RegExp.$2 * 255 / 100;
        this.blue   = +RegExp.$3 * 255 / 100;
    } else if (/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //rgba() color with absolute numbers
        this.type   = "color";
        this.red    = +RegExp.$1;
        this.green  = +RegExp.$2;
        this.blue   = +RegExp.$3;
        this.alpha  = +RegExp.$4;
    } else if (/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //rgba() color with percentages
        this.type   = "color";
        this.red    = +RegExp.$1 * 255 / 100;
        this.green  = +RegExp.$2 * 255 / 100;
        this.blue   = +RegExp.$3 * 255 / 100;
        this.alpha  = +RegExp.$4;
    } else if (/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { //hsl()
        this.type   = "color";
        this.hue    = +RegExp.$1;
        this.saturation = +RegExp.$2 / 100;
        this.lightness  = +RegExp.$3 / 100;
    } else if (/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //hsla() color with percentages
        this.type   = "color";
        this.hue    = +RegExp.$1;
        this.saturation = +RegExp.$2 / 100;
        this.lightness  = +RegExp.$3 / 100;
        this.alpha  = +RegExp.$4;
    } else if (/^url\(("([^\\"]|\\.)*")\)/i.test(text)) { //URI
        // generated by TokenStream.readURI, so always double-quoted.
        this.type   = "uri";
        this.uri    = PropertyValuePart.parseString(RegExp.$1);
    } else if (/^([^\(]+)\(/i.test(text)) {
        this.type   = "function";
        this.name   = RegExp.$1;
        this.value  = text;
    } else if (/^"([^\n\r\f\\"]|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*"/i.test(text)) {    //double-quoted string
        this.type   = "string";
        this.value  = PropertyValuePart.parseString(text);
    } else if (/^'([^\n\r\f\\']|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*'/i.test(text)) {    //single-quoted string
        this.type   = "string";
        this.value  = PropertyValuePart.parseString(text);
    } else if (Colors[text.toLowerCase()]) {  //named color
        this.type   = "color";
        temp        = Colors[text.toLowerCase()].substring(1);
        this.red    = parseInt(temp.substring(0, 2), 16);
        this.green  = parseInt(temp.substring(2, 4), 16);
        this.blue   = parseInt(temp.substring(4, 6), 16);
    } else if (/^[,\/]$/.test(text)) {
        this.type   = "operator";
        this.value  = text;
    } else if (/^-?[a-z_\u00A0-\uFFFF][a-z0-9\-_\u00A0-\uFFFF]*$/i.test(text)) {
        this.type   = "identifier";
        this.value  = text;
    }

    // There can be ambiguity with escape sequences in identifiers, as
    // well as with "color" parts which are also "identifiers", so record
    // an explicit hint when the token generating this PropertyValuePart
    // was an identifier.
    this.wasIdent = Boolean(hint.ident);

}

PropertyValuePart.prototype = new SyntaxUnit();
PropertyValuePart.prototype.constructor = PropertyValuePart;

/**
 * Helper method to parse a CSS string.
 */
PropertyValuePart.parseString = function(str) {
    str = str.slice(1, -1); // Strip surrounding single/double quotes
    var replacer = function(match, esc) {
        if (/^(\n|\r\n|\r|\f)$/.test(esc)) {
            return "";
        }
        var m = /^[0-9a-f]{1,6}/i.exec(esc);
        if (m) {
            var codePoint = parseInt(m[0], 16);
            if (String.fromCodePoint) {
                return String.fromCodePoint(codePoint);
            } else {
                // XXX No support for surrogates on old JavaScript engines.
                return String.fromCharCode(codePoint);
            }
        }
        return esc;
    };
    return str.replace(/\\(\r\n|[^\r0-9a-f]|[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)/ig,
                       replacer);
};

/**
 * Helper method to serialize a CSS string.
 */
PropertyValuePart.serializeString = function(value) {
    var replacer = function(match, c) {
        if (c === "\"") {
            return "\\" + c;
        }
        var cp = String.codePointAt ? String.codePointAt(0) :
            // We only escape non-surrogate chars, so using charCodeAt
            // is harmless here.
            String.charCodeAt(0);
        return "\\" + cp.toString(16) + " ";
    };
    return "\"" + value.replace(/["\r\n\f]/g, replacer) + "\"";
};

/**
 * Create a new syntax unit based solely on the given token.
 * Convenience method for creating a new syntax unit when
 * it represents a single token instead of multiple.
 * @param {Object} token The token object to represent.
 * @return {parserlib.css.PropertyValuePart} The object representing the token.
 * @static
 * @method fromToken
 */
PropertyValuePart.fromToken = function(token) {
    var part = new PropertyValuePart(token.value, token.startLine, token.startCol, {
        // Tokens can have escaped characters that would fool the type
        // identification in the PropertyValuePart constructor, so pass
        // in a hint if this was an identifier.
        ident: token.type === Tokens.IDENT
    });
    return part;
};

},{"../util/SyntaxUnit":26,"./Colors":1,"./Parser":6,"./Tokens":18}],12:[function(require,module,exports){
"use strict";

var Pseudos = module.exports = {
    __proto__:       null,
    ":first-letter": 1,
    ":first-line":   1,
    ":before":       1,
    ":after":        1
};

Pseudos.ELEMENT = 1;
Pseudos.CLASS = 2;

Pseudos.isElement = function(pseudo) {
    return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] === Pseudos.ELEMENT;
};

},{}],13:[function(require,module,exports){
"use strict";

module.exports = Selector;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");
var Specificity = require("./Specificity");

/**
 * Represents an entire single selector, including all parts but not
 * including multiple selectors (those separated by commas).
 * @namespace parserlib.css
 * @class Selector
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {Array} parts Array of selectors parts making up this selector.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function Selector(parts, line, col) {

    SyntaxUnit.call(this, parts.join(" "), line, col, Parser.SELECTOR_TYPE);

    /**
     * The parts that make up the selector.
     * @type Array
     * @property parts
     */
    this.parts = parts;

    /**
     * The specificity of the selector.
     * @type parserlib.css.Specificity
     * @property specificity
     */
    this.specificity = Specificity.calculate(this);

}

Selector.prototype = new SyntaxUnit();
Selector.prototype.constructor = Selector;


},{"../util/SyntaxUnit":26,"./Parser":6,"./Specificity":16}],14:[function(require,module,exports){
"use strict";

module.exports = SelectorPart;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a single part of a selector string, meaning a single set of
 * element name and modifiers. This does not include combinators such as
 * spaces, +, >, etc.
 * @namespace parserlib.css
 * @class SelectorPart
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {String} elementName The element name in the selector or null
 *      if there is no element name.
 * @param {Array} modifiers Array of individual modifiers for the element.
 *      May be empty if there are none.
 * @param {String} text The text representation of the unit.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function SelectorPart(elementName, modifiers, text, line, col) {

    SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_PART_TYPE);

    /**
     * The tag name of the element to which this part
     * of the selector affects.
     * @type String
     * @property elementName
     */
    this.elementName = elementName;

    /**
     * The parts that come after the element name, such as class names, IDs,
     * pseudo classes/elements, etc.
     * @type Array
     * @property modifiers
     */
    this.modifiers = modifiers;

}

SelectorPart.prototype = new SyntaxUnit();
SelectorPart.prototype.constructor = SelectorPart;


},{"../util/SyntaxUnit":26,"./Parser":6}],15:[function(require,module,exports){
"use strict";

module.exports = SelectorSubPart;

var SyntaxUnit = require("../util/SyntaxUnit");

var Parser = require("./Parser");

/**
 * Represents a selector modifier string, meaning a class name, element name,
 * element ID, pseudo rule, etc.
 * @namespace parserlib.css
 * @class SelectorSubPart
 * @extends parserlib.util.SyntaxUnit
 * @constructor
 * @param {String} text The text representation of the unit.
 * @param {String} type The type of selector modifier.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function SelectorSubPart(text, type, line, col) {

    SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_SUB_PART_TYPE);

    /**
     * The type of modifier.
     * @type String
     * @property type
     */
    this.type = type;

    /**
     * Some subparts have arguments, this represents them.
     * @type Array
     * @property args
     */
    this.args = [];

}

SelectorSubPart.prototype = new SyntaxUnit();
SelectorSubPart.prototype.constructor = SelectorSubPart;


},{"../util/SyntaxUnit":26,"./Parser":6}],16:[function(require,module,exports){
"use strict";

module.exports = Specificity;

var Pseudos = require("./Pseudos");
var SelectorPart = require("./SelectorPart");

/**
 * Represents a selector's specificity.
 * @namespace parserlib.css
 * @class Specificity
 * @constructor
 * @param {int} a Should be 1 for inline styles, zero for stylesheet styles
 * @param {int} b Number of ID selectors
 * @param {int} c Number of classes and pseudo classes
 * @param {int} d Number of element names and pseudo elements
 */
function Specificity(a, b, c, d) {
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
}

Specificity.prototype = {
    constructor: Specificity,

    /**
     * Compare this specificity to another.
     * @param {Specificity} other The other specificity to compare to.
     * @return {int} -1 if the other specificity is larger, 1 if smaller, 0 if equal.
     * @method compare
     */
    compare: function(other) {
        var comps = ["a", "b", "c", "d"],
            i, len;

        for (i=0, len=comps.length; i < len; i++) {
            if (this[comps[i]] < other[comps[i]]) {
                return -1;
            } else if (this[comps[i]] > other[comps[i]]) {
                return 1;
            }
        }

        return 0;
    },

    /**
     * Creates a numeric value for the specificity.
     * @return {int} The numeric value for the specificity.
     * @method valueOf
     */
    valueOf: function() {
        return (this.a * 1000) + (this.b * 100) + (this.c * 10) + this.d;
    },

    /**
     * Returns a string representation for specificity.
     * @return {String} The string representation of specificity.
     * @method toString
     */
    toString: function() {
        return this.a + "," + this.b + "," + this.c + "," + this.d;
    }

};

/**
 * Calculates the specificity of the given selector.
 * @param {parserlib.css.Selector} The selector to calculate specificity for.
 * @return {parserlib.css.Specificity} The specificity of the selector.
 * @static
 * @method calculate
 */
Specificity.calculate = function(selector) {

    var i, len,
        part,
        b=0, c=0, d=0;

    function updateValues(part) {

        var i, j, len, num,
            elementName = part.elementName ? part.elementName.text : "",
            modifier;

        if (elementName && elementName.charAt(elementName.length-1) !== "*") {
            d++;
        }

        for (i=0, len=part.modifiers.length; i < len; i++) {
            modifier = part.modifiers[i];
            switch (modifier.type) {
                case "class":
                case "attribute":
                    c++;
                    break;

                case "id":
                    b++;
                    break;

                case "pseudo":
                    if (Pseudos.isElement(modifier.text)) {
                        d++;
                    } else {
                        c++;
                    }
                    break;

                case "not":
                    for (j=0, num=modifier.args.length; j < num; j++) {
                        updateValues(modifier.args[j]);
                    }
            }
        }
    }

    for (i=0, len=selector.parts.length; i < len; i++) {
        part = selector.parts[i];

        if (part instanceof SelectorPart) {
            updateValues(part);
        }
    }

    return new Specificity(0, b, c, d);
};

},{"./Pseudos":12,"./SelectorPart":14}],17:[function(require,module,exports){
"use strict";

module.exports = TokenStream;

var TokenStreamBase = require("../util/TokenStreamBase");

var PropertyValuePart = require("./PropertyValuePart");
var Tokens = require("./Tokens");

var h = /^[0-9a-fA-F]$/,
    nonascii = /^[\u00A0-\uFFFF]$/,
    nl = /\n|\r\n|\r|\f/,
    whitespace = /\u0009|\u000a|\u000c|\u000d|\u0020/;

//-----------------------------------------------------------------------------
// Helper functions
//-----------------------------------------------------------------------------


function isHexDigit(c) {
    return c !== null && h.test(c);
}

function isDigit(c) {
    return c !== null && /\d/.test(c);
}

function isWhitespace(c) {
    return c !== null && whitespace.test(c);
}

function isNewLine(c) {
    return c !== null && nl.test(c);
}

function isNameStart(c) {
    return c !== null && /[a-z_\u00A0-\uFFFF\\]/i.test(c);
}

function isNameChar(c) {
    return c !== null && (isNameStart(c) || /[0-9\-\\]/.test(c));
}

function isIdentStart(c) {
    return c !== null && (isNameStart(c) || /\-\\/.test(c));
}

function mix(receiver, supplier) {
    for (var prop in supplier) {
        if (Object.prototype.hasOwnProperty.call(supplier, prop)) {
            receiver[prop] = supplier[prop];
        }
    }
    return receiver;
}

//-----------------------------------------------------------------------------
// CSS Token Stream
//-----------------------------------------------------------------------------


/**
 * A token stream that produces CSS tokens.
 * @param {String|Reader} input The source of text to tokenize.
 * @constructor
 * @class TokenStream
 * @namespace parserlib.css
 */
function TokenStream(input) {
    TokenStreamBase.call(this, input, Tokens);
}

TokenStream.prototype = mix(new TokenStreamBase(), {

    /**
     * Overrides the TokenStreamBase method of the same name
     * to produce CSS tokens.
     * @return {Object} A token object representing the next token.
     * @method _getToken
     * @private
     */
    _getToken: function() {

        var c,
            reader = this._reader,
            token   = null,
            startLine   = reader.getLine(),
            startCol    = reader.getCol();

        c = reader.read();


        while (c) {
            switch (c) {

                /*
                 * Potential tokens:
                 * - COMMENT
                 * - SLASH
                 * - CHAR
                 */
                case "/":

                    if (reader.peek() === "*") {
                        token = this.commentToken(c, startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - DASHMATCH
                 * - INCLUDES
                 * - PREFIXMATCH
                 * - SUFFIXMATCH
                 * - SUBSTRINGMATCH
                 * - CHAR
                 */
                case "|":
                case "~":
                case "^":
                case "$":
                case "*":
                    if (reader.peek() === "=") {
                        token = this.comparisonToken(c, startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - STRING
                 * - INVALID
                 */
                case "\"":
                case "'":
                    token = this.stringToken(c, startLine, startCol);
                    break;

                /*
                 * Potential tokens:
                 * - HASH
                 * - CHAR
                 */
                case "#":
                    if (isNameChar(reader.peek())) {
                        token = this.hashToken(c, startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - DOT
                 * - NUMBER
                 * - DIMENSION
                 * - PERCENTAGE
                 */
                case ".":
                    if (isDigit(reader.peek())) {
                        token = this.numberToken(c, startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - CDC
                 * - MINUS
                 * - NUMBER
                 * - DIMENSION
                 * - PERCENTAGE
                 */
                case "-":
                    if (reader.peek() === "-") {  //could be closing HTML-style comment
                        token = this.htmlCommentEndToken(c, startLine, startCol);
                    } else if (isNameStart(reader.peek())) {
                        token = this.identOrFunctionToken(c, startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - IMPORTANT_SYM
                 * - CHAR
                 */
                case "!":
                    token = this.importantToken(c, startLine, startCol);
                    break;

                /*
                 * Any at-keyword or CHAR
                 */
                case "@":
                    token = this.atRuleToken(c, startLine, startCol);
                    break;

                /*
                 * Potential tokens:
                 * - NOT
                 * - CHAR
                 */
                case ":":
                    token = this.notToken(c, startLine, startCol);
                    break;

                /*
                 * Potential tokens:
                 * - CDO
                 * - CHAR
                 */
                case "<":
                    token = this.htmlCommentStartToken(c, startLine, startCol);
                    break;

                /*
                 * Potential tokens:
                 * - IDENT
                 * - CHAR
                 */
                case "\\":
                    if (/[^\r\n\f]/.test(reader.peek())) {
                        token = this.identOrFunctionToken(this.readEscape(c, true), startLine, startCol);
                    } else {
                        token = this.charToken(c, startLine, startCol);
                    }
                    break;

                /*
                 * Potential tokens:
                 * - UNICODE_RANGE
                 * - URL
                 * - CHAR
                 */
                case "U":
                case "u":
                    if (reader.peek() === "+") {
                        token = this.unicodeRangeToken(c, startLine, startCol);
                        break;
                    }
                    /* falls through */
                default:

                    /*
                     * Potential tokens:
                     * - NUMBER
                     * - DIMENSION
                     * - LENGTH
                     * - FREQ
                     * - TIME
                     * - EMS
                     * - EXS
                     * - ANGLE
                     */
                    if (isDigit(c)) {
                        token = this.numberToken(c, startLine, startCol);
                    } else

                    /*
                     * Potential tokens:
                     * - S
                     */
                    if (isWhitespace(c)) {
                        token = this.whitespaceToken(c, startLine, startCol);
                    } else

                    /*
                     * Potential tokens:
                     * - IDENT
                     */
                    if (isIdentStart(c)) {
                        token = this.identOrFunctionToken(c, startLine, startCol);
                    } else {
                       /*
                        * Potential tokens:
                        * - CHAR
                        * - PLUS
                        */
                        token = this.charToken(c, startLine, startCol);
                    }

            }

            //make sure this token is wanted
            //TODO: check channel
            break;
        }

        if (!token && c === null) {
            token = this.createToken(Tokens.EOF, null, startLine, startCol);
        }

        return token;
    },

    //-------------------------------------------------------------------------
    // Methods to create tokens
    //-------------------------------------------------------------------------

    /**
     * Produces a token based on available data and the current
     * reader position information. This method is called by other
     * private methods to create tokens and is never called directly.
     * @param {int} tt The token type.
     * @param {String} value The text value of the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @param {Object} options (Optional) Specifies a channel property
     *      to indicate that a different channel should be scanned
     *      and/or a hide property indicating that the token should
     *      be hidden.
     * @return {Object} A token object.
     * @method createToken
     */
    createToken: function(tt, value, startLine, startCol, options) {
        var reader = this._reader;
        options = options || {};

        return {
            value:      value,
            type:       tt,
            channel:    options.channel,
            endChar:    options.endChar,
            hide:       options.hide || false,
            startLine:  startLine,
            startCol:   startCol,
            endLine:    reader.getLine(),
            endCol:     reader.getCol()
        };
    },

    //-------------------------------------------------------------------------
    // Methods to create specific tokens
    //-------------------------------------------------------------------------

    /**
     * Produces a token for any at-rule. If the at-rule is unknown, then
     * the token is for a single "@" character.
     * @param {String} first The first character for the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method atRuleToken
     */
    atRuleToken: function(first, startLine, startCol) {
        var rule    = first,
            reader  = this._reader,
            tt      = Tokens.CHAR,
            ident;

        /*
         * First, mark where we are. There are only four @ rules,
         * so anything else is really just an invalid token.
         * Basically, if this doesn't match one of the known @
         * rules, just return '@' as an unknown token and allow
         * parsing to continue after that point.
         */
        reader.mark();

        //try to find the at-keyword
        ident = this.readName();
        rule = first + ident;
        tt = Tokens.type(rule.toLowerCase());

        //if it's not valid, use the first character only and reset the reader
        if (tt === Tokens.CHAR || tt === Tokens.UNKNOWN) {
            if (rule.length > 1) {
                tt = Tokens.UNKNOWN_SYM;
            } else {
                tt = Tokens.CHAR;
                rule = first;
                reader.reset();
            }
        }

        return this.createToken(tt, rule, startLine, startCol);
    },

    /**
     * Produces a character token based on the given character
     * and location in the stream. If there's a special (non-standard)
     * token name, this is used; otherwise CHAR is used.
     * @param {String} c The character for the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method charToken
     */
    charToken: function(c, startLine, startCol) {
        var tt = Tokens.type(c);
        var opts = {};

        if (tt === -1) {
            tt = Tokens.CHAR;
        } else {
            opts.endChar = Tokens[tt].endChar;
        }

        return this.createToken(tt, c, startLine, startCol, opts);
    },

    /**
     * Produces a character token based on the given character
     * and location in the stream. If there's a special (non-standard)
     * token name, this is used; otherwise CHAR is used.
     * @param {String} first The first character for the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method commentToken
     */
    commentToken: function(first, startLine, startCol) {
        var comment = this.readComment(first);

        return this.createToken(Tokens.COMMENT, comment, startLine, startCol);
    },

    /**
     * Produces a comparison token based on the given character
     * and location in the stream. The next character must be
     * read and is already known to be an equals sign.
     * @param {String} c The character for the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method comparisonToken
     */
    comparisonToken: function(c, startLine, startCol) {
        var reader  = this._reader,
            comparison  = c + reader.read(),
            tt      = Tokens.type(comparison) || Tokens.CHAR;

        return this.createToken(tt, comparison, startLine, startCol);
    },

    /**
     * Produces a hash token based on the specified information. The
     * first character provided is the pound sign (#) and then this
     * method reads a name afterward.
     * @param {String} first The first character (#) in the hash name.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method hashToken
     */
    hashToken: function(first, startLine, startCol) {
        var name    = this.readName(first);

        return this.createToken(Tokens.HASH, name, startLine, startCol);
    },

    /**
     * Produces a CDO or CHAR token based on the specified information. The
     * first character is provided and the rest is read by the function to determine
     * the correct token to create.
     * @param {String} first The first character in the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method htmlCommentStartToken
     */
    htmlCommentStartToken: function(first, startLine, startCol) {
        var reader      = this._reader,
            text        = first;

        reader.mark();
        text += reader.readCount(3);

        if (text === "<!--") {
            return this.createToken(Tokens.CDO, text, startLine, startCol);
        } else {
            reader.reset();
            return this.charToken(first, startLine, startCol);
        }
    },

    /**
     * Produces a CDC or CHAR token based on the specified information. The
     * first character is provided and the rest is read by the function to determine
     * the correct token to create.
     * @param {String} first The first character in the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method htmlCommentEndToken
     */
    htmlCommentEndToken: function(first, startLine, startCol) {
        var reader      = this._reader,
            text        = first;

        reader.mark();
        text += reader.readCount(2);

        if (text === "-->") {
            return this.createToken(Tokens.CDC, text, startLine, startCol);
        } else {
            reader.reset();
            return this.charToken(first, startLine, startCol);
        }
    },

    /**
     * Produces an IDENT or FUNCTION token based on the specified information. The
     * first character is provided and the rest is read by the function to determine
     * the correct token to create.
     * @param {String} first The first character in the identifier.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method identOrFunctionToken
     */
    identOrFunctionToken: function(first, startLine, startCol) {
        var reader  = this._reader,
            ident   = this.readName(first),
            tt      = Tokens.IDENT,
            uriFns  = ["url(", "url-prefix(", "domain("],
            uri;

        //if there's a left paren immediately after, it's a URI or function
        if (reader.peek() === "(") {
            ident += reader.read();
            if (uriFns.indexOf(ident.toLowerCase()) > -1) {
                reader.mark();
                uri = this.readURI(ident);
                if (uri === null) {
                    //didn't find a valid URL or there's no closing paren
                    reader.reset();
                    tt = Tokens.FUNCTION;
                } else {
                    tt = Tokens.URI;
                    ident = uri;
                }
            } else {
                tt = Tokens.FUNCTION;
            }
        } else if (reader.peek() === ":") {  //might be an IE function

            //IE-specific functions always being with progid:
            if (ident.toLowerCase() === "progid") {
                ident += reader.readTo("(");
                tt = Tokens.IE_FUNCTION;
            }
        }

        return this.createToken(tt, ident, startLine, startCol);
    },

    /**
     * Produces an IMPORTANT_SYM or CHAR token based on the specified information. The
     * first character is provided and the rest is read by the function to determine
     * the correct token to create.
     * @param {String} first The first character in the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method importantToken
     */
    importantToken: function(first, startLine, startCol) {
        var reader      = this._reader,
            important   = first,
            tt          = Tokens.CHAR,
            temp,
            c;

        reader.mark();
        c = reader.read();

        while (c) {

            //there can be a comment in here
            if (c === "/") {

                //if the next character isn't a star, then this isn't a valid !important token
                if (reader.peek() !== "*") {
                    break;
                } else {
                    temp = this.readComment(c);
                    if (temp === "") {    //broken!
                        break;
                    }
                }
            } else if (isWhitespace(c)) {
                important += c + this.readWhitespace();
            } else if (/i/i.test(c)) {
                temp = reader.readCount(8);
                if (/mportant/i.test(temp)) {
                    important += c + temp;
                    tt = Tokens.IMPORTANT_SYM;

                }
                break;  //we're done
            } else {
                break;
            }

            c = reader.read();
        }

        if (tt === Tokens.CHAR) {
            reader.reset();
            return this.charToken(first, startLine, startCol);
        } else {
            return this.createToken(tt, important, startLine, startCol);
        }


    },

    /**
     * Produces a NOT or CHAR token based on the specified information. The
     * first character is provided and the rest is read by the function to determine
     * the correct token to create.
     * @param {String} first The first character in the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method notToken
     */
    notToken: function(first, startLine, startCol) {
        var reader      = this._reader,
            text        = first;

        reader.mark();
        text += reader.readCount(4);

        if (text.toLowerCase() === ":not(") {
            return this.createToken(Tokens.NOT, text, startLine, startCol);
        } else {
            reader.reset();
            return this.charToken(first, startLine, startCol);
        }
    },

    /**
     * Produces a number token based on the given character
     * and location in the stream. This may return a token of
     * NUMBER, EMS, EXS, LENGTH, ANGLE, TIME, FREQ, DIMENSION,
     * or PERCENTAGE.
     * @param {String} first The first character for the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method numberToken
     */
    numberToken: function(first, startLine, startCol) {
        var reader  = this._reader,
            value   = this.readNumber(first),
            ident,
            tt      = Tokens.NUMBER,
            c       = reader.peek();

        if (isIdentStart(c)) {
            ident = this.readName(reader.read());
            value += ident;

            if (/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(ident)) {
                tt = Tokens.LENGTH;
            } else if (/^deg|^rad$|^grad$/i.test(ident)) {
                tt = Tokens.ANGLE;
            } else if (/^ms$|^s$/i.test(ident)) {
                tt = Tokens.TIME;
            } else if (/^hz$|^khz$/i.test(ident)) {
                tt = Tokens.FREQ;
            } else if (/^dpi$|^dpcm$/i.test(ident)) {
                tt = Tokens.RESOLUTION;
            } else {
                tt = Tokens.DIMENSION;
            }

        } else if (c === "%") {
            value += reader.read();
            tt = Tokens.PERCENTAGE;
        }

        return this.createToken(tt, value, startLine, startCol);
    },

    /**
     * Produces a string token based on the given character
     * and location in the stream. Since strings may be indicated
     * by single or double quotes, a failure to match starting
     * and ending quotes results in an INVALID token being generated.
     * The first character in the string is passed in and then
     * the rest are read up to and including the final quotation mark.
     * @param {String} first The first character in the string.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method stringToken
     */
    stringToken: function(first, startLine, startCol) {
        var delim   = first,
            string  = first,
            reader  = this._reader,
            tt      = Tokens.STRING,
            c       = reader.read(),
            i;

        while (c) {
            string += c;

            if (c === "\\") {
                c = reader.read();
                if (c === null) {
                    break; // premature EOF after backslash
                } else if (/[^\r\n\f0-9a-f]/i.test(c)) {
                    // single-character escape
                    string += c;
                } else {
                    // read up to six hex digits
                    for (i=0; isHexDigit(c) && i<6; i++) {
                        string += c;
                        c = reader.read();
                    }
                    // swallow trailing newline or space
                    if (c === "\r" && reader.peek() === "\n") {
                        string += c;
                        c = reader.read();
                    }
                    if (isWhitespace(c)) {
                        string += c;
                    } else {
                        // This character is null or not part of the escape;
                        // jump back to the top to process it.
                        continue;
                    }
                }
            } else if (c === delim) {
                break; // delimiter found.
            } else if (isNewLine(reader.peek())) {
                // newline without an escapement: it's an invalid string
                tt = Tokens.INVALID;
                break;
            }
            c = reader.read();
        }

        //if c is null, that means we're out of input and the string was never closed
        if (c === null) {
            tt = Tokens.INVALID;
        }

        return this.createToken(tt, string, startLine, startCol);
    },

    unicodeRangeToken: function(first, startLine, startCol) {
        var reader  = this._reader,
            value   = first,
            temp,
            tt      = Tokens.CHAR;

        //then it should be a unicode range
        if (reader.peek() === "+") {
            reader.mark();
            value += reader.read();
            value += this.readUnicodeRangePart(true);

            //ensure there's an actual unicode range here
            if (value.length === 2) {
                reader.reset();
            } else {

                tt = Tokens.UNICODE_RANGE;

                //if there's a ? in the first part, there can't be a second part
                if (value.indexOf("?") === -1) {

                    if (reader.peek() === "-") {
                        reader.mark();
                        temp = reader.read();
                        temp += this.readUnicodeRangePart(false);

                        //if there's not another value, back up and just take the first
                        if (temp.length === 1) {
                            reader.reset();
                        } else {
                            value += temp;
                        }
                    }

                }
            }
        }

        return this.createToken(tt, value, startLine, startCol);
    },

    /**
     * Produces a S token based on the specified information. Since whitespace
     * may have multiple characters, this consumes all whitespace characters
     * into a single token.
     * @param {String} first The first character in the token.
     * @param {int} startLine The beginning line for the character.
     * @param {int} startCol The beginning column for the character.
     * @return {Object} A token object.
     * @method whitespaceToken
     */
    whitespaceToken: function(first, startLine, startCol) {
        var value   = first + this.readWhitespace();
        return this.createToken(Tokens.S, value, startLine, startCol);
    },


    //-------------------------------------------------------------------------
    // Methods to read values from the string stream
    //-------------------------------------------------------------------------

    readUnicodeRangePart: function(allowQuestionMark) {
        var reader  = this._reader,
            part = "",
            c       = reader.peek();

        //first read hex digits
        while (isHexDigit(c) && part.length < 6) {
            reader.read();
            part += c;
            c = reader.peek();
        }

        //then read question marks if allowed
        if (allowQuestionMark) {
            while (c === "?" && part.length < 6) {
                reader.read();
                part += c;
                c = reader.peek();
            }
        }

        //there can't be any other characters after this point

        return part;
    },

    readWhitespace: function() {
        var reader  = this._reader,
            whitespace = "",
            c       = reader.peek();

        while (isWhitespace(c)) {
            reader.read();
            whitespace += c;
            c = reader.peek();
        }

        return whitespace;
    },
    readNumber: function(first) {
        var reader  = this._reader,
            number  = first,
            hasDot  = (first === "."),
            c       = reader.peek();


        while (c) {
            if (isDigit(c)) {
                number += reader.read();
            } else if (c === ".") {
                if (hasDot) {
                    break;
                } else {
                    hasDot = true;
                    number += reader.read();
                }
            } else {
                break;
            }

            c = reader.peek();
        }

        return number;
    },

    // returns null w/o resetting reader if string is invalid.
    readString: function() {
        var token = this.stringToken(this._reader.read(), 0, 0);
        return token.type === Tokens.INVALID ? null : token.value;
    },

    // returns null w/o resetting reader if URI is invalid.
    readURI: function(first) {
        var reader  = this._reader,
            uri     = first,
            inner   = "",
            c       = reader.peek();

        //skip whitespace before
        while (c && isWhitespace(c)) {
            reader.read();
            c = reader.peek();
        }

        //it's a string
        if (c === "'" || c === "\"") {
            inner = this.readString();
            if (inner !== null) {
                inner = PropertyValuePart.parseString(inner);
            }
        } else {
            inner = this.readUnquotedURL();
        }

        c = reader.peek();

        //skip whitespace after
        while (c && isWhitespace(c)) {
            reader.read();
            c = reader.peek();
        }

        //if there was no inner value or the next character isn't closing paren, it's not a URI
        if (inner === null || c !== ")") {
            uri = null;
        } else {
            // Ensure argument to URL is always double-quoted
            // (This simplifies later processing in PropertyValuePart.)
            uri += PropertyValuePart.serializeString(inner) + reader.read();
        }

        return uri;
    },
    // This method never fails, although it may return an empty string.
    readUnquotedURL: function(first) {
        var reader  = this._reader,
            url     = first || "",
            c;

        for (c = reader.peek(); c; c = reader.peek()) {
            // Note that the grammar at
            // https://www.w3.org/TR/CSS2/grammar.html#scanner
            // incorrectly includes the backslash character in the
            // `url` production, although it is correctly omitted in
            // the `baduri1` production.
            if (nonascii.test(c) || /^[\-!#$%&*-\[\]-~]$/.test(c)) {
                url += c;
                reader.read();
            } else if (c === "\\") {
                if (/^[^\r\n\f]$/.test(reader.peek(2))) {
                    url += this.readEscape(reader.read(), true);
                } else {
                    break; // bad escape sequence.
                }
            } else {
                break; // bad character
            }
        }

        return url;
    },

    readName: function(first) {
        var reader  = this._reader,
            ident   = first || "",
            c;

        for (c = reader.peek(); c; c = reader.peek()) {
            if (c === "\\") {
                if (/^[^\r\n\f]$/.test(reader.peek(2))) {
                    ident += this.readEscape(reader.read(), true);
                } else {
                    // Bad escape sequence.
                    break;
                }
            } else if (isNameChar(c)) {
                ident += reader.read();
            } else {
                break;
            }
        }

        return ident;
    },

    readEscape: function(first, unescape) {
        var reader  = this._reader,
            cssEscape = first || "",
            i       = 0,
            c       = reader.peek();

        if (isHexDigit(c)) {
            do {
                cssEscape += reader.read();
                c = reader.peek();
            } while (c && isHexDigit(c) && ++i < 6);
        }

        if (cssEscape.length === 1) {
            if (/^[^\r\n\f0-9a-f]$/.test(c)) {
                reader.read();
                if (unescape) {
                    return c;
                }
            } else {
                // We should never get here (readName won't call readEscape
                // if the escape sequence is bad).
                throw new Error("Bad escape sequence.");
            }
        } else if (c === "\r") {
            reader.read();
            if (reader.peek() === "\n") {
                c += reader.read();
            }
        } else if (/^[ \t\n\f]$/.test(c)) {
            reader.read();
        } else {
            c = "";
        }

        if (unescape) {
            var cp = parseInt(cssEscape.slice(first.length), 16);
            return String.fromCodePoint ? String.fromCodePoint(cp) :
                String.fromCharCode(cp);
        }
        return cssEscape + c;
    },

    readComment: function(first) {
        var reader  = this._reader,
            comment = first || "",
            c       = reader.read();

        if (c === "*") {
            while (c) {
                comment += c;

                //look for end of comment
                if (comment.length > 2 && c === "*" && reader.peek() === "/") {
                    comment += reader.read();
                    break;
                }

                c = reader.read();
            }

            return comment;
        } else {
            return "";
        }

    }
});


},{"../util/TokenStreamBase":27,"./PropertyValuePart":11,"./Tokens":18}],18:[function(require,module,exports){
"use strict";

var Tokens = module.exports = [

    /*
     * The following token names are defined in CSS3 Grammar: https://www.w3.org/TR/css3-syntax/#lexical
     */

    // HTML-style comments
    { name: "CDO" },
    { name: "CDC" },

    // ignorables
    { name: "S", whitespace: true/*, channel: "ws"*/ },
    { name: "COMMENT", comment: true, hide: true, channel: "comment" },

    // attribute equality
    { name: "INCLUDES", text: "~=" },
    { name: "DASHMATCH", text: "|=" },
    { name: "PREFIXMATCH", text: "^=" },
    { name: "SUFFIXMATCH", text: "$=" },
    { name: "SUBSTRINGMATCH", text: "*=" },

    // identifier types
    { name: "STRING" },
    { name: "IDENT" },
    { name: "HASH" },

    // at-keywords
    { name: "IMPORT_SYM", text: "@import" },
    { name: "PAGE_SYM", text: "@page" },
    { name: "MEDIA_SYM", text: "@media" },
    { name: "FONT_FACE_SYM", text: "@font-face" },
    { name: "CHARSET_SYM", text: "@charset" },
    { name: "NAMESPACE_SYM", text: "@namespace" },
    { name: "SUPPORTS_SYM", text: "@supports" },
    { name: "VIEWPORT_SYM", text: ["@viewport", "@-ms-viewport", "@-o-viewport"] },
    { name: "DOCUMENT_SYM", text: ["@document", "@-moz-document"] },
    { name: "UNKNOWN_SYM" },
    //{ name: "ATKEYWORD"},

    // CSS3 animations
    { name: "KEYFRAMES_SYM", text: [ "@keyframes", "@-webkit-keyframes", "@-moz-keyframes", "@-o-keyframes" ] },

    // important symbol
    { name: "IMPORTANT_SYM" },

    // measurements
    { name: "LENGTH" },
    { name: "ANGLE" },
    { name: "TIME" },
    { name: "FREQ" },
    { name: "DIMENSION" },
    { name: "PERCENTAGE" },
    { name: "NUMBER" },

    // functions
    { name: "URI" },
    { name: "FUNCTION" },

    // Unicode ranges
    { name: "UNICODE_RANGE" },

    /*
     * The following token names are defined in CSS3 Selectors: https://www.w3.org/TR/css3-selectors/#selector-syntax
     */

    // invalid string
    { name: "INVALID" },

    // combinators
    { name: "PLUS", text: "+" },
    { name: "GREATER", text: ">" },
    { name: "COMMA", text: "," },
    { name: "TILDE", text: "~" },

    // modifier
    { name: "NOT" },

    /*
     * Defined in CSS3 Paged Media
     */
    { name: "TOPLEFTCORNER_SYM", text: "@top-left-corner" },
    { name: "TOPLEFT_SYM", text: "@top-left" },
    { name: "TOPCENTER_SYM", text: "@top-center" },
    { name: "TOPRIGHT_SYM", text: "@top-right" },
    { name: "TOPRIGHTCORNER_SYM", text: "@top-right-corner" },
    { name: "BOTTOMLEFTCORNER_SYM", text: "@bottom-left-corner" },
    { name: "BOTTOMLEFT_SYM", text: "@bottom-left" },
    { name: "BOTTOMCENTER_SYM", text: "@bottom-center" },
    { name: "BOTTOMRIGHT_SYM", text: "@bottom-right" },
    { name: "BOTTOMRIGHTCORNER_SYM", text: "@bottom-right-corner" },
    { name: "LEFTTOP_SYM", text: "@left-top" },
    { name: "LEFTMIDDLE_SYM", text: "@left-middle" },
    { name: "LEFTBOTTOM_SYM", text: "@left-bottom" },
    { name: "RIGHTTOP_SYM", text: "@right-top" },
    { name: "RIGHTMIDDLE_SYM", text: "@right-middle" },
    { name: "RIGHTBOTTOM_SYM", text: "@right-bottom" },

    /*
     * The following token names are defined in CSS3 Media Queries: https://www.w3.org/TR/css3-mediaqueries/#syntax
     */
    /*{ name: "MEDIA_ONLY", state: "media"},
    { name: "MEDIA_NOT", state: "media"},
    { name: "MEDIA_AND", state: "media"},*/
    { name: "RESOLUTION", state: "media" },

    /*
     * The following token names are not defined in any CSS specification but are used by the lexer.
     */

    // not a real token, but useful for stupid IE filters
    { name: "IE_FUNCTION" },

    // part of CSS3 grammar but not the Flex code
    { name: "CHAR" },

    // TODO: Needed?
    // Not defined as tokens, but might as well be
    {
        name: "PIPE",
        text: "|"
    },
    {
        name: "SLASH",
        text: "/"
    },
    {
        name: "MINUS",
        text: "-"
    },
    {
        name: "STAR",
        text: "*"
    },

    {
        name: "LBRACE",
        endChar: "}",
        text: "{"
    },
    {
        name: "RBRACE",
        text: "}"
    },
    {
        name: "LBRACKET",
        endChar: "]",
        text: "["
    },
    {
        name: "RBRACKET",
        text: "]"
    },
    {
        name: "EQUALS",
        text: "="
    },
    {
        name: "COLON",
        text: ":"
    },
    {
        name: "SEMICOLON",
        text: ";"
    },
    {
        name: "LPAREN",
        endChar: ")",
        text: "("
    },
    {
        name: "RPAREN",
        text: ")"
    },
    {
        name: "DOT",
        text: "."
    }
];

(function() {
    var nameMap = [],
        typeMap = Object.create(null);

    Tokens.UNKNOWN = -1;
    Tokens.unshift({ name:"EOF" });
    for (var i=0, len = Tokens.length; i < len; i++) {
        nameMap.push(Tokens[i].name);
        Tokens[Tokens[i].name] = i;
        if (Tokens[i].text) {
            if (Tokens[i].text instanceof Array) {
                for (var j=0; j < Tokens[i].text.length; j++) {
                    typeMap[Tokens[i].text[j]] = i;
                }
            } else {
                typeMap[Tokens[i].text] = i;
            }
        }
    }

    Tokens.name = function(tt) {
        return nameMap[tt];
    };

    Tokens.type = function(c) {
        return typeMap[c] || -1;
    };
})();

},{}],19:[function(require,module,exports){
"use strict";

/* exported Validation */

var Matcher = require("./Matcher");
var Properties = require("./Properties");
var ValidationTypes = require("./ValidationTypes");
var ValidationError = require("./ValidationError");
var PropertyValueIterator = require("./PropertyValueIterator");

var Validation = module.exports = {

    validate: function(property, value) {

        //normalize name
        var name        = property.toString().toLowerCase(),
            expression  = new PropertyValueIterator(value),
            spec        = Properties[name],
            part;

        if (!spec) {
            if (name.indexOf("-") !== 0) {    //vendor prefixed are ok
                throw new ValidationError("Unknown property '" + property + "'.", property.line, property.col);
            }
        } else if (typeof spec !== "number") {

            // All properties accept some CSS-wide values.
            // https://drafts.csswg.org/css-values-3/#common-keywords
            if (ValidationTypes.isAny(expression, "inherit | initial | unset")) {
                if (expression.hasNext()) {
                    part = expression.next();
                    throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
                }
                return;
            }

            // Property-specific validation.
            this.singleProperty(spec, expression);

        }

    },

    singleProperty: function(types, expression) {

        var result      = false,
            value       = expression.value,
            part;

        result = Matcher.parse(types).match(expression);

        if (!result) {
            if (expression.hasNext() && !expression.isFirst()) {
                part = expression.peek();
                throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
            } else {
                throw new ValidationError("Expected (" + ValidationTypes.describe(types) + ") but found '" + value + "'.", value.line, value.col);
            }
        } else if (expression.hasNext()) {
            part = expression.next();
            throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
        }

    }

};

},{"./Matcher":3,"./Properties":7,"./PropertyValueIterator":10,"./ValidationError":20,"./ValidationTypes":21}],20:[function(require,module,exports){
"use strict";

module.exports = ValidationError;

/**
 * Type to use when a validation error occurs.
 * @class ValidationError
 * @namespace parserlib.util
 * @constructor
 * @param {String} message The error message.
 * @param {int} line The line at which the error occurred.
 * @param {int} col The column at which the error occurred.
 */
function ValidationError(message, line, col) {

    /**
     * The column at which the error occurred.
     * @type int
     * @property col
     */
    this.col = col;

    /**
     * The line at which the error occurred.
     * @type int
     * @property line
     */
    this.line = line;

    /**
     * The text representation of the unit.
     * @type String
     * @property text
     */
    this.message = message;

}

//inherit from Error
ValidationError.prototype = new Error();

},{}],21:[function(require,module,exports){
"use strict";

var ValidationTypes = module.exports;

var Matcher = require("./Matcher");

function copy(to, from) {
    Object.keys(from).forEach(function(prop) {
        to[prop] = from[prop];
    });
}
copy(ValidationTypes, {

    isLiteral: function (part, literals) {
        var text = part.text.toString().toLowerCase(),
            args = literals.split(" | "),
            i, len, found = false;

        for (i=0, len=args.length; i < len && !found; i++) {
            if (args[i].charAt(0) === "<") {
                found = this.simple[args[i]](part);
            } else if (args[i].slice(-2) === "()") {
                found = (part.type === "function" &&
                         part.name === args[i].slice(0, -2));
            } else if (text === args[i].toLowerCase()) {
                found = true;
            }
        }

        return found;
    },

    isSimple: function(type) {
        return Boolean(this.simple[type]);
    },

    isComplex: function(type) {
        return Boolean(this.complex[type]);
    },

    describe: function(type) {
        if (this.complex[type] instanceof Matcher) {
            return this.complex[type].toString(0);
        }
        return type;
    },

    /**
     * Determines if the next part(s) of the given expression
     * are any of the given types.
     */
    isAny: function (expression, types) {
        var args = types.split(" | "),
            i, len, found = false;

        for (i=0, len=args.length; i < len && !found && expression.hasNext(); i++) {
            found = this.isType(expression, args[i]);
        }

        return found;
    },

    /**
     * Determines if the next part(s) of the given expression
     * are one of a group.
     */
    isAnyOfGroup: function(expression, types) {
        var args = types.split(" || "),
            i, len, found = false;

        for (i=0, len=args.length; i < len && !found; i++) {
            found = this.isType(expression, args[i]);
        }

        return found ? args[i-1] : false;
    },

    /**
     * Determines if the next part(s) of the given expression
     * are of a given type.
     */
    isType: function (expression, type) {
        var part = expression.peek(),
            result = false;

        if (type.charAt(0) !== "<") {
            result = this.isLiteral(part, type);
            if (result) {
                expression.next();
            }
        } else if (this.simple[type]) {
            result = this.simple[type](part);
            if (result) {
                expression.next();
            }
        } else if (this.complex[type] instanceof Matcher) {
            result = this.complex[type].match(expression);
        } else {
            result = this.complex[type](expression);
        }

        return result;
    },


    simple: {
        __proto__: null,

        "<absolute-size>":
            "xx-small | x-small | small | medium | large | x-large | xx-large",

        "<animateable-feature>":
            "scroll-position | contents | <animateable-feature-name>",

        "<animateable-feature-name>": function(part) {
            return this["<ident>"](part) &&
                !/^(unset|initial|inherit|will-change|auto|scroll-position|contents)$/i.test(part);
        },

        "<angle>": function(part) {
            return part.type === "angle";
        },

        "<attachment>": "scroll | fixed | local",

        "<attr>": "attr()",

        // inset() = inset( <shape-arg>{1,4} [round <border-radius>]? )
        // circle() = circle( [<shape-radius>]? [at <position>]? )
        // ellipse() = ellipse( [<shape-radius>{2}]? [at <position>]? )
        // polygon() = polygon( [<fill-rule>,]? [<shape-arg> <shape-arg>]# )
        "<basic-shape>": "inset() | circle() | ellipse() | polygon()",

        "<bg-image>": "<image> | <gradient> | none",

        "<border-style>":
            "none | hidden | dotted | dashed | solid | double | groove | " +
            "ridge | inset | outset",

        "<border-width>": "<length> | thin | medium | thick",

        "<box>": "padding-box | border-box | content-box",

        "<clip-source>": "<uri>",

        "<color>": function(part) {
            return part.type === "color" || String(part) === "transparent" || String(part) === "currentColor";
        },

        // The SVG <color> spec doesn't include "currentColor" or "transparent" as a color.
        "<color-svg>": function(part) {
            return part.type === "color";
        },

        "<content>": "content()",

        // https://www.w3.org/TR/css3-sizing/#width-height-keywords
        "<content-sizing>":
            "fill-available | -moz-available | -webkit-fill-available | " +
            "max-content | -moz-max-content | -webkit-max-content | " +
            "min-content | -moz-min-content | -webkit-min-content | " +
            "fit-content | -moz-fit-content | -webkit-fit-content",

        "<feature-tag-value>": function(part) {
            return part.type === "function" && /^[A-Z0-9]{4}$/i.test(part);
        },

        // custom() isn't actually in the spec
        "<filter-function>":
            "blur() | brightness() | contrast() | custom() | " +
            "drop-shadow() | grayscale() | hue-rotate() | invert() | " +
            "opacity() | saturate() | sepia()",

        "<flex-basis>": "<width>",

        "<flex-direction>": "row | row-reverse | column | column-reverse",

        "<flex-grow>": "<number>",

        "<flex-shrink>": "<number>",

        "<flex-wrap>": "nowrap | wrap | wrap-reverse",

        "<font-size>":
            "<absolute-size> | <relative-size> | <length> | <percentage>",

        "<font-stretch>":
            "normal | ultra-condensed | extra-condensed | condensed | " +
            "semi-condensed | semi-expanded | expanded | extra-expanded | " +
            "ultra-expanded",

        "<font-style>": "normal | italic | oblique",

        "<font-variant-caps>":
            "small-caps | all-small-caps | petite-caps | all-petite-caps | " +
            "unicase | titling-caps",

        "<font-variant-css21>": "normal | small-caps",

        "<font-weight>":
            "normal | bold | bolder | lighter | " +
            "100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900",

        "<generic-family>":
            "serif | sans-serif | cursive | fantasy | monospace",

        "<geometry-box>": "<shape-box> | fill-box | stroke-box | view-box",

        "<glyph-angle>": function(part) {
            return part.type === "angle" && part.units === "deg";
        },

        "<gradient>": function(part) {
            return part.type === "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(part);
        },

        "<icccolor>":
            "cielab() | cielch() | cielchab() | " +
            "icc-color() | icc-named-color()",

        //any identifier
        "<ident>": function(part) {
            return part.type === "identifier" || part.wasIdent;
        },

        "<ident-not-generic-family>": function(part) {
            return this["<ident>"](part) && !this["<generic-family>"](part);
        },

        "<image>": "<uri>",

        "<integer>": function(part) {
            return part.type === "integer";
        },

        "<length>": function(part) {
            if (part.type === "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(part)) {
                return true;
            } else {
                return part.type === "length" || part.type === "number" || part.type === "integer" || String(part) === "0";
            }
        },

        "<line>": function(part) {
            return part.type === "integer";
        },

        "<line-height>": "<number> | <length> | <percentage> | normal",

        "<margin-width>": "<length> | <percentage> | auto",

        "<miterlimit>": function(part) {
            return this["<number>"](part) && part.value >= 1;
        },

        "<nonnegative-length-or-percentage>": function(part) {
            return (this["<length>"](part) || this["<percentage>"](part)) &&
                (String(part) === "0" || part.type === "function" || (part.value) >= 0);
        },

        "<nonnegative-number-or-percentage>": function(part) {
            return (this["<number>"](part) || this["<percentage>"](part)) &&
                (String(part) === "0" || part.type === "function" || (part.value) >= 0);
        },

        "<number>": function(part) {
            return part.type === "number" || this["<integer>"](part);
        },

        "<opacity-value>": function(part) {
            return this["<number>"](part) && part.value >= 0 && part.value <= 1;
        },

        "<padding-width>": "<nonnegative-length-or-percentage>",

        "<percentage>": function(part) {
            return part.type === "percentage" || String(part) === "0";
        },

        "<relative-size>": "smaller | larger",

        "<shape>": "rect() | inset-rect()",

        "<shape-box>": "<box> | margin-box",

        "<single-animation-direction>":
            "normal | reverse | alternate | alternate-reverse",

        "<single-animation-name>": function(part) {
            return this["<ident>"](part) &&
                /^-?[a-z_][-a-z0-9_]+$/i.test(part) &&
                !/^(none|unset|initial|inherit)$/i.test(part);
        },

        "<string>": function(part) {
            return part.type === "string";
        },

        "<time>": function(part) {
            return part.type === "time";
        },

        "<uri>": function(part) {
            return part.type === "uri";
        },

        "<width>": "<margin-width>"
    },

    complex: {
        __proto__: null,

        "<azimuth>":
            "<angle>" +
            " | " +
            "[ [ left-side | far-left | left | center-left | center | " +
            "center-right | right | far-right | right-side ] || behind ]" +
            " | "+
            "leftwards | rightwards",

        "<bg-position>": "<position>#",

        "<bg-size>":
            "[ <length> | <percentage> | auto ]{1,2} | cover | contain",

        "<border-image-slice>":
        // [<number> | <percentage>]{1,4} && fill?
        // *but* fill can appear between any of the numbers
        Matcher.many([true /* first element is required */],
                     Matcher.cast("<nonnegative-number-or-percentage>"),
                     Matcher.cast("<nonnegative-number-or-percentage>"),
                     Matcher.cast("<nonnegative-number-or-percentage>"),
                     Matcher.cast("<nonnegative-number-or-percentage>"),
                     "fill"),

        "<border-radius>":
            "<nonnegative-length-or-percentage>{1,4} " +
            "[ / <nonnegative-length-or-percentage>{1,4} ]?",

        "<box-shadow>": "none | <shadow>#",

        "<clip-path>": "<basic-shape> || <geometry-box>",

        "<dasharray>":
        // "list of comma and/or white space separated <length>s and
        // <percentage>s".  There is a non-negative constraint.
        Matcher.cast("<nonnegative-length-or-percentage>")
            .braces(1, Infinity, "#", Matcher.cast(",").question()),

        "<family-name>":
            // <string> | <IDENT>+
            "<string> | <ident-not-generic-family> <ident>*",

        "<filter-function-list>": "[ <filter-function> | <uri> ]+",

        // https://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-property
        "<flex>":
            "none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]",

        "<font-family>": "[ <generic-family> | <family-name> ]#",

        "<font-shorthand>":
            "[ <font-style> || <font-variant-css21> || " +
            "<font-weight> || <font-stretch> ]? <font-size> " +
            "[ / <line-height> ]? <font-family>",

        "<font-variant-alternates>":
            // stylistic(<feature-value-name>)
            "stylistic() || " +
            "historical-forms || " +
            // styleset(<feature-value-name> #)
            "styleset() || " +
            // character-variant(<feature-value-name> #)
            "character-variant() || " +
            // swash(<feature-value-name>)
            "swash() || " +
            // ornaments(<feature-value-name>)
            "ornaments() || " +
            // annotation(<feature-value-name>)
            "annotation()",

        "<font-variant-ligatures>":
            // <common-lig-values>
            "[ common-ligatures | no-common-ligatures ] || " +
            // <discretionary-lig-values>
            "[ discretionary-ligatures | no-discretionary-ligatures ] || " +
            // <historical-lig-values>
            "[ historical-ligatures | no-historical-ligatures ] || " +
            // <contextual-alt-values>
            "[ contextual | no-contextual ]",

        "<font-variant-numeric>":
            // <numeric-figure-values>
            "[ lining-nums | oldstyle-nums ] || " +
            // <numeric-spacing-values>
            "[ proportional-nums | tabular-nums ] || " +
            // <numeric-fraction-values>
            "[ diagonal-fractions | stacked-fractions ] || " +
            "ordinal || slashed-zero",

        "<font-variant-east-asian>":
            // <east-asian-variant-values>
            "[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ] || " +
            // <east-asian-width-values>
            "[ full-width | proportional-width ] || " +
            "ruby",

        // Note that <color> here is "as defined in the SVG spec", which
        // is more restrictive that the <color> defined in the CSS spec.
        // none | currentColor | <color> [<icccolor>]? |
        // <funciri> [ none | currentColor | <color> [<icccolor>]? ]?
        "<paint>": "<paint-basic> | <uri> <paint-basic>?",

        // Helper definition for <paint> above.
        "<paint-basic>": "none | currentColor | <color-svg> <icccolor>?",

        "<position>":
            // Because our `alt` combinator is ordered, we need to test these
            // in order from longest possible match to shortest.
            "[ center | [ left | right ] [ <percentage> | <length> ]? ] && " +
            "[ center | [ top | bottom ] [ <percentage> | <length> ]? ]" +
            " | " +
            "[ left | center | right | <percentage> | <length> ] " +
            "[ top | center | bottom | <percentage> | <length> ]" +
            " | " +
            "[ left | center | right | top | bottom | <percentage> | <length> ]",

        "<repeat-style>":
            "repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}",

        "<shadow>":
        //inset? && [ <length>{2,4} && <color>? ]
        Matcher.many([true /* length is required */],
                     Matcher.cast("<length>").braces(2, 4), "inset", "<color>"),

        "<text-decoration>":
            "none | [ underline || overline || line-through || blink ]",

        "<will-change>":
            "auto | <animateable-feature>#",

        "<x-one-radius>":
            //[ <length> | <percentage> ] [ <length> | <percentage> ]?
            "[ <length> | <percentage> ]{1,2}"
    }
});

Object.keys(ValidationTypes.simple).forEach(function(nt) {
    var rule = ValidationTypes.simple[nt];
    if (typeof rule === "string") {
        ValidationTypes.simple[nt] = function(part) {
            return ValidationTypes.isLiteral(part, rule);
        };
    }
});

Object.keys(ValidationTypes.complex).forEach(function(nt) {
    var rule = ValidationTypes.complex[nt];
    if (typeof rule === "string") {
        ValidationTypes.complex[nt] = Matcher.parse(rule);
    }
});

// Because this is defined relative to other complex validation types,
// we need to define it *after* the rest of the types are initialized.
ValidationTypes.complex["<font-variant>"] =
    Matcher.oror({ expand: "<font-variant-ligatures>" },
                 { expand: "<font-variant-alternates>" },
                 "<font-variant-caps>",
                 { expand: "<font-variant-numeric>" },
                 { expand: "<font-variant-east-asian>" });

},{"./Matcher":3}],22:[function(require,module,exports){
"use strict";

module.exports = {
    Colors            : require("./Colors"),
    Combinator        : require("./Combinator"),
    Parser            : require("./Parser"),
    PropertyName      : require("./PropertyName"),
    PropertyValue     : require("./PropertyValue"),
    PropertyValuePart : require("./PropertyValuePart"),
    Matcher           : require("./Matcher"),
    MediaFeature      : require("./MediaFeature"),
    MediaQuery        : require("./MediaQuery"),
    Selector          : require("./Selector"),
    SelectorPart      : require("./SelectorPart"),
    SelectorSubPart   : require("./SelectorSubPart"),
    Specificity       : require("./Specificity"),
    TokenStream       : require("./TokenStream"),
    Tokens            : require("./Tokens"),
    ValidationError   : require("./ValidationError")
};

},{"./Colors":1,"./Combinator":2,"./Matcher":3,"./MediaFeature":4,"./MediaQuery":5,"./Parser":6,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./Specificity":16,"./TokenStream":17,"./Tokens":18,"./ValidationError":20}],23:[function(require,module,exports){
"use strict";

module.exports = EventTarget;

/**
 * A generic base to inherit from for any object
 * that needs event handling.
 * @class EventTarget
 * @constructor
 */
function EventTarget() {

    /**
     * The array of listeners for various events.
     * @type Object
     * @property _listeners
     * @private
     */
    this._listeners = Object.create(null);
}

EventTarget.prototype = {

    //restore constructor
    constructor: EventTarget,

    /**
     * Adds a listener for a given event type.
     * @param {String} type The type of event to add a listener for.
     * @param {Function} listener The function to call when the event occurs.
     * @return {void}
     * @method addListener
     */
    addListener: function(type, listener) {
        if (!this._listeners[type]) {
            this._listeners[type] = [];
        }

        this._listeners[type].push(listener);
    },

    /**
     * Fires an event based on the passed-in object.
     * @param {Object|String} event An object with at least a 'type' attribute
     *      or a string indicating the event name.
     * @return {void}
     * @method fire
     */
    fire: function(event) {
        if (typeof event === "string") {
            event = { type: event };
        }
        if (typeof event.target !== "undefined") {
            event.target = this;
        }

        if (typeof event.type === "undefined") {
            throw new Error("Event object missing 'type' property.");
        }

        if (this._listeners[event.type]) {

            //create a copy of the array and use that so listeners can't chane
            var listeners = this._listeners[event.type].concat();
            for (var i=0, len=listeners.length; i < len; i++) {
                listeners[i].call(this, event);
            }
        }
    },

    /**
     * Removes a listener for a given event type.
     * @param {String} type The type of event to remove a listener from.
     * @param {Function} listener The function to remove from the event.
     * @return {void}
     * @method removeListener
     */
    removeListener: function(type, listener) {
        if (this._listeners[type]) {
            var listeners = this._listeners[type];
            for (var i=0, len=listeners.length; i < len; i++) {
                if (listeners[i] === listener) {
                    listeners.splice(i, 1);
                    break;
                }
            }


        }
    }
};

},{}],24:[function(require,module,exports){
"use strict";

module.exports = StringReader;

/**
 * Convenient way to read through strings.
 * @namespace parserlib.util
 * @class StringReader
 * @constructor
 * @param {String} text The text to read.
 */
function StringReader(text) {

    /**
     * The input text with line endings normalized.
     * @property _input
     * @type String
     * @private
     */
    this._input = text.replace(/(\r\n?|\n)/g, "\n");


    /**
     * The row for the character to be read next.
     * @property _line
     * @type int
     * @private
     */
    this._line = 1;


    /**
     * The column for the character to be read next.
     * @property _col
     * @type int
     * @private
     */
    this._col = 1;

    /**
     * The index of the character in the input to be read next.
     * @property _cursor
     * @type int
     * @private
     */
    this._cursor = 0;
}

StringReader.prototype = {

    // restore constructor
    constructor: StringReader,

    //-------------------------------------------------------------------------
    // Position info
    //-------------------------------------------------------------------------

    /**
     * Returns the column of the character to be read next.
     * @return {int} The column of the character to be read next.
     * @method getCol
     */
    getCol: function() {
        return this._col;
    },

    /**
     * Returns the row of the character to be read next.
     * @return {int} The row of the character to be read next.
     * @method getLine
     */
    getLine: function() {
        return this._line;
    },

    /**
     * Determines if you're at the end of the input.
     * @return {Boolean} True if there's no more input, false otherwise.
     * @method eof
     */
    eof: function() {
        return this._cursor === this._input.length;
    },

    //-------------------------------------------------------------------------
    // Basic reading
    //-------------------------------------------------------------------------

    /**
     * Reads the next character without advancing the cursor.
     * @param {int} count How many characters to look ahead (default is 1).
     * @return {String} The next character or null if there is no next character.
     * @method peek
     */
    peek: function(count) {
        var c = null;
        count = typeof count === "undefined" ? 1 : count;

        // if we're not at the end of the input...
        if (this._cursor < this._input.length) {

            // get character and increment cursor and column
            c = this._input.charAt(this._cursor + count - 1);
        }

        return c;
    },

    /**
     * Reads the next character from the input and adjusts the row and column
     * accordingly.
     * @return {String} The next character or null if there is no next character.
     * @method read
     */
    read: function() {
        var c = null;

        // if we're not at the end of the input...
        if (this._cursor < this._input.length) {

            // if the last character was a newline, increment row count
            // and reset column count
            if (this._input.charAt(this._cursor) === "\n") {
                this._line++;
                this._col=1;
            } else {
                this._col++;
            }

            // get character and increment cursor and column
            c = this._input.charAt(this._cursor++);
        }

        return c;
    },

    //-------------------------------------------------------------------------
    // Misc
    //-------------------------------------------------------------------------

    /**
     * Saves the current location so it can be returned to later.
     * @method mark
     * @return {void}
     */
    mark: function() {
        this._bookmark = {
            cursor: this._cursor,
            line:   this._line,
            col:    this._col
        };
    },

    reset: function() {
        if (this._bookmark) {
            this._cursor = this._bookmark.cursor;
            this._line = this._bookmark.line;
            this._col = this._bookmark.col;
            delete this._bookmark;
        }
    },

    //-------------------------------------------------------------------------
    // Advanced reading
    //-------------------------------------------------------------------------

    /**
     * Reads up to and including the given string. Throws an error if that
     * string is not found.
     * @param {String} pattern The string to read.
     * @return {String} The string when it is found.
     * @throws Error when the string pattern is not found.
     * @method readTo
     */
    readTo: function(pattern) {

        var buffer = "",
            c;

        /*
         * First, buffer must be the same length as the pattern.
         * Then, buffer must end with the pattern or else reach the
         * end of the input.
         */
        while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) !== buffer.length - pattern.length) {
            c = this.read();
            if (c) {
                buffer += c;
            } else {
                throw new Error("Expected \"" + pattern + "\" at line " + this._line  + ", col " + this._col + ".");
            }
        }

        return buffer;

    },

    /**
     * Reads characters while each character causes the given
     * filter function to return true. The function is passed
     * in each character and either returns true to continue
     * reading or false to stop.
     * @param {Function} filter The function to read on each character.
     * @return {String} The string made up of all characters that passed the
     *      filter check.
     * @method readWhile
     */
    readWhile: function(filter) {

        var buffer = "",
            c = this.peek();

        while (c !== null && filter(c)) {
            buffer += this.read();
            c = this.peek();
        }

        return buffer;

    },

    /**
     * Reads characters that match either text or a regular expression and
     * returns those characters. If a match is found, the row and column
     * are adjusted; if no match is found, the reader's state is unchanged.
     * reading or false to stop.
     * @param {String|RegExp} matcher If a string, then the literal string
     *      value is searched for. If a regular expression, then any string
     *      matching the pattern is search for.
     * @return {String} The string made up of all characters that matched or
     *      null if there was no match.
     * @method readMatch
     */
    readMatch: function(matcher) {

        var source = this._input.substring(this._cursor),
            value = null;

        // if it's a string, just do a straight match
        if (typeof matcher === "string") {
            if (source.slice(0, matcher.length) === matcher) {
                value = this.readCount(matcher.length);
            }
        } else if (matcher instanceof RegExp) {
            if (matcher.test(source)) {
                value = this.readCount(RegExp.lastMatch.length);
            }
        }

        return value;
    },


    /**
     * Reads a given number of characters. If the end of the input is reached,
     * it reads only the remaining characters and does not throw an error.
     * @param {int} count The number of characters to read.
     * @return {String} The string made up the read characters.
     * @method readCount
     */
    readCount: function(count) {
        var buffer = "";

        while (count--) {
            buffer += this.read();
        }

        return buffer;
    }

};

},{}],25:[function(require,module,exports){
"use strict";

module.exports = SyntaxError;

/**
 * Type to use when a syntax error occurs.
 * @class SyntaxError
 * @namespace parserlib.util
 * @constructor
 * @param {String} message The error message.
 * @param {int} line The line at which the error occurred.
 * @param {int} col The column at which the error occurred.
 */
function SyntaxError(message, line, col) {
    Error.call(this);
    this.name = this.constructor.name;

    /**
     * The column at which the error occurred.
     * @type int
     * @property col
     */
    this.col = col;

    /**
     * The line at which the error occurred.
     * @type int
     * @property line
     */
    this.line = line;

    /**
     * The text representation of the unit.
     * @type String
     * @property text
     */
    this.message = message;

}

//inherit from Error
SyntaxError.prototype = Object.create(Error.prototype); // jshint ignore:line
SyntaxError.prototype.constructor = SyntaxError; // jshint ignore:line

},{}],26:[function(require,module,exports){
"use strict";

module.exports = SyntaxUnit;

/**
 * Base type to represent a single syntactic unit.
 * @class SyntaxUnit
 * @namespace parserlib.util
 * @constructor
 * @param {String} text The text of the unit.
 * @param {int} line The line of text on which the unit resides.
 * @param {int} col The column of text on which the unit resides.
 */
function SyntaxUnit(text, line, col, type) {


    /**
     * The column of text on which the unit resides.
     * @type int
     * @property col
     */
    this.col = col;

    /**
     * The line of text on which the unit resides.
     * @type int
     * @property line
     */
    this.line = line;

    /**
     * The text representation of the unit.
     * @type String
     * @property text
     */
    this.text = text;

    /**
     * The type of syntax unit.
     * @type int
     * @property type
     */
    this.type = type;
}

/**
 * Create a new syntax unit based solely on the given token.
 * Convenience method for creating a new syntax unit when
 * it represents a single token instead of multiple.
 * @param {Object} token The token object to represent.
 * @return {parserlib.util.SyntaxUnit} The object representing the token.
 * @static
 * @method fromToken
 */
SyntaxUnit.fromToken = function(token) {
    return new SyntaxUnit(token.value, token.startLine, token.startCol);
};

SyntaxUnit.prototype = {

    //restore constructor
    constructor: SyntaxUnit,

    /**
     * Returns the text representation of the unit.
     * @return {String} The text representation of the unit.
     * @method valueOf
     */
    valueOf: function() {
        return this.toString();
    },

    /**
     * Returns the text representation of the unit.
     * @return {String} The text representation of the unit.
     * @method toString
     */
    toString: function() {
        return this.text;
    }

};

},{}],27:[function(require,module,exports){
"use strict";

module.exports = TokenStreamBase;

var StringReader = require("./StringReader");
var SyntaxError = require("./SyntaxError");

/**
 * Generic TokenStream providing base functionality.
 * @class TokenStreamBase
 * @namespace parserlib.util
 * @constructor
 * @param {String|StringReader} input The text to tokenize or a reader from
 *      which to read the input.
 */
function TokenStreamBase(input, tokenData) {

    /**
     * The string reader for easy access to the text.
     * @type StringReader
     * @property _reader
     * @private
     */
    this._reader = new StringReader(input ? input.toString() : "");

    /**
     * Token object for the last consumed token.
     * @type Token
     * @property _token
     * @private
     */
    this._token = null;

    /**
     * The array of token information.
     * @type Array
     * @property _tokenData
     * @private
     */
    this._tokenData = tokenData;

    /**
     * Lookahead token buffer.
     * @type Array
     * @property _lt
     * @private
     */
    this._lt = [];

    /**
     * Lookahead token buffer index.
     * @type int
     * @property _ltIndex
     * @private
     */
    this._ltIndex = 0;

    this._ltIndexCache = [];
}

/**
 * Accepts an array of token information and outputs
 * an array of token data containing key-value mappings
 * and matching functions that the TokenStream needs.
 * @param {Array} tokens An array of token descriptors.
 * @return {Array} An array of processed token data.
 * @method createTokenData
 * @static
 */
TokenStreamBase.createTokenData = function(tokens) {

    var nameMap     = [],
        typeMap     = Object.create(null),
        tokenData     = tokens.concat([]),
        i            = 0,
        len            = tokenData.length+1;

    tokenData.UNKNOWN = -1;
    tokenData.unshift({ name:"EOF" });

    for (; i < len; i++) {
        nameMap.push(tokenData[i].name);
        tokenData[tokenData[i].name] = i;
        if (tokenData[i].text) {
            typeMap[tokenData[i].text] = i;
        }
    }

    tokenData.name = function(tt) {
        return nameMap[tt];
    };

    tokenData.type = function(c) {
        return typeMap[c];
    };

    return tokenData;
};

TokenStreamBase.prototype = {

    //restore constructor
    constructor: TokenStreamBase,

    //-------------------------------------------------------------------------
    // Matching methods
    //-------------------------------------------------------------------------

    /**
     * Determines if the next token matches the given token type.
     * If so, that token is consumed; if not, the token is placed
     * back onto the token stream. You can pass in any number of
     * token types and this will return true if any of the token
     * types is found.
     * @param {int|int[]} tokenTypes Either a single token type or an array of
     *      token types that the next token might be. If an array is passed,
     *      it's assumed that the token can be any of these.
     * @param {variant} channel (Optional) The channel to read from. If not
     *      provided, reads from the default (unnamed) channel.
     * @return {Boolean} True if the token type matches, false if not.
     * @method match
     */
    match: function(tokenTypes, channel) {

        //always convert to an array, makes things easier
        if (!(tokenTypes instanceof Array)) {
            tokenTypes = [tokenTypes];
        }

        var tt  = this.get(channel),
            i   = 0,
            len = tokenTypes.length;

        while (i < len) {
            if (tt === tokenTypes[i++]) {
                return true;
            }
        }

        //no match found, put the token back
        this.unget();
        return false;
    },

    /**
     * Determines if the next token matches the given token type.
     * If so, that token is consumed; if not, an error is thrown.
     * @param {int|int[]} tokenTypes Either a single token type or an array of
     *      token types that the next token should be. If an array is passed,
     *      it's assumed that the token must be one of these.
     * @return {void}
     * @method mustMatch
     */
    mustMatch: function(tokenTypes) {

        var token;

        //always convert to an array, makes things easier
        if (!(tokenTypes instanceof Array)) {
            tokenTypes = [tokenTypes];
        }

        if (!this.match.apply(this, arguments)) {
            token = this.LT(1);
            throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
                " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
        }
    },

    //-------------------------------------------------------------------------
    // Consuming methods
    //-------------------------------------------------------------------------

    /**
     * Keeps reading from the token stream until either one of the specified
     * token types is found or until the end of the input is reached.
     * @param {int|int[]} tokenTypes Either a single token type or an array of
     *      token types that the next token should be. If an array is passed,
     *      it's assumed that the token must be one of these.
     * @param {variant} channel (Optional) The channel to read from. If not
     *      provided, reads from the default (unnamed) channel.
     * @return {void}
     * @method advance
     */
    advance: function(tokenTypes, channel) {

        while (this.LA(0) !== 0 && !this.match(tokenTypes, channel)) {
            this.get();
        }

        return this.LA(0);
    },

    /**
     * Consumes the next token from the token stream.
     * @return {int} The token type of the token that was just consumed.
     * @method get
     */
    get: function(channel) {

        var tokenInfo   = this._tokenData,
            i           =0,
            token,
            info;

        //check the lookahead buffer first
        if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length) {

            i++;
            this._token = this._lt[this._ltIndex++];
            info = tokenInfo[this._token.type];

            //obey channels logic
            while ((info.channel !== undefined && channel !== info.channel) &&
                    this._ltIndex < this._lt.length) {
                this._token = this._lt[this._ltIndex++];
                info = tokenInfo[this._token.type];
                i++;
            }

            //here be dragons
            if ((info.channel === undefined || channel === info.channel) &&
                    this._ltIndex <= this._lt.length) {
                this._ltIndexCache.push(i);
                return this._token.type;
            }
        }

        //call token retriever method
        token = this._getToken();

        //if it should be hidden, don't save a token
        if (token.type > -1 && !tokenInfo[token.type].hide) {

            //apply token channel
            token.channel = tokenInfo[token.type].channel;

            //save for later
            this._token = token;
            this._lt.push(token);

            //save space that will be moved (must be done before array is truncated)
            this._ltIndexCache.push(this._lt.length - this._ltIndex + i);

            //keep the buffer under 5 items
            if (this._lt.length > 5) {
                this._lt.shift();
            }

            //also keep the shift buffer under 5 items
            if (this._ltIndexCache.length > 5) {
                this._ltIndexCache.shift();
            }

            //update lookahead index
            this._ltIndex = this._lt.length;
        }

        /*
         * Skip to the next token if:
         * 1. The token type is marked as hidden.
         * 2. The token type has a channel specified and it isn't the current channel.
         */
        info = tokenInfo[token.type];
        if (info &&
                (info.hide ||
                (info.channel !== undefined && channel !== info.channel))) {
            return this.get(channel);
        } else {
            //return just the type
            return token.type;
        }
    },

    /**
     * Looks ahead a certain number of tokens and returns the token type at
     * that position. This will throw an error if you lookahead past the
     * end of input, past the size of the lookahead buffer, or back past
     * the first token in the lookahead buffer.
     * @param {int} The index of the token type to retrieve. 0 for the
     *      current token, 1 for the next, -1 for the previous, etc.
     * @return {int} The token type of the token in the given position.
     * @method LA
     */
    LA: function(index) {
        var total = index,
            tt;
        if (index > 0) {
            //TODO: Store 5 somewhere
            if (index > 5) {
                throw new Error("Too much lookahead.");
            }

            //get all those tokens
            while (total) {
                tt = this.get();
                total--;
            }

            //unget all those tokens
            while (total < index) {
                this.unget();
                total++;
            }
        } else if (index < 0) {

            if (this._lt[this._ltIndex+index]) {
                tt = this._lt[this._ltIndex+index].type;
            } else {
                throw new Error("Too much lookbehind.");
            }

        } else {
            tt = this._token.type;
        }

        return tt;

    },

    /**
     * Looks ahead a certain number of tokens and returns the token at
     * that position. This will throw an error if you lookahead past the
     * end of input, past the size of the lookahead buffer, or back past
     * the first token in the lookahead buffer.
     * @param {int} The index of the token type to retrieve. 0 for the
     *      current token, 1 for the next, -1 for the previous, etc.
     * @return {Object} The token of the token in the given position.
     * @method LA
     */
    LT: function(index) {

        //lookahead first to prime the token buffer
        this.LA(index);

        //now find the token, subtract one because _ltIndex is already at the next index
        return this._lt[this._ltIndex+index-1];
    },

    /**
     * Returns the token type for the next token in the stream without
     * consuming it.
     * @return {int} The token type of the next token in the stream.
     * @method peek
     */
    peek: function() {
        return this.LA(1);
    },

    /**
     * Returns the actual token object for the last consumed token.
     * @return {Token} The token object for the last consumed token.
     * @method token
     */
    token: function() {
        return this._token;
    },

    /**
     * Returns the name of the token for the given token type.
     * @param {int} tokenType The type of token to get the name of.
     * @return {String} The name of the token or "UNKNOWN_TOKEN" for any
     *      invalid token type.
     * @method tokenName
     */
    tokenName: function(tokenType) {
        if (tokenType < 0 || tokenType > this._tokenData.length) {
            return "UNKNOWN_TOKEN";
        } else {
            return this._tokenData[tokenType].name;
        }
    },

    /**
     * Returns the token type value for the given token name.
     * @param {String} tokenName The name of the token whose value should be returned.
     * @return {int} The token type value for the given token name or -1
     *      for an unknown token.
     * @method tokenName
     */
    tokenType: function(tokenName) {
        return this._tokenData[tokenName] || -1;
    },

    /**
     * Returns the last consumed token to the token stream.
     * @method unget
     */
    unget: function() {
        //if (this._ltIndex > -1) {
        if (this._ltIndexCache.length) {
            this._ltIndex -= this._ltIndexCache.pop();//--;
            this._token = this._lt[this._ltIndex - 1];
        } else {
            throw new Error("Too much lookahead.");
        }
    }

};


},{"./StringReader":24,"./SyntaxError":25}],28:[function(require,module,exports){
"use strict";

module.exports = {
    StringReader    : require("./StringReader"),
    SyntaxError     : require("./SyntaxError"),
    SyntaxUnit      : require("./SyntaxUnit"),
    EventTarget     : require("./EventTarget"),
    TokenStreamBase : require("./TokenStreamBase")
};

},{"./EventTarget":23,"./StringReader":24,"./SyntaxError":25,"./SyntaxUnit":26,"./TokenStreamBase":27}],"parserlib":[function(require,module,exports){
"use strict";

module.exports = {
    css  : require("./css"),
    util : require("./util")
};

},{"./css":22,"./util":28}]},{},[]);

return require('parserlib');
})();
var clone = (function() {
'use strict';

/**
 * Clones (copies) an Object using deep copying.
 *
 * This function supports circular references by default, but if you are certain
 * there are no circular references in your object, you can save some CPU time
 * by calling clone(obj, false).
 *
 * Caution: if `circular` is false and `parent` contains circular references,
 * your program may enter an infinite loop and crash.
 *
 * @param `parent` - the object to be cloned
 * @param `circular` - set to true if the object to be cloned may contain
 *    circular references. (optional - true by default)
 * @param `depth` - set to a number if the object is only to be cloned to
 *    a particular depth. (optional - defaults to Infinity)
 * @param `prototype` - sets the prototype to be used when cloning an object.
 *    (optional - defaults to parent prototype).
*/
function clone(parent, circular, depth, prototype) {
  var filter;
  if (typeof circular === 'object') {
    depth = circular.depth;
    prototype = circular.prototype;
    filter = circular.filter;
    circular = circular.circular
  }
  // maintain two arrays for circular references, where corresponding parents
  // and children have the same index
  var allParents = [];
  var allChildren = [];

  var useBuffer = typeof Buffer != 'undefined';

  if (typeof circular == 'undefined')
    circular = true;

  if (typeof depth == 'undefined')
    depth = Infinity;

  // recurse this function so we don't reset allParents and allChildren
  function _clone(parent, depth) {
    // cloning null always returns null
    if (parent === null)
      return null;

    if (depth == 0)
      return parent;

    var child;
    var proto;
    if (typeof parent != 'object') {
      return parent;
    }

    if (clone.__isArray(parent)) {
      child = [];
    } else if (clone.__isRegExp(parent)) {
      child = new RegExp(parent.source, __getRegExpFlags(parent));
      if (parent.lastIndex) child.lastIndex = parent.lastIndex;
    } else if (clone.__isDate(parent)) {
      child = new Date(parent.getTime());
    } else if (useBuffer && Buffer.isBuffer(parent)) {
      child = new Buffer(parent.length);
      parent.copy(child);
      return child;
    } else {
      if (typeof prototype == 'undefined') {
        proto = Object.getPrototypeOf(parent);
        child = Object.create(proto);
      }
      else {
        child = Object.create(prototype);
        proto = prototype;
      }
    }

    if (circular) {
      var index = allParents.indexOf(parent);

      if (index != -1) {
        return allChildren[index];
      }
      allParents.push(parent);
      allChildren.push(child);
    }

    for (var i in parent) {
      var attrs;
      if (proto) {
        attrs = Object.getOwnPropertyDescriptor(proto, i);
      }

      if (attrs && attrs.set == null) {
        continue;
      }
      child[i] = _clone(parent[i], depth - 1);
    }

    return child;
  }

  return _clone(parent, depth);
}

/**
 * Simple flat clone using prototype, accepts only objects, usefull for property
 * override on FLAT configuration object (no nested props).
 *
 * USE WITH CAUTION! This may not behave as you wish if you do not know how this
 * works.
 */
clone.clonePrototype = function clonePrototype(parent) {
  if (parent === null)
    return null;

  var c = function () {};
  c.prototype = parent;
  return new c();
};

// private utility functions

function __objToStr(o) {
  return Object.prototype.toString.call(o);
};
clone.__objToStr = __objToStr;

function __isDate(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Date]';
};
clone.__isDate = __isDate;

function __isArray(o) {
  return typeof o === 'object' && __objToStr(o) === '[object Array]';
};
clone.__isArray = __isArray;

function __isRegExp(o) {
  return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
};
clone.__isRegExp = __isRegExp;

function __getRegExpFlags(re) {
  var flags = '';
  if (re.global) flags += 'g';
  if (re.ignoreCase) flags += 'i';
  if (re.multiline) flags += 'm';
  return flags;
};
clone.__getRegExpFlags = __getRegExpFlags;

return clone;
})();

if (typeof module === 'object' && module.exports) {
  module.exports = clone;
}

/**
 * Main CSSLint object.
 * @class CSSLint
 * @static
 * @extends parserlib.util.EventTarget
 */

/* global parserlib, clone, Reporter */
/* exported CSSLint */

var CSSLint = (function() {
    "use strict";

    var rules           = [],
        formatters      = [],
        embeddedRuleset = /\/\*\s*csslint([^\*]*)\*\//,
        api             = new parserlib.util.EventTarget();

    api.version = "1.0.3";

    //-------------------------------------------------------------------------
    // Rule Management
    //-------------------------------------------------------------------------

    /**
     * Adds a new rule to the engine.
     * @param {Object} rule The rule to add.
     * @method addRule
     */
    api.addRule = function(rule) {
        rules.push(rule);
        rules[rule.id] = rule;
    };

    /**
     * Clears all rule from the engine.
     * @method clearRules
     */
    api.clearRules = function() {
        rules = [];
    };

    /**
     * Returns the rule objects.
     * @return An array of rule objects.
     * @method getRules
     */
    api.getRules = function() {
        return [].concat(rules).sort(function(a, b) {
            return a.id > b.id ? 1 : 0;
        });
    };

    /**
     * Returns a ruleset configuration object with all current rules.
     * @return A ruleset object.
     * @method getRuleset
     */
    api.getRuleset = function() {
        var ruleset = {},
            i = 0,
            len = rules.length;

        while (i < len) {
            ruleset[rules[i++].id] = 1;    // by default, everything is a warning
        }

        return ruleset;
    };

    /**
     * Returns a ruleset object based on embedded rules.
     * @param {String} text A string of css containing embedded rules.
     * @param {Object} ruleset A ruleset object to modify.
     * @return {Object} A ruleset object.
     * @method getEmbeddedRuleset
     */
    function applyEmbeddedRuleset(text, ruleset) {
        var valueMap,
            embedded = text && text.match(embeddedRuleset),
            rules = embedded && embedded[1];

        if (rules) {
            valueMap = {
                "true": 2,  // true is error
                "": 1,      // blank is warning
                "false": 0, // false is ignore

                "2": 2,     // explicit error
                "1": 1,     // explicit warning
                "0": 0      // explicit ignore
            };

            rules.toLowerCase().split(",").forEach(function(rule) {
                var pair = rule.split(":"),
                    property = pair[0] || "",
                    value = pair[1] || "";

                ruleset[property.trim()] = valueMap[value.trim()];
            });
        }

        return ruleset;
    }

    //-------------------------------------------------------------------------
    // Formatters
    //-------------------------------------------------------------------------

    /**
     * Adds a new formatter to the engine.
     * @param {Object} formatter The formatter to add.
     * @method addFormatter
     */
    api.addFormatter = function(formatter) {
        // formatters.push(formatter);
        formatters[formatter.id] = formatter;
    };

    /**
     * Retrieves a formatter for use.
     * @param {String} formatId The name of the format to retrieve.
     * @return {Object} The formatter or undefined.
     * @method getFormatter
     */
    api.getFormatter = function(formatId) {
        return formatters[formatId];
    };

    /**
     * Formats the results in a particular format for a single file.
     * @param {Object} result The results returned from CSSLint.verify().
     * @param {String} filename The filename for which the results apply.
     * @param {String} formatId The name of the formatter to use.
     * @param {Object} options (Optional) for special output handling.
     * @return {String} A formatted string for the results.
     * @method format
     */
    api.format = function(results, filename, formatId, options) {
        var formatter = this.getFormatter(formatId),
            result = null;

        if (formatter) {
            result = formatter.startFormat();
            result += formatter.formatResults(results, filename, options || {});
            result += formatter.endFormat();
        }

        return result;
    };

    /**
     * Indicates if the given format is supported.
     * @param {String} formatId The ID of the format to check.
     * @return {Boolean} True if the format exists, false if not.
     * @method hasFormat
     */
    api.hasFormat = function(formatId) {
        return formatters.hasOwnProperty(formatId);
    };

    //-------------------------------------------------------------------------
    // Verification
    //-------------------------------------------------------------------------

    /**
     * Starts the verification process for the given CSS text.
     * @param {String} text The CSS text to verify.
     * @param {Object} ruleset (Optional) List of rules to apply. If null, then
     *      all rules are used. If a rule has a value of 1 then it's a warning,
     *      a value of 2 means it's an error.
     * @return {Object} Results of the verification.
     * @method verify
     */
    api.verify = function(text, ruleset) {

        var i = 0,
            reporter,
            lines,
            allow = {},
            ignore = [],
            report,
            parser = new parserlib.css.Parser({
                starHack: true,
                ieFilters: true,
                underscoreHack: true,
                strict: false
            });

        // normalize line endings
        lines = text.replace(/\n\r?/g, "$split$").split("$split$");

        // find 'allow' comments
        CSSLint.Util.forEach(lines, function (line, lineno) {
            var allowLine = line && line.match(/\/\*[ \t]*csslint[ \t]+allow:[ \t]*([^\*]*)\*\//i),
                allowRules = allowLine && allowLine[1],
                allowRuleset = {};

            if (allowRules) {
                allowRules.toLowerCase().split(",").forEach(function(allowRule) {
                    allowRuleset[allowRule.trim()] = true;
                });
                if (Object.keys(allowRuleset).length > 0) {
                    allow[lineno + 1] = allowRuleset;
                }
            }
        });

        var ignoreStart = null,
            ignoreEnd = null;
        CSSLint.Util.forEach(lines, function (line, lineno) {
            // Keep oldest, "unclosest" ignore:start
            if (ignoreStart === null && line.match(/\/\*[ \t]*csslint[ \t]+ignore:start[ \t]*\*\//i)) {
                ignoreStart = lineno;
            }

            if (line.match(/\/\*[ \t]*csslint[ \t]+ignore:end[ \t]*\*\//i)) {
                ignoreEnd = lineno;
            }

            if (ignoreStart !== null && ignoreEnd !== null) {
                ignore.push([ignoreStart, ignoreEnd]);
                ignoreStart = ignoreEnd = null;
            }
        });

        // Close remaining ignore block, if any
        if (ignoreStart !== null) {
            ignore.push([ignoreStart, lines.length]);
        }

        if (!ruleset) {
            ruleset = this.getRuleset();
        }

        if (embeddedRuleset.test(text)) {
            // defensively copy so that caller's version does not get modified
            ruleset = clone(ruleset);
            ruleset = applyEmbeddedRuleset(text, ruleset);
        }

        reporter = new Reporter(lines, ruleset, allow, ignore);

        ruleset.errors = 2;       // always report parsing errors as errors
        for (i in ruleset) {
            if (ruleset.hasOwnProperty(i) && ruleset[i]) {
                if (rules[i]) {
                    rules[i].init(parser, reporter);
                }
            }
        }


        // capture most horrible error type
        try {
            parser.parse(text);
        } catch (ex) {
            reporter.error("Fatal error, cannot continue: " + ex.message, ex.line, ex.col, {});
        }

        report = {
            messages    : reporter.messages,
            stats       : reporter.stats,
            ruleset     : reporter.ruleset,
            allow       : reporter.allow,
            ignore      : reporter.ignore
        };

        // sort by line numbers, rollups at the bottom
        report.messages.sort(function (a, b) {
            if (a.rollup && !b.rollup) {
                return 1;
            } else if (!a.rollup && b.rollup) {
                return -1;
            } else {
                return a.line - b.line;
            }
        });

        return report;
    };

    //-------------------------------------------------------------------------
    // Publish the API
    //-------------------------------------------------------------------------

    return api;

})();

/**
 * An instance of Report is used to report results of the
 * verification back to the main API.
 * @class Reporter
 * @constructor
 * @param {String[]} lines The text lines of the source.
 * @param {Object} ruleset The set of rules to work with, including if
 *      they are errors or warnings.
 * @param {Object} explicitly allowed lines
 * @param {[][]} ingore list of line ranges to be ignored
 */
function Reporter(lines, ruleset, allow, ignore) {
    "use strict";

    /**
     * List of messages being reported.
     * @property messages
     * @type String[]
     */
    this.messages = [];

    /**
     * List of statistics being reported.
     * @property stats
     * @type String[]
     */
    this.stats = [];

    /**
     * Lines of code being reported on. Used to provide contextual information
     * for messages.
     * @property lines
     * @type String[]
     */
    this.lines = lines;

    /**
     * Information about the rules. Used to determine whether an issue is an
     * error or warning.
     * @property ruleset
     * @type Object
     */
    this.ruleset = ruleset;

    /**
     * Lines with specific rule messages to leave out of the report.
     * @property allow
     * @type Object
     */
    this.allow = allow;
    if (!this.allow) {
        this.allow = {};
    }

    /**
     * Linesets not to include in the report.
     * @property ignore
     * @type [][]
     */
    this.ignore = ignore;
    if (!this.ignore) {
        this.ignore = [];
    }
}

Reporter.prototype = {

    // restore constructor
    constructor: Reporter,

    /**
     * Report an error.
     * @param {String} message The message to store.
     * @param {int} line The line number.
     * @param {int} col The column number.
     * @param {Object} rule The rule this message relates to.
     * @method error
     */
    error: function(message, line, col, rule) {
        "use strict";
        this.messages.push({
            type    : "error",
            line    : line,
            col     : col,
            message : message,
            evidence: this.lines[line-1],
            rule    : rule || {}
        });
    },

    /**
     * Report an warning.
     * @param {String} message The message to store.
     * @param {int} line The line number.
     * @param {int} col The column number.
     * @param {Object} rule The rule this message relates to.
     * @method warn
     * @deprecated Use report instead.
     */
    warn: function(message, line, col, rule) {
        "use strict";
        this.report(message, line, col, rule);
    },

    /**
     * Report an issue.
     * @param {String} message The message to store.
     * @param {int} line The line number.
     * @param {int} col The column number.
     * @param {Object} rule The rule this message relates to.
     * @method report
     */
    report: function(message, line, col, rule) {
        "use strict";

        // Check if rule violation should be allowed
        if (this.allow.hasOwnProperty(line) && this.allow[line].hasOwnProperty(rule.id)) {
            return;
        }

        var ignore = false;
        CSSLint.Util.forEach(this.ignore, function (range) {
            if (range[0] <= line && line <= range[1]) {
                ignore = true;
            }
        });
        if (ignore) {
            return;
        }

        this.messages.push({
            type    : this.ruleset[rule.id] === 2 ? "error" : "warning",
            line    : line,
            col     : col,
            message : message,
            evidence: this.lines[line-1],
            rule    : rule
        });
    },

    /**
     * Report some informational text.
     * @param {String} message The message to store.
     * @param {int} line The line number.
     * @param {int} col The column number.
     * @param {Object} rule The rule this message relates to.
     * @method info
     */
    info: function(message, line, col, rule) {
        "use strict";
        this.messages.push({
            type    : "info",
            line    : line,
            col     : col,
            message : message,
            evidence: this.lines[line-1],
            rule    : rule
        });
    },

    /**
     * Report some rollup error information.
     * @param {String} message The message to store.
     * @param {Object} rule The rule this message relates to.
     * @method rollupError
     */
    rollupError: function(message, rule) {
        "use strict";
        this.messages.push({
            type    : "error",
            rollup  : true,
            message : message,
            rule    : rule
        });
    },

    /**
     * Report some rollup warning information.
     * @param {String} message The message to store.
     * @param {Object} rule The rule this message relates to.
     * @method rollupWarn
     */
    rollupWarn: function(message, rule) {
        "use strict";
        this.messages.push({
            type    : "warning",
            rollup  : true,
            message : message,
            rule    : rule
        });
    },

    /**
     * Report a statistic.
     * @param {String} name The name of the stat to store.
     * @param {Variant} value The value of the stat.
     * @method stat
     */
    stat: function(name, value) {
        "use strict";
        this.stats[name] = value;
    }
};

// expose for testing purposes
CSSLint._Reporter = Reporter;

/*
 * Utility functions that make life easier.
 */
CSSLint.Util = {
    /*
     * Adds all properties from supplier onto receiver,
     * overwriting if the same name already exists on
     * receiver.
     * @param {Object} The object to receive the properties.
     * @param {Object} The object to provide the properties.
     * @return {Object} The receiver
     */
    mix: function(receiver, supplier) {
        "use strict";
        var prop;

        for (prop in supplier) {
            if (supplier.hasOwnProperty(prop)) {
                receiver[prop] = supplier[prop];
            }
        }

        return prop;
    },

    /*
     * Polyfill for array indexOf() method.
     * @param {Array} values The array to search.
     * @param {Variant} value The value to search for.
     * @return {int} The index of the value if found, -1 if not.
     */
    indexOf: function(values, value) {
        "use strict";
        if (values.indexOf) {
            return values.indexOf(value);
        } else {
            for (var i=0, len=values.length; i < len; i++) {
                if (values[i] === value) {
                    return i;
                }
            }
            return -1;
        }
    },

    /*
     * Polyfill for array forEach() method.
     * @param {Array} values The array to operate on.
     * @param {Function} func The function to call on each item.
     * @return {void}
     */
    forEach: function(values, func) {
        "use strict";
        if (values.forEach) {
            return values.forEach(func);
        } else {
            for (var i=0, len=values.length; i < len; i++) {
                func(values[i], i, values);
            }
        }
    }
};

/*
 * Rule: Don't use adjoining classes (.foo.bar).
 */

CSSLint.addRule({

    // rule information
    id: "adjoining-classes",
    name: "Disallow adjoining classes",
    desc: "Don't use adjoining classes.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-adjoining-classes",
    browsers: "IE6",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;
        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                modifier,
                classCount,
                i, j, k;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];
                for (j=0; j < selector.parts.length; j++) {
                    part = selector.parts[j];
                    if (part.type === parser.SELECTOR_PART_TYPE) {
                        classCount = 0;
                        for (k=0; k < part.modifiers.length; k++) {
                            modifier = part.modifiers[k];
                            if (modifier.type === "class") {
                                classCount++;
                            }
                            if (classCount > 1){
                                reporter.report("Adjoining classes: "+selectors[i].text, part.line, part.col, rule);
                            }
                        }
                    }
                }
            }
        });
    }

});

/*
 * Rule: Don't use width or height when using padding or border.
 */
CSSLint.addRule({

    // rule information
    id: "box-model",
    name: "Beware of broken box size",
    desc: "Don't use width or height when using padding or border.",
    url: "https://github.com/CSSLint/csslint/wiki/Beware-of-box-model-size",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            widthProperties = {
                border: 1,
                "border-left": 1,
                "border-right": 1,
                padding: 1,
                "padding-left": 1,
                "padding-right": 1
            },
            heightProperties = {
                border: 1,
                "border-bottom": 1,
                "border-top": 1,
                padding: 1,
                "padding-bottom": 1,
                "padding-top": 1
            },
            properties,
            boxSizing = false;

        function startRule() {
            properties = {};
            boxSizing = false;
        }

        function endRule() {
            var prop, value;

            if (!boxSizing) {
                if (properties.height) {
                    for (prop in heightProperties) {
                        if (heightProperties.hasOwnProperty(prop) && properties[prop]) {
                            value = properties[prop].value;
                            // special case for padding
                            if (!(prop === "padding" && value.parts.length === 2 && value.parts[0].value === 0)) {
                                reporter.report("Using height with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule);
                            }
                        }
                    }
                }

                if (properties.width) {
                    for (prop in widthProperties) {
                        if (widthProperties.hasOwnProperty(prop) && properties[prop]) {
                            value = properties[prop].value;

                            if (!(prop === "padding" && value.parts.length === 2 && value.parts[1].value === 0)) {
                                reporter.report("Using width with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule);
                            }
                        }
                    }
                }
            }
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var name = event.property.text.toLowerCase();

            if (heightProperties[name] || widthProperties[name]) {
                if (!/^0\S*$/.test(event.value) && !(name === "border" && event.value.toString() === "none")) {
                    properties[name] = {
                        line: event.property.line,
                        col: event.property.col,
                        value: event.value
                    };
                }
            } else {
                if (/^(width|height)/i.test(name) && /^(length|percentage)/.test(event.value.parts[0].type)) {
                    properties[name] = 1;
                } else if (name === "box-sizing") {
                    boxSizing = true;
                }
            }

        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);
        parser.addListener("endpage", endRule);
        parser.addListener("endpagemargin", endRule);
        parser.addListener("endkeyframerule", endRule);
        parser.addListener("endviewport", endRule);
    }

});

/*
 * Rule: box-sizing doesn't work in IE6 and IE7.
 */

CSSLint.addRule({

    // rule information
    id: "box-sizing",
    name: "Disallow use of box-sizing",
    desc: "The box-sizing properties isn't supported in IE6 and IE7.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-box-sizing",
    browsers: "IE6, IE7",
    tags: ["Compatibility"],

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("property", function(event) {
            var name = event.property.text.toLowerCase();

            if (name === "box-sizing") {
                reporter.report("The box-sizing property isn't supported in IE6 and IE7.", event.line, event.col, rule);
            }
        });
    }

});

/*
 * Rule: Use the bulletproof @font-face syntax to avoid 404's in old IE
 * (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax)
 */

CSSLint.addRule({

    // rule information
    id: "bulletproof-font-face",
    name: "Use the bulletproof @font-face syntax",
    desc: "Use the bulletproof @font-face syntax to avoid 404's in old IE (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax).",
    url: "https://github.com/CSSLint/csslint/wiki/Bulletproof-font-face",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            fontFaceRule = false,
            firstSrc = true,
            ruleFailed = false,
            line, col;

        // Mark the start of a @font-face declaration so we only test properties inside it
        parser.addListener("startfontface", function() {
            fontFaceRule = true;
        });

        parser.addListener("property", function(event) {
            // If we aren't inside an @font-face declaration then just return
            if (!fontFaceRule) {
                return;
            }

            var propertyName = event.property.toString().toLowerCase(),
                value = event.value.toString();

            // Set the line and col numbers for use in the endfontface listener
            line = event.line;
            col = event.col;

            // This is the property that we care about, we can ignore the rest
            if (propertyName === "src") {
                var regex = /^\s?url\(['"].+\.eot\?.*['"]\)\s*format\(['"]embedded-opentype['"]\).*$/i;

                // We need to handle the advanced syntax with two src properties
                if (!value.match(regex) && firstSrc) {
                    ruleFailed = true;
                    firstSrc = false;
                } else if (value.match(regex) && !firstSrc) {
                    ruleFailed = false;
                }
            }


        });

        // Back to normal rules that we don't need to test
        parser.addListener("endfontface", function() {
            fontFaceRule = false;

            if (ruleFailed) {
                reporter.report("@font-face declaration doesn't follow the fontspring bulletproof syntax.", line, col, rule);
            }
        });
    }
});

/*
 * Rule: Include all compatible vendor prefixes to reach a wider
 * range of users.
 */

CSSLint.addRule({

    // rule information
    id: "compatible-vendor-prefixes",
    name: "Require compatible vendor prefixes",
    desc: "Include all compatible vendor prefixes to reach a wider range of users.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-compatible-vendor-prefixes",
    browsers: "All",

    // initialization
    init: function (parser, reporter) {
        "use strict";
        var rule = this,
            compatiblePrefixes,
            properties,
            prop,
            variations,
            prefixed,
            i,
            len,
            inKeyFrame = false,
            arrayPush = Array.prototype.push,
            applyTo = [];

        // See http://peter.sh/experiments/vendor-prefixed-css-property-overview/ for details
        compatiblePrefixes = {
            "animation"                  : "webkit",
            "animation-delay"            : "webkit",
            "animation-direction"        : "webkit",
            "animation-duration"         : "webkit",
            "animation-fill-mode"        : "webkit",
            "animation-iteration-count"  : "webkit",
            "animation-name"             : "webkit",
            "animation-play-state"       : "webkit",
            "animation-timing-function"  : "webkit",
            "appearance"                 : "webkit moz",
            "border-end"                 : "webkit moz",
            "border-end-color"           : "webkit moz",
            "border-end-style"           : "webkit moz",
            "border-end-width"           : "webkit moz",
            "border-image"               : "webkit moz o",
            "border-radius"              : "webkit",
            "border-start"               : "webkit moz",
            "border-start-color"         : "webkit moz",
            "border-start-style"         : "webkit moz",
            "border-start-width"         : "webkit moz",
            "box-align"                  : "webkit moz ms",
            "box-direction"              : "webkit moz ms",
            "box-flex"                   : "webkit moz ms",
            "box-lines"                  : "webkit ms",
            "box-ordinal-group"          : "webkit moz ms",
            "box-orient"                 : "webkit moz ms",
            "box-pack"                   : "webkit moz ms",
            "box-sizing"                 : "",
            "box-shadow"                 : "",
            "column-count"               : "webkit moz ms",
            "column-gap"                 : "webkit moz ms",
            "column-rule"                : "webkit moz ms",
            "column-rule-color"          : "webkit moz ms",
            "column-rule-style"          : "webkit moz ms",
            "column-rule-width"          : "webkit moz ms",
            "column-width"               : "webkit moz ms",
            "hyphens"                    : "epub moz",
            "line-break"                 : "webkit ms",
            "margin-end"                 : "webkit moz",
            "margin-start"               : "webkit moz",
            "marquee-speed"              : "webkit wap",
            "marquee-style"              : "webkit wap",
            "padding-end"                : "webkit moz",
            "padding-start"              : "webkit moz",
            "tab-size"                   : "moz o",
            "text-size-adjust"           : "webkit ms",
            "transform"                  : "webkit ms",
            "transform-origin"           : "webkit ms",
            "transition"                 : "",
            "transition-delay"           : "",
            "transition-duration"        : "",
            "transition-property"        : "",
            "transition-timing-function" : "",
            "user-modify"                : "webkit moz",
            "user-select"                : "webkit moz ms",
            "word-break"                 : "epub ms",
            "writing-mode"               : "epub ms"
        };


        for (prop in compatiblePrefixes) {
            if (compatiblePrefixes.hasOwnProperty(prop)) {
                variations = [];
                prefixed = compatiblePrefixes[prop].split(" ");
                for (i = 0, len = prefixed.length; i < len; i++) {
                    variations.push("-" + prefixed[i] + "-" + prop);
                }
                compatiblePrefixes[prop] = variations;
                arrayPush.apply(applyTo, variations);
            }
        }

        parser.addListener("startrule", function () {
            properties = [];
        });

        parser.addListener("startkeyframes", function (event) {
            inKeyFrame = event.prefix || true;
        });

        parser.addListener("endkeyframes", function () {
            inKeyFrame = false;
        });

        parser.addListener("property", function (event) {
            var name = event.property;
            if (CSSLint.Util.indexOf(applyTo, name.text) > -1) {

                // e.g., -moz-transform is okay to be alone in @-moz-keyframes
                if (!inKeyFrame || typeof inKeyFrame !== "string" ||
                        name.text.indexOf("-" + inKeyFrame + "-") !== 0) {
                    properties.push(name);
                }
            }
        });

        parser.addListener("endrule", function () {
            if (!properties.length) {
                return;
            }

            var propertyGroups = {},
                i,
                len,
                name,
                prop,
                variations,
                value,
                full,
                actual,
                item,
                propertiesSpecified;

            for (i = 0, len = properties.length; i < len; i++) {
                name = properties[i];

                for (prop in compatiblePrefixes) {
                    if (compatiblePrefixes.hasOwnProperty(prop)) {
                        variations = compatiblePrefixes[prop];
                        if (CSSLint.Util.indexOf(variations, name.text) > -1) {
                            if (!propertyGroups[prop]) {
                                propertyGroups[prop] = {
                                    full: variations.slice(0),
                                    actual: [],
                                    actualNodes: []
                                };
                            }
                            if (CSSLint.Util.indexOf(propertyGroups[prop].actual, name.text) === -1) {
                                propertyGroups[prop].actual.push(name.text);
                                propertyGroups[prop].actualNodes.push(name);
                            }
                        }
                    }
                }
            }

            for (prop in propertyGroups) {
                if (propertyGroups.hasOwnProperty(prop)) {
                    value = propertyGroups[prop];
                    full = value.full;
                    actual = value.actual;

                    if (full.length > actual.length) {
                        for (i = 0, len = full.length; i < len; i++) {
                            item = full[i];
                            if (CSSLint.Util.indexOf(actual, item) === -1) {
                                propertiesSpecified = (actual.length === 1) ? actual[0] : (actual.length === 2) ? actual.join(" and ") : actual.join(", ");
                                reporter.report("The property " + item + " is compatible with " + propertiesSpecified + " and should be included as well.", value.actualNodes[0].line, value.actualNodes[0].col, rule);
                            }
                        }

                    }
                }
            }
        });
    }
});

/*
 * Rule: Certain properties don't play well with certain display values.
 * - float should not be used with inline-block
 * - height, width, margin-top, margin-bottom, float should not be used with inline
 * - vertical-align should not be used with block
 * - margin, float should not be used with table-*
 */

CSSLint.addRule({

    // rule information
    id: "display-property-grouping",
    name: "Require properties appropriate for display",
    desc: "Certain properties shouldn't be used with certain display property values.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-properties-appropriate-for-display",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        var propertiesToCheck = {
                display: 1,
                "float": "none",
                height: 1,
                width: 1,
                margin: 1,
                "margin-left": 1,
                "margin-right": 1,
                "margin-bottom": 1,
                "margin-top": 1,
                padding: 1,
                "padding-left": 1,
                "padding-right": 1,
                "padding-bottom": 1,
                "padding-top": 1,
                "vertical-align": 1
            },
            properties;

        function reportProperty(name, display, msg) {
            if (properties[name]) {
                if (typeof propertiesToCheck[name] !== "string" || properties[name].value.toLowerCase() !== propertiesToCheck[name]) {
                    reporter.report(msg || name + " can't be used with display: " + display + ".", properties[name].line, properties[name].col, rule);
                }
            }
        }

        function startRule() {
            properties = {};
        }

        function endRule() {

            var display = properties.display ? properties.display.value : null;
            if (display) {
                switch (display) {

                    case "inline":
                        // height, width, margin-top, margin-bottom, float should not be used with inline
                        reportProperty("height", display);
                        reportProperty("width", display);
                        reportProperty("margin", display);
                        reportProperty("margin-top", display);
                        reportProperty("margin-bottom", display);
                        reportProperty("float", display, "display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");
                        break;

                    case "block":
                        // vertical-align should not be used with block
                        reportProperty("vertical-align", display);
                        break;

                    case "inline-block":
                        // float should not be used with inline-block
                        reportProperty("float", display);
                        break;

                    default:
                        // margin, float should not be used with table
                        if (display.indexOf("table-") === 0) {
                            reportProperty("margin", display);
                            reportProperty("margin-left", display);
                            reportProperty("margin-right", display);
                            reportProperty("margin-top", display);
                            reportProperty("margin-bottom", display);
                            reportProperty("float", display);
                        }

                        // otherwise do nothing
                }
            }

        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var name = event.property.text.toLowerCase();

            if (propertiesToCheck[name]) {
                properties[name] = {
                    value: event.value.text,
                    line: event.property.line,
                    col: event.property.col
                };
            }
        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);
        parser.addListener("endkeyframerule", endRule);
        parser.addListener("endpagemargin", endRule);
        parser.addListener("endpage", endRule);
        parser.addListener("endviewport", endRule);

    }

});

/*
 * Rule: Disallow duplicate background-images (using url).
 */

CSSLint.addRule({

    // rule information
    id: "duplicate-background-images",
    name: "Disallow duplicate background images",
    desc: "Every background-image should be unique. Use a common class for e.g. sprites.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-background-images",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            stack = {};

        parser.addListener("property", function(event) {
            var name = event.property.text,
                value = event.value,
                i, len;

            if (name.match(/background/i)) {
                for (i=0, len=value.parts.length; i < len; i++) {
                    if (value.parts[i].type === "uri") {
                        if (typeof stack[value.parts[i].uri] === "undefined") {
                            stack[value.parts[i].uri] = event;
                        } else {
                            reporter.report("Background image '" + value.parts[i].uri + "' was used multiple times, first declared at line " + stack[value.parts[i].uri].line + ", col " + stack[value.parts[i].uri].col + ".", event.line, event.col, rule);
                        }
                    }
                }
            }
        });
    }
});

/*
 * Rule: Duplicate properties must appear one after the other. If an already-defined
 * property appears somewhere else in the rule, then it's likely an error.
 */

CSSLint.addRule({

    // rule information
    id: "duplicate-properties",
    name: "Disallow duplicate properties",
    desc: "Duplicate properties must appear one after the other.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-properties",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            properties,
            lastProperty;

        function startRule() {
            properties = {};
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var property = event.property,
                name = property.text.toLowerCase();

            if (properties[name] && (lastProperty !== name || properties[name] === event.value.text)) {
                reporter.report("Duplicate property '" + event.property + "' found.", event.line, event.col, rule);
            }

            properties[name] = event.value.text;
            lastProperty = name;

        });


    }

});

/*
 * Rule: Style rules without any properties defined should be removed.
 */

CSSLint.addRule({

    // rule information
    id: "empty-rules",
    name: "Disallow empty rules",
    desc: "Rules without any properties specified should be removed.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-empty-rules",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            count = 0;

        parser.addListener("startrule", function() {
            count=0;
        });

        parser.addListener("property", function() {
            count++;
        });

        parser.addListener("endrule", function(event) {
            var selectors = event.selectors;
            if (count === 0) {
                reporter.report("Rule is empty.", selectors[0].line, selectors[0].col, rule);
            }
        });
    }

});

/*
 * Rule: There should be no syntax errors. (Duh.)
 */

CSSLint.addRule({

    // rule information
    id: "errors",
    name: "Parsing Errors",
    desc: "This rule looks for recoverable syntax errors.",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("error", function(event) {
            reporter.error(event.message, event.line, event.col, rule);
        });

    }

});

CSSLint.addRule({

    // rule information
    id: "fallback-colors",
    name: "Require fallback colors",
    desc: "For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-fallback-colors",
    browsers: "IE6,IE7,IE8",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            lastProperty,
            propertiesToCheck = {
                color: 1,
                background: 1,
                "border-color": 1,
                "border-top-color": 1,
                "border-right-color": 1,
                "border-bottom-color": 1,
                "border-left-color": 1,
                border: 1,
                "border-top": 1,
                "border-right": 1,
                "border-bottom": 1,
                "border-left": 1,
                "background-color": 1
            };

        function startRule() {
            lastProperty = null;
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var property = event.property,
                name = property.text.toLowerCase(),
                parts = event.value.parts,
                i = 0,
                colorType = "",
                len = parts.length;

            if (propertiesToCheck[name]) {
                while (i < len) {
                    if (parts[i].type === "color") {
                        if ("alpha" in parts[i] || "hue" in parts[i]) {

                            if (/([^\)]+)\(/.test(parts[i])) {
                                colorType = RegExp.$1.toUpperCase();
                            }

                            if (!lastProperty || (lastProperty.property.text.toLowerCase() !== name || lastProperty.colorType !== "compat")) {
                                reporter.report("Fallback " + name + " (hex or RGB) should precede " + colorType + " " + name + ".", event.line, event.col, rule);
                            }
                        } else {
                            event.colorType = "compat";
                        }
                    }

                    i++;
                }
            }

            lastProperty = event;
        });

    }

});

/*
 * Rule: You shouldn't use more than 10 floats. If you do, there's probably
 * room for some abstraction.
 */

CSSLint.addRule({

    // rule information
    id: "floats",
    name: "Disallow too many floats",
    desc: "This rule tests if the float property is used too many times",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-too-many-floats",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;
        var count = 0;

        // count how many times "float" is used
        parser.addListener("property", function(event) {
            if (event.property.text.toLowerCase() === "float" &&
                    event.value.text.toLowerCase() !== "none") {
                count++;
            }
        });

        // report the results
        parser.addListener("endstylesheet", function() {
            reporter.stat("floats", count);
            if (count >= 10) {
                reporter.rollupWarn("Too many floats (" + count + "), you're probably using them for layout. Consider using a grid system instead.", rule);
            }
        });
    }

});

/*
 * Rule: Avoid too many @font-face declarations in the same stylesheet.
 */

CSSLint.addRule({

    // rule information
    id: "font-faces",
    name: "Don't use too many web fonts",
    desc: "Too many different web fonts in the same stylesheet.",
    url: "https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-web-fonts",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            count = 0;


        parser.addListener("startfontface", function() {
            count++;
        });

        parser.addListener("endstylesheet", function() {
            if (count > 5) {
                reporter.rollupWarn("Too many @font-face declarations (" + count + ").", rule);
            }
        });
    }

});

/*
 * Rule: You shouldn't need more than 9 font-size declarations.
 */

CSSLint.addRule({

    // rule information
    id: "font-sizes",
    name: "Disallow too many font sizes",
    desc: "Checks the number of font-size declarations.",
    url: "https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-font-size-declarations",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            count = 0;

        // check for use of "font-size"
        parser.addListener("property", function(event) {
            if (event.property.toString() === "font-size") {
                count++;
            }
        });

        // report the results
        parser.addListener("endstylesheet", function() {
            reporter.stat("font-sizes", count);
            if (count >= 10) {
                reporter.rollupWarn("Too many font-size declarations (" + count + "), abstraction needed.", rule);
            }
        });
    }

});

/*
 * Rule: When using a vendor-prefixed gradient, make sure to use them all.
 */

CSSLint.addRule({

    // rule information
    id: "gradients",
    name: "Require all gradient definitions",
    desc: "When using a vendor-prefixed gradient, make sure to use them all.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-all-gradient-definitions",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            gradients;

        parser.addListener("startrule", function() {
            gradients = {
                moz: 0,
                webkit: 0,
                oldWebkit: 0,
                o: 0
            };
        });

        parser.addListener("property", function(event) {

            if (/\-(moz|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(event.value)) {
                gradients[RegExp.$1] = 1;
            } else if (/\-webkit\-gradient/i.test(event.value)) {
                gradients.oldWebkit = 1;
            }

        });

        parser.addListener("endrule", function(event) {
            var missing = [];

            if (!gradients.moz) {
                missing.push("Firefox 3.6+");
            }

            if (!gradients.webkit) {
                missing.push("Webkit (Safari 5+, Chrome)");
            }

            if (!gradients.oldWebkit) {
                missing.push("Old Webkit (Safari 4+, Chrome)");
            }

            if (!gradients.o) {
                missing.push("Opera 11.1+");
            }

            if (missing.length && missing.length < 4) {
                reporter.report("Missing vendor-prefixed CSS gradients for " + missing.join(", ") + ".", event.selectors[0].line, event.selectors[0].col, rule);
            }

        });

    }

});

/*
 * Rule: Don't use IDs for selectors.
 */

CSSLint.addRule({

    // rule information
    id: "ids",
    name: "Disallow IDs in selectors",
    desc: "Selectors should not contain IDs.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-IDs-in-selectors",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;
        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                modifier,
                idCount,
                i, j, k;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];
                idCount = 0;

                for (j=0; j < selector.parts.length; j++) {
                    part = selector.parts[j];
                    if (part.type === parser.SELECTOR_PART_TYPE) {
                        for (k=0; k < part.modifiers.length; k++) {
                            modifier = part.modifiers[k];
                            if (modifier.type === "id") {
                                idCount++;
                            }
                        }
                    }
                }

                if (idCount === 1) {
                    reporter.report("Don't use IDs in selectors.", selector.line, selector.col, rule);
                } else if (idCount > 1) {
                    reporter.report(idCount + " IDs in the selector, really?", selector.line, selector.col, rule);
                }
            }

        });
    }

});

/*
 * Rule: IE6-9 supports up to 31 stylesheet import.
 * Reference:
 * http://blogs.msdn.com/b/ieinternals/archive/2011/05/14/internet-explorer-stylesheet-rule-selector-import-sheet-limit-maximum.aspx
 */

CSSLint.addRule({

    // rule information
    id: "import-ie-limit",
    name: "@import limit on IE6-IE9",
    desc: "IE6-9 supports up to 31 @import per stylesheet",
    browsers: "IE6, IE7, IE8, IE9",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            MAX_IMPORT_COUNT = 31,
            count = 0;

        function startPage() {
            count = 0;
        }

        parser.addListener("startpage", startPage);

        parser.addListener("import", function() {
            count++;
        });

        parser.addListener("endstylesheet", function() {
            if (count > MAX_IMPORT_COUNT) {
                reporter.rollupError(
                    "Too many @import rules (" + count + "). IE6-9 supports up to 31 import per stylesheet.",
                    rule
                );
            }
        });
    }

});

/*
 * Rule: Don't use @import, use <link> instead.
 */

CSSLint.addRule({

    // rule information
    id: "import",
    name: "Disallow @import",
    desc: "Don't use @import, use <link> instead.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-%40import",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("import", function(event) {
            reporter.report("@import prevents parallel downloads, use <link> instead.", event.line, event.col, rule);
        });

    }

});

/*
 * Rule: Make sure !important is not overused, this could lead to specificity
 * war. Display a warning on !important declarations, an error if it's
 * used more at least 10 times.
 */

CSSLint.addRule({

    // rule information
    id: "important",
    name: "Disallow !important",
    desc: "Be careful when using !important declaration",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-%21important",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            count = 0;

        // warn that important is used and increment the declaration counter
        parser.addListener("property", function(event) {
            if (event.important === true) {
                count++;
                reporter.report("Use of !important", event.line, event.col, rule);
            }
        });

        // if there are more than 10, show an error
        parser.addListener("endstylesheet", function() {
            reporter.stat("important", count);
            if (count >= 10) {
                reporter.rollupWarn("Too many !important declarations (" + count + "), try to use less than 10 to avoid specificity issues.", rule);
            }
        });
    }

});

/*
 * Rule: Properties should be known (listed in CSS3 specification) or
 * be a vendor-prefixed property.
 */

CSSLint.addRule({

    // rule information
    id: "known-properties",
    name: "Require use of known properties",
    desc: "Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-use-of-known-properties",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("property", function(event) {

            // the check is handled entirely by the parser-lib (https://github.com/nzakas/parser-lib)
            if (event.invalid) {
                reporter.report(event.invalid.message, event.line, event.col, rule);
            }

        });
    }

});

/*
 * Rule: All properties should be in alphabetical order.
 */

CSSLint.addRule({

    // rule information
    id: "order-alphabetical",
    name: "Alphabetical order",
    desc: "Assure properties are in alphabetical order",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            properties;

        var startRule = function () {
            properties = [];
        };

        var endRule = function(event) {
            var currentProperties = properties.join(","),
                expectedProperties = properties.sort().join(",");

            if (currentProperties !== expectedProperties) {
                reporter.report("Rule doesn't have all its properties in alphabetical order.", event.line, event.col, rule);
            }
        };

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var name = event.property.text,
                lowerCasePrefixLessName = name.toLowerCase().replace(/^-.*?-/, "");

            properties.push(lowerCasePrefixLessName);
        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);
        parser.addListener("endpage", endRule);
        parser.addListener("endpagemargin", endRule);
        parser.addListener("endkeyframerule", endRule);
        parser.addListener("endviewport", endRule);
    }

});

/*
 * Rule: outline: none or outline: 0 should only be used in a :focus rule
 *       and only if there are other properties in the same rule.
 */

CSSLint.addRule({

    // rule information
    id: "outline-none",
    name: "Disallow outline: none",
    desc: "Use of outline: none or outline: 0 should be limited to :focus rules.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-outline%3Anone",
    browsers: "All",
    tags: ["Accessibility"],

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            lastRule;

        function startRule(event) {
            if (event.selectors) {
                lastRule = {
                    line: event.line,
                    col: event.col,
                    selectors: event.selectors,
                    propCount: 0,
                    outline: false
                };
            } else {
                lastRule = null;
            }
        }

        function endRule() {
            if (lastRule) {
                if (lastRule.outline) {
                    if (lastRule.selectors.toString().toLowerCase().indexOf(":focus") === -1) {
                        reporter.report("Outlines should only be modified using :focus.", lastRule.line, lastRule.col, rule);
                    } else if (lastRule.propCount === 1) {
                        reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule);
                    }
                }
            }
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var name = event.property.text.toLowerCase(),
                value = event.value;

            if (lastRule) {
                lastRule.propCount++;
                if (name === "outline" && (value.toString() === "none" || value.toString() === "0")) {
                    lastRule.outline = true;
                }
            }

        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);
        parser.addListener("endpage", endRule);
        parser.addListener("endpagemargin", endRule);
        parser.addListener("endkeyframerule", endRule);
        parser.addListener("endviewport", endRule);

    }

});

/*
 * Rule: Don't use classes or IDs with elements (a.foo or a#foo).
 */

CSSLint.addRule({

    // rule information
    id: "overqualified-elements",
    name: "Disallow overqualified elements",
    desc: "Don't use classes or IDs with elements (a.foo or a#foo).",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-overqualified-elements",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            classes = {};

        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                modifier,
                i, j, k;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];

                for (j=0; j < selector.parts.length; j++) {
                    part = selector.parts[j];
                    if (part.type === parser.SELECTOR_PART_TYPE) {
                        for (k=0; k < part.modifiers.length; k++) {
                            modifier = part.modifiers[k];
                            if (part.elementName && modifier.type === "id") {
                                reporter.report("Element (" + part + ") is overqualified, just use " + modifier + " without element name.", part.line, part.col, rule);
                            } else if (modifier.type === "class") {

                                if (!classes[modifier]) {
                                    classes[modifier] = [];
                                }
                                classes[modifier].push({
                                    modifier: modifier,
                                    part: part
                                });
                            }
                        }
                    }
                }
            }
        });

        parser.addListener("endstylesheet", function() {

            var prop;
            for (prop in classes) {
                if (classes.hasOwnProperty(prop)) {

                    // one use means that this is overqualified
                    if (classes[prop].length === 1 && classes[prop][0].part.elementName) {
                        reporter.report("Element (" + classes[prop][0].part + ") is overqualified, just use " + classes[prop][0].modifier + " without element name.", classes[prop][0].part.line, classes[prop][0].part.col, rule);
                    }
                }
            }
        });
    }

});

/*
 * Rule: Headings (h1-h6) should not be qualified (namespaced).
 */

CSSLint.addRule({

    // rule information
    id: "qualified-headings",
    name: "Disallow qualified headings",
    desc: "Headings should not be qualified (namespaced).",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-qualified-headings",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                i, j;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];

                for (j=0; j < selector.parts.length; j++) {
                    part = selector.parts[j];
                    if (part.type === parser.SELECTOR_PART_TYPE) {
                        if (part.elementName && /h[1-6]/.test(part.elementName.toString()) && j > 0) {
                            reporter.report("Heading (" + part.elementName + ") should not be qualified.", part.line, part.col, rule);
                        }
                    }
                }
            }
        });
    }

});

/*
 * Rule: Selectors that look like regular expressions are slow and should be avoided.
 */

CSSLint.addRule({

    // rule information
    id: "regex-selectors",
    name: "Disallow selectors that look like regexs",
    desc: "Selectors that look like regular expressions are slow and should be avoided.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-selectors-that-look-like-regular-expressions",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                modifier,
                i, j, k;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];
                for (j=0; j < selector.parts.length; j++) {
                    part = selector.parts[j];
                    if (part.type === parser.SELECTOR_PART_TYPE) {
                        for (k=0; k < part.modifiers.length; k++) {
                            modifier = part.modifiers[k];
                            if (modifier.type === "attribute") {
                                if (/([~\|\^\$\*]=)/.test(modifier)) {
                                    reporter.report("Attribute selectors with " + RegExp.$1 + " are slow!", modifier.line, modifier.col, rule);
                                }
                            }

                        }
                    }
                }
            }
        });
    }

});

/*
 * Rule: Total number of rules should not exceed x.
 */

CSSLint.addRule({

    // rule information
    id: "rules-count",
    name: "Rules Count",
    desc: "Track how many rules there are.",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var count = 0;

        // count each rule
        parser.addListener("startrule", function() {
            count++;
        });

        parser.addListener("endstylesheet", function() {
            reporter.stat("rule-count", count);
        });
    }

});

/*
 * Rule: Warn people with approaching the IE 4095 limit
 */

CSSLint.addRule({

    // rule information
    id: "selector-max-approaching",
    name: "Warn when approaching the 4095 selector limit for IE",
    desc: "Will warn when selector count is >= 3800 selectors.",
    browsers: "IE",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this, count = 0;

        parser.addListener("startrule", function(event) {
            count += event.selectors.length;
        });

        parser.addListener("endstylesheet", function() {
            if (count >= 3800) {
                reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.", 0, 0, rule);
            }
        });
    }

});

/*
 * Rule: Warn people past the IE 4095 limit
 */

CSSLint.addRule({

    // rule information
    id: "selector-max",
    name: "Error when past the 4095 selector limit for IE",
    desc: "Will error when selector count is > 4095.",
    browsers: "IE",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this, count = 0;

        parser.addListener("startrule", function(event) {
            count += event.selectors.length;
        });

        parser.addListener("endstylesheet", function() {
            if (count > 4095) {
                reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.", 0, 0, rule);
            }
        });
    }

});

/*
 * Rule: Avoid new-line characters in selectors.
 */

CSSLint.addRule({

    // rule information
    id: "selector-newline",
    name: "Disallow new-line characters in selectors",
    desc: "New-line characters in selectors are usually a forgotten comma and not a descendant combinator.",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        function startRule(event) {
            var i, len, selector, p, n, pLen, part, part2, type, currentLine, nextLine,
                selectors = event.selectors;

            for (i = 0, len = selectors.length; i < len; i++) {
                selector = selectors[i];
                for (p = 0, pLen = selector.parts.length; p < pLen; p++) {
                    for (n = p + 1; n < pLen; n++) {
                        part = selector.parts[p];
                        part2 = selector.parts[n];
                        type = part.type;
                        currentLine = part.line;
                        nextLine = part2.line;

                        if (type === "descendant" && nextLine > currentLine) {
                            reporter.report("newline character found in selector (forgot a comma?)", currentLine, selectors[i].parts[0].col, rule);
                        }
                    }
                }

            }
        }

        parser.addListener("startrule", startRule);

    }
});

/*
 * Rule: Use shorthand properties where possible.
 *
 */

CSSLint.addRule({

    // rule information
    id: "shorthand",
    name: "Require shorthand properties",
    desc: "Use shorthand properties where possible.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-shorthand-properties",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            prop, i, len,
            propertiesToCheck = {},
            properties,
            mapping = {
                "margin": [
                    "margin-top",
                    "margin-bottom",
                    "margin-left",
                    "margin-right"
                ],
                "padding": [
                    "padding-top",
                    "padding-bottom",
                    "padding-left",
                    "padding-right"
                ]
            };

        // initialize propertiesToCheck
        for (prop in mapping) {
            if (mapping.hasOwnProperty(prop)) {
                for (i=0, len=mapping[prop].length; i < len; i++) {
                    propertiesToCheck[mapping[prop][i]] = prop;
                }
            }
        }

        function startRule() {
            properties = {};
        }

        // event handler for end of rules
        function endRule(event) {

            var prop, i, len, total;

            // check which properties this rule has
            for (prop in mapping) {
                if (mapping.hasOwnProperty(prop)) {
                    total=0;

                    for (i=0, len=mapping[prop].length; i < len; i++) {
                        total += properties[mapping[prop][i]] ? 1 : 0;
                    }

                    if (total === mapping[prop].length) {
                        reporter.report("The properties " + mapping[prop].join(", ") + " can be replaced by " + prop + ".", event.line, event.col, rule);
                    }
                }
            }
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);

        // check for use of "font-size"
        parser.addListener("property", function(event) {
            var name = event.property.toString().toLowerCase();

            if (propertiesToCheck[name]) {
                properties[name] = 1;
            }
        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);

    }

});

/*
 * Rule: Don't use properties with a star prefix.
 *
 */

CSSLint.addRule({

    // rule information
    id: "star-property-hack",
    name: "Disallow properties with a star prefix",
    desc: "Checks for the star property hack (targets IE6/7)",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-star-hack",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        // check if property name starts with "*"
        parser.addListener("property", function(event) {
            var property = event.property;

            if (property.hack === "*") {
                reporter.report("Property with star prefix found.", event.property.line, event.property.col, rule);
            }
        });
    }
});

/*
 * Rule: Don't use text-indent for image replacement if you need to support rtl.
 *
 */

CSSLint.addRule({

    // rule information
    id: "text-indent",
    name: "Disallow negative text-indent",
    desc: "Checks for text indent less than -99px",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-negative-text-indent",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            textIndent,
            direction;


        function startRule() {
            textIndent = false;
            direction = "inherit";
        }

        // event handler for end of rules
        function endRule() {
            if (textIndent && direction !== "ltr") {
                reporter.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.", textIndent.line, textIndent.col, rule);
            }
        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);

        // check for use of "font-size"
        parser.addListener("property", function(event) {
            var name = event.property.toString().toLowerCase(),
                value = event.value;

            if (name === "text-indent" && value.parts[0].value < -99) {
                textIndent = event.property;
            } else if (name === "direction" && value.toString() === "ltr") {
                direction = "ltr";
            }
        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);

    }

});

/*
 * Rule: Don't use properties with a underscore prefix.
 *
 */

CSSLint.addRule({

    // rule information
    id: "underscore-property-hack",
    name: "Disallow properties with an underscore prefix",
    desc: "Checks for the underscore property hack (targets IE6)",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-underscore-hack",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        // check if property name starts with "_"
        parser.addListener("property", function(event) {
            var property = event.property;

            if (property.hack === "_") {
                reporter.report("Property with underscore prefix found.", event.property.line, event.property.col, rule);
            }
        });
    }
});

/*
 * Rule: Headings (h1-h6) should be defined only once.
 */

CSSLint.addRule({

    // rule information
    id: "unique-headings",
    name: "Headings should only be defined once",
    desc: "Headings should be defined only once.",
    url: "https://github.com/CSSLint/csslint/wiki/Headings-should-only-be-defined-once",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        var headings = {
            h1: 0,
            h2: 0,
            h3: 0,
            h4: 0,
            h5: 0,
            h6: 0
        };

        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                pseudo,
                i, j;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];
                part = selector.parts[selector.parts.length-1];

                if (part.elementName && /(h[1-6])/i.test(part.elementName.toString())) {

                    for (j=0; j < part.modifiers.length; j++) {
                        if (part.modifiers[j].type === "pseudo") {
                            pseudo = true;
                            break;
                        }
                    }

                    if (!pseudo) {
                        headings[RegExp.$1]++;
                        if (headings[RegExp.$1] > 1) {
                            reporter.report("Heading (" + part.elementName + ") has already been defined.", part.line, part.col, rule);
                        }
                    }
                }
            }
        });

        parser.addListener("endstylesheet", function() {
            var prop,
                messages = [];

            for (prop in headings) {
                if (headings.hasOwnProperty(prop)) {
                    if (headings[prop] > 1) {
                        messages.push(headings[prop] + " " + prop + "s");
                    }
                }
            }

            if (messages.length) {
                reporter.rollupWarn("You have " + messages.join(", ") + " defined in this stylesheet.", rule);
            }
        });
    }

});

/*
 * Rule: Don't use universal selector because it's slow.
 */

CSSLint.addRule({

    // rule information
    id: "universal-selector",
    name: "Disallow universal selector",
    desc: "The universal selector (*) is known to be slow.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-universal-selector",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        parser.addListener("startrule", function(event) {
            var selectors = event.selectors,
                selector,
                part,
                i;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];

                part = selector.parts[selector.parts.length-1];
                if (part.elementName === "*") {
                    reporter.report(rule.desc, part.line, part.col, rule);
                }
            }
        });
    }

});

/*
 * Rule: Don't use unqualified attribute selectors because they're just like universal selectors.
 */

CSSLint.addRule({

    // rule information
    id: "unqualified-attributes",
    name: "Disallow unqualified attribute selectors",
    desc: "Unqualified attribute selectors are known to be slow.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-unqualified-attribute-selectors",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";

        var rule = this;

        parser.addListener("startrule", function(event) {

            var selectors = event.selectors,
                selectorContainsClassOrId = false,
                selector,
                part,
                modifier,
                i, k;

            for (i=0; i < selectors.length; i++) {
                selector = selectors[i];

                part = selector.parts[selector.parts.length-1];
                if (part.type === parser.SELECTOR_PART_TYPE) {
                    for (k=0; k < part.modifiers.length; k++) {
                        modifier = part.modifiers[k];

                        if (modifier.type === "class" || modifier.type === "id") {
                            selectorContainsClassOrId = true;
                            break;
                        }
                    }

                    if (!selectorContainsClassOrId) {
                        for (k=0; k < part.modifiers.length; k++) {
                            modifier = part.modifiers[k];
                            if (modifier.type === "attribute" && (!part.elementName || part.elementName === "*")) {
                                reporter.report(rule.desc, part.line, part.col, rule);
                            }
                        }
                    }
                }

            }
        });
    }

});

/*
 * Rule: When using a vendor-prefixed property, make sure to
 * include the standard one.
 */

CSSLint.addRule({

    // rule information
    id: "vendor-prefix",
    name: "Require standard property with vendor prefix",
    desc: "When using a vendor-prefixed property, make sure to include the standard one.",
    url: "https://github.com/CSSLint/csslint/wiki/Require-standard-property-with-vendor-prefix",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this,
            properties,
            num,
            propertiesToCheck = {
                "-webkit-border-radius": "border-radius",
                "-webkit-border-top-left-radius": "border-top-left-radius",
                "-webkit-border-top-right-radius": "border-top-right-radius",
                "-webkit-border-bottom-left-radius": "border-bottom-left-radius",
                "-webkit-border-bottom-right-radius": "border-bottom-right-radius",

                "-o-border-radius": "border-radius",
                "-o-border-top-left-radius": "border-top-left-radius",
                "-o-border-top-right-radius": "border-top-right-radius",
                "-o-border-bottom-left-radius": "border-bottom-left-radius",
                "-o-border-bottom-right-radius": "border-bottom-right-radius",

                "-moz-border-radius": "border-radius",
                "-moz-border-radius-topleft": "border-top-left-radius",
                "-moz-border-radius-topright": "border-top-right-radius",
                "-moz-border-radius-bottomleft": "border-bottom-left-radius",
                "-moz-border-radius-bottomright": "border-bottom-right-radius",

                "-moz-column-count": "column-count",
                "-webkit-column-count": "column-count",

                "-moz-column-gap": "column-gap",
                "-webkit-column-gap": "column-gap",

                "-moz-column-rule": "column-rule",
                "-webkit-column-rule": "column-rule",

                "-moz-column-rule-style": "column-rule-style",
                "-webkit-column-rule-style": "column-rule-style",

                "-moz-column-rule-color": "column-rule-color",
                "-webkit-column-rule-color": "column-rule-color",

                "-moz-column-rule-width": "column-rule-width",
                "-webkit-column-rule-width": "column-rule-width",

                "-moz-column-width": "column-width",
                "-webkit-column-width": "column-width",

                "-webkit-column-span": "column-span",
                "-webkit-columns": "columns",

                "-moz-box-shadow": "box-shadow",
                "-webkit-box-shadow": "box-shadow",

                "-moz-transform": "transform",
                "-webkit-transform": "transform",
                "-o-transform": "transform",
                "-ms-transform": "transform",

                "-moz-transform-origin": "transform-origin",
                "-webkit-transform-origin": "transform-origin",
                "-o-transform-origin": "transform-origin",
                "-ms-transform-origin": "transform-origin",

                "-moz-box-sizing": "box-sizing",
                "-webkit-box-sizing": "box-sizing"
            };

        // event handler for beginning of rules
        function startRule() {
            properties = {};
            num = 1;
        }

        // event handler for end of rules
        function endRule() {
            var prop,
                i,
                len,
                needed,
                actual,
                needsStandard = [];

            for (prop in properties) {
                if (propertiesToCheck[prop]) {
                    needsStandard.push({
                        actual: prop,
                        needed: propertiesToCheck[prop]
                    });
                }
            }

            for (i=0, len=needsStandard.length; i < len; i++) {
                needed = needsStandard[i].needed;
                actual = needsStandard[i].actual;

                if (!properties[needed]) {
                    reporter.report("Missing standard property '" + needed + "' to go along with '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule);
                } else {
                    // make sure standard property is last
                    if (properties[needed][0].pos < properties[actual][0].pos) {
                        reporter.report("Standard property '" + needed + "' should come after vendor-prefixed property '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule);
                    }
                }
            }

        }

        parser.addListener("startrule", startRule);
        parser.addListener("startfontface", startRule);
        parser.addListener("startpage", startRule);
        parser.addListener("startpagemargin", startRule);
        parser.addListener("startkeyframerule", startRule);
        parser.addListener("startviewport", startRule);

        parser.addListener("property", function(event) {
            var name = event.property.text.toLowerCase();

            if (!properties[name]) {
                properties[name] = [];
            }

            properties[name].push({
                name: event.property,
                value: event.value,
                pos: num++
            });
        });

        parser.addListener("endrule", endRule);
        parser.addListener("endfontface", endRule);
        parser.addListener("endpage", endRule);
        parser.addListener("endpagemargin", endRule);
        parser.addListener("endkeyframerule", endRule);
        parser.addListener("endviewport", endRule);
    }

});

/*
 * Rule: You don't need to specify units when a value is 0.
 */

CSSLint.addRule({

    // rule information
    id: "zero-units",
    name: "Disallow units for 0 values",
    desc: "You don't need to specify units when a value is 0.",
    url: "https://github.com/CSSLint/csslint/wiki/Disallow-units-for-zero-values",
    browsers: "All",

    // initialization
    init: function(parser, reporter) {
        "use strict";
        var rule = this;

        // count how many times "float" is used
        parser.addListener("property", function(event) {
            var parts = event.value.parts,
                i = 0,
                len = parts.length;

            while (i < len) {
                if ((parts[i].units || parts[i].type === "percentage") && parts[i].value === 0 && parts[i].type !== "time") {
                    reporter.report("Values of 0 shouldn't have units specified.", parts[i].line, parts[i].col, rule);
                }
                i++;
            }

        });

    }

});

(function() {
    "use strict";

    /**
     * Replace special characters before write to output.
     *
     * Rules:
     *  - single quotes is the escape sequence for double-quotes
     *  - &amp; is the escape sequence for &
     *  - &lt; is the escape sequence for <
     *  - &gt; is the escape sequence for >
     *
     * @param {String} message to escape
     * @return escaped message as {String}
     */
    var xmlEscape = function(str) {
        if (!str || str.constructor !== String) {
            return "";
        }

        return str.replace(/["&><]/g, function(match) {
            switch (match) {
                case "\"":
                    return "&quot;";
                case "&":
                    return "&amp;";
                case "<":
                    return "&lt;";
                case ">":
                    return "&gt;";
            }
        });
    };

    CSSLint.addFormatter({
        // format information
        id: "checkstyle-xml",
        name: "Checkstyle XML format",

        /**
         * Return opening root XML tag.
         * @return {String} to prepend before all results
         */
        startFormat: function() {
            return "<?xml version=\"1.0\" encoding=\"utf-8\"?><checkstyle>";
        },

        /**
         * Return closing root XML tag.
         * @return {String} to append after all results
         */
        endFormat: function() {
            return "</checkstyle>";
        },

        /**
         * Returns message when there is a file read error.
         * @param {String} filename The name of the file that caused the error.
         * @param {String} message The error message
         * @return {String} The error message.
         */
        readError: function(filename, message) {
            return "<file name=\"" + xmlEscape(filename) + "\"><error line=\"0\" column=\"0\" severty=\"error\" message=\"" + xmlEscape(message) + "\"></error></file>";
        },

        /**
         * Given CSS Lint results for a file, return output for this format.
         * @param results {Object} with error and warning messages
         * @param filename {String} relative file path
         * @param options {Object} (UNUSED for now) specifies special handling of output
         * @return {String} output for results
         */
        formatResults: function(results, filename/*, options*/) {
            var messages = results.messages,
                output = [];

            /**
             * Generate a source string for a rule.
             * Checkstyle source strings usually resemble Java class names e.g
             * net.csslint.SomeRuleName
             * @param {Object} rule
             * @return rule source as {String}
             */
            var generateSource = function(rule) {
                if (!rule || !("name" in rule)) {
                    return "";
                }
                return "net.csslint." + rule.name.replace(/\s/g, "");
            };


            if (messages.length > 0) {
                output.push("<file name=\""+filename+"\">");
                CSSLint.Util.forEach(messages, function (message) {
                    // ignore rollups for now
                    if (!message.rollup) {
                        output.push("<error line=\"" + message.line + "\" column=\"" + message.col + "\" severity=\"" + message.type + "\"" +
                          " message=\"" + xmlEscape(message.message) + "\" source=\"" + generateSource(message.rule) +"\"/>");
                    }
                });
                output.push("</file>");
            }

            return output.join("");
        }
    });

}());

CSSLint.addFormatter({
    // format information
    id: "compact",
    name: "Compact, 'porcelain' format",

    /**
     * Return content to be printed before all file results.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        return "";
    },

    /**
     * Return content to be printed after all file results.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        return "";
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path
     * @param options {Object} (Optional) specifies special handling of output
     * @return {String} output for results
     */
    formatResults: function(results, filename, options) {
        "use strict";
        var messages = results.messages,
            output = "";
        options = options || {};

        /**
         * Capitalize and return given string.
         * @param str {String} to capitalize
         * @return {String} capitalized
         */
        var capitalize = function(str) {
            return str.charAt(0).toUpperCase() + str.slice(1);
        };

        if (messages.length === 0) {
            return options.quiet ? "" : filename + ": Lint Free!";
        }

        CSSLint.Util.forEach(messages, function(message) {
            if (message.rollup) {
                output += filename + ": " + capitalize(message.type) + " - " + message.message + " (" + message.rule.id + ")\n";
            } else {
                output += filename + ": line " + message.line +
                    ", col " + message.col + ", " + capitalize(message.type) + " - " + message.message + " (" + message.rule.id + ")\n";
            }
        });

        return output;
    }
});

CSSLint.addFormatter({
    // format information
    id: "csslint-xml",
    name: "CSSLint XML format",

    /**
     * Return opening root XML tag.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        return "<?xml version=\"1.0\" encoding=\"utf-8\"?><csslint>";
    },

    /**
     * Return closing root XML tag.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        return "</csslint>";
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path
     * @param options {Object} (UNUSED for now) specifies special handling of output
     * @return {String} output for results
     */
    formatResults: function(results, filename/*, options*/) {
        "use strict";
        var messages = results.messages,
            output = [];

        /**
         * Replace special characters before write to output.
         *
         * Rules:
         *  - single quotes is the escape sequence for double-quotes
         *  - &amp; is the escape sequence for &
         *  - &lt; is the escape sequence for <
         *  - &gt; is the escape sequence for >
         *
         * @param {String} message to escape
         * @return escaped message as {String}
         */
        var escapeSpecialCharacters = function(str) {
            if (!str || str.constructor !== String) {
                return "";
            }
            return str.replace(/"/g, "'").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        };

        if (messages.length > 0) {
            output.push("<file name=\""+filename+"\">");
            CSSLint.Util.forEach(messages, function (message) {
                if (message.rollup) {
                    output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
                } else {
                    output.push("<issue line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" +
                        " reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
                }
            });
            output.push("</file>");
        }

        return output.join("");
    }
});

/* globals JSON: true */

CSSLint.addFormatter({
    // format information
    id: "json",
    name: "JSON",

    /**
     * Return content to be printed before all file results.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        this.json = [];
        return "";
    },

    /**
     * Return content to be printed after all file results.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        var ret = "";
        if (this.json.length > 0) {
            if (this.json.length === 1) {
                ret = JSON.stringify(this.json[0]);
            } else {
                ret = JSON.stringify(this.json);
            }
        }
        return ret;
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path (Unused)
     * @return {String} output for results
     */
    formatResults: function(results, filename, options) {
        "use strict";
        if (results.messages.length > 0 || !options.quiet) {
            this.json.push({
                filename: filename,
                messages: results.messages,
                stats: results.stats
            });
        }
        return "";
    }
});

CSSLint.addFormatter({
    // format information
    id: "junit-xml",
    name: "JUNIT XML format",

    /**
     * Return opening root XML tag.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        return "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites>";
    },

    /**
     * Return closing root XML tag.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        return "</testsuites>";
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path
     * @param options {Object} (UNUSED for now) specifies special handling of output
     * @return {String} output for results
     */
    formatResults: function(results, filename/*, options*/) {
        "use strict";

        var messages = results.messages,
            output = [],
            tests = {
                "error": 0,
                "failure": 0
            };

        /**
         * Generate a source string for a rule.
         * JUNIT source strings usually resemble Java class names e.g
         * net.csslint.SomeRuleName
         * @param {Object} rule
         * @return rule source as {String}
         */
        var generateSource = function(rule) {
            if (!rule || !("name" in rule)) {
                return "";
            }
            return "net.csslint." + rule.name.replace(/\s/g, "");
        };

        /**
         * Replace special characters before write to output.
         *
         * Rules:
         *  - single quotes is the escape sequence for double-quotes
         *  - &lt; is the escape sequence for <
         *  - &gt; is the escape sequence for >
         *
         * @param {String} message to escape
         * @return escaped message as {String}
         */
        var escapeSpecialCharacters = function(str) {

            if (!str || str.constructor !== String) {
                return "";
            }

            return str.replace(/"/g, "'").replace(/</g, "&lt;").replace(/>/g, "&gt;");

        };

        if (messages.length > 0) {

            messages.forEach(function (message) {

                // since junit has no warning class
                // all issues as errors
                var type = message.type === "warning" ? "error" : message.type;

                // ignore rollups for now
                if (!message.rollup) {

                    // build the test case separately, once joined
                    // we'll add it to a custom array filtered by type
                    output.push("<testcase time=\"0\" name=\"" + generateSource(message.rule) + "\">");
                    output.push("<" + type + " message=\"" + escapeSpecialCharacters(message.message) + "\"><![CDATA[" + message.line + ":" + message.col + ":" + escapeSpecialCharacters(message.evidence) + "]]></" + type + ">");
                    output.push("</testcase>");

                    tests[type] += 1;

                }

            });

            output.unshift("<testsuite time=\"0\" tests=\"" + messages.length + "\" skipped=\"0\" errors=\"" + tests.error + "\" failures=\"" + tests.failure + "\" package=\"net.csslint\" name=\"" + filename + "\">");
            output.push("</testsuite>");

        }

        return output.join("");

    }
});

CSSLint.addFormatter({
    // format information
    id: "lint-xml",
    name: "Lint XML format",

    /**
     * Return opening root XML tag.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        return "<?xml version=\"1.0\" encoding=\"utf-8\"?><lint>";
    },

    /**
     * Return closing root XML tag.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        return "</lint>";
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path
     * @param options {Object} (UNUSED for now) specifies special handling of output
     * @return {String} output for results
     */
    formatResults: function(results, filename/*, options*/) {
        "use strict";
        var messages = results.messages,
            output = [];

        /**
         * Replace special characters before write to output.
         *
         * Rules:
         *  - single quotes is the escape sequence for double-quotes
         *  - &amp; is the escape sequence for &
         *  - &lt; is the escape sequence for <
         *  - &gt; is the escape sequence for >
         *
         * @param {String} message to escape
         * @return escaped message as {String}
         */
        var escapeSpecialCharacters = function(str) {
            if (!str || str.constructor !== String) {
                return "";
            }
            return str.replace(/"/g, "'").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
        };

        if (messages.length > 0) {

            output.push("<file name=\""+filename+"\">");
            CSSLint.Util.forEach(messages, function (message) {
                if (message.rollup) {
                    output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
                } else {
                    var rule = "";
                    if (message.rule && message.rule.id) {
                        rule = "rule=\"" + escapeSpecialCharacters(message.rule.id) + "\" ";
                    }
                    output.push("<issue " + rule + "line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" +
                        " reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
                }
            });
            output.push("</file>");
        }

        return output.join("");
    }
});

CSSLint.addFormatter({
    // format information
    id: "text",
    name: "Plain Text",

    /**
     * Return content to be printed before all file results.
     * @return {String} to prepend before all results
     */
    startFormat: function() {
        "use strict";
        return "";
    },

    /**
     * Return content to be printed after all file results.
     * @return {String} to append after all results
     */
    endFormat: function() {
        "use strict";
        return "";
    },

    /**
     * Given CSS Lint results for a file, return output for this format.
     * @param results {Object} with error and warning messages
     * @param filename {String} relative file path
     * @param options {Object} (Optional) specifies special handling of output
     * @return {String} output for results
     */
    formatResults: function(results, filename, options) {
        "use strict";
        var messages = results.messages,
            output = "";
        options = options || {};

        if (messages.length === 0) {
            return options.quiet ? "" : "\n\ncsslint: No errors in " + filename + ".";
        }

        output = "\n\ncsslint: There ";
        if (messages.length === 1) {
            output += "is 1 problem";
        } else {
            output += "are " + messages.length + " problems";
        }
        output += " in " + filename + ".";

        var pos = filename.lastIndexOf("/"),
            shortFilename = filename;

        if (pos === -1) {
            pos = filename.lastIndexOf("\\");
        }
        if (pos > -1) {
            shortFilename = filename.substring(pos+1);
        }

        CSSLint.Util.forEach(messages, function (message, i) {
            output = output + "\n\n" + shortFilename;
            if (message.rollup) {
                output += "\n" + (i+1) + ": " + message.type;
                output += "\n" + message.message;
            } else {
                output += "\n" + (i+1) + ": " + message.type + " at line " + message.line + ", col " + message.col;
                output += "\n" + message.message;
                output += "\n" + message.evidence;
            }
        });

        return output;
    }
});

return CSSLint;
})();/**
 * @preserve JSizes - JQuery plugin v0.33
 *
 * Licensed under the revised BSD License.
 * Copyright 2008-2010 Bram Stein
 * All rights reserved.
 */
/*global jQuery*/
(function ($) {
    'use strict';
    var num = function (value) {
        return parseInt(value, 10) || 0;
    };

    /**
     * Sets or gets the values for min-width, min-height, max-width
     * and max-height.
     */
    $.each(['min', 'max'], function (i, name) {
        $.fn[name + 'Size'] = function (value) {
            var width, height;
            if (value) {
                if (value.width !== undefined) {
                    this.css(name + '-width', value.width);
                }
                if (value.height !== undefined) {
                    this.css(name + '-height', value.height);
                }
            } else {
                width = this.css(name + '-width');
                height = this.css(name + '-height');
                // Apparently:
                //  * Opera returns -1px instead of none
                //  * IE6 returns undefined instead of none
                return {'width': (name === 'max' && (width === undefined || width === 'none' || num(width) === -1) && Number.MAX_VALUE) || num(width),
                    'height': (name === 'max' && (height === undefined || height === 'none' || num(height) === -1) && Number.MAX_VALUE) || num(height)};
            }
            return this;
        };
    });

    /**
     * Returns whether or not an element is visible.
     */
    $.fn.isVisible = function () {
        return this.is(':visible');
    };

    /**
     * Sets or gets the values for border, margin and padding.
     */
    $.each(['border', 'margin', 'padding'], function (i, name) {
        $.fn[name] = function (value) {
            if (value) {
                if (value.top !== undefined) {
                    this.css(name + '-top' + (name === 'border' ? '-width' : ''), value.top);
                }
                if (value.bottom !== undefined) {
                    this.css(name + '-bottom' + (name === 'border' ? '-width' : ''), value.bottom);
                }
                if (value.left !== undefined) {
                    this.css(name + '-left' + (name === 'border' ? '-width' : ''), value.left);
                }
                if (value.right !== undefined) {
                    this.css(name + '-right' + (name === 'border' ? '-width' : ''), value.right);
                }
            } else {
                return {top: num(this.css(name + '-top' + (name === 'border' ? '-width' : ''))),
                    bottom: num(this.css(name + '-bottom' + (name === 'border' ? '-width' : ''))),
                    left: num(this.css(name + '-left' + (name === 'border' ? '-width' : ''))),
                    right: num(this.css(name + '-right' + (name === 'border' ? '-width' : '')))};
            }
            return this;
        };
    });
}(jQuery));/* globals jQuery, _, socssOptions, Backbone, CodeMirror, console, cssjs, wp */

( function ( $, _, socssOptions ) {
	
	var socss = {
		model: {},
		collection: {},
		view: {},
		fn: {}
	};
	
	window.socss = socss;
	
	socss.model.CustomCssModel = Backbone.Model.extend( {
		defaults: {
			postId: null,
			postTitle: null,
			css: null,
		},
		
		urlRoot: socssOptions.postCssUrlRoot,
		
		url: function () {
			return this.urlRoot + '&postId=' + this.get( 'postId' );
		}
	} );
	
	socss.model.CustomCssCollection = Backbone.Collection.extend( {
		model: socss.model.CustomCssModel,
		
		modelId: function( attrs ) {
			return attrs.postId;
		},
	} );
	
	socss.model.CSSEditorModel = Backbone.Model.extend( {
		defaults: {
			customCssPosts: null,
		}
	} );
	
	/**
	 * The toolbar view
	 */
	socss.view.toolbar = Backbone.View.extend( {
		
		button: _.template( '<li><a href="#<%= action %>" class="toolbar-button socss-button"><%= text %></a></li>' ),
		
		events: {
			'click .socss-button:not(.save)': 'triggerEvent',
		},
		
		triggerEvent: function ( event ) {
			event.preventDefault();
			var $target = $( event.currentTarget );
			$target.trigger( 'blur' );
			var value = $target.attr( 'href' ).replace( '#', '' );
			this.$el.trigger( 'click_' + value );
		},
		
		addButton: function ( text, action ) {
			var button = $( this.button( { text: text, action: action } ) )
			.appendTo( this.$( '.toolbar-function-buttons .toolbar-buttons' ) );
			
			return button;
		},
	} );
	
	/**
	 * The editor view, which handles codemirror stuff
	 *
	 * model: socss.model.CSSEditorModel
	 *
	 */
	socss.view.editor = Backbone.View.extend( {
		
		codeMirror: null,
		snippets: null,
		toolbar: null,
		visualProperties: null,
		
		inspector: null,
		
		cssSelectors: [],
		
		initValue: null,
		
		events: {
			'click_expand .custom-css-toolbar': 'toggleExpand',
			'click_visual .custom-css-toolbar': 'showVisualEditor',
			'click .socss-button.save': 'save',
			'submit': 'onSubmit',
		},
		
		initialize: function ( options ) {
			
			this.listenTo( this.model, 'change:selectedPost', this.getSelectedPostCss );
			
			this.getSelectedPostCss().then( function () {
				
				if ( options.openVisualEditor ) {
					this.showVisualEditor();
				}
			}.bind( this ) );
			
		},

		save: function () {
			socss.save( this );
		},
		
		getSelectedPostCss: function () {
			var selectedPost = this.model.get( 'selectedPost' );
			var promise;
			if ( selectedPost && ! selectedPost.has( 'css' ) ) {
				promise = selectedPost.fetch();
			} else {
				promise = new $.Deferred().resolve();
			}
			
			return promise.then( this.render.bind( this ) );
		},
		
		render: function () {
			
			var selectedPost = this.model.get( 'selectedPost' );
			
			if ( selectedPost && !selectedPost.has( 'css' ) ) {
				return this;
			}
			
			if ( !this.codeMirror ) {
				this.setupEditor();
			}
			
			if ( ! this.toolbar ) {
				this.toolbar = new socss.view.toolbar( {
					el: this.$( '.custom-css-toolbar' ),
					model: this.model,
				} );
				this.toolbar.render();
			}
			
			if ( !this.visualProperties ) {
				this.visualProperties = new socss.view.properties( {
					editor: this,
					el: $( '#so-custom-css-properties' )
				} );
				this.visualProperties.render();
			}
			
			if ( !this.preview ) {
				this.preview = new socss.view.preview( {
					editor: this,
					model: this.model,
					el: this.$( '.custom-css-preview' ),
					initURL: socssOptions.homeURL,
				} );
				this.preview.render();
			}
			
			if ( selectedPost ) {
				this.codeMirror.setValue( selectedPost.get( 'css' ) );
				this.codeMirror.clearHistory();
			}
			
			return this;
		},
		
		/**
		 * Do the initial setup of the CodeMirror editor
		 */
		setupEditor: function () {			
			// Setup the Codemirror instance
			var $textArea = this.$( 'textarea.css-editor' );
			this.initValue = $textArea.val();
			// Pad with empty lines so the editor takes up all the white space. To try make sure user gets copy/paste
			// options in context menu.
			var newlineMatches = this.initValue.match( /\n/gm );
			var lineCount = newlineMatches ? newlineMatches.length + 1 : 1;
			var paddedValue = this.initValue;
			$textArea.val( paddedValue );

			var codeMirrorSettings = {
				tabSize: 2,
				lineNumbers: true,
				mode: 'css',
				theme: $textArea.data( 'theme' ),
				inputStyle: 'contenteditable', //necessary to allow context menu (right click) copy/paste etc.
				gutters: [
					"CodeMirror-lint-markers"
				],
				lint: true,
				search: true,
				dialog: true,
				annotateScrollbar: true,
				extraKeys: {
					'Ctrl-F': 'findPersistent',
					'Alt-G': 'jumpToLine',
				},
			}

			if ( typeof wp.codeEditor != "undefined" ) {
				codeMirrorSettings = _.extend(
					wp.codeEditor.defaultSettings.codemirror,
					codeMirrorSettings
				);
				this.codeMirror = wp.codeEditor.initialize( $textArea.get( 0 ), codeMirrorSettings ).codemirror;
			} else {
				this.registerCodeMirrorAutocomplete();
				this.codeMirror = CodeMirror.fromTextArea( $textArea.get( 0 ), codeMirrorSettings );
				this.setupCodeMirrorExtensions();
			}

			var editor = this.codeMirror;
			$( '#so_css_editor_theme' ).on( 'change', function() {
				if ( $( this ).val() == 1 ) {
					editor.setOption( 'theme', 'neat' );
				} else {
					editor.setOption( 'theme', 'ambiance' );
				}
			} );

			this.codeMirror.on( 'change', function ( cm, change ) {
				var selectedPost = this.model.get( 'selectedPost' );
				if ( selectedPost && selectedPost.get( 'css' ) !== cm.getValue().trim() ) {
					selectedPost.set( 'css', cm.getValue().trim() );
				}
			}.bind( this ) );
			
			// Make sure the user doesn't leave without saving
			$( window ).on( 'beforeunload', function () {
				var editorValue = this.codeMirror.getValue().trim();
				if ( editorValue !== this.initValue ) {
					return socssOptions.loc.leave;
				}
			}.bind( this ) );
			
			
			// Set the container to visible overflow once the editor is setup
			this.$el.find( '.custom-css-container' ).css( 'overflow', 'visible' );
			this.scaleEditor();
			
			// Scale the editor whenever the window is resized
			$( window ).on( 'resize', function () {
				this.scaleEditor();
			}.bind( this ) );
		},
		
		onSubmit: function () {
			this.initValue = this.codeMirror.getValue().trim();
		},
		
		/**
		 * Register the autocomplete helper. Based on css-hint.js in the codemirror addon folder.
		 */
		registerCodeMirrorAutocomplete: function () {
			var pseudoClasses = {
				link: 1, visited: 1, active: 1, hover: 1, focus: 1,
				"first-letter": 1, "first-line": 1, "first-child": 1,
				before: 1, after: 1, lang: 1
			};
			
			CodeMirror.registerHelper( "hint", "css", function ( cm ) {
				var cur = cm.getCursor(), token = cm.getTokenAt( cur );
				var inner = CodeMirror.innerMode( cm.getMode(), token.state );
				if ( inner.mode.name !== "css" ) {
					return;
				}
				
				if ( token.type === "keyword" && "!important".indexOf( token.string ) === 0 ) {
					return {
						list: [ "!important" ], from: CodeMirror.Pos( cur.line, token.start ),
						to: CodeMirror.Pos( cur.line, token.end )
					};
				}
				
				var start = token.start, end = cur.ch, word = token.string.slice( 0, end - start );
				if ( /[^\w$_-]/.test( word ) ) {
					word = "";
					start = end = cur.ch;
				}
				
				var spec = CodeMirror.resolveMode( "text/css" );
				
				var result = [];
				
				function add( keywords ) {
					for ( var name in keywords ) {
						if ( !word || name.lastIndexOf( word, 0 ) === 0 ) {
							result.push( name );
						}
					}
				}
				
				var st = inner.state.state;
				
				if ( st === 'top' ) {
					// We're going to autocomplete the selector using our own set of rules
					var line = cm.getLine( cur.line ).trim();
					
					var selectors = this.cssSelectors;
					for ( var i = 0; i < selectors.length; i++ ) {
						if ( selectors[ i ].selector.indexOf( line ) !== -1 ) {
							result.push( selectors[ i ].selector );
						}
					}
					
					if ( result.length ) {
						return {
							list: result,
							from: CodeMirror.Pos( cur.line, 0 ),
							to: CodeMirror.Pos( cur.line, end )
						};
					}
				}
				else {
					
					if ( st === "pseudo" || token.type === "variable-3" ) {
						add( pseudoClasses );
					}
					else if ( st === "block" || st === "maybeprop" ) {
						add( spec.propertyKeywords );
					}
					else if ( st === "prop" || st === "parens" || st === "at" || st === "params" ) {
						add( spec.valueKeywords );
						add( spec.colorKeywords );
					}
					else if ( st === "media" || st === "media_parens" ) {
						add( spec.mediaTypes );
						add( spec.mediaFeatures );
					}
					
					if ( result.length ) {
						return {
							list: result,
							from: CodeMirror.Pos( cur.line, start ),
							to: CodeMirror.Pos( cur.line, end )
						};
					}
					
				}
				
			}.bind( this ) );
		},
		
		setupCodeMirrorExtensions: function () {
			
			this.codeMirror.on( 'cursorActivity', function ( cm ) {
				var cur = cm.getCursor(), token = cm.getTokenAt( cur );
				var inner = CodeMirror.innerMode( cm.getMode(), token.state );
				
				// If we have a qualifier selected, then highlight that in the preview
				if ( token.type === 'qualifier' || token.type === 'tag' || token.type === 'builtin' ) {
					var line = cm.getLine( cur.line );
					var selector = line.substring( 0, token.end );
					
					this.preview.highlight( selector );
				}
				else {
					this.preview.clearHighlight();
				}
			}.bind( this ) );
			
			if ( typeof CodeMirror.showHint == 'function' ) {
				// This sets up automatic autocompletion at all times
				this.codeMirror.on( 'keyup', function ( cm, e ) {
					if (
						( e.keyCode >= 65 && e.keyCode <= 90 ) ||
						( e.keyCode === 189 && !e.shiftKey ) ||
						( e.keyCode === 190 && !e.shiftKey ) ||
						( e.keyCode === 51 && e.shiftKey ) ||
						( e.keyCode === 189 && e.shiftKey )
					) {
						cm.showHint( {
							completeSingle: false
						} );
					}
				} );
			}
		},
		
		/**
		 * Scale the size of the editor depending on whether it's expanded or not
		 */
		scaleEditor: function () {
			var windowHeight = $( window ).outerHeight();
			var areaHeight;
			if ( this.$el.hasClass( 'expanded' ) ) {
				// If we're in the expanded view, then resize the editor
				this.$el.find( '.CodeMirror-scroll' ).css( 'max-height', '' );
				areaHeight = windowHeight - this.$( '.custom-css-toolbar' ).outerHeight();
				this.codeMirror.setSize( '100%', areaHeight );
				this.$el.find( '.CodeMirror-scroll' ).css( 'height', '100%' );
			}
			else {
				// Attempt to calculate approximate space available for editor when not expanded.
				var $form = $( '#so-custom-css-form' );
				var otherEltsHeight = $( '#wpadminbar' ).outerHeight( true ) +
					$( '#siteorigin-custom-css' ).find( '> h2' ).outerHeight( true ) +
					$form.find( '> .custom-css-toolbar' ).outerHeight( true ) +
					$form.find( '> .so-css-footer' ).outerHeight( true ) +
					parseFloat( $( '#wpbody-content' ).css( 'padding-bottom' ) );

				areaHeight = windowHeight - otherEltsHeight;
				// The container has a min-height of 300px so we need to ensure the areaHeight is at least that large.
				if ( areaHeight < 300 ) {
					areaHeight = 300;
				}

				this.codeMirror.setSize( '100%', 'auto' );
				this.$el.find( '.CodeMirror-scroll' ).css( 'height', areaHeight + 'px' );
			}
			this.$el.find( '.CodeMirror-code' ).css( 'height', areaHeight + 'px' );
		},
		
		/**
		 * Check if the editor is in expanded mode
		 * @returns bool
		 */
		isExpanded: function () {
			return this.$el.hasClass( 'expanded' );
		},
		
		/**
		 * Toggle if this is expanded or not
		 */
		toggleExpand: function ( e ) {
			$( '.editor-expand' ).attr( 'title', $( '.so-css-icon-' + ( this.isExpanded() ? 'expand' : 'compress ') ).attr( 'title' ) );
			this.$el.toggleClass( 'expanded' );
			this.scaleEditor();
		},
		
		/**
		 * Set the expanded state of the editor
		 * @param expanded
		 */
		setExpand: function ( expanded ) {
			if ( expanded ) {
				this.$el.addClass( 'expanded' );
			}
			else {
				this.$el.removeClass( 'expanded' );
			}
			this.scaleEditor();
		},
		
		/**
		 * Show the visual editor view.
		 */
		showVisualEditor: function () {
			this.visualProperties.loadCSS( this.codeMirror.getValue().trim() );
			this.visualProperties.show();
		},
		
		/**
		 * Set the snippets available to this editor
		 */
		setSnippets: function ( snippets ) {
			if ( !_.isEmpty( snippets ) ) {
				
				this.snippets = new socss.view.snippets( {
					snippets: snippets
				} );
				this.snippets.editor = this;
				
				this.snippets.render();
				this.toolbar.addButton( 'Snippets', 'snippets' );
				this.toolbar.on( 'click_snippets', function () {
					this.snippets.show();
				}.bind( this ) );
			}
		},
		
		/**
		 * Add some CSS to the editor.
		 * @param css
		 */
		addCode: function ( css ) {
			var editor = this.codeMirror;
			
			var before_css = '';
			if ( editor.doc.lineCount() === 1 && editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
				before_css = "";
			}
			else if ( editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
				before_css = "\n";
			}
			else {
				before_css = "\n\n";
			}
			
			// Now insert the code in the editor
			editor.doc.setCursor(
				editor.doc.lastLine(),
				editor.doc.getLine( editor.doc.lastLine() ).length
			);
			editor.doc.replaceSelection( before_css + css );
		},
		
		addEmptySelector: function ( selector ) {
			this.addCode( selector + " {\n  \n}" );
		},
		
		/**
		 * Sets the inspector view that's being used by the editor
		 */
		setInspector: function ( inspector ) {
			this.inspector = inspector;
			this.cssSelectors = inspector.pageSelectors;
			
			// A selector is clicked in the inspector
			inspector.on( 'click_selector', function ( selector ) {
				if ( this.visualProperties.isVisible() ) {
					this.visualProperties.addSelector( selector );
				}
				else {
					this.addEmptySelector( selector );
				}
			}.bind( this ) );
			
			// A property is clicked in the inspector
			inspector.on( 'click_property', function ( property ) {
				if ( !this.visualProperties.isVisible() ) {
					this.codeMirror.replaceSelection( property + ";\n  " );
				}
			}.bind( this ) );
			
			inspector.on( 'set_active_element', function ( el, selectors ) {
				if ( this.visualProperties.isVisible() && selectors.length ) {
					this.visualProperties.addSelector( selectors[ 0 ].selector );
				}
			}.bind( this ) );
		}
		
	} );
	
	/**
	 * The preview.
	 */
	socss.view.preview = Backbone.View.extend( {
		
		template: _.template( $( '#template-preview-window' ).html() ),
		editor: null,
		originalUri: null,
		currentUri: null,
		
		events: {
			'mouseleave #preview-iframe': 'clearHighlight',
			'keydown #preview-navigator input[type="text"]': 'reloadPreview',
		},
		
		initialize: function ( attr ) {
			this.editor = attr.editor;
			
			this.listenTo( this.model, 'change:selectedPost', this.render.bind( this ) );
			
			this.originalUri = new URI( attr.initURL );
			this.currentUri = new URI( attr.initURL );
			
			this.editor.codeMirror.on( 'change', function ( cm, c ) {
				this.updatePreviewCss();
			}.bind( this ) );
		},
		
		render: function () {
			
			var selectedPost = this.model.get( 'selectedPost' );
			
			if ( selectedPost && !selectedPost.has( 'postUrl' ) ) {
				selectedPost.fetch().then( this.render.bind( this ) );
				return this;
			}
			
			this.$el.html( this.template() );
			
			if ( selectedPost ) {
				this.currentUri = new URI( selectedPost.get( 'postUrl' ) );
			}
			
			this.currentUri.removeQuery( 'so_css_preview', 1 );
			this.$( '#preview-navigator input' ).val( this.currentUri.toString() );
			this.currentUri.addQuery( 'so_css_preview', 1 );
			
			this.$( '#preview-iframe' )
				.attr( 'src', this.currentUri.toString() )
				// 'load' event doesn't bubble so can't be used in the events hash
				.on( 'load', this.initPreview.bind( this ) );
		},
		
		initPreview: function () {
			var $$ = this.$( '#preview-iframe' );
			
			// Update the current URI with the iframe URI
			this.currentUri = new URI( $$.contents().get( 0 ).location.href );
			this.currentUri.removeQuery( 'so_css_preview' );
			this.$( '#preview-navigator input' ).val( this.currentUri.toString() );
			this.currentUri.addQuery( 'so_css_preview', 1 );

			var wcCheck = $$.contents().find( '.single-product' ).length;
			$$.contents().find( 'a' ).each( function () {
				var link = $( this );
				var href = link.attr( 'href' );
				if ( href === undefined || ( wcCheck && link.parents( '.wc-tabs' ).length ) ) {
					return true;
				}

				var firstSeperator = ( href.indexOf( '?' ) === -1 ? '?' : '&' );
				link.attr( 'href', href + firstSeperator + 'so_css_preview=1' );
			} );
			
			this.updatePreviewCss();
		},
		
		reloadPreview: function ( e ) {
			var $$ = this.$( '#preview-navigator input[type="text"]' );
			
			if ( e.keyCode === 13 ) {
				e.preventDefault();
				
				var newUri = new URI( $$.val() );
				
				// Validate the URI
				if (
					this.originalUri.host() !== newUri.host() ||
					this.originalUri.protocol() !== newUri.protocol()
				) {
					$$.trigger( 'blur' );
					alert( $$.data( 'invalid-uri' ) );
					$$.trigger( 'focus' );
				}
				else {
					newUri.addQuery( 'so_css_preview', 1 );
					this.$( '#preview-iframe' ).attr( 'src', newUri.toString() );
				}
			}
		},
		
		/**
		 * Update the preview CSS from the CodeMirror value in the editor
		 */
		updatePreviewCss: function () {
			var preview = this.$( '#preview-iframe' );
			if ( preview.length === 0 ) {
				return;
			}
			
			var head = preview.contents().find( 'head' );
			if ( head.find( 'style.siteorigin-custom-css' ).length === 0 ) {
				head.append( '<style class="siteorigin-custom-css" type="text/css"></style>' );
			}
			var style = head.find( 'style.siteorigin-custom-css' );
			
			// Update the CSS after a short delay
			var css = this.editor.codeMirror.getValue().trim();
			style.html( css );
		},
		
		/**
		 * Highlight all elements with a given selector
		 */
		highlight: function ( selector ) {
			try {
				this.editor.inspector.hl.highlight( selector );
			}
			catch ( err ) {
				console.log( 'No inspector to highlight with' );
			}
		},
		
		/**
		 * Clear the currently highlighted elements in preview
		 */
		clearHighlight: function () {
			try {
				this.editor.inspector.hl.clear();
			}
			catch ( err ) {
				console.log( 'No inspector to highlight with' );
			}
		}
		
	} );
	
	/**
	 * The dialog for the snippets browser
	 */
	socss.view.snippets = Backbone.View.extend( {
		template: _.template( $( '#template-snippet-browser' ).html() ),
		snippet: _.template( '<li class="snippet"><%- name %></li>' ),
		className: 'css-editor-snippet-browser',
		snippets: null,
		editor: null,
		
		events: {
			'click .close': 'hide',
			'click .buttons .insert-snippet': 'insertSnippet',
			'click .snippet': 'clickSnippet',
		},
		
		currentSnippet: null,
		
		initialize: function ( args ) {
			this.snippets = args.snippets;
		},
		
		render: function () {
			this.$el.html( this.template() );
			for ( var i = 0; i < this.snippets.length; i++ ) {
				$( this.snippet( { name: this.snippets[ i ].Name } ) )
				.data( {
					'description': this.snippets[ i ].Description,
					'css': this.snippets[ i ].css
				} )
				.appendTo( this.$( 'ul.snippets' ) );
			}
			
			// Click on the first one
			this.$( '.snippets li.snippet' ).eq( 0 ).trigger( 'click' );
			
			this.attach();
			return this;
		},
		
		clickSnippet: function ( event ) {
			event.preventDefault();
			var $$ = $( event.currentTarget );
			
			this.$( '.snippets li.snippet' ).removeClass( 'active' );
			$( this ).addClass( 'active' );
			this.viewSnippet( {
				name: $$.html(),
				description: $$.data( 'description' ),
				css: $$.data( 'css' )
			} );
		},
		
		viewSnippet: function ( args ) {
			var w = this.$( '.main .snippet-view' );
			
			w.find( '.snippet-title' ).html( args.name );
			w.find( '.snippet-description' ).html( args.description );
			w.find( '.snippet-code' ).html( args.css );
			
			this.currentSnippet = args;
		},
		
		insertSnippet: function () {
			var editor = this.editor.codeMirror;
			var css = this.currentSnippet.css;
			
			var before_css = '';
			if ( editor.doc.lineCount() === 1 && editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
				before_css = "";
			}
			else if ( editor.doc.getLine( editor.doc.lastLine() ).length === 0 ) {
				before_css = "\n";
			}
			else {
				before_css = "\n\n";
			}
			
			// Now insert the code in the editor
			editor.doc.setCursor(
				editor.doc.lastLine(),
				editor.doc.getLine( editor.doc.lastLine() ).length
			);
			editor.doc.replaceSelection( before_css + css );
			
			this.hide();
		},
		
		attach: function () {
			this.$el.appendTo( 'body' );
		},
		
		show: function () {
			this.$el.show();
		},
		
		hide: function () {
			this.$el.hide();
		}
	} );

	socss.save = function ( view ) {
		let saveBtn = $( '#siteorigin-custom-css .save' );
		var css;

		if ( ! saveBtn.hasClass( 'button-primary-disabled' ) ) {
			saveBtn.addClass( 'button-primary-disabled' )

			// Which view is the user using?
			if ( typeof view.editor != 'undefined' ) {
				// Visual.
				css = view.editor.codeMirror.getValue().trim();
				view.updateMainEditor( true );
			} else {
				// Expanded.
				css = view.codeMirror.getValue().trim();
			}
			$.post(
				socssOptions.ajaxurl,
				{
					action: 'socss_save_css',
					css: css,
				},
				null,
				'html'
			).done( function ( response ) {
				if ( response.length ) {
					// Update was successful. Update revisions list.
					$( '.custom-revisions-list' ).html( response );
				}
			})
			.fail( function ( error ) {
				// Something went wrong. Output the error message as an alert.
				alert( error.responseText );
			} )
			.always( function () {
				saveBtn.removeClass( 'button-primary-disabled' )
			} );
		}
	};

	/**
	 * The visual properties editor
	 */
	socss.view.properties = Backbone.View.extend( {
		
		tabTemplate: _.template( '<li data-section="<%- id %>"><span class="so-css-icon so-css-icon-<%- icon %>"></span> <%- title %></li>' ),
		sectionTemplate: _.template( '<div class="section" data-section="<%- id %>"><table class="fields-table"><tbody></tbody></table></div>' ),
		controllerTemplate: _.template( '<tr><th scope="row"><%- title %></th><td></td></tr>' ),
		
		/**
		 * The controllers for each of the properties
		 */
		propertyControllers: [],
		
		/**
		 * The editor view
		 */
		editor: null,
		
		/**
		 * The current, raw CSS
		 */
		css: '',
		
		/**
		 * Parsed CSS
		 */
		parsed: {},
		
		/**
		 * The current active selector
		 */
		activeSelector: '',
		
		/**
		 * Was the editor expanded before we went into the property editor
		 */
		editorExpandedBefore: false,
		
		events: {
			'click .close': 'hide',
			'click .save': 'save',
			'click .section-tabs li': 'onTabClick',
			'change .toolbar select': 'onToolbarSelectChange',
		},
		
		/**
		 * Initialize the properties editor with a new model
		 */
		initialize: function ( options ) {
			this.parser = window.css;
			this.editor = options.editor;
		},
		
		/**
		 * Render the property editor
		 */
		render: function () {
			// Clean up for potential re-renders
			this.$( '.section-tabs' ).empty();
			this.$( '.sections' ).empty();
			this.$( '.toolbar select' ).off();
			this.propertyControllers = [];
			
			var controllers = socssOptions.propertyControllers;
			
			for ( var id in controllers ) {
				// Create the tabs
				var $t = $( this.tabTemplate( {
					id: id,
					icon: controllers[ id ].icon,
					title: controllers[ id ].title
				} ) ).appendTo( this.$( '.section-tabs' ) );
				
				// Create the section wrapper
				var $s = $( this.sectionTemplate( {
					id: id
				} ) ).appendTo( this.$( '.sections' ) );
				
				// Now lets add the controllers
				if ( !_.isEmpty( controllers[ id ].controllers ) ) {
					
					for ( var i = 0; i < controllers[ id ].controllers.length; i++ ) {
						
						var $c = $( this.controllerTemplate( {
							title: controllers[ id ].controllers[ i ].title
						} ) ).appendTo( $s.find( 'tbody' ) );
						
						var controllerAtts = controllers[ id ].controllers[ i ];
						var controller;
						
						if ( typeof socss.view.properties.controllers[ controllerAtts.type ] === 'undefined' ) {
							// Setup a default controller
							controller = new socss.view.propertyController( {
								el: $c.find( 'td' ),
								propertiesView: this,
								args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
							} );
						}
						else {
							// Setup a specific controller
							controller = new socss.view.properties.controllers[ controllerAtts.type ]( {
								el: $c.find( 'td' ),
								propertiesView: this,
								args: ( typeof controllerAtts.args === 'undefined' ? {} : controllerAtts.args )
							} );
						}
						
						this.propertyControllers.push( controller );
						
						// Setup and render the controller
						controller.render();
					}
				}
			}
			
			// Switch to the first tab.
			this.$( '.section-tabs li' ).eq( 0 ).trigger( 'click' );
		},
		
		onTabClick: function ( event ) {
			var $$ = $( event.currentTarget );
			var show = this.$( '.sections .section[data-section="' + $$.data( 'section' ) + '"]' );
			
			this.$( '.sections .section' ).not( show ).hide().removeClass( 'active' );
			show.show().addClass( 'active' );
			
			this.$( '.section-tabs li' ).not( $$ ).removeClass( 'active' );
			$$.addClass( 'active' );
		},
		
		onToolbarSelectChange: function ( event ) {
			this.setActiveSelector( $( event.currentTarget ).find( ':selected' ).data( 'selector' ) );
		},
		
		/**
		 * Sets the rule value for the active selector
		 * @param rule
		 * @param value
		 */
		setRuleValue: function ( rule, value ) {
			if (
				typeof this.activeSelector === 'undefined' ||
				typeof this.activeSelector.declarations === 'undefined'
			) {
				return;
			}
			
			var declarations = this.activeSelector.declarations;
			var newRule = true;
			var valueChanged = false;
			for ( var i = 0; i < declarations.length; i++ ) {
				if ( declarations[ i ].property === rule ) {
					newRule = false;
					var declaration = declarations[ i ];
					if ( declaration.value !== value ) {
						declaration.value = value;
						valueChanged = true;
					}
					
					// Remove empty declarations
					if ( _.isEmpty( declaration.value ) ) {
						declarations.splice( declarations.indexOf( declaration ) );
					}
					break;
				}
			}
			
			if ( newRule && !_.isEmpty( value ) ) {
				declarations.push( {
					property: rule,
					value: value,
					type: 'declaration',
				} );
				valueChanged = true;
			}
			
			if ( valueChanged ) {
				this.updateMainEditor( false );
			}
		},
		
		/**
		 * Adds the @import rule value if it doesn't already exist.
		 *
		 * @param newRule
		 *
		 */
		addImport: function ( newRule ) {
			
			// get @import rules
			// check if any have the same value
			// if not, then add the new @ rule
			
			var importRules = _.filter( this.parsed.stylesheet.rules, function ( rule ) {
				return rule.type === 'import';
			} );
			var exists = _.any( importRules, function ( rule ) {
				return rule.import === newRule.import;
			} );
			
			if ( !exists ) {
				// Add it to the top!
				// @import statements must precede other rule types.
				this.parsed.stylesheet.rules.unshift( newRule );
				this.updateMainEditor( false );
			}
			
		},
		
		/**
		 * Find @import which completely or partially contains the specified value.
		 *
		 * @param value
		 */
		findImport: function ( value ) {
			return _.find( this.parsed.stylesheet.rules, function ( rule ) {
				return rule.type === 'import' && rule.import.indexOf( value ) > -1;
			} );
		},
		
		/**
		 * Find @import which completely or partially contains the identifier value and update it's import property.
		 *
		 * @param identifier
		 * @param value
		 */
		updateImport: function ( identifier, value ) {
			var importRule = this.findImport( identifier );
			if ( importRule.import !== value.import ) {
				importRule.import = value.import;
				this.updateMainEditor( false );
			}
		},
		
		/**
		 * Find @import which completely or partially contains the identifier value and remove it.
		 *
		 * @param identifier
		 */
		removeImport: function ( identifier ) {
			var importIndex = _.findIndex( this.parsed.stylesheet.rules, function ( rule ) {
				return rule.type === 'import' && rule.import.indexOf( identifier ) > -1;
			} );
			if ( importIndex > -1 ) {
				this.parsed.stylesheet.rules.splice( importIndex, 1 );
			}
		},
		
		/**
		 * Get the rule value for the active selector
		 * @param rule
		 */
		getRuleValue: function ( rule ) {
			if ( typeof this.activeSelector === 'undefined' || typeof this.activeSelector.declarations === 'undefined' ) {
				return '';
			}
			
			var declarations = this.activeSelector.declarations;
			for ( var i = 0; i < declarations.length; i++ ) {
				if ( declarations[ i ].property === rule ) {
					return declarations[ i ].value;
				}
			}
			return '';
		},
		
		/**
		 * Update the main editor with the value of the parsed CSS
		 */
		updateMainEditor: function ( compress ) {
			//TODO: add back compress option to remove/merge duplicated CSS selectors.
			this.editor.codeMirror.setValue( this.parser.stringify( this.parsed ) );
		},
		
		/**
		 * Show the properties editor
		 */
		show: function () {
			this.editorExpandedBefore = this.editor.isExpanded();
			this.editor.setExpand( true );
			
			this.$el.show().animate( { 'left': 0 }, 'fast' );
		},
		
		/**
		 * Hide the properties editor
		 */
		hide: function () {
			this.editor.setExpand( this.editorExpandedBefore );
			this.$el.animate( { 'left': -338 }, 'fast', function () {
				$( this ).hide();
			} );
			
			// Update the main editor with compressed CSS when we close the properties editor
			this.updateMainEditor( true );
		},

		save: function () {
			socss.save( this );
		},
		
		/**
		 * @returns boolean
		 */
		isVisible: function () {
			return this.$el.is( ':visible' );
		},
		
		/**
		 * Loads a single CSS selector and associated properties into the model
		 * @param css
		 */
		loadCSS: function ( css, activeSelector ) {
			this.css = css;
			
			// Load the CSS
			this.parsed = this.parser.parse( css, {
				silent: true
			} );
			var rules = this.parsed.stylesheet.rules;
			
			// Add the dropdown menu items
			var dropdown = this.$( '.toolbar select' ).empty();
			for ( var i = 0; i < rules.length; i++ ) {
				var rule = rules[ i ];
				
				// Exclude @import statements
				if ( !_.contains( [ 'rule', 'media' ], rule.type ) ) {
					continue;
				}
				
				if ( rule.type === 'media' ) {
					
					for ( var j = 0; j < rule.rules.length; j++ ) {
						var mediaRule = '@media ' + rule.media;
						var subRule = rule.rules[ j ];
						if ( subRule.type != 'rule' ) {
							continue;
						}
						dropdown.append(
							$( '<option>' )
							.html( mediaRule + ': ' + subRule.selectors.join( ',' ) )
							.attr( 'val', mediaRule + ': ' + subRule.selectors.join( ',' ) )
							.data( 'selector', subRule )
						);
					}
					
				}
				else {
					dropdown.append(
						$( '<option>' )
						.html( rule.selectors.join( ',' ) )
						.attr( 'val', rule.selectors.join( ',' ) )
						.data( 'selector', rule )
					);
				}
			}
			
			if ( typeof activeSelector === 'undefined' ) {
				activeSelector = dropdown.find( 'option' ).eq( 0 ).attr( 'val' );
			}
			if ( !_.isEmpty( activeSelector ) ) {
				dropdown.val( activeSelector ).trigger( 'change' );
			}
		},
		
		/**
		 * Set the selector that we're currently dealing with
		 * @param selector
		 */
		setActiveSelector: function ( selector ) {
			this.activeSelector = selector;
			for ( var i = 0; i < this.propertyControllers.length; i++ ) {
				this.propertyControllers[ i ].refreshFromRule();
			}
		},
		
		/**
		 * Add or select a selector.
		 *
		 * @param selector
		 */
		addSelector: function ( selector ) {
			// Check if this selector already exists
			var dropdown = this.$( '.toolbar select' );
			dropdown.val( selector );
			
			if ( dropdown.val() === selector ) {
				// Trigger a change event to load the existing selector
				dropdown.trigger( 'change' );
			}
			else {
				// The selector doesn't exist, so add it to the CSS, then reload
				this.editor.addEmptySelector( selector );
				this.loadCSS( this.editor.codeMirror.getValue().trim(), selector );
			}
			
			dropdown.addClass( 'highlighted' );
			setTimeout( function () {
				dropdown.removeClass( 'highlighted' );
			}, 2000 );
		}
		
	} );
	
	// The basic property controller
	socss.view.propertyController = Backbone.View.extend( {
		
		template: _.template( '<input type="text" value="" class="socss-property-controller-input"/>' ),
		activeRule: null,
		args: null,
		propertiesView: null,
		
		events: {
			'change .socss-property-controller-input': 'onChange',
			'keyup input.socss-property-controller-input': 'onChange',
		},
		
		initialize: function ( args ) {
			
			this.args = args.args;
			this.propertiesView = args.propertiesView;
			
			// If sub-views items define their own events hash with the same keys as above they will override those on
			// the above events hash.
			this.events = _.extend( socss.view.propertyController.prototype.events, this.events );
			this.delegateEvents( this.events );
			
			// By default, update the active rule whenever things change
			this.on( 'set_value', this.updateRule, this );
			this.on( 'change', this.updateRule, this );
		},
		
		/**
		 * Render the property field controller
		 */
		render: function () {
			this.$el.append( $( this.template( {} ) ) );
			this.field = this.$( 'input.socss-property-controller-input' );
		},
		
		onChange: function () {
			this.trigger( 'change', this.field.val() );
		},
		
		/**
		 * Update the value of an active rule
		 */
		updateRule: function () {
			this.propertiesView.setRuleValue(
				this.args.property,
				this.getValue()
			);
		},
		
		/**
		 * This is called when the selector changes
		 */
		refreshFromRule: function () {
			var value = this.propertiesView.getRuleValue( this.args.property );
			this.setValue( value, { silent: true } );
		},
		
		/**
		 * Get the current value
		 * @return string
		 */
		getValue: function () {
			return this.field.val();
		},
		
		/**
		 * Set the current value
		 * @param socss.view.properties val
		 */
		setValue: function ( val, options ) {
			options = _.extend( { silent: false }, options );
			
			this.field.val( val );
			
			if ( !options.silent ) {
				this.trigger( 'set_value', val );
			}
		},
		
		/**
		 * Reset the current value
		 */
		reset: function ( options ) {
			options = _.extend( { silent: false }, options );
			
			this.setValue( '', options );
		}
		
	} );
	
	// All the value controllers
	socss.view.properties.controllers = {};
	
	// The color controller
	socss.view.properties.controllers.color = socss.view.propertyController.extend( {
		
		render: function () {
			socss.view.propertyController.prototype.render.apply( this, arguments );
			// Set this up as a color picker
			this.field.minicolors( {} );
			
		},
		
		onChange: function () {
			this.trigger( 'change', this.field.minicolors( 'value' ) );
		},
		
		getValue: function () {
			return this.field.minicolors( 'value' ).trim();
		},
		
		setValue: function ( val, options ) {
			options = _.extend( { silent: false }, options );
			
			this.field.minicolors( 'value', val );
			
			if ( !options.silent ) {
				this.trigger( 'set_value', val );
			}
		}
		
	} );
	
	// The dropdown select box controller
	socss.view.properties.controllers.select = socss.view.propertyController.extend( {
		template: _.template( '<select class="socss-property-controller-input"></select>' ),
		
		events: {
			'click .select-tab': 'onSelect',
		},
		
		render: function () {
			this.$el.append( $( this.template( {} ) ) );
			this.field = this.$( 'select' );
			
			// Add the unchanged option
			this.field.append( $( '<option value=""></option>' ).html( '' ) );
			
			// Add all the options to the dropdown
			for ( var k in this.args.options ) {
				this.field.append( $( '<option></option>' ).attr( 'value', k ).html( this.args.options[ k ] ) );
			}
			
			if ( typeof this.args.option_icons !== 'undefined' ) {
				this.setupVisualSelect();
			}
		},
		
		setupVisualSelect: function () {
			this.field.hide();
			
			var $tc = $( '<div class="select-tabs"></div>' ).appendTo( this.$el );
			
			// Add the none value
			$( '<div class="select-tab" data-value=""><span class="so-css-icon so-css-icon-circle"></span></div>' ).appendTo( $tc );
			
			// Now add one for each of the option icons
			for ( var k in this.args.option_icons ) {
				$( '<div class="select-tab"></div>' )
				.appendTo( $tc )
				.append(
					$( '<span class="so-css-icon"></span>' )
					.addClass( 'so-css-icon-' + this.args.option_icons[ k ] )
				)
				.attr( 'data-value', k )
				;
			}
			
			$tc.find( '.select-tab' ).css( 'width', 100 / ( $tc.find( '>div' ).length ) + "%" );
		},
		
		onSelect: function ( event ) {
			this.$( '.select-tab' ).removeClass( 'active' );
			var $t = $( event.currentTarget );
			$t.addClass( 'active' );
			this.field.val( $t.data( 'value' ) ).trigger( 'change' );
		},
		
		/**
		 * Set the current value
		 * @param socss.view.properties val
		 */
		setValue: function ( val, options ) {
			options = _.extend( { silent: false }, options );
			
			this.field.val( val );
			
			this.$( '.select-tabs .select-tab' ).removeClass( 'active' ).filter( '[data-value="' + val + '"]' ).addClass( 'active' );
			
			if ( !options.silent ) {
				this.trigger( 'set_value', val );
			}
		}
		
	} );
	
	// A field that lets a user upload an image
	socss.view.properties.controllers.image = socss.view.propertyController.extend( {
		template: _.template( '<input type="text" value="" /> <span class="select socss-button"><span class="so-css-icon so-css-icon-upload"></span></span>' ),
		
		events: {
			'click .select': 'openMedia',
		},
		
		render: function () {
			this.media = wp.media( {
				// Set the title of the modal.
				title: socssOptions.loc.select_image,
				
				// Tell the modal to show only images.
				library: {
					type: 'image'
				},
				
				// Customize the submit button.
				button: {
					// Set the text of the button.
					text: socssOptions.loc.select,
					// Tell the button not to close the modal, since we're
					// going to refresh the page when the image is selected.
					close: false
				}
			} );
			
			this.$el.append( $( this.template( {
				select: socssOptions.loc.select
			} ) ) );
			
			this.field = this.$el.find( 'input' );
			
			this.media.on( 'select', function () {
				// Grab the selected attachment.
				var attachment = this.media.state().get( 'selection' ).first().attributes;
				var val = this.args.value.replace( '{{url}}', attachment.url );
				
				// Change the field value and trigger a change event
				this.field.val( val ).trigger( 'change' );
				this.trigger( 'set_value', val );
				
				// Close the image selector
				this.media.close();
				
			}.bind( this ) );
		},
		
		openMedia: function () {
			this.media.open();
		},
		
	} );
	
	// A simple measurement field
	socss.view.properties.controllers.measurement = socss.view.propertyController.extend( {
		
		wrapperClass: 'socss-field-measurement',
		
		events: {
			'click .toggle-dropdown': 'toggleUnitDropdown',
			'click .dropdown li': 'onSelectUnit',
			'keydown .socss-field-input': 'onInputKeyPress',
			'keyup .socss-field-input': 'onInputKeyUp',
		},
		
		render: function () {
			socss.view.propertyController.prototype.render.apply( this, arguments );
			
			this.setupMeasurementField();
		},
		
		setValue: function ( val, options ) {
			options = _.extend( { silent: false }, options );
			this.field.val( val ).trigger( 'measurement_refresh' );
			if ( !options.silent ) {
				this.trigger( 'set_value', val );
			}
		},
		
		units: [
			'px',
			'%',
			'em',
			'cm',
			'mm',
			'in',
			'pt',
			'pc',
			'ex',
			'ch',
			'rem',
			'vw',
			'vh',
			'vmin',
			'vmax'
		],
		
		parseUnits: function ( value ) {
			var escapeRegExp = function ( str ) {
				return str.replace( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&" );
			};
			
			var regexUnits = this.units.map( escapeRegExp );
			var regex = new RegExp( '([0-9\\.\\-]+)(' + regexUnits.join( '|' ) + ')?', 'i' );
			var result = regex.exec( value );
			
			if ( result === null ) {
				return {
					value: '',
					unit: ''
				};
			}
			else {
				return {
					value: result[ 1 ],
					unit: result[ 2 ] === undefined ? '' : result[ 2 ]
				};
			}
		},
		
		setupMeasurementField: function () {
			var defaultUnit = 'px';
			
			this.field.hide();
			this.$el.addClass( this.wrapperClass ).data( 'unit', defaultUnit );
			
			// Create the fake input field
			var $fi = $( '<input type="text" class="socss-field-input"/>' ).appendTo( this.$el );
			$( '<span class="toggle-dropdown dashicons dashicons-arrow-down"></span>' ).appendTo( this.$el );
			var $dd = $( '<ul class="dropdown"></ul>' ).appendTo( this.$el );
			var $u = $( '<span class="units"></span>' ).html( defaultUnit ).appendTo( this.$el );
			
			for ( var i = 0; i < this.units.length; i++ ) {
				var $o = $( '<li></li>' ).html( this.units[ i ] ).data( 'unit', this.units[ i ] );
				if ( this.units[ i ] === defaultUnit ) {
					$o.addClass( 'active' );
				}
				$dd.append( $o );
			}
			
			this.field.on( 'measurement_refresh', function () {
				var value = this.parseUnits( this.field.val() );
				$fi.val( value.value );
				
				var unit = value.unit === '' ? defaultUnit : value.unit;
				this.$el.data( 'unit', unit );
				$u.html( unit );
				
				var $pl = $( '<span class="socss-hidden-placeholder"></span>' )
				.css( {
					'font-size': '14px'
				} )
				.html( value.value )
				.appendTo( 'body' );
				var width = $pl.width();
				width = Math.min( width, 63 );
				$pl.remove();
				
				$u.css( 'left', width + 12 );
			}.bind( this ) );
			
			// Now add the increment/decrement buttons
			var $diw = $( '<div class="socss-diw"></div>' ).appendTo( this.$el );
			var $dec = $( '<div class="dec-button socss-button"><span class="so-css-icon so-css-icon-minus"></span></div>' ).appendTo( $diw );
			var $inc = $( '<div class="inc-button socss-button"><span class="so-css-icon so-css-icon-plus"></span></div>' ).appendTo( $diw );
			
			this.setupStepButton( $dec );
			this.setupStepButton( $inc );
			
		},
		
		updateValue: function () {
			var $fi = this.$( '.socss-field-input' );
			var value = this.parseUnits( $fi.val() );
			
			if ( value.unit !== '' && value.unit !== this.$el.data( 'unit' ) ) {
				$fi.val( value.value );
				this.setUnit( value.unit );
			}
			
			if ( value.value === '' ) {
				this.field.val( '' );
			}
			else {
				this.field.val( value.value + this.$el.data( 'unit' ) );
			}
			this.field.trigger( 'change' );
		},
		
		setUnit: function ( unit ) {
			this.$( '.units' ).html( unit );
			this.$el.data( 'unit', unit );
			this.$( '.socss-field-input' ).trigger( 'keydown' );
		},
		
		toggleUnitDropdown: function () {
			this.$( '.dropdown' ).toggle();
		},
		
		onSelectUnit: function ( event ) {
			this.toggleUnitDropdown();
			this.setUnit( $( event.currentTarget ).data( 'unit' ) );
			this.updateValue();
		},
		
		onInputKeyUp: function( event ) {
			this.onInputKeyPress( event );
			this.updateValue();
		},
		
		onInputKeyPress: function ( event ) {
			var $fi = this.$( '.socss-field-input' );
			
			var char = '';
			if ( event.type === 'keydown' ) {
				if ( event.keyCode >= 48 && event.keyCode <= 57 ) {
					char = String.fromCharCode( event.keyCode );
				}
				else if ( event.keyCode === 189 ) {
					char = '-';
				}
				else if ( event.keyCode === 190 ) {
					char = '.';
				}
			}
			
			var $pl = $( '<span class="socss-hidden-placeholder"></span>' )
			.css( {
				'font-size': '14px'
			} )
			.html( $fi.val() + char )
			.appendTo( 'body' );
			var width = $pl.width();
			width = Math.min( width, 63 );
			$pl.remove();
			
			this.$( '.units' ).css( 'left', width + 12 );
		},
		
		stepValue: function ( direction ) {
			var value = Number.parseInt( this.parseUnits( this.field.val() ).value );
			
			if ( Number.isNaN( value ) ) {
				value = 0;
			}
			
			var newVal = value + direction;
			
			this.$( '.socss-field-input' ).val( newVal );
			this.updateValue();
			this.field.trigger( 'measurement_refresh' );
		},
		
		setupStepButton: function ( $button ) {
			var direction = $button.is( '.dec-button' ) ? -1 : 1;
			var intervalId;
			var timeoutId;
			$button.on( 'mousedown', function() {
				this.stepValue( direction );
				timeoutId = setTimeout( function () {
					intervalId = setInterval( function () {
						this.stepValue( direction );
					}.bind( this ), 50 );
				}.bind( this ), 500 );
			}.bind( this ) ).on( 'mouseup mouseout', function () {
				if ( timeoutId ) {
					clearTimeout( timeoutId );
					timeoutId = null;
				}
				if ( intervalId ) {
					clearInterval( intervalId );
					intervalId = null;
				}
			} );
		},
	} );
	
	// A simple measurement field
	socss.view.properties.controllers.number = socss.view.propertyController.extend( {
		
		initialize: function ( args ) {
			socss.view.propertyController.prototype.initialize.apply( this, arguments );
			
			this.args = _.extend( {
				change: null,
				default: 0,
				increment: 1,
				decrement: -1,
				max: null,
				min: null
			}, args.args );
		},
		
		render: function () {
			socss.view.propertyController.prototype.render.apply( this, arguments );
			
			this.setupNumberField();
		},
		
		setupNumberField: function () {
			
			this.$el.addClass( 'socss-field-number' );
			
			// Now add the increment/decrement buttons
			var $diw = $( '<div class="socss-diw"></div>' ).appendTo( this.$el );
			var $dec = $( '<div class="dec-button socss-button"><span class="so-css-icon so-css-icon-minus"></span></div>' ).appendTo( $diw );
			var $inc = $( '<div class="inc-button socss-button"><span class="so-css-icon so-css-icon-plus"></span></div>' ).appendTo( $diw );
			
			this.setupStepButton( $dec );
			this.setupStepButton( $inc );
			
			return this;
		},
		
		stepValue: function ( direction ) {
			var value = Number.parseFloat( this.field.val() );
			
			if ( Number.isNaN( value ) ) {
				value = this.args.default;
			}
			
			var newVal = value + direction;
			
			newVal = Math.round( newVal * 100 ) / 100;

				if ( this.args.max !== null ) {
					newVal = Math.min( this.args.max, newVal );
				}

				if ( this.args.min !== null ) {
					newVal = Math.max( this.args.min, newVal );
				}
			
			this.field.val( newVal );
			this.field.trigger( 'change' );
		},
		
		setupStepButton: function ( $button ) {
			var direction = $button.is( '.dec-button' ) ? this.args.decrement : this.args.increment;
			var intervalId;
			var timeoutId;
			$button.on( 'mousedown', function() {
				this.stepValue( direction );
				timeoutId = setTimeout( function () {
					intervalId = setInterval( function () {
						this.stepValue( direction );
					}.bind( this ), 50 );
				}.bind( this ), 500 );
			}.bind( this ) ).on( 'mouseup mouseout', function () {
				if ( timeoutId ) {
					clearTimeout( timeoutId );
					timeoutId = null;
				}
				if ( intervalId ) {
					clearInterval( intervalId );
					intervalId = null;
				}
			} );
		},
		
	} );
	
	
	socss.view.properties.controllers.sides = socss.view.propertyController.extend( {
		
		template: _.template( $( '#template-sides-field' ).html().trim() ),
		
		controllers: [],
		
		events: {
			'click .select-tab': 'onTabClick',
		},
		
		render: function () {
			
			socss.view.propertyController.prototype.render.apply( this, arguments );
			
			if ( !this.args.hasAll ) {
				this.$( '.select-tab' ).eq( 0 ).remove();
				this.$( '.select-tab' ).css( 'width', '25%' );
			}

			if ( ! this.args.isRadius ) {
				this.$( '.select-tabs[data-type="radius"]' ).remove();
			} else {
				this.$( '.select-tabs[data-type="box"]' ).remove();
			}
			
			this.$( '.select-tab' ).each( function ( index, element ) {
				var dir = $( element ).data( 'direction' );
				
				var container = $( '<li class="side">' )
				.appendTo( this.$( '.sides' ) )
				.hide();
				
				for ( var i = 0; i < this.args.controllers.length; i++ ) {
					
					var controllerArgs = this.args.controllers[ i ];
					
					if ( typeof socss.view.properties.controllers[ controllerArgs.type ] ) {
						
						// Create the measurement view
						var property = '';
						if ( dir === 'all' ) {
							property = controllerArgs.args.propertyAll;
						}
						else {
							property = controllerArgs.args.property.replace( '{dir}', dir );
						}
						
						var theseControllerArgs = _.extend( {}, controllerArgs.args, { property: property } );
						
						var controller = new socss.view.properties.controllers[ controllerArgs.type ]( {
							el: $( '<div>' ).appendTo( container ),
							propertiesView: this.propertiesView,
							args: theseControllerArgs
						} );
						
						// Setup and render the measurement controller and register it with the properties view
						controller.render();
						this.propertiesView.propertyControllers.push( controller );
					}
				}
				
			}.bind( this ) );
			
			// Select the first tab by default
			this.$( '.select-tab' ).eq( 0 ).click();
		},
		
		onTabClick: function ( event ) {
			var $tabs = this.$( '.select-tab' );
			$tabs.removeClass( 'active' );
			
			var $tab = $( event.currentTarget );
			$tab.addClass( 'active' );
			
			var $sides = this.$( '.sides .side' )
			$sides.hide();
			
			$sides.eq( $tabs.index( $tab ) ).show();
		},
	} );

	// This is a placeholder for the full font_select in SiteOrigin Premium
	socss.view.properties.controllers.font_select = socss.view.propertyController.extend( {
		template: _.template( $('#template-webfont-teaser').html().trim() )
	});
	
} )( jQuery, _, socssOptions );

// Setup the main editor
jQuery( function ( $ ) {
	var socss = window.socss;
	
	var editorModel = new socss.model.CSSEditorModel( {
		customCssPosts: socssOptions.customCssPosts,
	} );
	
	// Setup the editor
	var editor = new socss.view.editor( {
		el: $( '#so-custom-css-form' ).get( 0 ),
		model: editorModel,
		openVisualEditor: socssOptions.openVisualEditor,
	} );
	// editor.render();
	editor.setSnippets( socssOptions.snippets );
	
	// This is for hiding the getting started video
	$( '#so-custom-css-getting-started a.hide' ).on( 'click', function( e ) {
		e.preventDefault();
		$( '#so-custom-css-getting-started' ).slideUp();
		$.get( $( this ).attr( 'href' ) );
	} );
	
	window.socss.mainEditor = editor;
	$( socss ).trigger( 'initialized' );

	$( '.button-primary[name="siteorigin_custom_css_save"]' ).on( 'click', function() {
		$( '#so-custom-css-form' ).trigger( 'submit' );
	} );

	$( '.installer-link' ).on( 'click', function( e ) {
		e.preventDefault();
		$( this ).hide();
		$( '.installer-container' ).slideDown( 'fast' );
	} );

	$( '.installer_status' ).on( 'change', function() {
		var $$ = $( this );
		$$.prop( 'disabled', true );
		jQuery.post(
			ajaxurl,
			{
				action: 'so_installer_status',
				nonce: $$.data( 'nonce' ),
				status: $$.is( ':checked' )
			},
			function() {
				$$.prop( 'disabled', false );
			}
		);
	} );
} );
!function t(e,r,n){function o(s,a){if(!r[s]){if(!e[s]){var u="function"==typeof require&&require;if(!a&&u)return u(s,!0);if(i)return i(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[s]={exports:{}};e[s][0].call(l.exports,(function(t){return o(e[s][1][t]||t)}),l,l.exports,t,e,r,n)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;s<n.length;s++)o(n[s]);return o}({1:[function(t,e,r){"use strict";r.byteLength=function(t){var e=c(t),r=e[0],n=e[1];return 3*(r+n)/4-n},r.toByteArray=function(t){var e,r,n=c(t),s=n[0],a=n[1],u=new i(function(t,e,r){return 3*(e+r)/4-r}(0,s,a)),l=0,h=a>0?s-4:s;for(r=0;r<h;r+=4)e=o[t.charCodeAt(r)]<<18|o[t.charCodeAt(r+1)]<<12|o[t.charCodeAt(r+2)]<<6|o[t.charCodeAt(r+3)],u[l++]=e>>16&255,u[l++]=e>>8&255,u[l++]=255&e;2===a&&(e=o[t.charCodeAt(r)]<<2|o[t.charCodeAt(r+1)]>>4,u[l++]=255&e);1===a&&(e=o[t.charCodeAt(r)]<<10|o[t.charCodeAt(r+1)]<<4|o[t.charCodeAt(r+2)]>>2,u[l++]=e>>8&255,u[l++]=255&e);return u},r.fromByteArray=function(t){for(var e,r=t.length,o=r%3,i=[],s=0,a=r-o;s<a;s+=16383)i.push(l(t,s,s+16383>a?a:s+16383));1===o?(e=t[r-1],i.push(n[e>>2]+n[e<<4&63]+"==")):2===o&&(e=(t[r-2]<<8)+t[r-1],i.push(n[e>>10]+n[e>>4&63]+n[e<<2&63]+"="));return i.join("")};for(var n=[],o=[],i="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",a=0,u=s.length;a<u;++a)n[a]=s[a],o[s.charCodeAt(a)]=a;function c(t){var e=t.length;if(e%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");return-1===r&&(r=e),[r,r===e?0:4-r%4]}function l(t,e,r){for(var o,i,s=[],a=e;a<r;a+=3)o=(t[a]<<16&16711680)+(t[a+1]<<8&65280)+(255&t[a+2]),s.push(n[(i=o)>>18&63]+n[i>>12&63]+n[i>>6&63]+n[63&i]);return s.join("")}o["-".charCodeAt(0)]=62,o["_".charCodeAt(0)]=63},{}],2:[function(t,e,r){},{}],3:[function(t,e,r){(function(e){
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */
"use strict";var n=t("base64-js"),o=t("ieee754");r.Buffer=e,r.SlowBuffer=function(t){+t!=t&&(t=0);return e.alloc(+t)},r.INSPECT_MAX_BYTES=50;function i(t){if(t>2147483647)throw new RangeError('The value "'+t+'" is invalid for option "size"');var r=new Uint8Array(t);return r.__proto__=e.prototype,r}function e(t,e,r){if("number"==typeof t){if("string"==typeof e)throw new TypeError('The "string" argument must be of type string. Received type number');return u(t)}return s(t,e,r)}function s(t,r,n){if("string"==typeof t)return function(t,r){"string"==typeof r&&""!==r||(r="utf8");if(!e.isEncoding(r))throw new TypeError("Unknown encoding: "+r);var n=0|h(t,r),o=i(n),s=o.write(t,r);s!==n&&(o=o.slice(0,s));return o}(t,r);if(ArrayBuffer.isView(t))return c(t);if(null==t)throw TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t);if(N(t,ArrayBuffer)||t&&N(t.buffer,ArrayBuffer))return function(t,r,n){if(r<0||t.byteLength<r)throw new RangeError('"offset" is outside of buffer bounds');if(t.byteLength<r+(n||0))throw new RangeError('"length" is outside of buffer bounds');var o;o=void 0===r&&void 0===n?new Uint8Array(t):void 0===n?new Uint8Array(t,r):new Uint8Array(t,r,n);return o.__proto__=e.prototype,o}(t,r,n);if("number"==typeof t)throw new TypeError('The "value" argument must not be of type number. Received type number');var o=t.valueOf&&t.valueOf();if(null!=o&&o!==t)return e.from(o,r,n);var s=function(t){if(e.isBuffer(t)){var r=0|l(t.length),n=i(r);return 0===n.length?n:(t.copy(n,0,0,r),n)}if(void 0!==t.length)return"number"!=typeof t.length||F(t.length)?i(0):c(t);if("Buffer"===t.type&&Array.isArray(t.data))return c(t.data)}(t);if(s)return s;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof t[Symbol.toPrimitive])return e.from(t[Symbol.toPrimitive]("string"),r,n);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof t)}function a(t){if("number"!=typeof t)throw new TypeError('"size" argument must be of type number');if(t<0)throw new RangeError('The value "'+t+'" is invalid for option "size"')}function u(t){return a(t),i(t<0?0:0|l(t))}function c(t){for(var e=t.length<0?0:0|l(t.length),r=i(e),n=0;n<e;n+=1)r[n]=255&t[n];return r}function l(t){if(t>=2147483647)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+2147483647..toString(16)+" bytes");return 0|t}function h(t,r){if(e.isBuffer(t))return t.length;if(ArrayBuffer.isView(t)||N(t,ArrayBuffer))return t.byteLength;if("string"!=typeof t)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof t);var n=t.length,o=arguments.length>2&&!0===arguments[2];if(!o&&0===n)return 0;for(var i=!1;;)switch(r){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":return B(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return k(t).length;default:if(i)return o?-1:B(t).length;r=(""+r).toLowerCase(),i=!0}}function f(t,e,r){var n=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return L(this,e,r);case"utf8":case"utf-8":return C(this,e,r);case"ascii":return E(this,e,r);case"latin1":case"binary":return S(this,e,r);case"base64":return A(this,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,e,r);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}function p(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function g(t,r,n,o,i){if(0===t.length)return-1;if("string"==typeof n?(o=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),F(n=+n)&&(n=i?0:t.length-1),n<0&&(n=t.length+n),n>=t.length){if(i)return-1;n=t.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof r&&(r=e.from(r,o)),e.isBuffer(r))return 0===r.length?-1:m(t,r,n,o,i);if("number"==typeof r)return r&=255,"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,r,n):Uint8Array.prototype.lastIndexOf.call(t,r,n):m(t,[r],n,o,i);throw new TypeError("val must be string, number or Buffer")}function m(t,e,r,n,o){var i,s=1,a=t.length,u=e.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||e.length<2)return-1;s=2,a/=2,u/=2,r/=2}function c(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(o){var l=-1;for(i=r;i<a;i++)if(c(t,i)===c(e,-1===l?0:i-l)){if(-1===l&&(l=i),i-l+1===u)return l*s}else-1!==l&&(i-=i-l),l=-1}else for(r+u>a&&(r=a-u),i=r;i>=0;i--){for(var h=!0,f=0;f<u;f++)if(c(t,i+f)!==c(e,f)){h=!1;break}if(h)return i}return-1}function d(t,e,r,n){r=Number(r)||0;var o=t.length-r;n?(n=Number(n))>o&&(n=o):n=o;var i=e.length;n>i/2&&(n=i/2);for(var s=0;s<n;++s){var a=parseInt(e.substr(2*s,2),16);if(F(a))return s;t[r+s]=a}return s}function y(t,e,r,n){return P(B(e,t.length-r),t,r,n)}function v(t,e,r,n){return P(function(t){for(var e=[],r=0;r<t.length;++r)e.push(255&t.charCodeAt(r));return e}(e),t,r,n)}function w(t,e,r,n){return v(t,e,r,n)}function b(t,e,r,n){return P(k(e),t,r,n)}function _(t,e,r,n){return P(function(t,e){for(var r,n,o,i=[],s=0;s<t.length&&!((e-=2)<0);++s)r=t.charCodeAt(s),n=r>>8,o=r%256,i.push(o),i.push(n);return i}(e,t.length-r),t,r,n)}function A(t,e,r){return 0===e&&r===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(e,r))}function C(t,e,r){r=Math.min(t.length,r);for(var n=[],o=e;o<r;){var i,s,a,u,c=t[o],l=null,h=c>239?4:c>223?3:c>191?2:1;if(o+h<=r)switch(h){case 1:c<128&&(l=c);break;case 2:128==(192&(i=t[o+1]))&&(u=(31&c)<<6|63&i)>127&&(l=u);break;case 3:i=t[o+1],s=t[o+2],128==(192&i)&&128==(192&s)&&(u=(15&c)<<12|(63&i)<<6|63&s)>2047&&(u<55296||u>57343)&&(l=u);break;case 4:i=t[o+1],s=t[o+2],a=t[o+3],128==(192&i)&&128==(192&s)&&128==(192&a)&&(u=(15&c)<<18|(63&i)<<12|(63&s)<<6|63&a)>65535&&u<1114112&&(l=u)}null===l?(l=65533,h=1):l>65535&&(l-=65536,n.push(l>>>10&1023|55296),l=56320|1023&l),n.push(l),o+=h}return function(t){var e=t.length;if(e<=4096)return String.fromCharCode.apply(String,t);var r="",n=0;for(;n<e;)r+=String.fromCharCode.apply(String,t.slice(n,n+=4096));return r}(n)}r.kMaxLength=2147483647,e.TYPED_ARRAY_SUPPORT=function(){try{var t=new Uint8Array(1);return t.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===t.foo()}catch(t){return!1}}(),e.TYPED_ARRAY_SUPPORT||"undefined"==typeof console||"function"!=typeof console.error||console.error("This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support."),Object.defineProperty(e.prototype,"parent",{enumerable:!0,get:function(){if(e.isBuffer(this))return this.buffer}}),Object.defineProperty(e.prototype,"offset",{enumerable:!0,get:function(){if(e.isBuffer(this))return this.byteOffset}}),"undefined"!=typeof Symbol&&null!=Symbol.species&&e[Symbol.species]===e&&Object.defineProperty(e,Symbol.species,{value:null,configurable:!0,enumerable:!1,writable:!1}),e.poolSize=8192,e.from=function(t,e,r){return s(t,e,r)},e.prototype.__proto__=Uint8Array.prototype,e.__proto__=Uint8Array,e.alloc=function(t,e,r){return function(t,e,r){return a(t),t<=0?i(t):void 0!==e?"string"==typeof r?i(t).fill(e,r):i(t).fill(e):i(t)}(t,e,r)},e.allocUnsafe=function(t){return u(t)},e.allocUnsafeSlow=function(t){return u(t)},e.isBuffer=function(t){return null!=t&&!0===t._isBuffer&&t!==e.prototype},e.compare=function(t,r){if(N(t,Uint8Array)&&(t=e.from(t,t.offset,t.byteLength)),N(r,Uint8Array)&&(r=e.from(r,r.offset,r.byteLength)),!e.isBuffer(t)||!e.isBuffer(r))throw new TypeError('The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array');if(t===r)return 0;for(var n=t.length,o=r.length,i=0,s=Math.min(n,o);i<s;++i)if(t[i]!==r[i]){n=t[i],o=r[i];break}return n<o?-1:o<n?1:0},e.isEncoding=function(t){switch(String(t).toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"latin1":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return!0;default:return!1}},e.concat=function(t,r){if(!Array.isArray(t))throw new TypeError('"list" argument must be an Array of Buffers');if(0===t.length)return e.alloc(0);var n;if(void 0===r)for(r=0,n=0;n<t.length;++n)r+=t[n].length;var o=e.allocUnsafe(r),i=0;for(n=0;n<t.length;++n){var s=t[n];if(N(s,Uint8Array)&&(s=e.from(s)),!e.isBuffer(s))throw new TypeError('"list" argument must be an Array of Buffers');s.copy(o,i),i+=s.length}return o},e.byteLength=h,e.prototype._isBuffer=!0,e.prototype.swap16=function(){var t=this.length;if(t%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(var e=0;e<t;e+=2)p(this,e,e+1);return this},e.prototype.swap32=function(){var t=this.length;if(t%4!=0)throw new RangeError("Buffer size must be a multiple of 32-bits");for(var e=0;e<t;e+=4)p(this,e,e+3),p(this,e+1,e+2);return this},e.prototype.swap64=function(){var t=this.length;if(t%8!=0)throw new RangeError("Buffer size must be a multiple of 64-bits");for(var e=0;e<t;e+=8)p(this,e,e+7),p(this,e+1,e+6),p(this,e+2,e+5),p(this,e+3,e+4);return this},e.prototype.toString=function(){var t=this.length;return 0===t?"":0===arguments.length?C(this,0,t):f.apply(this,arguments)},e.prototype.toLocaleString=e.prototype.toString,e.prototype.equals=function(t){if(!e.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===e.compare(this,t)},e.prototype.inspect=function(){var t="",e=r.INSPECT_MAX_BYTES;return t=this.toString("hex",0,e).replace(/(.{2})/g,"$1 ").trim(),this.length>e&&(t+=" ... "),"<Buffer "+t+">"},e.prototype.compare=function(t,r,n,o,i){if(N(t,Uint8Array)&&(t=e.from(t,t.offset,t.byteLength)),!e.isBuffer(t))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof t);if(void 0===r&&(r=0),void 0===n&&(n=t?t.length:0),void 0===o&&(o=0),void 0===i&&(i=this.length),r<0||n>t.length||o<0||i>this.length)throw new RangeError("out of range index");if(o>=i&&r>=n)return 0;if(o>=i)return-1;if(r>=n)return 1;if(this===t)return 0;for(var s=(i>>>=0)-(o>>>=0),a=(n>>>=0)-(r>>>=0),u=Math.min(s,a),c=this.slice(o,i),l=t.slice(r,n),h=0;h<u;++h)if(c[h]!==l[h]){s=c[h],a=l[h];break}return s<a?-1:a<s?1:0},e.prototype.includes=function(t,e,r){return-1!==this.indexOf(t,e,r)},e.prototype.indexOf=function(t,e,r){return g(this,t,e,r,!0)},e.prototype.lastIndexOf=function(t,e,r){return g(this,t,e,r,!1)},e.prototype.write=function(t,e,r,n){if(void 0===e)n="utf8",r=this.length,e=0;else if(void 0===r&&"string"==typeof e)n=e,r=this.length,e=0;else{if(!isFinite(e))throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported");e>>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}var o=this.length-e;if((void 0===r||r>o)&&(r=o),t.length>0&&(r<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");n||(n="utf8");for(var i=!1;;)switch(n){case"hex":return d(this,t,e,r);case"utf8":case"utf-8":return y(this,t,e,r);case"ascii":return v(this,t,e,r);case"latin1":case"binary":return w(this,t,e,r);case"base64":return b(this,t,e,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return _(this,t,e,r);default:if(i)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),i=!0}},e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function E(t,e,r){var n="";r=Math.min(t.length,r);for(var o=e;o<r;++o)n+=String.fromCharCode(127&t[o]);return n}function S(t,e,r){var n="";r=Math.min(t.length,r);for(var o=e;o<r;++o)n+=String.fromCharCode(t[o]);return n}function L(t,e,r){var n=t.length;(!e||e<0)&&(e=0),(!r||r<0||r>n)&&(r=n);for(var o="",i=e;i<r;++i)o+=j(t[i]);return o}function R(t,e,r){for(var n=t.slice(e,r),o="",i=0;i<n.length;i+=2)o+=String.fromCharCode(n[i]+256*n[i+1]);return o}function O(t,e,r){if(t%1!=0||t<0)throw new RangeError("offset is not uint");if(t+e>r)throw new RangeError("Trying to access beyond buffer length")}function M(t,r,n,o,i,s){if(!e.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(r>i||r<s)throw new RangeError('"value" argument is out of bounds');if(n+o>t.length)throw new RangeError("Index out of range")}function T(t,e,r,n,o,i){if(r+n>t.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function x(t,e,r,n,i){return e=+e,r>>>=0,i||T(t,0,r,4),o.write(t,e,r,n,23,4),r+4}function U(t,e,r,n,i){return e=+e,r>>>=0,i||T(t,0,r,8),o.write(t,e,r,n,52,8),r+8}e.prototype.slice=function(t,r){var n=this.length;(t=~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),(r=void 0===r?n:~~r)<0?(r+=n)<0&&(r=0):r>n&&(r=n),r<t&&(r=t);var o=this.subarray(t,r);return o.__proto__=e.prototype,o},e.prototype.readUIntLE=function(t,e,r){t>>>=0,e>>>=0,r||O(t,e,this.length);for(var n=this[t],o=1,i=0;++i<e&&(o*=256);)n+=this[t+i]*o;return n},e.prototype.readUIntBE=function(t,e,r){t>>>=0,e>>>=0,r||O(t,e,this.length);for(var n=this[t+--e],o=1;e>0&&(o*=256);)n+=this[t+--e]*o;return n},e.prototype.readUInt8=function(t,e){return t>>>=0,e||O(t,1,this.length),this[t]},e.prototype.readUInt16LE=function(t,e){return t>>>=0,e||O(t,2,this.length),this[t]|this[t+1]<<8},e.prototype.readUInt16BE=function(t,e){return t>>>=0,e||O(t,2,this.length),this[t]<<8|this[t+1]},e.prototype.readUInt32LE=function(t,e){return t>>>=0,e||O(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},e.prototype.readUInt32BE=function(t,e){return t>>>=0,e||O(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},e.prototype.readIntLE=function(t,e,r){t>>>=0,e>>>=0,r||O(t,e,this.length);for(var n=this[t],o=1,i=0;++i<e&&(o*=256);)n+=this[t+i]*o;return n>=(o*=128)&&(n-=Math.pow(2,8*e)),n},e.prototype.readIntBE=function(t,e,r){t>>>=0,e>>>=0,r||O(t,e,this.length);for(var n=e,o=1,i=this[t+--n];n>0&&(o*=256);)i+=this[t+--n]*o;return i>=(o*=128)&&(i-=Math.pow(2,8*e)),i},e.prototype.readInt8=function(t,e){return t>>>=0,e||O(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},e.prototype.readInt16LE=function(t,e){t>>>=0,e||O(t,2,this.length);var r=this[t]|this[t+1]<<8;return 32768&r?4294901760|r:r},e.prototype.readInt16BE=function(t,e){t>>>=0,e||O(t,2,this.length);var r=this[t+1]|this[t]<<8;return 32768&r?4294901760|r:r},e.prototype.readInt32LE=function(t,e){return t>>>=0,e||O(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},e.prototype.readInt32BE=function(t,e){return t>>>=0,e||O(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},e.prototype.readFloatLE=function(t,e){return t>>>=0,e||O(t,4,this.length),o.read(this,t,!0,23,4)},e.prototype.readFloatBE=function(t,e){return t>>>=0,e||O(t,4,this.length),o.read(this,t,!1,23,4)},e.prototype.readDoubleLE=function(t,e){return t>>>=0,e||O(t,8,this.length),o.read(this,t,!0,52,8)},e.prototype.readDoubleBE=function(t,e){return t>>>=0,e||O(t,8,this.length),o.read(this,t,!1,52,8)},e.prototype.writeUIntLE=function(t,e,r,n){(t=+t,e>>>=0,r>>>=0,n)||M(this,t,e,r,Math.pow(2,8*r)-1,0);var o=1,i=0;for(this[e]=255&t;++i<r&&(o*=256);)this[e+i]=t/o&255;return e+r},e.prototype.writeUIntBE=function(t,e,r,n){(t=+t,e>>>=0,r>>>=0,n)||M(this,t,e,r,Math.pow(2,8*r)-1,0);var o=r-1,i=1;for(this[e+o]=255&t;--o>=0&&(i*=256);)this[e+o]=t/i&255;return e+r},e.prototype.writeUInt8=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,1,255,0),this[e]=255&t,e+1},e.prototype.writeUInt16LE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,2,65535,0),this[e]=255&t,this[e+1]=t>>>8,e+2},e.prototype.writeUInt16BE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,2,65535,0),this[e]=t>>>8,this[e+1]=255&t,e+2},e.prototype.writeUInt32LE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,4,4294967295,0),this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t,e+4},e.prototype.writeUInt32BE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,4,4294967295,0),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},e.prototype.writeIntLE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var o=Math.pow(2,8*r-1);M(this,t,e,r,o-1,-o)}var i=0,s=1,a=0;for(this[e]=255&t;++i<r&&(s*=256);)t<0&&0===a&&0!==this[e+i-1]&&(a=1),this[e+i]=(t/s>>0)-a&255;return e+r},e.prototype.writeIntBE=function(t,e,r,n){if(t=+t,e>>>=0,!n){var o=Math.pow(2,8*r-1);M(this,t,e,r,o-1,-o)}var i=r-1,s=1,a=0;for(this[e+i]=255&t;--i>=0&&(s*=256);)t<0&&0===a&&0!==this[e+i+1]&&(a=1),this[e+i]=(t/s>>0)-a&255;return e+r},e.prototype.writeInt8=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,1,127,-128),t<0&&(t=255+t+1),this[e]=255&t,e+1},e.prototype.writeInt16LE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,2,32767,-32768),this[e]=255&t,this[e+1]=t>>>8,e+2},e.prototype.writeInt16BE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,2,32767,-32768),this[e]=t>>>8,this[e+1]=255&t,e+2},e.prototype.writeInt32LE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,4,2147483647,-2147483648),this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24,e+4},e.prototype.writeInt32BE=function(t,e,r){return t=+t,e>>>=0,r||M(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t,e+4},e.prototype.writeFloatLE=function(t,e,r){return x(this,t,e,!0,r)},e.prototype.writeFloatBE=function(t,e,r){return x(this,t,e,!1,r)},e.prototype.writeDoubleLE=function(t,e,r){return U(this,t,e,!0,r)},e.prototype.writeDoubleBE=function(t,e,r){return U(this,t,e,!1,r)},e.prototype.copy=function(t,r,n,o){if(!e.isBuffer(t))throw new TypeError("argument should be a Buffer");if(n||(n=0),o||0===o||(o=this.length),r>=t.length&&(r=t.length),r||(r=0),o>0&&o<n&&(o=n),o===n)return 0;if(0===t.length||0===this.length)return 0;if(r<0)throw new RangeError("targetStart out of bounds");if(n<0||n>=this.length)throw new RangeError("Index out of range");if(o<0)throw new RangeError("sourceEnd out of bounds");o>this.length&&(o=this.length),t.length-r<o-n&&(o=t.length-r+n);var i=o-n;if(this===t&&"function"==typeof Uint8Array.prototype.copyWithin)this.copyWithin(r,n,o);else if(this===t&&n<r&&r<o)for(var s=i-1;s>=0;--s)t[s+r]=this[s+n];else Uint8Array.prototype.set.call(t,this.subarray(n,o),r);return i},e.prototype.fill=function(t,r,n,o){if("string"==typeof t){if("string"==typeof r?(o=r,r=0,n=this.length):"string"==typeof n&&(o=n,n=this.length),void 0!==o&&"string"!=typeof o)throw new TypeError("encoding must be a string");if("string"==typeof o&&!e.isEncoding(o))throw new TypeError("Unknown encoding: "+o);if(1===t.length){var i=t.charCodeAt(0);("utf8"===o&&i<128||"latin1"===o)&&(t=i)}}else"number"==typeof t&&(t&=255);if(r<0||this.length<r||this.length<n)throw new RangeError("Out of range index");if(n<=r)return this;var s;if(r>>>=0,n=void 0===n?this.length:n>>>0,t||(t=0),"number"==typeof t)for(s=r;s<n;++s)this[s]=t;else{var a=e.isBuffer(t)?t:e.from(t,o),u=a.length;if(0===u)throw new TypeError('The value "'+t+'" is invalid for argument "value"');for(s=0;s<n-r;++s)this[s+r]=a[s%u]}return this};var I=/[^+/0-9A-Za-z-_]/g;function j(t){return t<16?"0"+t.toString(16):t.toString(16)}function B(t,e){var r;e=e||1/0;for(var n=t.length,o=null,i=[],s=0;s<n;++s){if((r=t.charCodeAt(s))>55295&&r<57344){if(!o){if(r>56319){(e-=3)>-1&&i.push(239,191,189);continue}if(s+1===n){(e-=3)>-1&&i.push(239,191,189);continue}o=r;continue}if(r<56320){(e-=3)>-1&&i.push(239,191,189),o=r;continue}r=65536+(o-55296<<10|r-56320)}else o&&(e-=3)>-1&&i.push(239,191,189);if(o=null,r<128){if((e-=1)<0)break;i.push(r)}else if(r<2048){if((e-=2)<0)break;i.push(r>>6|192,63&r|128)}else if(r<65536){if((e-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function k(t){return n.toByteArray(function(t){if((t=(t=t.split("=")[0]).trim().replace(I,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function P(t,e,r,n){for(var o=0;o<n&&!(o+r>=e.length||o>=t.length);++o)e[o+r]=t[o];return o}function N(t,e){return t instanceof e||null!=t&&null!=t.constructor&&null!=t.constructor.name&&t.constructor.name===e.name}function F(t){return t!=t}}).call(this,t("buffer").Buffer)},{"base64-js":1,buffer:3,ieee754:4}],4:[function(t,e,r){r.read=function(t,e,r,n,o){var i,s,a=8*o-n-1,u=(1<<a)-1,c=u>>1,l=-7,h=r?o-1:0,f=r?-1:1,p=t[e+h];for(h+=f,i=p&(1<<-l)-1,p>>=-l,l+=a;l>0;i=256*i+t[e+h],h+=f,l-=8);for(s=i&(1<<-l)-1,i>>=-l,l+=n;l>0;s=256*s+t[e+h],h+=f,l-=8);if(0===i)i=1-c;else{if(i===u)return s?NaN:1/0*(p?-1:1);s+=Math.pow(2,n),i-=c}return(p?-1:1)*s*Math.pow(2,i-n)},r.write=function(t,e,r,n,o,i){var s,a,u,c=8*i-o-1,l=(1<<c)-1,h=l>>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:i-1,g=n?1:-1,m=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(a=isNaN(e)?1:0,s=l):(s=Math.floor(Math.log(e)/Math.LN2),e*(u=Math.pow(2,-s))<1&&(s--,u*=2),(e+=s+h>=1?f/u:f*Math.pow(2,1-h))*u>=2&&(s++,u/=2),s+h>=l?(a=0,s=l):s+h>=1?(a=(e*u-1)*Math.pow(2,o),s+=h):(a=e*Math.pow(2,h-1)*Math.pow(2,o),s=0));o>=8;t[r+p]=255&a,p+=g,a/=256,o-=8);for(s=s<<o|a,c+=o;c>0;t[r+p]=255&s,p+=g,s/=256,c-=8);t[r+p-g]|=128*m}},{}],5:[function(t,e,r){(function(t){function e(t,e){for(var r=0,n=t.length-1;n>=0;n--){var o=t[n];"."===o?t.splice(n,1):".."===o?(t.splice(n,1),r++):r&&(t.splice(n,1),r--)}if(e)for(;r--;r)t.unshift("..");return t}function n(t,e){if(t.filter)return t.filter(e);for(var r=[],n=0;n<t.length;n++)e(t[n],n,t)&&r.push(t[n]);return r}r.resolve=function(){for(var r="",o=!1,i=arguments.length-1;i>=-1&&!o;i--){var s=i>=0?arguments[i]:t.cwd();if("string"!=typeof s)throw new TypeError("Arguments to path.resolve must be strings");s&&(r=s+"/"+r,o="/"===s.charAt(0))}return(o?"/":"")+(r=e(n(r.split("/"),(function(t){return!!t})),!o).join("/"))||"."},r.normalize=function(t){var i=r.isAbsolute(t),s="/"===o(t,-1);return(t=e(n(t.split("/"),(function(t){return!!t})),!i).join("/"))||i||(t="."),t&&s&&(t+="/"),(i?"/":"")+t},r.isAbsolute=function(t){return"/"===t.charAt(0)},r.join=function(){var t=Array.prototype.slice.call(arguments,0);return r.normalize(n(t,(function(t,e){if("string"!=typeof t)throw new TypeError("Arguments to path.join must be strings");return t})).join("/"))},r.relative=function(t,e){function n(t){for(var e=0;e<t.length&&""===t[e];e++);for(var r=t.length-1;r>=0&&""===t[r];r--);return e>r?[]:t.slice(e,r-e+1)}t=r.resolve(t).substr(1),e=r.resolve(e).substr(1);for(var o=n(t.split("/")),i=n(e.split("/")),s=Math.min(o.length,i.length),a=s,u=0;u<s;u++)if(o[u]!==i[u]){a=u;break}var c=[];for(u=a;u<o.length;u++)c.push("..");return(c=c.concat(i.slice(a))).join("/")},r.sep="/",r.delimiter=":",r.dirname=function(t){if("string"!=typeof t&&(t+=""),0===t.length)return".";for(var e=t.charCodeAt(0),r=47===e,n=-1,o=!0,i=t.length-1;i>=1;--i)if(47===(e=t.charCodeAt(i))){if(!o){n=i;break}}else o=!1;return-1===n?r?"/":".":r&&1===n?"/":t.slice(0,n)},r.basename=function(t,e){var r=function(t){"string"!=typeof t&&(t+="");var e,r=0,n=-1,o=!0;for(e=t.length-1;e>=0;--e)if(47===t.charCodeAt(e)){if(!o){r=e+1;break}}else-1===n&&(o=!1,n=e+1);return-1===n?"":t.slice(r,n)}(t);return e&&r.substr(-1*e.length)===e&&(r=r.substr(0,r.length-e.length)),r},r.extname=function(t){"string"!=typeof t&&(t+="");for(var e=-1,r=0,n=-1,o=!0,i=0,s=t.length-1;s>=0;--s){var a=t.charCodeAt(s);if(47!==a)-1===n&&(o=!1,n=s+1),46===a?-1===e?e=s:1!==i&&(i=1):-1!==e&&(i=-1);else if(!o){r=s+1;break}}return-1===e||-1===n||0===i||1===i&&e===n-1&&e===r+1?"":t.slice(e,n)};var o="b"==="ab".substr(-1)?function(t,e,r){return t.substr(e,r)}:function(t,e,r){return e<0&&(e=t.length+e),t.substr(e,r)}}).call(this,t("_process"))},{_process:6}],6:[function(t,e,r){var n,o,i=e.exports={};function s(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===s||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:s}catch(t){n=s}try{o="function"==typeof clearTimeout?clearTimeout:a}catch(t){o=a}}();var c,l=[],h=!1,f=-1;function p(){h&&c&&(h=!1,c.length?l=c.concat(l):f=-1,l.length&&g())}function g(){if(!h){var t=u(p);h=!0;for(var e=l.length;e;){for(c=l,l=[];++f<e;)c&&c[f].run();f=-1,e=l.length}c=null,h=!1,function(t){if(o===clearTimeout)return clearTimeout(t);if((o===a||!o)&&clearTimeout)return o=clearTimeout,clearTimeout(t);try{o(t)}catch(e){try{return o.call(null,t)}catch(e){return o.call(this,t)}}}(t)}}function m(t,e){this.fun=t,this.array=e}function d(){}i.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)e[r-1]=arguments[r];l.push(new m(t,e)),1!==l.length||h||u(g)},m.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=d,i.addListener=d,i.once=d,i.off=d,i.removeListener=d,i.removeAllListeners=d,i.emit=d,i.prependListener=d,i.prependOnceListener=d,i.listeners=function(t){return[]},i.binding=function(t){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(t){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}},{}],7:[function(t,e,r){(function(t){!function(n){var o="object"==typeof r&&r&&!r.nodeType&&r,i="object"==typeof e&&e&&!e.nodeType&&e,s="object"==typeof t&&t;s.global!==s&&s.window!==s&&s.self!==s||(n=s);var a,u,c=2147483647,l=/^xn--/,h=/[^\x20-\x7E]/,f=/[\x2E\u3002\uFF0E\uFF61]/g,p={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},g=Math.floor,m=String.fromCharCode;function d(t){throw new RangeError(p[t])}function y(t,e){for(var r=t.length,n=[];r--;)n[r]=e(t[r]);return n}function v(t,e){var r=t.split("@"),n="";return r.length>1&&(n=r[0]+"@",t=r[1]),n+y((t=t.replace(f,".")).split("."),e).join(".")}function w(t){for(var e,r,n=[],o=0,i=t.length;o<i;)(e=t.charCodeAt(o++))>=55296&&e<=56319&&o<i?56320==(64512&(r=t.charCodeAt(o++)))?n.push(((1023&e)<<10)+(1023&r)+65536):(n.push(e),o--):n.push(e);return n}function b(t){return y(t,(function(t){var e="";return t>65535&&(e+=m((t-=65536)>>>10&1023|55296),t=56320|1023&t),e+=m(t)})).join("")}function _(t,e){return t+22+75*(t<26)-((0!=e)<<5)}function A(t,e,r){var n=0;for(t=r?g(t/700):t>>1,t+=g(t/e);t>455;n+=36)t=g(t/35);return g(n+36*t/(t+38))}function C(t){var e,r,n,o,i,s,a,u,l,h,f,p=[],m=t.length,y=0,v=128,w=72;for((r=t.lastIndexOf("-"))<0&&(r=0),n=0;n<r;++n)t.charCodeAt(n)>=128&&d("not-basic"),p.push(t.charCodeAt(n));for(o=r>0?r+1:0;o<m;){for(i=y,s=1,a=36;o>=m&&d("invalid-input"),((u=(f=t.charCodeAt(o++))-48<10?f-22:f-65<26?f-65:f-97<26?f-97:36)>=36||u>g((c-y)/s))&&d("overflow"),y+=u*s,!(u<(l=a<=w?1:a>=w+26?26:a-w));a+=36)s>g(c/(h=36-l))&&d("overflow"),s*=h;w=A(y-i,e=p.length+1,0==i),g(y/e)>c-v&&d("overflow"),v+=g(y/e),y%=e,p.splice(y++,0,v)}return b(p)}function E(t){var e,r,n,o,i,s,a,u,l,h,f,p,y,v,b,C=[];for(p=(t=w(t)).length,e=128,r=0,i=72,s=0;s<p;++s)(f=t[s])<128&&C.push(m(f));for(n=o=C.length,o&&C.push("-");n<p;){for(a=c,s=0;s<p;++s)(f=t[s])>=e&&f<a&&(a=f);for(a-e>g((c-r)/(y=n+1))&&d("overflow"),r+=(a-e)*y,e=a,s=0;s<p;++s)if((f=t[s])<e&&++r>c&&d("overflow"),f==e){for(u=r,l=36;!(u<(h=l<=i?1:l>=i+26?26:l-i));l+=36)b=u-h,v=36-h,C.push(m(_(h+b%v,0))),u=g(b/v);C.push(m(_(u,0))),i=A(r,y,n==o),r=0,++n}++r,++e}return C.join("")}if(a={version:"1.4.1",ucs2:{decode:w,encode:b},decode:C,encode:E,toASCII:function(t){return v(t,(function(t){return h.test(t)?"xn--"+E(t):t}))},toUnicode:function(t){return v(t,(function(t){return l.test(t)?C(t.slice(4).toLowerCase()):t}))}},"function"==typeof define&&"object"==typeof define.amd&&define.amd)define("punycode",(function(){return a}));else if(o&&i)if(e.exports==o)i.exports=a;else for(u in a)a.hasOwnProperty(u)&&(o[u]=a[u]);else n.punycode=a}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],8:[function(t,e,r){"use strict";function n(t,e){return Object.prototype.hasOwnProperty.call(t,e)}e.exports=function(t,e,r,i){e=e||"&",r=r||"=";var s={};if("string"!=typeof t||0===t.length)return s;var a=/\+/g;t=t.split(e);var u=1e3;i&&"number"==typeof i.maxKeys&&(u=i.maxKeys);var c=t.length;u>0&&c>u&&(c=u);for(var l=0;l<c;++l){var h,f,p,g,m=t[l].replace(a,"%20"),d=m.indexOf(r);d>=0?(h=m.substr(0,d),f=m.substr(d+1)):(h=m,f=""),p=decodeURIComponent(h),g=decodeURIComponent(f),n(s,p)?o(s[p])?s[p].push(g):s[p]=[s[p],g]:s[p]=g}return s};var o=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}},{}],9:[function(t,e,r){"use strict";var n=function(t){switch(typeof t){case"string":return t;case"boolean":return t?"true":"false";case"number":return isFinite(t)?t:"";default:return""}};e.exports=function(t,e,r,a){return e=e||"&",r=r||"=",null===t&&(t=void 0),"object"==typeof t?i(s(t),(function(s){var a=encodeURIComponent(n(s))+r;return o(t[s])?i(t[s],(function(t){return a+encodeURIComponent(n(t))})).join(e):a+encodeURIComponent(n(t[s]))})).join(e):a?encodeURIComponent(n(a))+r+encodeURIComponent(n(t)):""};var o=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)};function i(t,e){if(t.map)return t.map(e);for(var r=[],n=0;n<t.length;n++)r.push(e(t[n],n));return r}var s=Object.keys||function(t){var e=[];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&e.push(r);return e}},{}],10:[function(t,e,r){"use strict";r.decode=r.parse=t("./decode"),r.encode=r.stringify=t("./encode")},{"./decode":8,"./encode":9}],11:[function(t,e,r){(function(e,n){var o=t("process/browser.js").nextTick,i=Function.prototype.apply,s=Array.prototype.slice,a={},u=0;function c(t,e){this._id=t,this._clearFn=e}r.setTimeout=function(){return new c(i.call(setTimeout,window,arguments),clearTimeout)},r.setInterval=function(){return new c(i.call(setInterval,window,arguments),clearInterval)},r.clearTimeout=r.clearInterval=function(t){t.close()},c.prototype.unref=c.prototype.ref=function(){},c.prototype.close=function(){this._clearFn.call(window,this._id)},r.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},r.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},r._unrefActive=r.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout((function(){t._onTimeout&&t._onTimeout()}),e))},r.setImmediate="function"==typeof e?e:function(t){var e=u++,n=!(arguments.length<2)&&s.call(arguments,1);return a[e]=!0,o((function(){a[e]&&(n?t.apply(null,n):t.call(null),r.clearImmediate(e))})),e},r.clearImmediate="function"==typeof n?n:function(t){delete a[t]}}).call(this,t("timers").setImmediate,t("timers").clearImmediate)},{"process/browser.js":6,timers:11}],12:[function(t,e,r){"use strict";var n=t("punycode"),o=t("./util");function i(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}r.parse=w,r.resolve=function(t,e){return w(t,!1,!0).resolve(e)},r.resolveObject=function(t,e){return t?w(t,!1,!0).resolveObject(e):e},r.format=function(t){o.isString(t)&&(t=w(t));return t instanceof i?t.format():i.prototype.format.call(t)},r.Url=i;var s=/^([a-z0-9.+-]+:)/i,a=/:[0-9]*$/,u=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,c=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r","\n","\t"]),l=["'"].concat(c),h=["%","/","?",";","#"].concat(l),f=["/","?","#"],p=/^[+a-z0-9A-Z_-]{0,63}$/,g=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,m={javascript:!0,"javascript:":!0},d={javascript:!0,"javascript:":!0},y={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},v=t("querystring");function w(t,e,r){if(t&&o.isObject(t)&&t instanceof i)return t;var n=new i;return n.parse(t,e,r),n}i.prototype.parse=function(t,e,r){if(!o.isString(t))throw new TypeError("Parameter 'url' must be a string, not "+typeof t);var i=t.indexOf("?"),a=-1!==i&&i<t.indexOf("#")?"?":"#",c=t.split(a);c[0]=c[0].replace(/\\/g,"/");var w=t=c.join(a);if(w=w.trim(),!r&&1===t.split("#").length){var b=u.exec(w);if(b)return this.path=w,this.href=w,this.pathname=b[1],b[2]?(this.search=b[2],this.query=e?v.parse(this.search.substr(1)):this.search.substr(1)):e&&(this.search="",this.query={}),this}var _=s.exec(w);if(_){var A=(_=_[0]).toLowerCase();this.protocol=A,w=w.substr(_.length)}if(r||_||w.match(/^\/\/[^@\/]+@[^@\/]+/)){var C="//"===w.substr(0,2);!C||_&&d[_]||(w=w.substr(2),this.slashes=!0)}if(!d[_]&&(C||_&&!y[_])){for(var E,S,L=-1,R=0;R<f.length;R++){-1!==(O=w.indexOf(f[R]))&&(-1===L||O<L)&&(L=O)}-1!==(S=-1===L?w.lastIndexOf("@"):w.lastIndexOf("@",L))&&(E=w.slice(0,S),w=w.slice(S+1),this.auth=decodeURIComponent(E)),L=-1;for(R=0;R<h.length;R++){var O;-1!==(O=w.indexOf(h[R]))&&(-1===L||O<L)&&(L=O)}-1===L&&(L=w.length),this.host=w.slice(0,L),w=w.slice(L),this.parseHost(),this.hostname=this.hostname||"";var M="["===this.hostname[0]&&"]"===this.hostname[this.hostname.length-1];if(!M)for(var T=this.hostname.split(/\./),x=(R=0,T.length);R<x;R++){var U=T[R];if(U&&!U.match(p)){for(var I="",j=0,B=U.length;j<B;j++)U.charCodeAt(j)>127?I+="x":I+=U[j];if(!I.match(p)){var k=T.slice(0,R),P=T.slice(R+1),N=U.match(g);N&&(k.push(N[1]),P.unshift(N[2])),P.length&&(w="/"+P.join(".")+w),this.hostname=k.join(".");break}}}this.hostname.length>255?this.hostname="":this.hostname=this.hostname.toLowerCase(),M||(this.hostname=n.toASCII(this.hostname));var F=this.port?":"+this.port:"",q=this.hostname||"";this.host=q+F,this.href+=this.host,M&&(this.hostname=this.hostname.substr(1,this.hostname.length-2),"/"!==w[0]&&(w="/"+w))}if(!m[A])for(R=0,x=l.length;R<x;R++){var D=l[R];if(-1!==w.indexOf(D)){var G=encodeURIComponent(D);G===D&&(G=escape(D)),w=w.split(D).join(G)}}var z=w.indexOf("#");-1!==z&&(this.hash=w.substr(z),w=w.slice(0,z));var V=w.indexOf("?");if(-1!==V?(this.search=w.substr(V),this.query=w.substr(V+1),e&&(this.query=v.parse(this.query)),w=w.slice(0,V)):e&&(this.search="",this.query={}),w&&(this.pathname=w),y[A]&&this.hostname&&!this.pathname&&(this.pathname="/"),this.pathname||this.search){F=this.pathname||"";var $=this.search||"";this.path=F+$}return this.href=this.format(),this},i.prototype.format=function(){var t=this.auth||"";t&&(t=(t=encodeURIComponent(t)).replace(/%3A/i,":"),t+="@");var e=this.protocol||"",r=this.pathname||"",n=this.hash||"",i=!1,s="";this.host?i=t+this.host:this.hostname&&(i=t+(-1===this.hostname.indexOf(":")?this.hostname:"["+this.hostname+"]"),this.port&&(i+=":"+this.port)),this.query&&o.isObject(this.query)&&Object.keys(this.query).length&&(s=v.stringify(this.query));var a=this.search||s&&"?"+s||"";return e&&":"!==e.substr(-1)&&(e+=":"),this.slashes||(!e||y[e])&&!1!==i?(i="//"+(i||""),r&&"/"!==r.charAt(0)&&(r="/"+r)):i||(i=""),n&&"#"!==n.charAt(0)&&(n="#"+n),a&&"?"!==a.charAt(0)&&(a="?"+a),e+i+(r=r.replace(/[?#]/g,(function(t){return encodeURIComponent(t)})))+(a=a.replace("#","%23"))+n},i.prototype.resolve=function(t){return this.resolveObject(w(t,!1,!0)).format()},i.prototype.resolveObject=function(t){if(o.isString(t)){var e=new i;e.parse(t,!1,!0),t=e}for(var r=new i,n=Object.keys(this),s=0;s<n.length;s++){var a=n[s];r[a]=this[a]}if(r.hash=t.hash,""===t.href)return r.href=r.format(),r;if(t.slashes&&!t.protocol){for(var u=Object.keys(t),c=0;c<u.length;c++){var l=u[c];"protocol"!==l&&(r[l]=t[l])}return y[r.protocol]&&r.hostname&&!r.pathname&&(r.path=r.pathname="/"),r.href=r.format(),r}if(t.protocol&&t.protocol!==r.protocol){if(!y[t.protocol]){for(var h=Object.keys(t),f=0;f<h.length;f++){var p=h[f];r[p]=t[p]}return r.href=r.format(),r}if(r.protocol=t.protocol,t.host||d[t.protocol])r.pathname=t.pathname;else{for(var g=(t.pathname||"").split("/");g.length&&!(t.host=g.shift()););t.host||(t.host=""),t.hostname||(t.hostname=""),""!==g[0]&&g.unshift(""),g.length<2&&g.unshift(""),r.pathname=g.join("/")}if(r.search=t.search,r.query=t.query,r.host=t.host||"",r.auth=t.auth,r.hostname=t.hostname||t.host,r.port=t.port,r.pathname||r.search){var m=r.pathname||"",v=r.search||"";r.path=m+v}return r.slashes=r.slashes||t.slashes,r.href=r.format(),r}var w=r.pathname&&"/"===r.pathname.charAt(0),b=t.host||t.pathname&&"/"===t.pathname.charAt(0),_=b||w||r.host&&t.pathname,A=_,C=r.pathname&&r.pathname.split("/")||[],E=(g=t.pathname&&t.pathname.split("/")||[],r.protocol&&!y[r.protocol]);if(E&&(r.hostname="",r.port=null,r.host&&(""===C[0]?C[0]=r.host:C.unshift(r.host)),r.host="",t.protocol&&(t.hostname=null,t.port=null,t.host&&(""===g[0]?g[0]=t.host:g.unshift(t.host)),t.host=null),_=_&&(""===g[0]||""===C[0])),b)r.host=t.host||""===t.host?t.host:r.host,r.hostname=t.hostname||""===t.hostname?t.hostname:r.hostname,r.search=t.search,r.query=t.query,C=g;else if(g.length)C||(C=[]),C.pop(),C=C.concat(g),r.search=t.search,r.query=t.query;else if(!o.isNullOrUndefined(t.search)){if(E)r.hostname=r.host=C.shift(),(M=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=M.shift(),r.host=r.hostname=M.shift());return r.search=t.search,r.query=t.query,o.isNull(r.pathname)&&o.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.href=r.format(),r}if(!C.length)return r.pathname=null,r.search?r.path="/"+r.search:r.path=null,r.href=r.format(),r;for(var S=C.slice(-1)[0],L=(r.host||t.host||C.length>1)&&("."===S||".."===S)||""===S,R=0,O=C.length;O>=0;O--)"."===(S=C[O])?C.splice(O,1):".."===S?(C.splice(O,1),R++):R&&(C.splice(O,1),R--);if(!_&&!A)for(;R--;R)C.unshift("..");!_||""===C[0]||C[0]&&"/"===C[0].charAt(0)||C.unshift(""),L&&"/"!==C.join("/").substr(-1)&&C.push("");var M,T=""===C[0]||C[0]&&"/"===C[0].charAt(0);E&&(r.hostname=r.host=T?"":C.length?C.shift():"",(M=!!(r.host&&r.host.indexOf("@")>0)&&r.host.split("@"))&&(r.auth=M.shift(),r.host=r.hostname=M.shift()));return(_=_||r.host&&C.length)&&!T&&C.unshift(""),C.length?r.pathname=C.join("/"):(r.pathname=null,r.path=null),o.isNull(r.pathname)&&o.isNull(r.search)||(r.path=(r.pathname?r.pathname:"")+(r.search?r.search:"")),r.auth=t.auth||r.auth,r.slashes=r.slashes||t.slashes,r.href=r.format(),r},i.prototype.parseHost=function(){var t=this.host,e=a.exec(t);e&&(":"!==(e=e[0])&&(this.port=e.substr(1)),t=t.substr(0,t.length-e.length)),t&&(this.hostname=t)}},{"./util":13,punycode:7,querystring:10}],13:[function(t,e,r){"use strict";e.exports={isString:function(t){return"string"==typeof t},isObject:function(t){return"object"==typeof t&&null!==t},isNull:function(t){return null===t},isNullOrUndefined:function(t){return null==t}}},{}],14:[function(t,e,r){window.css=t("css")},{css:16}],15:[function(t,e,r){(function(t){!function(r){"use strict";var n,o="function"==typeof(n=r.atob)?n:"function"==typeof t?function(e){return new t(e,"base64").toString("binary")}:"object"==typeof r.base64js?function(t){var e=r.base64js.b64ToByteArray(t);return Array.prototype.map.call(e,(function(t){return String.fromCharCode(t)})).join("")}:function(){throw new Error("You're probably in an old browser or an iOS webworker. It might help to include beatgammit's base64-js.")};r.atob=o,"object"==typeof e&&e&&e.exports&&(e.exports=o)}(window)}).call(this,t("buffer").Buffer)},{buffer:3}],16:[function(t,e,r){r.parse=t("./lib/parse"),r.stringify=t("./lib/stringify")},{"./lib/parse":17,"./lib/stringify":21}],17:[function(t,e,r){var n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;function o(t){return t?t.replace(/^\s+|\s+$/g,""):""}e.exports=function(t,e){e=e||{};var r=1,i=1;function s(t){var e=t.match(/\n/g);e&&(r+=e.length);var n=t.lastIndexOf("\n");i=~n?t.length-n:i+t.length}function a(){var t={line:r,column:i};return function(e){return e.position=new u(t),m(),e}}function u(t){this.start=t,this.end={line:r,column:i},this.source=e.source}u.prototype.content=t;var c=[];function l(n){var o=new Error(e.source+":"+r+":"+i+": "+n);if(o.reason=n,o.filename=e.source,o.line=r,o.column=i,o.source=t,!e.silent)throw o;c.push(o)}function h(){return g(/^{\s*/)}function f(){return g(/^}/)}function p(){var e,r=[];for(m(),d(r);t.length&&"}"!=t.charAt(0)&&(e=R()||O());)!1!==e&&(r.push(e),d(r));return r}function g(e){var r=e.exec(t);if(r){var n=r[0];return s(n),t=t.slice(n.length),r}}function m(){g(/^\s*/)}function d(t){var e;for(t=t||[];e=y();)!1!==e&&t.push(e);return t}function y(){var e=a();if("/"==t.charAt(0)&&"*"==t.charAt(1)){for(var r=2;""!=t.charAt(r)&&("*"!=t.charAt(r)||"/"!=t.charAt(r+1));)++r;if(r+=2,""===t.charAt(r-1))return l("End of comment missing");var n=t.slice(2,r-2);return i+=2,s(n),t=t.slice(r),i+=2,e({type:"comment",comment:n})}}function v(){var t=g(/^([^{]+)/);if(t)return o(t[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g,"").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g,(function(t){return t.replace(/,/g,"‌")})).split(/\s*(?![^(]*\)),\s*/).map((function(t){return t.replace(/\u200C/g,",")}))}function w(){var t=a(),e=g(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);if(e){if(e=o(e[0]),!g(/^:\s*/))return l("property missing ':'");var r=g(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/),i=t({type:"declaration",property:e.replace(n,""),value:r?o(r[0]).replace(n,""):""});return g(/^[;\s]*/),i}}function b(){var t,e=[];if(!h())return l("missing '{'");for(d(e);t=w();)!1!==t&&(e.push(t),d(e));return f()?e:l("missing '}'")}function _(){for(var t,e=[],r=a();t=g(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/);)e.push(t[1]),g(/^,\s*/);if(e.length)return r({type:"keyframe",values:e,declarations:b()})}var A,C=L("import"),E=L("charset"),S=L("namespace");function L(t){var e=new RegExp("^@"+t+"\\s*([^;]+);");return function(){var r=a(),n=g(e);if(n){var o={type:t};return o[t]=n[1].trim(),r(o)}}}function R(){if("@"==t[0])return function(){var t=a();if(e=g(/^@([-\w]+)?keyframes\s*/)){var e,r=e[1];if(!(e=g(/^([-\w]+)\s*/)))return l("@keyframes missing name");var n,o=e[1];if(!h())return l("@keyframes missing '{'");for(var i=d();n=_();)i.push(n),i=i.concat(d());return f()?t({type:"keyframes",name:o,vendor:r,keyframes:i}):l("@keyframes missing '}'")}}()||function(){var t=a(),e=g(/^@media *([^{]+)/);if(e){var r=o(e[1]);if(!h())return l("@media missing '{'");var n=d().concat(p());return f()?t({type:"media",media:r,rules:n}):l("@media missing '}'")}}()||function(){var t=a(),e=g(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);if(e)return t({type:"custom-media",name:o(e[1]),media:o(e[2])})}()||function(){var t=a(),e=g(/^@supports *([^{]+)/);if(e){var r=o(e[1]);if(!h())return l("@supports missing '{'");var n=d().concat(p());return f()?t({type:"supports",supports:r,rules:n}):l("@supports missing '}'")}}()||C()||E()||S()||function(){var t=a(),e=g(/^@([-\w]+)?document *([^{]+)/);if(e){var r=o(e[1]),n=o(e[2]);if(!h())return l("@document missing '{'");var i=d().concat(p());return f()?t({type:"document",document:n,vendor:r,rules:i}):l("@document missing '}'")}}()||function(){var t=a();if(g(/^@page */)){var e=v()||[];if(!h())return l("@page missing '{'");for(var r,n=d();r=w();)n.push(r),n=n.concat(d());return f()?t({type:"page",selectors:e,declarations:n}):l("@page missing '}'")}}()||function(){var t=a();if(g(/^@host\s*/)){if(!h())return l("@host missing '{'");var e=d().concat(p());return f()?t({type:"host",rules:e}):l("@host missing '}'")}}()||function(){var t=a();if(g(/^@font-face\s*/)){if(!h())return l("@font-face missing '{'");for(var e,r=d();e=w();)r.push(e),r=r.concat(d());return f()?t({type:"font-face",declarations:r}):l("@font-face missing '}'")}}()}function O(){var t=a(),e=v();return e?(d(),t({type:"rule",selectors:e,declarations:b()})):l("selector missing")}return function t(e,r){var n=e&&"string"==typeof e.type,o=n?e:r;for(var i in e){var s=e[i];Array.isArray(s)?s.forEach((function(e){t(e,o)})):s&&"object"==typeof s&&t(s,o)}n&&Object.defineProperty(e,"parent",{configurable:!0,writable:!0,enumerable:!1,value:r||null});return e}((A=p(),{type:"stylesheet",stylesheet:{source:e.source,rules:A,parsingErrors:c}}))}},{}],18:[function(t,e,r){function n(t){this.options=t||{}}e.exports=n,n.prototype.emit=function(t){return t},n.prototype.visit=function(t){return this[t.type](t)},n.prototype.mapVisit=function(t,e){var r="";e=e||"";for(var n=0,o=t.length;n<o;n++)r+=this.visit(t[n]),e&&n<o-1&&(r+=this.emit(e));return r}},{}],19:[function(t,e,r){var n=t("./compiler"),o=t("inherits");function i(t){n.call(this,t)}e.exports=i,o(i,n),i.prototype.compile=function(t){return t.stylesheet.rules.map(this.visit,this).join("")},i.prototype.comment=function(t){return this.emit("",t.position)},i.prototype.import=function(t){return this.emit("@import "+t.import+";",t.position)},i.prototype.media=function(t){return this.emit("@media "+t.media,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}")},i.prototype.document=function(t){var e="@"+(t.vendor||"")+"document "+t.document;return this.emit(e,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}")},i.prototype.charset=function(t){return this.emit("@charset "+t.charset+";",t.position)},i.prototype.namespace=function(t){return this.emit("@namespace "+t.namespace+";",t.position)},i.prototype.supports=function(t){return this.emit("@supports "+t.supports,t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}")},i.prototype.keyframes=function(t){return this.emit("@"+(t.vendor||"")+"keyframes "+t.name,t.position)+this.emit("{")+this.mapVisit(t.keyframes)+this.emit("}")},i.prototype.keyframe=function(t){var e=t.declarations;return this.emit(t.values.join(","),t.position)+this.emit("{")+this.mapVisit(e)+this.emit("}")},i.prototype.page=function(t){var e=t.selectors.length?t.selectors.join(", "):"";return this.emit("@page "+e,t.position)+this.emit("{")+this.mapVisit(t.declarations)+this.emit("}")},i.prototype["font-face"]=function(t){return this.emit("@font-face",t.position)+this.emit("{")+this.mapVisit(t.declarations)+this.emit("}")},i.prototype.host=function(t){return this.emit("@host",t.position)+this.emit("{")+this.mapVisit(t.rules)+this.emit("}")},i.prototype["custom-media"]=function(t){return this.emit("@custom-media "+t.name+" "+t.media+";",t.position)},i.prototype.rule=function(t){var e=t.declarations;return e.length?this.emit(t.selectors.join(","),t.position)+this.emit("{")+this.mapVisit(e)+this.emit("}"):""},i.prototype.declaration=function(t){return this.emit(t.property+":"+t.value,t.position)+this.emit(";")}},{"./compiler":18,inherits:24}],20:[function(t,e,r){var n=t("./compiler"),o=t("inherits");function i(t){t=t||{},n.call(this,t),this.indentation=t.indent}e.exports=i,o(i,n),i.prototype.compile=function(t){return this.stylesheet(t)},i.prototype.stylesheet=function(t){return this.mapVisit(t.stylesheet.rules,"\n\n")},i.prototype.comment=function(t){return this.emit(this.indent()+"/*"+t.comment+"*/",t.position)},i.prototype.import=function(t){return this.emit("@import "+t.import+";",t.position)},i.prototype.media=function(t){return this.emit("@media "+t.media,t.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},i.prototype.document=function(t){var e="@"+(t.vendor||"")+"document "+t.document;return this.emit(e,t.position)+this.emit("  {\n"+this.indent(1))+this.mapVisit(t.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},i.prototype.charset=function(t){return this.emit("@charset "+t.charset+";",t.position)},i.prototype.namespace=function(t){return this.emit("@namespace "+t.namespace+";",t.position)},i.prototype.supports=function(t){return this.emit("@supports "+t.supports,t.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},i.prototype.keyframes=function(t){return this.emit("@"+(t.vendor||"")+"keyframes "+t.name,t.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t.keyframes,"\n")+this.emit(this.indent(-1)+"}")},i.prototype.keyframe=function(t){var e=t.declarations;return this.emit(this.indent())+this.emit(t.values.join(", "),t.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(e,"\n")+this.emit(this.indent(-1)+"\n"+this.indent()+"}\n")},i.prototype.page=function(t){var e=t.selectors.length?t.selectors.join(", ")+" ":"";return this.emit("@page "+e,t.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(t.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},i.prototype["font-face"]=function(t){return this.emit("@font-face ",t.position)+this.emit("{\n")+this.emit(this.indent(1))+this.mapVisit(t.declarations,"\n")+this.emit(this.indent(-1))+this.emit("\n}")},i.prototype.host=function(t){return this.emit("@host",t.position)+this.emit(" {\n"+this.indent(1))+this.mapVisit(t.rules,"\n\n")+this.emit(this.indent(-1)+"\n}")},i.prototype["custom-media"]=function(t){return this.emit("@custom-media "+t.name+" "+t.media+";",t.position)},i.prototype.rule=function(t){var e=this.indent(),r=t.declarations;return r.length?this.emit(t.selectors.map((function(t){return e+t})).join(",\n"),t.position)+this.emit(" {\n")+this.emit(this.indent(1))+this.mapVisit(r,"\n")+this.emit(this.indent(-1))+this.emit("\n"+this.indent()+"}"):""},i.prototype.declaration=function(t){return this.emit(this.indent())+this.emit(t.property+": "+t.value,t.position)+this.emit(";")},i.prototype.indent=function(t){return this.level=this.level||1,null!=t?(this.level+=t,""):Array(this.level).join(this.indentation||"  ")}},{"./compiler":18,inherits:24}],21:[function(t,e,r){var n=t("./compress"),o=t("./identity");e.exports=function(e,r){var i=(r=r||{}).compress?new n(r):new o(r);if(r.sourcemap){t("./source-map-support")(i);var s=i.compile(e);return i.applySourceMaps(),{code:s,map:"generator"===r.sourcemap?i.map:i.map.toJSON()}}return s=i.compile(e)}},{"./compress":19,"./identity":20,"./source-map-support":22}],22:[function(t,e,r){var n=t("source-map").SourceMapGenerator,o=t("source-map").SourceMapConsumer,i=t("source-map-resolve"),s=t("fs"),a=t("path");e.exports=function(t){for(var e in t._comment=t.comment,t.map=new n,t.position={line:1,column:1},t.files={},r)t[e]=r[e]};const u=function(t){return"\\"===a.sep?t.replace(/\\/g,"/").replace(/^[a-z]:\/?/i,"/"):t};r.updatePosition=function(t){var e=t.match(/\n/g);e&&(this.position.line+=e.length);var r=t.lastIndexOf("\n");this.position.column=~r?t.length-r:this.position.column+t.length},r.emit=function(t,e){if(e){var r=u(e.source||"source.css");this.map.addMapping({source:r,generated:{line:this.position.line,column:Math.max(this.position.column-1,0)},original:{line:e.start.line,column:e.start.column-1}}),this.addFile(r,e)}return this.updatePosition(t),t},r.addFile=function(t,e){"string"==typeof e.content&&(Object.prototype.hasOwnProperty.call(this.files,t)||(this.files[t]=e.content))},r.applySourceMaps=function(){Object.keys(this.files).forEach((function(t){var e=this.files[t];if(this.map.setSourceContent(t,e),!1!==this.options.inputSourcemaps){var r=i.resolveSync(e,t,s.readFileSync);if(r){var n=new o(r.map),c=r.sourcesRelativeTo;this.map.applySourceMap(n,t,u(a.dirname(c)))}}}),this)},r.comment=function(t){return/^# sourceMappingURL=/.test(t.comment)?this.emit("",t.position):this._comment(t)}},{fs:2,path:5,"source-map":36,"source-map-resolve":25}],23:[function(t,e,r){"use strict";var n=new RegExp("%[a-f0-9]{2}","gi"),o=new RegExp("(%[a-f0-9]{2})+","gi");function i(t,e){try{return decodeURIComponent(t.join(""))}catch(t){}if(1===t.length)return t;e=e||1;var r=t.slice(0,e),n=t.slice(e);return Array.prototype.concat.call([],i(r),i(n))}function s(t){try{return decodeURIComponent(t)}catch(o){for(var e=t.match(n),r=1;r<e.length;r++)e=(t=i(e,r).join("")).match(n);return t}}e.exports=function(t){if("string"!=typeof t)throw new TypeError("Expected `encodedURI` to be of type `string`, got `"+typeof t+"`");try{return t=t.replace(/\+/g," "),decodeURIComponent(t)}catch(e){return function(t){for(var e={"%FE%FF":"��","%FF%FE":"��"},r=o.exec(t);r;){try{e[r[0]]=decodeURIComponent(r[0])}catch(t){var n=s(r[0]);n!==r[0]&&(e[r[0]]=n)}r=o.exec(t)}e["%C2"]="�";for(var i=Object.keys(e),a=0;a<i.length;a++){var u=i[a];t=t.replace(new RegExp(u,"g"),e[u])}return t}(t)}}},{}],24:[function(t,e,r){"function"==typeof Object.create?e.exports=function(t,e){e&&(t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(t,e){if(e){t.super_=e;var r=function(){};r.prototype=e.prototype,t.prototype=new r,t.prototype.constructor=t}}},{}],25:[function(t,e,r){(function(r){var n=t("atob"),o=t("url"),i=t("path"),s=t("decode-uri-component");function a(){return Array.prototype.reduce.call(arguments,(function(t,e){return o.resolve(t,e)}))}function u(t){return"\\"===i.sep?t.replace(/\\/g,"/").replace(/^[a-z]:\/?/i,"/"):t}function c(t){return s(t.replace(/\+/g,"%2B"))}function l(t,e,n){r((function(){t(e,n)}))}function h(t,e){try{return JSON.parse(t.replace(/^\)\]\}'/,""))}catch(t){throw t.sourceMapData=e,t}}function f(t,e,r){var n=c(e);try{return String(t(n))}catch(t){throw t.sourceMapData=r,t}}var p=/[#@] sourceMappingURL=([^\s'"]*)/,g=RegExp("(?:/\\*(?:\\s*\r?\n(?://)?)?(?:"+p.source+")\\s*\\*/|//(?:"+p.source+"))\\s*");function m(t,e,r,n){var o;try{o=b(t,e)}catch(t){return l(n,t)}if(!o||o.map)return l(n,null,o);r(c(o.url),(function(t,e){if(t)return t.sourceMapData=o,n(t);o.map=String(e);try{o.map=h(o.map,o)}catch(t){return n(t)}n(null,o)}))}function d(t,e,r){var n=b(t,e);return!n||n.map?n:(n.map=f(r,n.url,n),n.map=h(n.map,n),n)}var y=/^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/,v=/^(?:application|text)\/json$/;function w(t){if("undefined"==typeof TextDecoder||"undefined"==typeof Uint8Array)return n(t);var e=function(t){for(var e=n(t),r=e.length,o=new Uint8Array(r),i=0;i<r;i++)o[i]=e.charCodeAt(i);return o}(t);return new TextDecoder("utf-8",{fatal:!0}).decode(e)}function b(t,e){e=u(e);var r=function(t){var e=t.match(g);return e?e[1]||e[2]||"":null}(t);if(!r)return null;var n=r.match(y);if(n){var o=n[1]||"text/plain",i=n[2]||"",s=n[3]||"",c={sourceMappingURL:r,url:null,sourcesRelativeTo:e,map:s};if(!v.test(o)){var l=new Error("Unuseful data uri mime type: "+o);throw l.sourceMapData=c,l}try{c.map=h(";base64"===i?w(s):decodeURIComponent(s),c)}catch(l){throw l.sourceMapData=c,l}return c}var f=a(e,r);return{sourceMappingURL:r,url:f,sourcesRelativeTo:f,map:null}}function _(t,e,r,n,o){"function"==typeof n&&(o=n,n={});var i=t.sources?t.sources.length:0,s={sourcesResolved:[],sourcesContent:[]};if(0!==i){var a=function(){0===--i&&o(null,s)};E(t,e,n,(function(t,e,n){if(s.sourcesResolved[n]=t,"string"==typeof e)s.sourcesContent[n]=e,l(a,null);else{var o=c(t);r(o,(function(t,e){s.sourcesContent[n]=t||String(e),a()}))}}))}else l(o,null,s)}function A(t,e,r,n){var o={sourcesResolved:[],sourcesContent:[]};return t.sources&&0!==t.sources.length?(E(t,e,n,(function(t,e,n){if(o.sourcesResolved[n]=t,null!==r)if("string"==typeof e)o.sourcesContent[n]=e;else{var i=c(t);try{o.sourcesContent[n]=String(r(i))}catch(t){o.sourcesContent[n]=t}}})),o):o}var C=/\/?$/;function E(t,e,r,n){var o;r=r||{},e=u(e);for(var i=0,s=t.sources.length;i<s;i++)o=null,"string"==typeof r.sourceRoot?o=r.sourceRoot:"string"==typeof t.sourceRoot&&!1!==r.sourceRoot&&(o=t.sourceRoot),n(null===o||""===o?a(e,t.sources[i]):a(e,o.replace(C,"/"),t.sources[i]),(t.sourcesContent||[])[i],i)}e.exports={resolveSourceMap:m,resolveSourceMapSync:d,resolveSources:_,resolveSourcesSync:A,resolve:function(t,e,r,n,o){if("function"==typeof n&&(o=n,n={}),null===t){var i={sourceMappingURL:null,url:e,sourcesRelativeTo:e,map:null},s=c(e);r(s,(function(t,e){if(t)return t.sourceMapData=i,o(t);i.map=String(e);try{i.map=h(i.map,i)}catch(t){return o(t)}a(i)}))}else m(t,e,r,(function(t,e){return t?o(t):e?void a(e):o(null,null)}));function a(t){_(t.map,t.sourcesRelativeTo,r,n,(function(e,r){if(e)return o(e);t.sourcesResolved=r.sourcesResolved,t.sourcesContent=r.sourcesContent,o(null,t)}))}},resolveSync:function(t,e,r,n){var o;if(null===t){(o={sourceMappingURL:null,url:e,sourcesRelativeTo:e,map:null}).map=f(r,e,o),o.map=h(o.map,o)}else if(!(o=d(t,e,r)))return null;var i=A(o.map,o.sourcesRelativeTo,r,n);return o.sourcesResolved=i.sourcesResolved,o.sourcesContent=i.sourcesContent,o},parseMapToJSON:h}}).call(this,t("timers").setImmediate)},{atob:15,"decode-uri-component":23,path:5,timers:11,url:12}],26:[function(t,e,r){var n=t("./util"),o=Object.prototype.hasOwnProperty,i="undefined"!=typeof Map;function s(){this._array=[],this._set=i?new Map:Object.create(null)}s.fromArray=function(t,e){for(var r=new s,n=0,o=t.length;n<o;n++)r.add(t[n],e);return r},s.prototype.size=function(){return i?this._set.size:Object.getOwnPropertyNames(this._set).length},s.prototype.add=function(t,e){var r=i?t:n.toSetString(t),s=i?this.has(t):o.call(this._set,r),a=this._array.length;s&&!e||this._array.push(t),s||(i?this._set.set(t,a):this._set[r]=a)},s.prototype.has=function(t){if(i)return this._set.has(t);var e=n.toSetString(t);return o.call(this._set,e)},s.prototype.indexOf=function(t){if(i){var e=this._set.get(t);if(e>=0)return e}else{var r=n.toSetString(t);if(o.call(this._set,r))return this._set[r]}throw new Error('"'+t+'" is not in the set.')},s.prototype.at=function(t){if(t>=0&&t<this._array.length)return this._array[t];throw new Error("No element indexed by "+t)},s.prototype.toArray=function(){return this._array.slice()},r.ArraySet=s},{"./util":35}],27:[function(t,e,r){var n=t("./base64");r.encode=function(t){var e,r="",o=function(t){return t<0?1+(-t<<1):0+(t<<1)}(t);do{e=31&o,(o>>>=5)>0&&(e|=32),r+=n.encode(e)}while(o>0);return r},r.decode=function(t,e,r){var o,i,s,a,u=t.length,c=0,l=0;do{if(e>=u)throw new Error("Expected more digits in base 64 VLQ value.");if(-1===(i=n.decode(t.charCodeAt(e++))))throw new Error("Invalid base64 digit: "+t.charAt(e-1));o=!!(32&i),c+=(i&=31)<<l,l+=5}while(o);r.value=(a=(s=c)>>1,1==(1&s)?-a:a),r.rest=e}},{"./base64":28}],28:[function(t,e,r){var n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");r.encode=function(t){if(0<=t&&t<n.length)return n[t];throw new TypeError("Must be between 0 and 63: "+t)},r.decode=function(t){return 65<=t&&t<=90?t-65:97<=t&&t<=122?t-97+26:48<=t&&t<=57?t-48+52:43==t?62:47==t?63:-1}},{}],29:[function(t,e,r){r.GREATEST_LOWER_BOUND=1,r.LEAST_UPPER_BOUND=2,r.search=function(t,e,n,o){if(0===e.length)return-1;var i=function t(e,n,o,i,s,a){var u=Math.floor((n-e)/2)+e,c=s(o,i[u],!0);return 0===c?u:c>0?n-u>1?t(u,n,o,i,s,a):a==r.LEAST_UPPER_BOUND?n<i.length?n:-1:u:u-e>1?t(e,u,o,i,s,a):a==r.LEAST_UPPER_BOUND?u:e<0?-1:e}(-1,e.length,t,e,n,o||r.GREATEST_LOWER_BOUND);if(i<0)return-1;for(;i-1>=0&&0===n(e[i],e[i-1],!0);)--i;return i}},{}],30:[function(t,e,r){var n=t("./util");function o(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}o.prototype.unsortedForEach=function(t,e){this._array.forEach(t,e)},o.prototype.add=function(t){var e,r,o,i,s,a;e=this._last,r=t,o=e.generatedLine,i=r.generatedLine,s=e.generatedColumn,a=r.generatedColumn,i>o||i==o&&a>=s||n.compareByGeneratedPositionsInflated(e,r)<=0?(this._last=t,this._array.push(t)):(this._sorted=!1,this._array.push(t))},o.prototype.toArray=function(){return this._sorted||(this._array.sort(n.compareByGeneratedPositionsInflated),this._sorted=!0),this._array},r.MappingList=o},{"./util":35}],31:[function(t,e,r){function n(t,e,r){var n=t[e];t[e]=t[r],t[r]=n}function o(t,e,r,i){if(r<i){var s=r-1;n(t,(l=r,h=i,Math.round(l+Math.random()*(h-l))),i);for(var a=t[i],u=r;u<i;u++)e(t[u],a)<=0&&n(t,s+=1,u);n(t,s+1,u);var c=s+1;o(t,e,r,c-1),o(t,e,c+1,i)}var l,h}r.quickSort=function(t,e){o(t,e,0,t.length-1)}},{}],32:[function(t,e,r){var n=t("./util"),o=t("./binary-search"),i=t("./array-set").ArraySet,s=t("./base64-vlq"),a=t("./quick-sort").quickSort;function u(t,e){var r=t;return"string"==typeof t&&(r=n.parseSourceMapInput(t)),null!=r.sections?new h(r,e):new c(r,e)}function c(t,e){var r=t;"string"==typeof t&&(r=n.parseSourceMapInput(t));var o=n.getArg(r,"version"),s=n.getArg(r,"sources"),a=n.getArg(r,"names",[]),u=n.getArg(r,"sourceRoot",null),c=n.getArg(r,"sourcesContent",null),l=n.getArg(r,"mappings"),h=n.getArg(r,"file",null);if(o!=this._version)throw new Error("Unsupported version: "+o);u&&(u=n.normalize(u)),s=s.map(String).map(n.normalize).map((function(t){return u&&n.isAbsolute(u)&&n.isAbsolute(t)?n.relative(u,t):t})),this._names=i.fromArray(a.map(String),!0),this._sources=i.fromArray(s,!0),this._absoluteSources=this._sources.toArray().map((function(t){return n.computeSourceURL(u,t,e)})),this.sourceRoot=u,this.sourcesContent=c,this._mappings=l,this._sourceMapURL=e,this.file=h}function l(){this.generatedLine=0,this.generatedColumn=0,this.source=null,this.originalLine=null,this.originalColumn=null,this.name=null}function h(t,e){var r=t;"string"==typeof t&&(r=n.parseSourceMapInput(t));var o=n.getArg(r,"version"),s=n.getArg(r,"sections");if(o!=this._version)throw new Error("Unsupported version: "+o);this._sources=new i,this._names=new i;var a={line:-1,column:0};this._sections=s.map((function(t){if(t.url)throw new Error("Support for url field in sections not implemented.");var r=n.getArg(t,"offset"),o=n.getArg(r,"line"),i=n.getArg(r,"column");if(o<a.line||o===a.line&&i<a.column)throw new Error("Section offsets must be ordered and non-overlapping.");return a=r,{generatedOffset:{generatedLine:o+1,generatedColumn:i+1},consumer:new u(n.getArg(t,"map"),e)}}))}u.fromSourceMap=function(t,e){return c.fromSourceMap(t,e)},u.prototype._version=3,u.prototype.__generatedMappings=null,Object.defineProperty(u.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){return this.__generatedMappings||this._parseMappings(this._mappings,this.sourceRoot),this.__generatedMappings}}),u.prototype.__originalMappings=null,Object.defineProperty(u.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){return this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot),this.__originalMappings}}),u.prototype._charIsMappingSeparator=function(t,e){var r=t.charAt(e);return";"===r||","===r},u.prototype._parseMappings=function(t,e){throw new Error("Subclasses must implement _parseMappings")},u.GENERATED_ORDER=1,u.ORIGINAL_ORDER=2,u.GREATEST_LOWER_BOUND=1,u.LEAST_UPPER_BOUND=2,u.prototype.eachMapping=function(t,e,r){var o,i=e||null;switch(r||u.GENERATED_ORDER){case u.GENERATED_ORDER:o=this._generatedMappings;break;case u.ORIGINAL_ORDER:o=this._originalMappings;break;default:throw new Error("Unknown order of iteration.")}var s=this.sourceRoot;o.map((function(t){var e=null===t.source?null:this._sources.at(t.source);return{source:e=n.computeSourceURL(s,e,this._sourceMapURL),generatedLine:t.generatedLine,generatedColumn:t.generatedColumn,originalLine:t.originalLine,originalColumn:t.originalColumn,name:null===t.name?null:this._names.at(t.name)}}),this).forEach(t,i)},u.prototype.allGeneratedPositionsFor=function(t){var e=n.getArg(t,"line"),r={source:n.getArg(t,"source"),originalLine:e,originalColumn:n.getArg(t,"column",0)};if(r.source=this._findSourceIndex(r.source),r.source<0)return[];var i=[],s=this._findMapping(r,this._originalMappings,"originalLine","originalColumn",n.compareByOriginalPositions,o.LEAST_UPPER_BOUND);if(s>=0){var a=this._originalMappings[s];if(void 0===t.column)for(var u=a.originalLine;a&&a.originalLine===u;)i.push({line:n.getArg(a,"generatedLine",null),column:n.getArg(a,"generatedColumn",null),lastColumn:n.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s];else for(var c=a.originalColumn;a&&a.originalLine===e&&a.originalColumn==c;)i.push({line:n.getArg(a,"generatedLine",null),column:n.getArg(a,"generatedColumn",null),lastColumn:n.getArg(a,"lastGeneratedColumn",null)}),a=this._originalMappings[++s]}return i},r.SourceMapConsumer=u,c.prototype=Object.create(u.prototype),c.prototype.consumer=u,c.prototype._findSourceIndex=function(t){var e,r=t;if(null!=this.sourceRoot&&(r=n.relative(this.sourceRoot,r)),this._sources.has(r))return this._sources.indexOf(r);for(e=0;e<this._absoluteSources.length;++e)if(this._absoluteSources[e]==t)return e;return-1},c.fromSourceMap=function(t,e){var r=Object.create(c.prototype),o=r._names=i.fromArray(t._names.toArray(),!0),s=r._sources=i.fromArray(t._sources.toArray(),!0);r.sourceRoot=t._sourceRoot,r.sourcesContent=t._generateSourcesContent(r._sources.toArray(),r.sourceRoot),r.file=t._file,r._sourceMapURL=e,r._absoluteSources=r._sources.toArray().map((function(t){return n.computeSourceURL(r.sourceRoot,t,e)}));for(var u=t._mappings.toArray().slice(),h=r.__generatedMappings=[],f=r.__originalMappings=[],p=0,g=u.length;p<g;p++){var m=u[p],d=new l;d.generatedLine=m.generatedLine,d.generatedColumn=m.generatedColumn,m.source&&(d.source=s.indexOf(m.source),d.originalLine=m.originalLine,d.originalColumn=m.originalColumn,m.name&&(d.name=o.indexOf(m.name)),f.push(d)),h.push(d)}return a(r.__originalMappings,n.compareByOriginalPositions),r},c.prototype._version=3,Object.defineProperty(c.prototype,"sources",{get:function(){return this._absoluteSources.slice()}}),c.prototype._parseMappings=function(t,e){for(var r,o,i,u,c,h=1,f=0,p=0,g=0,m=0,d=0,y=t.length,v=0,w={},b={},_=[],A=[];v<y;)if(";"===t.charAt(v))h++,v++,f=0;else if(","===t.charAt(v))v++;else{for((r=new l).generatedLine=h,u=v;u<y&&!this._charIsMappingSeparator(t,u);u++);if(i=w[o=t.slice(v,u)])v+=o.length;else{for(i=[];v<u;)s.decode(t,v,b),c=b.value,v=b.rest,i.push(c);if(2===i.length)throw new Error("Found a source, but no line and column");if(3===i.length)throw new Error("Found a source and line, but no column");w[o]=i}r.generatedColumn=f+i[0],f=r.generatedColumn,i.length>1&&(r.source=m+i[1],m+=i[1],r.originalLine=p+i[2],p=r.originalLine,r.originalLine+=1,r.originalColumn=g+i[3],g=r.originalColumn,i.length>4&&(r.name=d+i[4],d+=i[4])),A.push(r),"number"==typeof r.originalLine&&_.push(r)}a(A,n.compareByGeneratedPositionsDeflated),this.__generatedMappings=A,a(_,n.compareByOriginalPositions),this.__originalMappings=_},c.prototype._findMapping=function(t,e,r,n,i,s){if(t[r]<=0)throw new TypeError("Line must be greater than or equal to 1, got "+t[r]);if(t[n]<0)throw new TypeError("Column must be greater than or equal to 0, got "+t[n]);return o.search(t,e,i,s)},c.prototype.computeColumnSpans=function(){for(var t=0;t<this._generatedMappings.length;++t){var e=this._generatedMappings[t];if(t+1<this._generatedMappings.length){var r=this._generatedMappings[t+1];if(e.generatedLine===r.generatedLine){e.lastGeneratedColumn=r.generatedColumn-1;continue}}e.lastGeneratedColumn=1/0}},c.prototype.originalPositionFor=function(t){var e={generatedLine:n.getArg(t,"line"),generatedColumn:n.getArg(t,"column")},r=this._findMapping(e,this._generatedMappings,"generatedLine","generatedColumn",n.compareByGeneratedPositionsDeflated,n.getArg(t,"bias",u.GREATEST_LOWER_BOUND));if(r>=0){var o=this._generatedMappings[r];if(o.generatedLine===e.generatedLine){var i=n.getArg(o,"source",null);null!==i&&(i=this._sources.at(i),i=n.computeSourceURL(this.sourceRoot,i,this._sourceMapURL));var s=n.getArg(o,"name",null);return null!==s&&(s=this._names.at(s)),{source:i,line:n.getArg(o,"originalLine",null),column:n.getArg(o,"originalColumn",null),name:s}}}return{source:null,line:null,column:null,name:null}},c.prototype.hasContentsOfAllSources=function(){return!!this.sourcesContent&&(this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some((function(t){return null==t})))},c.prototype.sourceContentFor=function(t,e){if(!this.sourcesContent)return null;var r=this._findSourceIndex(t);if(r>=0)return this.sourcesContent[r];var o,i=t;if(null!=this.sourceRoot&&(i=n.relative(this.sourceRoot,i)),null!=this.sourceRoot&&(o=n.urlParse(this.sourceRoot))){var s=i.replace(/^file:\/\//,"");if("file"==o.scheme&&this._sources.has(s))return this.sourcesContent[this._sources.indexOf(s)];if((!o.path||"/"==o.path)&&this._sources.has("/"+i))return this.sourcesContent[this._sources.indexOf("/"+i)]}if(e)return null;throw new Error('"'+i+'" is not in the SourceMap.')},c.prototype.generatedPositionFor=function(t){var e=n.getArg(t,"source");if((e=this._findSourceIndex(e))<0)return{line:null,column:null,lastColumn:null};var r={source:e,originalLine:n.getArg(t,"line"),originalColumn:n.getArg(t,"column")},o=this._findMapping(r,this._originalMappings,"originalLine","originalColumn",n.compareByOriginalPositions,n.getArg(t,"bias",u.GREATEST_LOWER_BOUND));if(o>=0){var i=this._originalMappings[o];if(i.source===r.source)return{line:n.getArg(i,"generatedLine",null),column:n.getArg(i,"generatedColumn",null),lastColumn:n.getArg(i,"lastGeneratedColumn",null)}}return{line:null,column:null,lastColumn:null}},r.BasicSourceMapConsumer=c,h.prototype=Object.create(u.prototype),h.prototype.constructor=u,h.prototype._version=3,Object.defineProperty(h.prototype,"sources",{get:function(){for(var t=[],e=0;e<this._sections.length;e++)for(var r=0;r<this._sections[e].consumer.sources.length;r++)t.push(this._sections[e].consumer.sources[r]);return t}}),h.prototype.originalPositionFor=function(t){var e={generatedLine:n.getArg(t,"line"),generatedColumn:n.getArg(t,"column")},r=o.search(e,this._sections,(function(t,e){var r=t.generatedLine-e.generatedOffset.generatedLine;return r||t.generatedColumn-e.generatedOffset.generatedColumn})),i=this._sections[r];return i?i.consumer.originalPositionFor({line:e.generatedLine-(i.generatedOffset.generatedLine-1),column:e.generatedColumn-(i.generatedOffset.generatedLine===e.generatedLine?i.generatedOffset.generatedColumn-1:0),bias:t.bias}):{source:null,line:null,column:null,name:null}},h.prototype.hasContentsOfAllSources=function(){return this._sections.every((function(t){return t.consumer.hasContentsOfAllSources()}))},h.prototype.sourceContentFor=function(t,e){for(var r=0;r<this._sections.length;r++){var n=this._sections[r].consumer.sourceContentFor(t,!0);if(n)return n}if(e)return null;throw new Error('"'+t+'" is not in the SourceMap.')},h.prototype.generatedPositionFor=function(t){for(var e=0;e<this._sections.length;e++){var r=this._sections[e];if(-1!==r.consumer._findSourceIndex(n.getArg(t,"source"))){var o=r.consumer.generatedPositionFor(t);if(o)return{line:o.line+(r.generatedOffset.generatedLine-1),column:o.column+(r.generatedOffset.generatedLine===o.line?r.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}},h.prototype._parseMappings=function(t,e){this.__generatedMappings=[],this.__originalMappings=[];for(var r=0;r<this._sections.length;r++)for(var o=this._sections[r],i=o.consumer._generatedMappings,s=0;s<i.length;s++){var u=i[s],c=o.consumer._sources.at(u.source);c=n.computeSourceURL(o.consumer.sourceRoot,c,this._sourceMapURL),this._sources.add(c),c=this._sources.indexOf(c);var l=null;u.name&&(l=o.consumer._names.at(u.name),this._names.add(l),l=this._names.indexOf(l));var h={source:c,generatedLine:u.generatedLine+(o.generatedOffset.generatedLine-1),generatedColumn:u.generatedColumn+(o.generatedOffset.generatedLine===u.generatedLine?o.generatedOffset.generatedColumn-1:0),originalLine:u.originalLine,originalColumn:u.originalColumn,name:l};this.__generatedMappings.push(h),"number"==typeof h.originalLine&&this.__originalMappings.push(h)}a(this.__generatedMappings,n.compareByGeneratedPositionsDeflated),a(this.__originalMappings,n.compareByOriginalPositions)},r.IndexedSourceMapConsumer=h},{"./array-set":26,"./base64-vlq":27,"./binary-search":29,"./quick-sort":31,"./util":35}],33:[function(t,e,r){var n=t("./base64-vlq"),o=t("./util"),i=t("./array-set").ArraySet,s=t("./mapping-list").MappingList;function a(t){t||(t={}),this._file=o.getArg(t,"file",null),this._sourceRoot=o.getArg(t,"sourceRoot",null),this._skipValidation=o.getArg(t,"skipValidation",!1),this._sources=new i,this._names=new i,this._mappings=new s,this._sourcesContents=null}a.prototype._version=3,a.fromSourceMap=function(t){var e=t.sourceRoot,r=new a({file:t.file,sourceRoot:e});return t.eachMapping((function(t){var n={generated:{line:t.generatedLine,column:t.generatedColumn}};null!=t.source&&(n.source=t.source,null!=e&&(n.source=o.relative(e,n.source)),n.original={line:t.originalLine,column:t.originalColumn},null!=t.name&&(n.name=t.name)),r.addMapping(n)})),t.sources.forEach((function(n){var i=n;null!==e&&(i=o.relative(e,n)),r._sources.has(i)||r._sources.add(i);var s=t.sourceContentFor(n);null!=s&&r.setSourceContent(n,s)})),r},a.prototype.addMapping=function(t){var e=o.getArg(t,"generated"),r=o.getArg(t,"original",null),n=o.getArg(t,"source",null),i=o.getArg(t,"name",null);this._skipValidation||this._validateMapping(e,r,n,i),null!=n&&(n=String(n),this._sources.has(n)||this._sources.add(n)),null!=i&&(i=String(i),this._names.has(i)||this._names.add(i)),this._mappings.add({generatedLine:e.line,generatedColumn:e.column,originalLine:null!=r&&r.line,originalColumn:null!=r&&r.column,source:n,name:i})},a.prototype.setSourceContent=function(t,e){var r=t;null!=this._sourceRoot&&(r=o.relative(this._sourceRoot,r)),null!=e?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[o.toSetString(r)]=e):this._sourcesContents&&(delete this._sourcesContents[o.toSetString(r)],0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))},a.prototype.applySourceMap=function(t,e,r){var n=e;if(null==e){if(null==t.file)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');n=t.file}var s=this._sourceRoot;null!=s&&(n=o.relative(s,n));var a=new i,u=new i;this._mappings.unsortedForEach((function(e){if(e.source===n&&null!=e.originalLine){var i=t.originalPositionFor({line:e.originalLine,column:e.originalColumn});null!=i.source&&(e.source=i.source,null!=r&&(e.source=o.join(r,e.source)),null!=s&&(e.source=o.relative(s,e.source)),e.originalLine=i.line,e.originalColumn=i.column,null!=i.name&&(e.name=i.name))}var c=e.source;null==c||a.has(c)||a.add(c);var l=e.name;null==l||u.has(l)||u.add(l)}),this),this._sources=a,this._names=u,t.sources.forEach((function(e){var n=t.sourceContentFor(e);null!=n&&(null!=r&&(e=o.join(r,e)),null!=s&&(e=o.relative(s,e)),this.setSourceContent(e,n))}),this)},a.prototype._validateMapping=function(t,e,r,n){if(e&&"number"!=typeof e.line&&"number"!=typeof e.column)throw new Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if((!(t&&"line"in t&&"column"in t&&t.line>0&&t.column>=0)||e||r||n)&&!(t&&"line"in t&&"column"in t&&e&&"line"in e&&"column"in e&&t.line>0&&t.column>=0&&e.line>0&&e.column>=0&&r))throw new Error("Invalid mapping: "+JSON.stringify({generated:t,source:r,original:e,name:n}))},a.prototype._serializeMappings=function(){for(var t,e,r,i,s=0,a=1,u=0,c=0,l=0,h=0,f="",p=this._mappings.toArray(),g=0,m=p.length;g<m;g++){if(t="",(e=p[g]).generatedLine!==a)for(s=0;e.generatedLine!==a;)t+=";",a++;else if(g>0){if(!o.compareByGeneratedPositionsInflated(e,p[g-1]))continue;t+=","}t+=n.encode(e.generatedColumn-s),s=e.generatedColumn,null!=e.source&&(i=this._sources.indexOf(e.source),t+=n.encode(i-h),h=i,t+=n.encode(e.originalLine-1-c),c=e.originalLine-1,t+=n.encode(e.originalColumn-u),u=e.originalColumn,null!=e.name&&(r=this._names.indexOf(e.name),t+=n.encode(r-l),l=r)),f+=t}return f},a.prototype._generateSourcesContent=function(t,e){return t.map((function(t){if(!this._sourcesContents)return null;null!=e&&(t=o.relative(e,t));var r=o.toSetString(t);return Object.prototype.hasOwnProperty.call(this._sourcesContents,r)?this._sourcesContents[r]:null}),this)},a.prototype.toJSON=function(){var t={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return null!=this._file&&(t.file=this._file),null!=this._sourceRoot&&(t.sourceRoot=this._sourceRoot),this._sourcesContents&&(t.sourcesContent=this._generateSourcesContent(t.sources,t.sourceRoot)),t},a.prototype.toString=function(){return JSON.stringify(this.toJSON())},r.SourceMapGenerator=a},{"./array-set":26,"./base64-vlq":27,"./mapping-list":30,"./util":35}],34:[function(t,e,r){var n=t("./source-map-generator").SourceMapGenerator,o=t("./util"),i=/(\r?\n)/,s="$$$isSourceNode$$$";function a(t,e,r,n,o){this.children=[],this.sourceContents={},this.line=null==t?null:t,this.column=null==e?null:e,this.source=null==r?null:r,this.name=null==o?null:o,this[s]=!0,null!=n&&this.add(n)}a.fromStringWithSourceMap=function(t,e,r){var n=new a,s=t.split(i),u=0,c=function(){return t()+(t()||"");function t(){return u<s.length?s[u++]:void 0}},l=1,h=0,f=null;return e.eachMapping((function(t){if(null!==f){if(!(l<t.generatedLine)){var e=(r=s[u]||"").substr(0,t.generatedColumn-h);return s[u]=r.substr(t.generatedColumn-h),h=t.generatedColumn,p(f,e),void(f=t)}p(f,c()),l++,h=0}for(;l<t.generatedLine;)n.add(c()),l++;if(h<t.generatedColumn){var r=s[u]||"";n.add(r.substr(0,t.generatedColumn)),s[u]=r.substr(t.generatedColumn),h=t.generatedColumn}f=t}),this),u<s.length&&(f&&p(f,c()),n.add(s.splice(u).join(""))),e.sources.forEach((function(t){var i=e.sourceContentFor(t);null!=i&&(null!=r&&(t=o.join(r,t)),n.setSourceContent(t,i))})),n;function p(t,e){if(null===t||void 0===t.source)n.add(e);else{var i=r?o.join(r,t.source):t.source;n.add(new a(t.originalLine,t.originalColumn,i,e,t.name))}}},a.prototype.add=function(t){if(Array.isArray(t))t.forEach((function(t){this.add(t)}),this);else{if(!t[s]&&"string"!=typeof t)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+t);t&&this.children.push(t)}return this},a.prototype.prepend=function(t){if(Array.isArray(t))for(var e=t.length-1;e>=0;e--)this.prepend(t[e]);else{if(!t[s]&&"string"!=typeof t)throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+t);this.children.unshift(t)}return this},a.prototype.walk=function(t){for(var e,r=0,n=this.children.length;r<n;r++)(e=this.children[r])[s]?e.walk(t):""!==e&&t(e,{source:this.source,line:this.line,column:this.column,name:this.name})},a.prototype.join=function(t){var e,r,n=this.children.length;if(n>0){for(e=[],r=0;r<n-1;r++)e.push(this.children[r]),e.push(t);e.push(this.children[r]),this.children=e}return this},a.prototype.replaceRight=function(t,e){var r=this.children[this.children.length-1];return r[s]?r.replaceRight(t,e):"string"==typeof r?this.children[this.children.length-1]=r.replace(t,e):this.children.push("".replace(t,e)),this},a.prototype.setSourceContent=function(t,e){this.sourceContents[o.toSetString(t)]=e},a.prototype.walkSourceContents=function(t){for(var e=0,r=this.children.length;e<r;e++)this.children[e][s]&&this.children[e].walkSourceContents(t);var n=Object.keys(this.sourceContents);for(e=0,r=n.length;e<r;e++)t(o.fromSetString(n[e]),this.sourceContents[n[e]])},a.prototype.toString=function(){var t="";return this.walk((function(e){t+=e})),t},a.prototype.toStringWithSourceMap=function(t){var e={code:"",line:1,column:0},r=new n(t),o=!1,i=null,s=null,a=null,u=null;return this.walk((function(t,n){e.code+=t,null!==n.source&&null!==n.line&&null!==n.column?(i===n.source&&s===n.line&&a===n.column&&u===n.name||r.addMapping({source:n.source,original:{line:n.line,column:n.column},generated:{line:e.line,column:e.column},name:n.name}),i=n.source,s=n.line,a=n.column,u=n.name,o=!0):o&&(r.addMapping({generated:{line:e.line,column:e.column}}),i=null,o=!1);for(var c=0,l=t.length;c<l;c++)10===t.charCodeAt(c)?(e.line++,e.column=0,c+1===l?(i=null,o=!1):o&&r.addMapping({source:n.source,original:{line:n.line,column:n.column},generated:{line:e.line,column:e.column},name:n.name})):e.column++})),this.walkSourceContents((function(t,e){r.setSourceContent(t,e)})),{code:e.code,map:r}},r.SourceNode=a},{"./source-map-generator":33,"./util":35}],35:[function(t,e,r){r.getArg=function(t,e,r){if(e in t)return t[e];if(3===arguments.length)return r;throw new Error('"'+e+'" is a required argument.')};var n=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,o=/^data:.+\,.+$/;function i(t){var e=t.match(n);return e?{scheme:e[1],auth:e[2],host:e[3],port:e[4],path:e[5]}:null}function s(t){var e="";return t.scheme&&(e+=t.scheme+":"),e+="//",t.auth&&(e+=t.auth+"@"),t.host&&(e+=t.host),t.port&&(e+=":"+t.port),t.path&&(e+=t.path),e}function a(t){var e=t,n=i(t);if(n){if(!n.path)return t;e=n.path}for(var o,a=r.isAbsolute(e),u=e.split(/\/+/),c=0,l=u.length-1;l>=0;l--)"."===(o=u[l])?u.splice(l,1):".."===o?c++:c>0&&(""===o?(u.splice(l+1,c),c=0):(u.splice(l,2),c--));return""===(e=u.join("/"))&&(e=a?"/":"."),n?(n.path=e,s(n)):e}function u(t,e){""===t&&(t="."),""===e&&(e=".");var r=i(e),n=i(t);if(n&&(t=n.path||"/"),r&&!r.scheme)return n&&(r.scheme=n.scheme),s(r);if(r||e.match(o))return e;if(n&&!n.host&&!n.path)return n.host=e,s(n);var u="/"===e.charAt(0)?e:a(t.replace(/\/+$/,"")+"/"+e);return n?(n.path=u,s(n)):u}r.urlParse=i,r.urlGenerate=s,r.normalize=a,r.join=u,r.isAbsolute=function(t){return"/"===t.charAt(0)||n.test(t)},r.relative=function(t,e){""===t&&(t="."),t=t.replace(/\/$/,"");for(var r=0;0!==e.indexOf(t+"/");){var n=t.lastIndexOf("/");if(n<0)return e;if((t=t.slice(0,n)).match(/^([^\/]+:\/)?\/*$/))return e;++r}return Array(r+1).join("../")+e.substr(t.length+1)};var c=!("__proto__"in Object.create(null));function l(t){return t}function h(t){if(!t)return!1;var e=t.length;if(e<9)return!1;if(95!==t.charCodeAt(e-1)||95!==t.charCodeAt(e-2)||111!==t.charCodeAt(e-3)||116!==t.charCodeAt(e-4)||111!==t.charCodeAt(e-5)||114!==t.charCodeAt(e-6)||112!==t.charCodeAt(e-7)||95!==t.charCodeAt(e-8)||95!==t.charCodeAt(e-9))return!1;for(var r=e-10;r>=0;r--)if(36!==t.charCodeAt(r))return!1;return!0}function f(t,e){return t===e?0:null===t?1:null===e?-1:t>e?1:-1}r.toSetString=c?l:function(t){return h(t)?"$"+t:t},r.fromSetString=c?l:function(t){return h(t)?t.slice(1):t},r.compareByOriginalPositions=function(t,e,r){var n=f(t.source,e.source);return 0!==n?n:0!==(n=t.originalLine-e.originalLine)?n:0!==(n=t.originalColumn-e.originalColumn)||r?n:0!==(n=t.generatedColumn-e.generatedColumn)?n:0!==(n=t.generatedLine-e.generatedLine)?n:f(t.name,e.name)},r.compareByGeneratedPositionsDeflated=function(t,e,r){var n=t.generatedLine-e.generatedLine;return 0!==n?n:0!==(n=t.generatedColumn-e.generatedColumn)||r?n:0!==(n=f(t.source,e.source))?n:0!==(n=t.originalLine-e.originalLine)?n:0!==(n=t.originalColumn-e.originalColumn)?n:f(t.name,e.name)},r.compareByGeneratedPositionsInflated=function(t,e){var r=t.generatedLine-e.generatedLine;return 0!==r?r:0!==(r=t.generatedColumn-e.generatedColumn)?r:0!==(r=f(t.source,e.source))?r:0!==(r=t.originalLine-e.originalLine)?r:0!==(r=t.originalColumn-e.originalColumn)?r:f(t.name,e.name)},r.parseSourceMapInput=function(t){return JSON.parse(t.replace(/^\)]}'[^\n]*\n/,""))},r.computeSourceURL=function(t,e,r){if(e=e||"",t&&("/"!==t[t.length-1]&&"/"!==e[0]&&(t+="/"),e=t+e),r){var n=i(r);if(!n)throw new Error("sourceMapURL could not be parsed");if(n.path){var o=n.path.lastIndexOf("/");o>=0&&(n.path=n.path.substring(0,o+1))}e=u(s(n),e)}return a(e)}},{}],36:[function(t,e,r){r.SourceMapGenerator=t("./lib/source-map-generator").SourceMapGenerator,r.SourceMapConsumer=t("./lib/source-map-consumer").SourceMapConsumer,r.SourceNode=t("./lib/source-node").SourceNode},{"./lib/source-map-consumer":32,"./lib/source-map-generator":33,"./lib/source-node":34}]},{},[14]);/**
 * Calculates the specificity of CSS selectors
 * https://github.com/keeganstreet/specificity - licensed under MIT.
 *
 * Returns an array of objects with the following properties:
 *  - selector: the input
 *  - specificity: e.g. 0,1,0,0
 *  - parts: array with details about each part of the selector that counts towards the specificity
 */
var SPECIFICITY = (function() {
    var calculate,
        calculateSingle;

    calculate = function(input) {
        var selectors,
            selector,
            i,
            len,
            results = [];

        // Separate input by commas
        selectors = input.split(',');

        for (i = 0, len = selectors.length; i < len; i += 1) {
            selector = selectors[i];
            if (selector.length > 0) {
                results.push(calculateSingle(selector));
            }
        }

        return results;
    };

    // Calculate the specificity for a selector by dividing it into simple selectors and counting them
    calculateSingle = function(input) {
        var selector = input,
            findMatch,
            typeCount = {
                'a': 0,
                'b': 0,
                'c': 0
            },
            parts = [],
        // The following regular expressions assume that selectors matching the preceding regular expressions have been removed
            attributeRegex = /(\[[^\]]+\])/g,
            idRegex = /(#[^\s\+>~\.\[:]+)/g,
            classRegex = /(\.[^\s\+>~\.\[:]+)/g,
            pseudoElementRegex = /(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi,
        // A regex for pseudo classes with brackets - :nth-child(), :nth-last-child(), :nth-of-type(), :nth-last-type(), :lang()
            pseudoClassWithBracketsRegex = /(:[\w-]+\([^\)]*\))/gi,
        // A regex for other pseudo classes, which don't have brackets
            pseudoClassRegex = /(:[^\s\+>~\.\[:]+)/g,
            elementRegex = /([^\s\+>~\.\[:]+)/g;

        // Find matches for a regular expression in a string and push their details to parts
        // Type is "a" for IDs, "b" for classes, attributes and pseudo-classes and "c" for elements and pseudo-elements
        findMatch = function(regex, type) {
            var matches, i, len, match, index, length;
            if (regex.test(selector)) {
                matches = selector.match(regex);
                for (i = 0, len = matches.length; i < len; i += 1) {
                    typeCount[type] += 1;
                    match = matches[i];
                    index = selector.indexOf(match);
                    length = match.length;
                    parts.push({
                        selector: match,
                        type: type,
                        index: index,
                        length: length
                    });
                    // Replace this simple selector with whitespace so it won't be counted in further simple selectors
                    selector = selector.replace(match, Array(length + 1).join(' '));
                }
            }
        };

        // Remove the negation psuedo-class (:not) but leave its argument because specificity is calculated on its argument
        (function() {
            var regex = /:not\(([^\)]*)\)/g;
            if (regex.test(selector)) {
                selector = selector.replace(regex, '     $1 ');
            }
        }());

        // Remove anything after a left brace in case a user has pasted in a rule, not just a selector
        (function() {
            var regex = /{[^]*/gm,
                matches, i, len, match;
            if (regex.test(selector)) {
                matches = selector.match(regex);
                for (i = 0, len = matches.length; i < len; i += 1) {
                    match = matches[i];
                    selector = selector.replace(match, Array(match.length + 1).join(' '));
                }
            }
        }());

        // Add attribute selectors to parts collection (type b)
        findMatch(attributeRegex, 'b');

        // Add ID selectors to parts collection (type a)
        findMatch(idRegex, 'a');

        // Add class selectors to parts collection (type b)
        findMatch(classRegex, 'b');

        // Add pseudo-element selectors to parts collection (type c)
        findMatch(pseudoElementRegex, 'c');

        // Add pseudo-class selectors to parts collection (type b)
        findMatch(pseudoClassWithBracketsRegex, 'b');
        findMatch(pseudoClassRegex, 'b');

        // Remove universal selector and separator characters
        selector = selector.replace(/[\*\s\+>~]/g, ' ');

        // Remove any stray dots or hashes which aren't attached to words
        // These may be present if the user is live-editing this selector
        selector = selector.replace(/[#\.]/g, ' ');

        // The only things left should be element selectors (type c)
        findMatch(elementRegex, 'c');

        // Order the parts in the order they appear in the original selector
        // This is neater for external apps to deal with
        parts.sort(function(a, b) {
            return a.index - b.index;
        });

        return {
            selector: input,
            specificity: '0,' + typeCount.a.toString() + ',' + typeCount.b.toString() + ',' + typeCount.c.toString(),
            parts: parts
        };
    };

    return {
        calculate: calculate
    };
}());/*!
 * URI.js - Mutating URLs
 *
 * Version: 1.18.1
 *
 * Author: Rodney Rehm
 * Web: http://medialize.github.io/URI.js/
 *
 * Licensed under
 *   MIT License http://www.opensource.org/licenses/mit-license
 *
 */
!function(t,e){"use strict";t.URI=function(t,e,r,s){var n=s&&s.URI;function a(t,e){var r=arguments.length>=1,s=arguments.length>=2;if(!(this instanceof a))return r?s?new a(t,e):new a(t):new a;if(void 0===t){if(r)throw new TypeError("undefined is not a valid argument for URI");t="undefined"!=typeof location?location.href+"":""}return this.href(t),void 0!==e?this.absoluteTo(e):this}a.version="1.18.1";var i=a.prototype,o=Object.prototype.hasOwnProperty;function h(t){return t.replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")}function u(t){return void 0===t?"Undefined":String(Object.prototype.toString.call(t)).slice(8,-1)}function p(t){return"Array"===u(t)}function c(t,e){var r,s,n={};if("RegExp"===u(e))n=null;else if(p(e))for(r=0,s=e.length;r<s;r++)n[e[r]]=!0;else n[e]=!0;for(r=0,s=t.length;r<s;r++){(n&&void 0!==n[t[r]]||!n&&e.test(t[r]))&&(t.splice(r,1),s--,r--)}return t}function l(t,e){var r,s;if(p(e)){for(r=0,s=e.length;r<s;r++)if(!l(t,e[r]))return!1;return!0}var n=u(e);for(r=0,s=t.length;r<s;r++)if("RegExp"===n){if("string"==typeof t[r]&&t[r].match(e))return!0}else if(t[r]===e)return!0;return!1}function d(t,e){if(!p(t)||!p(e))return!1;if(t.length!==e.length)return!1;t.sort(),e.sort();for(var r=0,s=t.length;r<s;r++)if(t[r]!==e[r])return!1;return!0}function f(t){return t.replace(/^\/+|\/+$/g,"")}function m(t){return escape(t)}function g(t){return encodeURIComponent(t).replace(/[!'()*]/g,m).replace(/\*/g,"%2A")}a._parts=function(){return{protocol:null,username:null,password:null,hostname:null,urn:null,port:null,path:null,query:null,fragment:null,duplicateQueryParameters:a.duplicateQueryParameters,escapeQuerySpace:a.escapeQuerySpace}},a.duplicateQueryParameters=!1,a.escapeQuerySpace=!0,a.protocol_expression=/^[a-z][a-z0-9.+-]*$/i,a.idn_expression=/[^a-z0-9\.-]/i,a.punycode_expression=/(xn--)/i,a.ip4_expression=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,a.ip6_expression=/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/,a.find_uri_expression=/\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi,a.findUri={start:/\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,end:/[\s\r\n]|$/,trim:/[`!()\[\]{};:'".,<>?«»“”„‘’]+$/},a.defaultPorts={http:"80",https:"443",ftp:"21",gopher:"70",ws:"80",wss:"443"},a.invalid_hostname_characters=/[^a-zA-Z0-9\.-]/,a.domAttributes={a:"href",blockquote:"cite",link:"href",base:"href",script:"src",form:"action",img:"src",area:"href",iframe:"src",embed:"src",source:"src",track:"src",input:"src",audio:"src",video:"src"},a.getDomAttribute=function(t){if(t&&t.nodeName){var e=t.nodeName.toLowerCase();if("input"!==e||"image"===t.type)return a.domAttributes[e]}},a.encode=g,a.decode=decodeURIComponent,a.iso8859=function(){a.encode=escape,a.decode=unescape},a.unicode=function(){a.encode=g,a.decode=decodeURIComponent},a.characters={pathname:{encode:{expression:/%(24|26|2B|2C|3B|3D|3A|40)/gi,map:{"%24":"$","%26":"&","%2B":"+","%2C":",","%3B":";","%3D":"=","%3A":":","%40":"@"}},decode:{expression:/[\/\?#]/g,map:{"/":"%2F","?":"%3F","#":"%23"}}},reserved:{encode:{expression:/%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/gi,map:{"%3A":":","%2F":"/","%3F":"?","%23":"#","%5B":"[","%5D":"]","%40":"@","%21":"!","%24":"$","%26":"&","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"="}}},urnpath:{encode:{expression:/%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/gi,map:{"%21":"!","%24":"$","%27":"'","%28":"(","%29":")","%2A":"*","%2B":"+","%2C":",","%3B":";","%3D":"=","%40":"@"}},decode:{expression:/[\/\?#:]/g,map:{"/":"%2F","?":"%3F","#":"%23",":":"%3A"}}}},a.encodeQuery=function(t,e){var r=a.encode(t+"");return void 0===e&&(e=a.escapeQuerySpace),e?r.replace(/%20/g,"+"):r},a.decodeQuery=function(t,e){t+="",void 0===e&&(e=a.escapeQuerySpace);try{return a.decode(e?t.replace(/\+/g,"%20"):t)}catch(e){return t}};var _,y={encode:"encode",decode:"decode"},v=function(t,e){return function(r){try{return a[e](r+"").replace(a.characters[t][e].expression,(function(r){return a.characters[t][e].map[r]}))}catch(t){return r}}};for(_ in y)a[_+"PathSegment"]=v("pathname",y[_]),a[_+"UrnPathSegment"]=v("urnpath",y[_]);var b=function(t,e,r){return function(s){var n;n=r?function(t){return a[e](a[r](t))}:a[e];for(var i=(s+"").split(t),o=0,h=i.length;o<h;o++)i[o]=n(i[o]);return i.join(t)}};function w(t){return function(e,r){return void 0===e?this._parts[t]||"":(this._parts[t]=e||null,this.build(!r),this)}}function Q(t,e){return function(r,s){return void 0===r?this._parts[t]||"":(null!==r&&(r+="").charAt(0)===e&&(r=r.substring(1)),this._parts[t]=r,this.build(!s),this)}}a.decodePath=b("/","decodePathSegment"),a.decodeUrnPath=b(":","decodeUrnPathSegment"),a.recodePath=b("/","encodePathSegment","decode"),a.recodeUrnPath=b(":","encodeUrnPathSegment","decode"),a.encodeReserved=v("reserved","encode"),a.parse=function(t,e){var r;return e||(e={}),(r=t.indexOf("#"))>-1&&(e.fragment=t.substring(r+1)||null,t=t.substring(0,r)),(r=t.indexOf("?"))>-1&&(e.query=t.substring(r+1)||null,t=t.substring(0,r)),"//"===t.substring(0,2)?(e.protocol=null,t=t.substring(2),t=a.parseAuthority(t,e)):(r=t.indexOf(":"))>-1&&(e.protocol=t.substring(0,r)||null,e.protocol&&!e.protocol.match(a.protocol_expression)?e.protocol=void 0:"//"===t.substring(r+1,r+3)?(t=t.substring(r+3),t=a.parseAuthority(t,e)):(t=t.substring(r+1),e.urn=!0)),e.path=t,e},a.parseHost=function(t,e){var r,s,n=(t=t.replace(/\\/g,"/")).indexOf("/");if(-1===n&&(n=t.length),"["===t.charAt(0))r=t.indexOf("]"),e.hostname=t.substring(1,r)||null,e.port=t.substring(r+2,n)||null,"/"===e.port&&(e.port=null);else{var a=t.indexOf(":"),i=t.indexOf("/"),o=t.indexOf(":",a+1);-1!==o&&(-1===i||o<i)?(e.hostname=t.substring(0,n)||null,e.port=null):(s=t.substring(0,n).split(":"),e.hostname=s[0]||null,e.port=s[1]||null)}return e.hostname&&"/"!==t.substring(n).charAt(0)&&(n++,t="/"+t),t.substring(n)||"/"},a.parseAuthority=function(t,e){return t=a.parseUserinfo(t,e),a.parseHost(t,e)},a.parseUserinfo=function(t,e){var r,s=t.indexOf("/"),n=t.lastIndexOf("@",s>-1?s:t.length-1);return n>-1&&(-1===s||n<s)?(r=t.substring(0,n).split(":"),e.username=r[0]?a.decode(r[0]):null,r.shift(),e.password=r[0]?a.decode(r.join(":")):null,t=t.substring(n+1)):(e.username=null,e.password=null),t},a.parseQuery=function(t,e){if(!t)return{};if(!(t=t.replace(/&+/g,"&").replace(/^\?*&*|&+$/g,"")))return{};for(var r,s,n,i={},h=t.split("&"),u=h.length,p=0;p<u;p++)r=h[p].split("="),s=a.decodeQuery(r.shift(),e),n=r.length?a.decodeQuery(r.join("="),e):null,o.call(i,s)?("string"!=typeof i[s]&&null!==i[s]||(i[s]=[i[s]]),i[s].push(n)):i[s]=n;return i},a.build=function(t){var e="";return t.protocol&&(e+=t.protocol+":"),t.urn||!e&&!t.hostname||(e+="//"),e+=a.buildAuthority(t)||"","string"==typeof t.path&&("/"!==t.path.charAt(0)&&"string"==typeof t.hostname&&(e+="/"),e+=t.path),"string"==typeof t.query&&t.query&&(e+="?"+t.query),"string"==typeof t.fragment&&t.fragment&&(e+="#"+t.fragment),e},a.buildHost=function(t){var e="";return t.hostname?(a.ip6_expression.test(t.hostname)?e+="["+t.hostname+"]":e+=t.hostname,t.port&&(e+=":"+t.port),e):""},a.buildAuthority=function(t){return a.buildUserinfo(t)+a.buildHost(t)},a.buildUserinfo=function(t){var e="";return t.username&&(e+=a.encode(t.username)),t.password&&(e+=":"+a.encode(t.password)),e&&(e+="@"),e},a.buildQuery=function(t,e,r){var s,n,i,h,u="";for(n in t)if(o.call(t,n)&&n)if(p(t[n]))for(s={},i=0,h=t[n].length;i<h;i++)void 0!==t[n][i]&&void 0===s[t[n][i]+""]&&(u+="&"+a.buildQueryParameter(n,t[n][i],r),!0!==e&&(s[t[n][i]+""]=!0));else void 0!==t[n]&&(u+="&"+a.buildQueryParameter(n,t[n],r));return u.substring(1)},a.buildQueryParameter=function(t,e,r){return a.encodeQuery(t,r)+(null!==e?"="+a.encodeQuery(e,r):"")},a.addQuery=function(t,e,r){if("object"==typeof e)for(var s in e)o.call(e,s)&&a.addQuery(t,s,e[s]);else{if("string"!=typeof e)throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");if(void 0===t[e])return void(t[e]=r);"string"==typeof t[e]&&(t[e]=[t[e]]),p(r)||(r=[r]),t[e]=(t[e]||[]).concat(r)}},a.removeQuery=function(t,e,r){var s,n,i;if(p(e))for(s=0,n=e.length;s<n;s++)t[e[s]]=void 0;else if("RegExp"===u(e))for(i in t)e.test(i)&&(t[i]=void 0);else if("object"==typeof e)for(i in e)o.call(e,i)&&a.removeQuery(t,i,e[i]);else{if("string"!=typeof e)throw new TypeError("URI.removeQuery() accepts an object, string, RegExp as the first parameter");void 0!==r?"RegExp"===u(r)?!p(t[e])&&r.test(t[e])?t[e]=void 0:t[e]=c(t[e],r):t[e]!==String(r)||p(r)&&1!==r.length?p(t[e])&&(t[e]=c(t[e],r)):t[e]=void 0:t[e]=void 0}},a.hasQuery=function(t,e,r,s){switch(u(e)){case"String":break;case"RegExp":for(var n in t)if(o.call(t,n)&&e.test(n)&&(void 0===r||a.hasQuery(t,n,r)))return!0;return!1;case"Object":for(var i in e)if(o.call(e,i)&&!a.hasQuery(t,i,e[i]))return!1;return!0;default:throw new TypeError("URI.hasQuery() accepts a string, regular expression or object as the name parameter")}switch(u(r)){case"Undefined":return e in t;case"Boolean":return r===Boolean(p(t[e])?t[e].length:t[e]);case"Function":return!!r(t[e],e,t);case"Array":return!!p(t[e])&&(s?l:d)(t[e],r);case"RegExp":return p(t[e])?!!s&&l(t[e],r):Boolean(t[e]&&t[e].match(r));case"Number":r=String(r);case"String":return p(t[e])?!!s&&l(t[e],r):t[e]===r;default:throw new TypeError("URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter")}},a.joinPaths=function(){for(var t=[],e=[],r=0,s=0;s<arguments.length;s++){var n=new a(arguments[s]);t.push(n);for(var i=n.segment(),o=0;o<i.length;o++)"string"==typeof i[o]&&e.push(i[o]),i[o]&&r++}if(!e.length||!r)return new a("");var h=new a("").segment(e);return""!==t[0].path()&&"/"!==t[0].path().slice(0,1)||h.path("/"+h.path()),h.normalize()},a.commonPath=function(t,e){var r,s=Math.min(t.length,e.length);for(r=0;r<s;r++)if(t.charAt(r)!==e.charAt(r)){r--;break}return r<1?t.charAt(0)===e.charAt(0)&&"/"===t.charAt(0)?"/":"":("/"===t.charAt(r)&&"/"===e.charAt(r)||(r=t.substring(0,r).lastIndexOf("/")),t.substring(0,r+1))},a.withinString=function(t,e,r){r||(r={});var s=r.start||a.findUri.start,n=r.end||a.findUri.end,i=r.trim||a.findUri.trim,o=/[a-z0-9-]=["']?$/i;for(s.lastIndex=0;;){var h=s.exec(t);if(!h)break;var u=h.index;if(r.ignoreHtml){var p=t.slice(Math.max(u-3,0),u);if(p&&o.test(p))continue}var c=u+t.slice(u).search(n),l=t.slice(u,c).replace(i,"");if(!r.ignore||!r.ignore.test(l)){var d=e(l,u,c=u+l.length,t);t=t.slice(0,u)+d+t.slice(c),s.lastIndex=u+d.length}}return s.lastIndex=0,t},a.ensureValidHostname=function(e){if(e.match(a.invalid_hostname_characters)){if(!t)throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-] and Punycode.js is not available');if(t.toASCII(e).match(a.invalid_hostname_characters))throw new TypeError('Hostname "'+e+'" contains characters other than [A-Z0-9.-]')}},a.noConflict=function(t){if(t){var e={URI:this.noConflict()};return s.URITemplate&&"function"==typeof s.URITemplate.noConflict&&(e.URITemplate=s.URITemplate.noConflict()),s.IPv6&&"function"==typeof s.IPv6.noConflict&&(e.IPv6=s.IPv6.noConflict()),s.SecondLevelDomains&&"function"==typeof s.SecondLevelDomains.noConflict&&(e.SecondLevelDomains=s.SecondLevelDomains.noConflict()),e}return s.URI===this&&(s.URI=n),this},i.build=function(t){return!0===t?this._deferred_build=!0:(void 0===t||this._deferred_build)&&(this._string=a.build(this._parts),this._deferred_build=!1),this},i.clone=function(){return new a(this)},i.valueOf=i.toString=function(){return this.build(!1)._string},i.protocol=w("protocol"),i.username=w("username"),i.password=w("password"),i.hostname=w("hostname"),i.port=w("port"),i.query=Q("query","?"),i.fragment=Q("fragment","#"),i.search=function(t,e){var r=this.query(t,e);return"string"==typeof r&&r.length?"?"+r:r},i.hash=function(t,e){var r=this.fragment(t,e);return"string"==typeof r&&r.length?"#"+r:r},i.pathname=function(t,e){if(void 0===t||!0===t){var r=this._parts.path||(this._parts.hostname?"/":"");return t?(this._parts.urn?a.decodeUrnPath:a.decodePath)(r):r}return this._parts.urn?this._parts.path=t?a.recodeUrnPath(t):"":this._parts.path=t?a.recodePath(t):"/",this.build(!e),this},i.path=i.pathname,i.href=function(t,e){var r;if(void 0===t)return this.toString();this._string="",this._parts=a._parts();var s=t instanceof a,n="object"==typeof t&&(t.hostname||t.path||t.pathname);t.nodeName&&(t=t[a.getDomAttribute(t)]||"",n=!1);if(!s&&n&&void 0!==t.pathname&&(t=t.toString()),"string"==typeof t||t instanceof String)this._parts=a.parse(String(t),this._parts);else{if(!s&&!n)throw new TypeError("invalid input");var i=s?t._parts:t;for(r in i)o.call(this._parts,r)&&(this._parts[r]=i[r])}return this.build(!e),this},i.is=function(t){var e=!1,s=!1,n=!1,i=!1,o=!1,h=!1,u=!1,p=!this._parts.urn;switch(this._parts.hostname&&(p=!1,s=a.ip4_expression.test(this._parts.hostname),n=a.ip6_expression.test(this._parts.hostname),o=(i=!(e=s||n))&&r&&r.has(this._parts.hostname),h=i&&a.idn_expression.test(this._parts.hostname),u=i&&a.punycode_expression.test(this._parts.hostname)),t.toLowerCase()){case"relative":return p;case"absolute":return!p;case"domain":case"name":return i;case"sld":return o;case"ip":return e;case"ip4":case"ipv4":case"inet4":return s;case"ip6":case"ipv6":case"inet6":return n;case"idn":return h;case"url":return!this._parts.urn;case"urn":return!!this._parts.urn;case"punycode":return u}return null};var A=i.protocol,P=i.port,x=i.hostname;i.protocol=function(t,e){if(void 0!==t&&t&&!(t=t.replace(/:(\/\/)?$/,"")).match(a.protocol_expression))throw new TypeError('Protocol "'+t+"\" contains characters other than [A-Z0-9.+-] or doesn't start with [A-Z]");return A.call(this,t,e)},i.scheme=i.protocol,i.port=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0!==t&&(0===t&&(t=null),t&&(":"===(t+="").charAt(0)&&(t=t.substring(1)),t.match(/[^0-9]/))))throw new TypeError('Port "'+t+'" contains characters other than [0-9]');return P.call(this,t,e)},i.hostname=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0!==t){var r={};if("/"!==a.parseHost(t,r))throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-]');t=r.hostname}return x.call(this,t,e)},i.origin=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t){var r=this.protocol();return this.authority()?(r?r+"://":"")+this.authority():""}var s=a(t);return this.protocol(s.protocol()).authority(s.authority()).build(!e),this},i.host=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t)return this._parts.hostname?a.buildHost(this._parts):"";if("/"!==a.parseHost(t,this._parts))throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-]');return this.build(!e),this},i.authority=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t)return this._parts.hostname?a.buildAuthority(this._parts):"";if("/"!==a.parseAuthority(t,this._parts))throw new TypeError('Hostname "'+t+'" contains characters other than [A-Z0-9.-]');return this.build(!e),this},i.userinfo=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t){var r=a.buildUserinfo(this._parts);return r?r.substring(0,r.length-1):r}return"@"!==t[t.length-1]&&(t+="@"),a.parseUserinfo(t,this._parts),this.build(!e),this},i.resource=function(t,e){var r;return void 0===t?this.path()+this.search()+this.hash():(r=a.parse(t),this._parts.path=r.path,this._parts.query=r.query,this._parts.fragment=r.fragment,this.build(!e),this)},i.subdomain=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t){if(!this._parts.hostname||this.is("IP"))return"";var r=this._parts.hostname.length-this.domain().length-1;return this._parts.hostname.substring(0,r)||""}var s=this._parts.hostname.length-this.domain().length,n=this._parts.hostname.substring(0,s),i=new RegExp("^"+h(n));return t&&"."!==t.charAt(t.length-1)&&(t+="."),t&&a.ensureValidHostname(t),this._parts.hostname=this._parts.hostname.replace(i,t),this.build(!e),this},i.domain=function(t,e){if(this._parts.urn)return void 0===t?"":this;if("boolean"==typeof t&&(e=t,t=void 0),void 0===t){if(!this._parts.hostname||this.is("IP"))return"";var r=this._parts.hostname.match(/\./g);if(r&&r.length<2)return this._parts.hostname;var s=this._parts.hostname.length-this.tld(e).length-1;return s=this._parts.hostname.lastIndexOf(".",s-1)+1,this._parts.hostname.substring(s)||""}if(!t)throw new TypeError("cannot set domain empty");if(a.ensureValidHostname(t),!this._parts.hostname||this.is("IP"))this._parts.hostname=t;else{var n=new RegExp(h(this.domain())+"$");this._parts.hostname=this._parts.hostname.replace(n,t)}return this.build(!e),this},i.tld=function(t,e){if(this._parts.urn)return void 0===t?"":this;if("boolean"==typeof t&&(e=t,t=void 0),void 0===t){if(!this._parts.hostname||this.is("IP"))return"";var s=this._parts.hostname.lastIndexOf("."),n=this._parts.hostname.substring(s+1);return!0!==e&&r&&r.list[n.toLowerCase()]&&r.get(this._parts.hostname)||n}var a;if(!t)throw new TypeError("cannot set TLD empty");if(t.match(/[^a-zA-Z0-9-]/)){if(!r||!r.is(t))throw new TypeError('TLD "'+t+'" contains characters other than [A-Z0-9]');a=new RegExp(h(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(a,t)}else{if(!this._parts.hostname||this.is("IP"))throw new ReferenceError("cannot set TLD on non-domain host");a=new RegExp(h(this.tld())+"$"),this._parts.hostname=this._parts.hostname.replace(a,t)}return this.build(!e),this},i.directory=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t||!0===t){if(!this._parts.path&&!this._parts.hostname)return"";if("/"===this._parts.path)return"/";var r=this._parts.path.length-this.filename().length-1,s=this._parts.path.substring(0,r)||(this._parts.hostname?"/":"");return t?a.decodePath(s):s}var n=this._parts.path.length-this.filename().length,i=this._parts.path.substring(0,n),o=new RegExp("^"+h(i));return this.is("relative")||(t||(t="/"),"/"!==t.charAt(0)&&(t="/"+t)),t&&"/"!==t.charAt(t.length-1)&&(t+="/"),t=a.recodePath(t),this._parts.path=this._parts.path.replace(o,t),this.build(!e),this},i.filename=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t||!0===t){if(!this._parts.path||"/"===this._parts.path)return"";var r=this._parts.path.lastIndexOf("/"),s=this._parts.path.substring(r+1);return t?a.decodePathSegment(s):s}var n=!1;"/"===t.charAt(0)&&(t=t.substring(1)),t.match(/\.?\//)&&(n=!0);var i=new RegExp(h(this.filename())+"$");return t=a.recodePath(t),this._parts.path=this._parts.path.replace(i,t),n?this.normalizePath(e):this.build(!e),this},i.suffix=function(t,e){if(this._parts.urn)return void 0===t?"":this;if(void 0===t||!0===t){if(!this._parts.path||"/"===this._parts.path)return"";var r,s,n=this.filename(),i=n.lastIndexOf(".");return-1===i?"":(r=n.substring(i+1),s=/^[a-z0-9%]+$/i.test(r)?r:"",t?a.decodePathSegment(s):s)}"."===t.charAt(0)&&(t=t.substring(1));var o,u=this.suffix();if(u)o=t?new RegExp(h(u)+"$"):new RegExp(h("."+u)+"$");else{if(!t)return this;this._parts.path+="."+a.recodePath(t)}return o&&(t=a.recodePath(t),this._parts.path=this._parts.path.replace(o,t)),this.build(!e),this},i.segment=function(t,e,r){var s=this._parts.urn?":":"/",n=this.path(),a="/"===n.substring(0,1),i=n.split(s);if(void 0!==t&&"number"!=typeof t&&(r=e,e=t,t=void 0),void 0!==t&&"number"!=typeof t)throw new Error('Bad segment "'+t+'", must be 0-based integer');if(a&&i.shift(),t<0&&(t=Math.max(i.length+t,0)),void 0===e)return void 0===t?i:i[t];if(null===t||void 0===i[t])if(p(e)){i=[];for(var o=0,h=e.length;o<h;o++)(e[o].length||i.length&&i[i.length-1].length)&&(i.length&&!i[i.length-1].length&&i.pop(),i.push(f(e[o])))}else(e||"string"==typeof e)&&(e=f(e),""===i[i.length-1]?i[i.length-1]=e:i.push(e));else e?i[t]=f(e):i.splice(t,1);return a&&i.unshift(""),this.path(i.join(s),r)},i.segmentCoded=function(t,e,r){var s,n,i;if("number"!=typeof t&&(r=e,e=t,t=void 0),void 0===e){if(p(s=this.segment(t,e,r)))for(n=0,i=s.length;n<i;n++)s[n]=a.decode(s[n]);else s=void 0!==s?a.decode(s):void 0;return s}if(p(e))for(n=0,i=e.length;n<i;n++)e[n]=a.encode(e[n]);else e="string"==typeof e||e instanceof String?a.encode(e):e;return this.segment(t,e,r)};var S=i.query;return i.query=function(t,e){if(!0===t)return a.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("function"==typeof t){var r=a.parseQuery(this._parts.query,this._parts.escapeQuerySpace),s=t.call(this,r);return this._parts.query=a.buildQuery(s||r,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),this.build(!e),this}return void 0!==t&&"string"!=typeof t?(this._parts.query=a.buildQuery(t,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),this.build(!e),this):S.call(this,t,e)},i.setQuery=function(t,e,r){var s=a.parseQuery(this._parts.query,this._parts.escapeQuerySpace);if("string"==typeof t||t instanceof String)s[t]=void 0!==e?e:null;else{if("object"!=typeof t)throw new TypeError("URI.addQuery() accepts an object, string as the name parameter");for(var n in t)o.call(t,n)&&(s[n]=t[n])}return this._parts.query=a.buildQuery(s,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),"string"!=typeof t&&(r=e),this.build(!r),this},i.addQuery=function(t,e,r){var s=a.parseQuery(this._parts.query,this._parts.escapeQuerySpace);return a.addQuery(s,t,void 0===e?null:e),this._parts.query=a.buildQuery(s,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),"string"!=typeof t&&(r=e),this.build(!r),this},i.removeQuery=function(t,e,r){var s=a.parseQuery(this._parts.query,this._parts.escapeQuerySpace);return a.removeQuery(s,t,e),this._parts.query=a.buildQuery(s,this._parts.duplicateQueryParameters,this._parts.escapeQuerySpace),"string"!=typeof t&&(r=e),this.build(!r),this},i.hasQuery=function(t,e,r){var s=a.parseQuery(this._parts.query,this._parts.escapeQuerySpace);return a.hasQuery(s,t,e,r)},i.setSearch=i.setQuery,i.addSearch=i.addQuery,i.removeSearch=i.removeQuery,i.hasSearch=i.hasQuery,i.normalize=function(){return this._parts.urn?this.normalizeProtocol(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build():this.normalizeProtocol(!1).normalizeHostname(!1).normalizePort(!1).normalizePath(!1).normalizeQuery(!1).normalizeFragment(!1).build()},i.normalizeProtocol=function(t){return"string"==typeof this._parts.protocol&&(this._parts.protocol=this._parts.protocol.toLowerCase(),this.build(!t)),this},i.normalizeHostname=function(r){return this._parts.hostname&&(this.is("IDN")&&t?this._parts.hostname=t.toASCII(this._parts.hostname):this.is("IPv6")&&e&&(this._parts.hostname=e.best(this._parts.hostname)),this._parts.hostname=this._parts.hostname.toLowerCase(),this.build(!r)),this},i.normalizePort=function(t){return"string"==typeof this._parts.protocol&&this._parts.port===a.defaultPorts[this._parts.protocol]&&(this._parts.port=null,this.build(!t)),this},i.normalizePath=function(t){var e,r=this._parts.path;if(!r)return this;if(this._parts.urn)return this._parts.path=a.recodeUrnPath(this._parts.path),this.build(!t),this;if("/"===this._parts.path)return this;var s,n,i="";for("/"!==(r=a.recodePath(r)).charAt(0)&&(e=!0,r="/"+r),"/.."!==r.slice(-3)&&"/."!==r.slice(-2)||(r+="/"),r=r.replace(/(\/(\.\/)+)|(\/\.$)/g,"/").replace(/\/{2,}/g,"/"),e&&(i=r.substring(1).match(/^(\.\.\/)+/)||"")&&(i=i[0]);-1!==(s=r.search(/\/\.\.(\/|$)/));)0!==s?(-1===(n=r.substring(0,s).lastIndexOf("/"))&&(n=s),r=r.substring(0,n)+r.substring(s+3)):r=r.substring(3);return e&&this.is("relative")&&(r=i+r.substring(1)),this._parts.path=r,this.build(!t),this},i.normalizePathname=i.normalizePath,i.normalizeQuery=function(t){return"string"==typeof this._parts.query&&(this._parts.query.length?this.query(a.parseQuery(this._parts.query,this._parts.escapeQuerySpace)):this._parts.query=null,this.build(!t)),this},i.normalizeFragment=function(t){return this._parts.fragment||(this._parts.fragment=null,this.build(!t)),this},i.normalizeSearch=i.normalizeQuery,i.normalizeHash=i.normalizeFragment,i.iso8859=function(){var t=a.encode,e=a.decode;a.encode=escape,a.decode=decodeURIComponent;try{this.normalize()}finally{a.encode=t,a.decode=e}return this},i.unicode=function(){var t=a.encode,e=a.decode;a.encode=g,a.decode=unescape;try{this.normalize()}finally{a.encode=t,a.decode=e}return this},i.readable=function(){var e=this.clone();e.username("").password("").normalize();var r="";if(e._parts.protocol&&(r+=e._parts.protocol+"://"),e._parts.hostname&&(e.is("punycode")&&t?(r+=t.toUnicode(e._parts.hostname),e._parts.port&&(r+=":"+e._parts.port)):r+=e.host()),e._parts.hostname&&e._parts.path&&"/"!==e._parts.path.charAt(0)&&(r+="/"),r+=e.path(!0),e._parts.query){for(var s="",n=0,i=e._parts.query.split("&"),o=i.length;n<o;n++){var h=(i[n]||"").split("=");s+="&"+a.decodeQuery(h[0],this._parts.escapeQuerySpace).replace(/&/g,"%26"),void 0!==h[1]&&(s+="="+a.decodeQuery(h[1],this._parts.escapeQuerySpace).replace(/&/g,"%26"))}r+="?"+s.substring(1)}return r+=a.decodeQuery(e.hash(),!0)},i.absoluteTo=function(t){var e,r,s,n=this.clone(),i=["protocol","username","password","hostname","port"];if(this._parts.urn)throw new Error("URNs do not have any generally defined hierarchical components");if(t instanceof a||(t=new a(t)),n._parts.protocol||(n._parts.protocol=t._parts.protocol),this._parts.hostname)return n;for(r=0;s=i[r];r++)n._parts[s]=t._parts[s];return n._parts.path?".."===n._parts.path.substring(-2)&&(n._parts.path+="/"):(n._parts.path=t._parts.path,n._parts.query||(n._parts.query=t._parts.query)),"/"!==n.path().charAt(0)&&(e=(e=t.directory())||(0===t.path().indexOf("/")?"/":""),n._parts.path=(e?e+"/":"")+n._parts.path,n.normalizePath()),n.build(),n},i.relativeTo=function(t){var e,r,s,n,i,o=this.clone().normalize();if(o._parts.urn)throw new Error("URNs do not have any generally defined hierarchical components");if(t=new a(t).normalize(),e=o._parts,r=t._parts,n=o.path(),i=t.path(),"/"!==n.charAt(0))throw new Error("URI is already relative");if("/"!==i.charAt(0))throw new Error("Cannot calculate a URI relative to another relative URI");if(e.protocol===r.protocol&&(e.protocol=null),e.username!==r.username||e.password!==r.password)return o.build();if(null!==e.protocol||null!==e.username||null!==e.password)return o.build();if(e.hostname!==r.hostname||e.port!==r.port)return o.build();if(e.hostname=null,e.port=null,n===i)return e.path="",o.build();if(!(s=a.commonPath(n,i)))return o.build();var h=r.path.substring(s.length).replace(/[^\/]*$/,"").replace(/.*?\//g,"../");return e.path=h+e.path.substring(s.length)||"./",o.build()},i.equals=function(t){var e,r,s,n,i,h=this.clone(),u=new a(t),c={};if(h.normalize(),u.normalize(),h.toString()===u.toString())return!0;if(s=h.query(),n=u.query(),h.query(""),u.query(""),h.toString()!==u.toString())return!1;if(s.length!==n.length)return!1;for(i in e=a.parseQuery(s,this._parts.escapeQuerySpace),r=a.parseQuery(n,this._parts.escapeQuerySpace),e)if(o.call(e,i)){if(p(e[i])){if(!d(e[i],r[i]))return!1}else if(e[i]!==r[i])return!1;c[i]=!0}for(i in r)if(o.call(r,i)&&!c[i])return!1;return!0},i.duplicateQueryParameters=function(t){return this._parts.duplicateQueryParameters=!!t,this},i.escapeQuerySpace=function(t){return this._parts.escapeQuerySpace=!!t,this},a}(t.punycode,t.IPv6,t.SecondLevelDomains,t)}(this);/**
 * @preserve JSizes - JQuery plugin v0.33
 *
 * Licensed under the revised BSD License.
 * Copyright 2008-2010 Bram Stein
 * All rights reserved.
 */
!function(t){"use strict";var i=function(t){return parseInt(t,10)||0};t.each(["min","max"],(function(s,h){t.fn[h+"Size"]=function(t){var s,o;return t?(void 0!==t.width&&this.css(h+"-width",t.width),void 0!==t.height&&this.css(h+"-height",t.height),this):(s=this.css(h+"-width"),o=this.css(h+"-height"),{width:"max"===h&&(void 0===s||"none"===s||-1===i(s))&&Number.MAX_VALUE||i(s),height:"max"===h&&(void 0===o||"none"===o||-1===i(o))&&Number.MAX_VALUE||i(o)})}})),t.fn.isVisible=function(){return this.is(":visible")},t.each(["border","margin","padding"],(function(s,h){t.fn[h]=function(t){return t?(void 0!==t.top&&this.css(h+"-top"+("border"===h?"-width":""),t.top),void 0!==t.bottom&&this.css(h+"-bottom"+("border"===h?"-width":""),t.bottom),void 0!==t.left&&this.css(h+"-left"+("border"===h?"-width":""),t.left),void 0!==t.right&&this.css(h+"-right"+("border"===h?"-width":""),t.right),this):{top:i(this.css(h+"-top"+("border"===h?"-width":""))),bottom:i(this.css(h+"-bottom"+("border"===h?"-width":""))),left:i(this.css(h+"-left"+("border"===h?"-width":""))),right:i(this.css(h+"-right"+("border"===h?"-width":"")))}}}))}(jQuery);(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
'use strict'

exports.byteLength = byteLength
exports.toByteArray = toByteArray
exports.fromByteArray = fromByteArray

var lookup = []
var revLookup = []
var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array

var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
for (var i = 0, len = code.length; i < len; ++i) {
  lookup[i] = code[i]
  revLookup[code.charCodeAt(i)] = i
}

// Support decoding URL-safe base64 strings, as Node.js does.
// See: https://en.wikipedia.org/wiki/Base64#URL_applications
revLookup['-'.charCodeAt(0)] = 62
revLookup['_'.charCodeAt(0)] = 63

function getLens (b64) {
  var len = b64.length

  if (len % 4 > 0) {
    throw new Error('Invalid string. Length must be a multiple of 4')
  }

  // Trim off extra bytes after placeholder bytes are found
  // See: https://github.com/beatgammit/base64-js/issues/42
  var validLen = b64.indexOf('=')
  if (validLen === -1) validLen = len

  var placeHoldersLen = validLen === len
    ? 0
    : 4 - (validLen % 4)

  return [validLen, placeHoldersLen]
}

// base64 is 4/3 + up to two characters of the original data
function byteLength (b64) {
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function _byteLength (b64, validLen, placeHoldersLen) {
  return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen
}

function toByteArray (b64) {
  var tmp
  var lens = getLens(b64)
  var validLen = lens[0]
  var placeHoldersLen = lens[1]

  var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))

  var curByte = 0

  // if there are placeholders, only get up to the last complete 4 chars
  var len = placeHoldersLen > 0
    ? validLen - 4
    : validLen

  var i
  for (i = 0; i < len; i += 4) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 18) |
      (revLookup[b64.charCodeAt(i + 1)] << 12) |
      (revLookup[b64.charCodeAt(i + 2)] << 6) |
      revLookup[b64.charCodeAt(i + 3)]
    arr[curByte++] = (tmp >> 16) & 0xFF
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 2) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 2) |
      (revLookup[b64.charCodeAt(i + 1)] >> 4)
    arr[curByte++] = tmp & 0xFF
  }

  if (placeHoldersLen === 1) {
    tmp =
      (revLookup[b64.charCodeAt(i)] << 10) |
      (revLookup[b64.charCodeAt(i + 1)] << 4) |
      (revLookup[b64.charCodeAt(i + 2)] >> 2)
    arr[curByte++] = (tmp >> 8) & 0xFF
    arr[curByte++] = tmp & 0xFF
  }

  return arr
}

function tripletToBase64 (num) {
  return lookup[num >> 18 & 0x3F] +
    lookup[num >> 12 & 0x3F] +
    lookup[num >> 6 & 0x3F] +
    lookup[num & 0x3F]
}

function encodeChunk (uint8, start, end) {
  var tmp
  var output = []
  for (var i = start; i < end; i += 3) {
    tmp =
      ((uint8[i] << 16) & 0xFF0000) +
      ((uint8[i + 1] << 8) & 0xFF00) +
      (uint8[i + 2] & 0xFF)
    output.push(tripletToBase64(tmp))
  }
  return output.join('')
}

function fromByteArray (uint8) {
  var tmp
  var len = uint8.length
  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
  var parts = []
  var maxChunkLength = 16383 // must be multiple of 3

  // go through the array every three bytes, we'll deal with trailing stuff later
  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
    parts.push(encodeChunk(
      uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)
    ))
  }

  // pad the end with zeros, but make sure to not forget the extra bytes
  if (extraBytes === 1) {
    tmp = uint8[len - 1]
    parts.push(
      lookup[tmp >> 2] +
      lookup[(tmp << 4) & 0x3F] +
      '=='
    )
  } else if (extraBytes === 2) {
    tmp = (uint8[len - 2] << 8) + uint8[len - 1]
    parts.push(
      lookup[tmp >> 10] +
      lookup[(tmp >> 4) & 0x3F] +
      lookup[(tmp << 2) & 0x3F] +
      '='
    )
  }

  return parts.join('')
}

},{}],2:[function(require,module,exports){

},{}],3:[function(require,module,exports){
(function (Buffer){
/*!
 * The buffer module from node.js, for the browser.
 *
 * @author   Feross Aboukhadijeh <https://feross.org>
 * @license  MIT
 */
/* eslint-disable no-proto */

'use strict'

var base64 = require('base64-js')
var ieee754 = require('ieee754')

exports.Buffer = Buffer
exports.SlowBuffer = SlowBuffer
exports.INSPECT_MAX_BYTES = 50

var K_MAX_LENGTH = 0x7fffffff
exports.kMaxLength = K_MAX_LENGTH

/**
 * If `Buffer.TYPED_ARRAY_SUPPORT`:
 *   === true    Use Uint8Array implementation (fastest)
 *   === false   Print warning and recommend using `buffer` v4.x which has an Object
 *               implementation (most compatible, even IE6)
 *
 * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
 * Opera 11.6+, iOS 4.2+.
 *
 * We report that the browser does not support typed arrays if the are not subclassable
 * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array`
 * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support
 * for __proto__ and has a buggy typed array implementation.
 */
Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()

if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
    typeof console.error === 'function') {
  console.error(
    'This browser lacks typed array (Uint8Array) support which is required by ' +
    '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
  )
}

function typedArraySupport () {
  // Can typed array instances can be augmented?
  try {
    var arr = new Uint8Array(1)
    arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } }
    return arr.foo() === 42
  } catch (e) {
    return false
  }
}

Object.defineProperty(Buffer.prototype, 'parent', {
  enumerable: true,
  get: function () {
    if (!Buffer.isBuffer(this)) return undefined
    return this.buffer
  }
})

Object.defineProperty(Buffer.prototype, 'offset', {
  enumerable: true,
  get: function () {
    if (!Buffer.isBuffer(this)) return undefined
    return this.byteOffset
  }
})

function createBuffer (length) {
  if (length > K_MAX_LENGTH) {
    throw new RangeError('The value "' + length + '" is invalid for option "size"')
  }
  // Return an augmented `Uint8Array` instance
  var buf = new Uint8Array(length)
  buf.__proto__ = Buffer.prototype
  return buf
}

/**
 * The Buffer constructor returns instances of `Uint8Array` that have their
 * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
 * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
 * and the `Uint8Array` methods. Square bracket notation works as expected -- it
 * returns a single octet.
 *
 * The `Uint8Array` prototype remains unmodified.
 */

function Buffer (arg, encodingOrOffset, length) {
  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new TypeError(
        'The "string" argument must be of type string. Received type number'
      )
    }
    return allocUnsafe(arg)
  }
  return from(arg, encodingOrOffset, length)
}

// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
if (typeof Symbol !== 'undefined' && Symbol.species != null &&
    Buffer[Symbol.species] === Buffer) {
  Object.defineProperty(Buffer, Symbol.species, {
    value: null,
    configurable: true,
    enumerable: false,
    writable: false
  })
}

Buffer.poolSize = 8192 // not used by this implementation

function from (value, encodingOrOffset, length) {
  if (typeof value === 'string') {
    return fromString(value, encodingOrOffset)
  }

  if (ArrayBuffer.isView(value)) {
    return fromArrayLike(value)
  }

  if (value == null) {
    throw TypeError(
      'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
      'or Array-like Object. Received type ' + (typeof value)
    )
  }

  if (isInstance(value, ArrayBuffer) ||
      (value && isInstance(value.buffer, ArrayBuffer))) {
    return fromArrayBuffer(value, encodingOrOffset, length)
  }

  if (typeof value === 'number') {
    throw new TypeError(
      'The "value" argument must not be of type number. Received type number'
    )
  }

  var valueOf = value.valueOf && value.valueOf()
  if (valueOf != null && valueOf !== value) {
    return Buffer.from(valueOf, encodingOrOffset, length)
  }

  var b = fromObject(value)
  if (b) return b

  if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null &&
      typeof value[Symbol.toPrimitive] === 'function') {
    return Buffer.from(
      value[Symbol.toPrimitive]('string'), encodingOrOffset, length
    )
  }

  throw new TypeError(
    'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' +
    'or Array-like Object. Received type ' + (typeof value)
  )
}

/**
 * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
 * if value is a number.
 * Buffer.from(str[, encoding])
 * Buffer.from(array)
 * Buffer.from(buffer)
 * Buffer.from(arrayBuffer[, byteOffset[, length]])
 **/
Buffer.from = function (value, encodingOrOffset, length) {
  return from(value, encodingOrOffset, length)
}

// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug:
// https://github.com/feross/buffer/pull/148
Buffer.prototype.__proto__ = Uint8Array.prototype
Buffer.__proto__ = Uint8Array

function assertSize (size) {
  if (typeof size !== 'number') {
    throw new TypeError('"size" argument must be of type number')
  } else if (size < 0) {
    throw new RangeError('The value "' + size + '" is invalid for option "size"')
  }
}

function alloc (size, fill, encoding) {
  assertSize(size)
  if (size <= 0) {
    return createBuffer(size)
  }
  if (fill !== undefined) {
    // Only pay attention to encoding if it's a string. This
    // prevents accidentally sending in a number that would
    // be interpretted as a start offset.
    return typeof encoding === 'string'
      ? createBuffer(size).fill(fill, encoding)
      : createBuffer(size).fill(fill)
  }
  return createBuffer(size)
}

/**
 * Creates a new filled Buffer instance.
 * alloc(size[, fill[, encoding]])
 **/
Buffer.alloc = function (size, fill, encoding) {
  return alloc(size, fill, encoding)
}

function allocUnsafe (size) {
  assertSize(size)
  return createBuffer(size < 0 ? 0 : checked(size) | 0)
}

/**
 * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
 * */
Buffer.allocUnsafe = function (size) {
  return allocUnsafe(size)
}
/**
 * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
 */
Buffer.allocUnsafeSlow = function (size) {
  return allocUnsafe(size)
}

function fromString (string, encoding) {
  if (typeof encoding !== 'string' || encoding === '') {
    encoding = 'utf8'
  }

  if (!Buffer.isEncoding(encoding)) {
    throw new TypeError('Unknown encoding: ' + encoding)
  }

  var length = byteLength(string, encoding) | 0
  var buf = createBuffer(length)

  var actual = buf.write(string, encoding)

  if (actual !== length) {
    // Writing a hex string, for example, that contains invalid characters will
    // cause everything after the first invalid character to be ignored. (e.g.
    // 'abxxcd' will be treated as 'ab')
    buf = buf.slice(0, actual)
  }

  return buf
}

function fromArrayLike (array) {
  var length = array.length < 0 ? 0 : checked(array.length) | 0
  var buf = createBuffer(length)
  for (var i = 0; i < length; i += 1) {
    buf[i] = array[i] & 255
  }
  return buf
}

function fromArrayBuffer (array, byteOffset, length) {
  if (byteOffset < 0 || array.byteLength < byteOffset) {
    throw new RangeError('"offset" is outside of buffer bounds')
  }

  if (array.byteLength < byteOffset + (length || 0)) {
    throw new RangeError('"length" is outside of buffer bounds')
  }

  var buf
  if (byteOffset === undefined && length === undefined) {
    buf = new Uint8Array(array)
  } else if (length === undefined) {
    buf = new Uint8Array(array, byteOffset)
  } else {
    buf = new Uint8Array(array, byteOffset, length)
  }

  // Return an augmented `Uint8Array` instance
  buf.__proto__ = Buffer.prototype
  return buf
}

function fromObject (obj) {
  if (Buffer.isBuffer(obj)) {
    var len = checked(obj.length) | 0
    var buf = createBuffer(len)

    if (buf.length === 0) {
      return buf
    }

    obj.copy(buf, 0, 0, len)
    return buf
  }

  if (obj.length !== undefined) {
    if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
      return createBuffer(0)
    }
    return fromArrayLike(obj)
  }

  if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
    return fromArrayLike(obj.data)
  }
}

function checked (length) {
  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
  // length is NaN (which is otherwise coerced to zero.)
  if (length >= K_MAX_LENGTH) {
    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                         'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
  }
  return length | 0
}

function SlowBuffer (length) {
  if (+length != length) { // eslint-disable-line eqeqeq
    length = 0
  }
  return Buffer.alloc(+length)
}

Buffer.isBuffer = function isBuffer (b) {
  return b != null && b._isBuffer === true &&
    b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false
}

Buffer.compare = function compare (a, b) {
  if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength)
  if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength)
  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
    throw new TypeError(
      'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array'
    )
  }

  if (a === b) return 0

  var x = a.length
  var y = b.length

  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
    if (a[i] !== b[i]) {
      x = a[i]
      y = b[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

Buffer.isEncoding = function isEncoding (encoding) {
  switch (String(encoding).toLowerCase()) {
    case 'hex':
    case 'utf8':
    case 'utf-8':
    case 'ascii':
    case 'latin1':
    case 'binary':
    case 'base64':
    case 'ucs2':
    case 'ucs-2':
    case 'utf16le':
    case 'utf-16le':
      return true
    default:
      return false
  }
}

Buffer.concat = function concat (list, length) {
  if (!Array.isArray(list)) {
    throw new TypeError('"list" argument must be an Array of Buffers')
  }

  if (list.length === 0) {
    return Buffer.alloc(0)
  }

  var i
  if (length === undefined) {
    length = 0
    for (i = 0; i < list.length; ++i) {
      length += list[i].length
    }
  }

  var buffer = Buffer.allocUnsafe(length)
  var pos = 0
  for (i = 0; i < list.length; ++i) {
    var buf = list[i]
    if (isInstance(buf, Uint8Array)) {
      buf = Buffer.from(buf)
    }
    if (!Buffer.isBuffer(buf)) {
      throw new TypeError('"list" argument must be an Array of Buffers')
    }
    buf.copy(buffer, pos)
    pos += buf.length
  }
  return buffer
}

function byteLength (string, encoding) {
  if (Buffer.isBuffer(string)) {
    return string.length
  }
  if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) {
    return string.byteLength
  }
  if (typeof string !== 'string') {
    throw new TypeError(
      'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' +
      'Received type ' + typeof string
    )
  }

  var len = string.length
  var mustMatch = (arguments.length > 2 && arguments[2] === true)
  if (!mustMatch && len === 0) return 0

  // Use a for loop to avoid recursion
  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'ascii':
      case 'latin1':
      case 'binary':
        return len
      case 'utf8':
      case 'utf-8':
        return utf8ToBytes(string).length
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return len * 2
      case 'hex':
        return len >>> 1
      case 'base64':
        return base64ToBytes(string).length
      default:
        if (loweredCase) {
          return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8
        }
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}
Buffer.byteLength = byteLength

function slowToString (encoding, start, end) {
  var loweredCase = false

  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
  // property of a typed array.

  // This behaves neither like String nor Uint8Array in that we set start/end
  // to their upper/lower bounds if the value passed is out of range.
  // undefined is handled specially as per ECMA-262 6th Edition,
  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
  if (start === undefined || start < 0) {
    start = 0
  }
  // Return early if start > this.length. Done here to prevent potential uint32
  // coercion fail below.
  if (start > this.length) {
    return ''
  }

  if (end === undefined || end > this.length) {
    end = this.length
  }

  if (end <= 0) {
    return ''
  }

  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
  end >>>= 0
  start >>>= 0

  if (end <= start) {
    return ''
  }

  if (!encoding) encoding = 'utf8'

  while (true) {
    switch (encoding) {
      case 'hex':
        return hexSlice(this, start, end)

      case 'utf8':
      case 'utf-8':
        return utf8Slice(this, start, end)

      case 'ascii':
        return asciiSlice(this, start, end)

      case 'latin1':
      case 'binary':
        return latin1Slice(this, start, end)

      case 'base64':
        return base64Slice(this, start, end)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return utf16leSlice(this, start, end)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = (encoding + '').toLowerCase()
        loweredCase = true
    }
  }
}

// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
// reliably in a browserify context because there could be multiple different
// copies of the 'buffer' package in use. This method works even for Buffer
// instances that were created from another copy of the `buffer` package.
// See: https://github.com/feross/buffer/issues/154
Buffer.prototype._isBuffer = true

function swap (b, n, m) {
  var i = b[n]
  b[n] = b[m]
  b[m] = i
}

Buffer.prototype.swap16 = function swap16 () {
  var len = this.length
  if (len % 2 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 16-bits')
  }
  for (var i = 0; i < len; i += 2) {
    swap(this, i, i + 1)
  }
  return this
}

Buffer.prototype.swap32 = function swap32 () {
  var len = this.length
  if (len % 4 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 32-bits')
  }
  for (var i = 0; i < len; i += 4) {
    swap(this, i, i + 3)
    swap(this, i + 1, i + 2)
  }
  return this
}

Buffer.prototype.swap64 = function swap64 () {
  var len = this.length
  if (len % 8 !== 0) {
    throw new RangeError('Buffer size must be a multiple of 64-bits')
  }
  for (var i = 0; i < len; i += 8) {
    swap(this, i, i + 7)
    swap(this, i + 1, i + 6)
    swap(this, i + 2, i + 5)
    swap(this, i + 3, i + 4)
  }
  return this
}

Buffer.prototype.toString = function toString () {
  var length = this.length
  if (length === 0) return ''
  if (arguments.length === 0) return utf8Slice(this, 0, length)
  return slowToString.apply(this, arguments)
}

Buffer.prototype.toLocaleString = Buffer.prototype.toString

Buffer.prototype.equals = function equals (b) {
  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
  if (this === b) return true
  return Buffer.compare(this, b) === 0
}

Buffer.prototype.inspect = function inspect () {
  var str = ''
  var max = exports.INSPECT_MAX_BYTES
  str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim()
  if (this.length > max) str += ' ... '
  return '<Buffer ' + str + '>'
}

Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
  if (isInstance(target, Uint8Array)) {
    target = Buffer.from(target, target.offset, target.byteLength)
  }
  if (!Buffer.isBuffer(target)) {
    throw new TypeError(
      'The "target" argument must be one of type Buffer or Uint8Array. ' +
      'Received type ' + (typeof target)
    )
  }

  if (start === undefined) {
    start = 0
  }
  if (end === undefined) {
    end = target ? target.length : 0
  }
  if (thisStart === undefined) {
    thisStart = 0
  }
  if (thisEnd === undefined) {
    thisEnd = this.length
  }

  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
    throw new RangeError('out of range index')
  }

  if (thisStart >= thisEnd && start >= end) {
    return 0
  }
  if (thisStart >= thisEnd) {
    return -1
  }
  if (start >= end) {
    return 1
  }

  start >>>= 0
  end >>>= 0
  thisStart >>>= 0
  thisEnd >>>= 0

  if (this === target) return 0

  var x = thisEnd - thisStart
  var y = end - start
  var len = Math.min(x, y)

  var thisCopy = this.slice(thisStart, thisEnd)
  var targetCopy = target.slice(start, end)

  for (var i = 0; i < len; ++i) {
    if (thisCopy[i] !== targetCopy[i]) {
      x = thisCopy[i]
      y = targetCopy[i]
      break
    }
  }

  if (x < y) return -1
  if (y < x) return 1
  return 0
}

// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
//
// Arguments:
// - buffer - a Buffer to search
// - val - a string, Buffer, or number
// - byteOffset - an index into `buffer`; will be clamped to an int32
// - encoding - an optional encoding, relevant is val is a string
// - dir - true for indexOf, false for lastIndexOf
function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  // Empty buffer means no match
  if (buffer.length === 0) return -1

  // Normalize byteOffset
  if (typeof byteOffset === 'string') {
    encoding = byteOffset
    byteOffset = 0
  } else if (byteOffset > 0x7fffffff) {
    byteOffset = 0x7fffffff
  } else if (byteOffset < -0x80000000) {
    byteOffset = -0x80000000
  }
  byteOffset = +byteOffset // Coerce to Number.
  if (numberIsNaN(byteOffset)) {
    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
    byteOffset = dir ? 0 : (buffer.length - 1)
  }

  // Normalize byteOffset: negative offsets start from the end of the buffer
  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
  if (byteOffset >= buffer.length) {
    if (dir) return -1
    else byteOffset = buffer.length - 1
  } else if (byteOffset < 0) {
    if (dir) byteOffset = 0
    else return -1
  }

  // Normalize val
  if (typeof val === 'string') {
    val = Buffer.from(val, encoding)
  }

  // Finally, search either indexOf (if dir is true) or lastIndexOf
  if (Buffer.isBuffer(val)) {
    // Special case: looking for empty string/buffer always fails
    if (val.length === 0) {
      return -1
    }
    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
  } else if (typeof val === 'number') {
    val = val & 0xFF // Search for a byte value [0-255]
    if (typeof Uint8Array.prototype.indexOf === 'function') {
      if (dir) {
        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
      } else {
        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
      }
    }
    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
  }

  throw new TypeError('val must be string, number or Buffer')
}

function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  var indexSize = 1
  var arrLength = arr.length
  var valLength = val.length

  if (encoding !== undefined) {
    encoding = String(encoding).toLowerCase()
    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
        encoding === 'utf16le' || encoding === 'utf-16le') {
      if (arr.length < 2 || val.length < 2) {
        return -1
      }
      indexSize = 2
      arrLength /= 2
      valLength /= 2
      byteOffset /= 2
    }
  }

  function read (buf, i) {
    if (indexSize === 1) {
      return buf[i]
    } else {
      return buf.readUInt16BE(i * indexSize)
    }
  }

  var i
  if (dir) {
    var foundIndex = -1
    for (i = byteOffset; i < arrLength; i++) {
      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
        if (foundIndex === -1) foundIndex = i
        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
      } else {
        if (foundIndex !== -1) i -= i - foundIndex
        foundIndex = -1
      }
    }
  } else {
    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
    for (i = byteOffset; i >= 0; i--) {
      var found = true
      for (var j = 0; j < valLength; j++) {
        if (read(arr, i + j) !== read(val, j)) {
          found = false
          break
        }
      }
      if (found) return i
    }
  }

  return -1
}

Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
  return this.indexOf(val, byteOffset, encoding) !== -1
}

Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
}

Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
}

function hexWrite (buf, string, offset, length) {
  offset = Number(offset) || 0
  var remaining = buf.length - offset
  if (!length) {
    length = remaining
  } else {
    length = Number(length)
    if (length > remaining) {
      length = remaining
    }
  }

  var strLen = string.length

  if (length > strLen / 2) {
    length = strLen / 2
  }
  for (var i = 0; i < length; ++i) {
    var parsed = parseInt(string.substr(i * 2, 2), 16)
    if (numberIsNaN(parsed)) return i
    buf[offset + i] = parsed
  }
  return i
}

function utf8Write (buf, string, offset, length) {
  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
}

function asciiWrite (buf, string, offset, length) {
  return blitBuffer(asciiToBytes(string), buf, offset, length)
}

function latin1Write (buf, string, offset, length) {
  return asciiWrite(buf, string, offset, length)
}

function base64Write (buf, string, offset, length) {
  return blitBuffer(base64ToBytes(string), buf, offset, length)
}

function ucs2Write (buf, string, offset, length) {
  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
}

Buffer.prototype.write = function write (string, offset, length, encoding) {
  // Buffer#write(string)
  if (offset === undefined) {
    encoding = 'utf8'
    length = this.length
    offset = 0
  // Buffer#write(string, encoding)
  } else if (length === undefined && typeof offset === 'string') {
    encoding = offset
    length = this.length
    offset = 0
  // Buffer#write(string, offset[, length][, encoding])
  } else if (isFinite(offset)) {
    offset = offset >>> 0
    if (isFinite(length)) {
      length = length >>> 0
      if (encoding === undefined) encoding = 'utf8'
    } else {
      encoding = length
      length = undefined
    }
  } else {
    throw new Error(
      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
    )
  }

  var remaining = this.length - offset
  if (length === undefined || length > remaining) length = remaining

  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
    throw new RangeError('Attempt to write outside buffer bounds')
  }

  if (!encoding) encoding = 'utf8'

  var loweredCase = false
  for (;;) {
    switch (encoding) {
      case 'hex':
        return hexWrite(this, string, offset, length)

      case 'utf8':
      case 'utf-8':
        return utf8Write(this, string, offset, length)

      case 'ascii':
        return asciiWrite(this, string, offset, length)

      case 'latin1':
      case 'binary':
        return latin1Write(this, string, offset, length)

      case 'base64':
        // Warning: maxLength not taken into account in base64Write
        return base64Write(this, string, offset, length)

      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return ucs2Write(this, string, offset, length)

      default:
        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
        encoding = ('' + encoding).toLowerCase()
        loweredCase = true
    }
  }
}

Buffer.prototype.toJSON = function toJSON () {
  return {
    type: 'Buffer',
    data: Array.prototype.slice.call(this._arr || this, 0)
  }
}

function base64Slice (buf, start, end) {
  if (start === 0 && end === buf.length) {
    return base64.fromByteArray(buf)
  } else {
    return base64.fromByteArray(buf.slice(start, end))
  }
}

function utf8Slice (buf, start, end) {
  end = Math.min(buf.length, end)
  var res = []

  var i = start
  while (i < end) {
    var firstByte = buf[i]
    var codePoint = null
    var bytesPerSequence = (firstByte > 0xEF) ? 4
      : (firstByte > 0xDF) ? 3
        : (firstByte > 0xBF) ? 2
          : 1

    if (i + bytesPerSequence <= end) {
      var secondByte, thirdByte, fourthByte, tempCodePoint

      switch (bytesPerSequence) {
        case 1:
          if (firstByte < 0x80) {
            codePoint = firstByte
          }
          break
        case 2:
          secondByte = buf[i + 1]
          if ((secondByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
            if (tempCodePoint > 0x7F) {
              codePoint = tempCodePoint
            }
          }
          break
        case 3:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
              codePoint = tempCodePoint
            }
          }
          break
        case 4:
          secondByte = buf[i + 1]
          thirdByte = buf[i + 2]
          fourthByte = buf[i + 3]
          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
              codePoint = tempCodePoint
            }
          }
      }
    }

    if (codePoint === null) {
      // we did not generate a valid codePoint so insert a
      // replacement char (U+FFFD) and advance only 1 byte
      codePoint = 0xFFFD
      bytesPerSequence = 1
    } else if (codePoint > 0xFFFF) {
      // encode to utf16 (surrogate pair dance)
      codePoint -= 0x10000
      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
      codePoint = 0xDC00 | codePoint & 0x3FF
    }

    res.push(codePoint)
    i += bytesPerSequence
  }

  return decodeCodePointsArray(res)
}

// Based on http://stackoverflow.com/a/22747272/680742, the browser with
// the lowest limit is Chrome, with 0x10000 args.
// We go 1 magnitude less, for safety
var MAX_ARGUMENTS_LENGTH = 0x1000

function decodeCodePointsArray (codePoints) {
  var len = codePoints.length
  if (len <= MAX_ARGUMENTS_LENGTH) {
    return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
  }

  // Decode in chunks to avoid "call stack size exceeded".
  var res = ''
  var i = 0
  while (i < len) {
    res += String.fromCharCode.apply(
      String,
      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
    )
  }
  return res
}

function asciiSlice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i] & 0x7F)
  }
  return ret
}

function latin1Slice (buf, start, end) {
  var ret = ''
  end = Math.min(buf.length, end)

  for (var i = start; i < end; ++i) {
    ret += String.fromCharCode(buf[i])
  }
  return ret
}

function hexSlice (buf, start, end) {
  var len = buf.length

  if (!start || start < 0) start = 0
  if (!end || end < 0 || end > len) end = len

  var out = ''
  for (var i = start; i < end; ++i) {
    out += toHex(buf[i])
  }
  return out
}

function utf16leSlice (buf, start, end) {
  var bytes = buf.slice(start, end)
  var res = ''
  for (var i = 0; i < bytes.length; i += 2) {
    res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
  }
  return res
}

Buffer.prototype.slice = function slice (start, end) {
  var len = this.length
  start = ~~start
  end = end === undefined ? len : ~~end

  if (start < 0) {
    start += len
    if (start < 0) start = 0
  } else if (start > len) {
    start = len
  }

  if (end < 0) {
    end += len
    if (end < 0) end = 0
  } else if (end > len) {
    end = len
  }

  if (end < start) end = start

  var newBuf = this.subarray(start, end)
  // Return an augmented `Uint8Array` instance
  newBuf.__proto__ = Buffer.prototype
  return newBuf
}

/*
 * Need to make sure that buffer isn't trying to write out of bounds.
 */
function checkOffset (offset, ext, length) {
  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
}

Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }

  return val
}

Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    checkOffset(offset, byteLength, this.length)
  }

  var val = this[offset + --byteLength]
  var mul = 1
  while (byteLength > 0 && (mul *= 0x100)) {
    val += this[offset + --byteLength] * mul
  }

  return val
}

Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 1, this.length)
  return this[offset]
}

Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  return this[offset] | (this[offset + 1] << 8)
}

Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  return (this[offset] << 8) | this[offset + 1]
}

Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return ((this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16)) +
      (this[offset + 3] * 0x1000000)
}

Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] * 0x1000000) +
    ((this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    this[offset + 3])
}

Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var val = this[offset]
  var mul = 1
  var i = 0
  while (++i < byteLength && (mul *= 0x100)) {
    val += this[offset + i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) checkOffset(offset, byteLength, this.length)

  var i = byteLength
  var mul = 1
  var val = this[offset + --i]
  while (i > 0 && (mul *= 0x100)) {
    val += this[offset + --i] * mul
  }
  mul *= 0x80

  if (val >= mul) val -= Math.pow(2, 8 * byteLength)

  return val
}

Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 1, this.length)
  if (!(this[offset] & 0x80)) return (this[offset])
  return ((0xff - this[offset] + 1) * -1)
}

Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset] | (this[offset + 1] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 2, this.length)
  var val = this[offset + 1] | (this[offset] << 8)
  return (val & 0x8000) ? val | 0xFFFF0000 : val
}

Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset]) |
    (this[offset + 1] << 8) |
    (this[offset + 2] << 16) |
    (this[offset + 3] << 24)
}

Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)

  return (this[offset] << 24) |
    (this[offset + 1] << 16) |
    (this[offset + 2] << 8) |
    (this[offset + 3])
}

Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, true, 23, 4)
}

Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 4, this.length)
  return ieee754.read(this, offset, false, 23, 4)
}

Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, true, 52, 8)
}

Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
  offset = offset >>> 0
  if (!noAssert) checkOffset(offset, 8, this.length)
  return ieee754.read(this, offset, false, 52, 8)
}

function checkInt (buf, value, offset, ext, max, min) {
  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
}

Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var mul = 1
  var i = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  byteLength = byteLength >>> 0
  if (!noAssert) {
    var maxBytes = Math.pow(2, 8 * byteLength) - 1
    checkInt(this, value, offset, byteLength, maxBytes, 0)
  }

  var i = byteLength - 1
  var mul = 1
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    this[offset + i] = (value / mul) & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
  this[offset] = (value & 0xff)
  return offset + 1
}

Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  return offset + 2
}

Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
  this[offset] = (value >>> 8)
  this[offset + 1] = (value & 0xff)
  return offset + 2
}

Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  this[offset + 3] = (value >>> 24)
  this[offset + 2] = (value >>> 16)
  this[offset + 1] = (value >>> 8)
  this[offset] = (value & 0xff)
  return offset + 4
}

Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
  this[offset] = (value >>> 24)
  this[offset + 1] = (value >>> 16)
  this[offset + 2] = (value >>> 8)
  this[offset + 3] = (value & 0xff)
  return offset + 4
}

Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    var limit = Math.pow(2, (8 * byteLength) - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = 0
  var mul = 1
  var sub = 0
  this[offset] = value & 0xFF
  while (++i < byteLength && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    var limit = Math.pow(2, (8 * byteLength) - 1)

    checkInt(this, value, offset, byteLength, limit - 1, -limit)
  }

  var i = byteLength - 1
  var mul = 1
  var sub = 0
  this[offset + i] = value & 0xFF
  while (--i >= 0 && (mul *= 0x100)) {
    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
      sub = 1
    }
    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
  }

  return offset + byteLength
}

Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
  if (value < 0) value = 0xff + value + 1
  this[offset] = (value & 0xff)
  return offset + 1
}

Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  return offset + 2
}

Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
  this[offset] = (value >>> 8)
  this[offset + 1] = (value & 0xff)
  return offset + 2
}

Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  this[offset] = (value & 0xff)
  this[offset + 1] = (value >>> 8)
  this[offset + 2] = (value >>> 16)
  this[offset + 3] = (value >>> 24)
  return offset + 4
}

Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
  if (value < 0) value = 0xffffffff + value + 1
  this[offset] = (value >>> 24)
  this[offset + 1] = (value >>> 16)
  this[offset + 2] = (value >>> 8)
  this[offset + 3] = (value & 0xff)
  return offset + 4
}

function checkIEEE754 (buf, value, offset, ext, max, min) {
  if (offset + ext > buf.length) throw new RangeError('Index out of range')
  if (offset < 0) throw new RangeError('Index out of range')
}

function writeFloat (buf, value, offset, littleEndian, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
  }
  ieee754.write(buf, value, offset, littleEndian, 23, 4)
  return offset + 4
}

Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
  return writeFloat(this, value, offset, true, noAssert)
}

Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
  return writeFloat(this, value, offset, false, noAssert)
}

function writeDouble (buf, value, offset, littleEndian, noAssert) {
  value = +value
  offset = offset >>> 0
  if (!noAssert) {
    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
  }
  ieee754.write(buf, value, offset, littleEndian, 52, 8)
  return offset + 8
}

Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
  return writeDouble(this, value, offset, true, noAssert)
}

Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
  return writeDouble(this, value, offset, false, noAssert)
}

// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
Buffer.prototype.copy = function copy (target, targetStart, start, end) {
  if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer')
  if (!start) start = 0
  if (!end && end !== 0) end = this.length
  if (targetStart >= target.length) targetStart = target.length
  if (!targetStart) targetStart = 0
  if (end > 0 && end < start) end = start

  // Copy 0 bytes; we're done
  if (end === start) return 0
  if (target.length === 0 || this.length === 0) return 0

  // Fatal error conditions
  if (targetStart < 0) {
    throw new RangeError('targetStart out of bounds')
  }
  if (start < 0 || start >= this.length) throw new RangeError('Index out of range')
  if (end < 0) throw new RangeError('sourceEnd out of bounds')

  // Are we oob?
  if (end > this.length) end = this.length
  if (target.length - targetStart < end - start) {
    end = target.length - targetStart + start
  }

  var len = end - start

  if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') {
    // Use built-in when available, missing from IE11
    this.copyWithin(targetStart, start, end)
  } else if (this === target && start < targetStart && targetStart < end) {
    // descending copy from end
    for (var i = len - 1; i >= 0; --i) {
      target[i + targetStart] = this[i + start]
    }
  } else {
    Uint8Array.prototype.set.call(
      target,
      this.subarray(start, end),
      targetStart
    )
  }

  return len
}

// Usage:
//    buffer.fill(number[, offset[, end]])
//    buffer.fill(buffer[, offset[, end]])
//    buffer.fill(string[, offset[, end]][, encoding])
Buffer.prototype.fill = function fill (val, start, end, encoding) {
  // Handle string cases:
  if (typeof val === 'string') {
    if (typeof start === 'string') {
      encoding = start
      start = 0
      end = this.length
    } else if (typeof end === 'string') {
      encoding = end
      end = this.length
    }
    if (encoding !== undefined && typeof encoding !== 'string') {
      throw new TypeError('encoding must be a string')
    }
    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
      throw new TypeError('Unknown encoding: ' + encoding)
    }
    if (val.length === 1) {
      var code = val.charCodeAt(0)
      if ((encoding === 'utf8' && code < 128) ||
          encoding === 'latin1') {
        // Fast path: If `val` fits into a single byte, use that numeric value.
        val = code
      }
    }
  } else if (typeof val === 'number') {
    val = val & 255
  }

  // Invalid ranges are not set to a default, so can range check early.
  if (start < 0 || this.length < start || this.length < end) {
    throw new RangeError('Out of range index')
  }

  if (end <= start) {
    return this
  }

  start = start >>> 0
  end = end === undefined ? this.length : end >>> 0

  if (!val) val = 0

  var i
  if (typeof val === 'number') {
    for (i = start; i < end; ++i) {
      this[i] = val
    }
  } else {
    var bytes = Buffer.isBuffer(val)
      ? val
      : Buffer.from(val, encoding)
    var len = bytes.length
    if (len === 0) {
      throw new TypeError('The value "' + val +
        '" is invalid for argument "value"')
    }
    for (i = 0; i < end - start; ++i) {
      this[i + start] = bytes[i % len]
    }
  }

  return this
}

// HELPER FUNCTIONS
// ================

var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g

function base64clean (str) {
  // Node takes equal signs as end of the Base64 encoding
  str = str.split('=')[0]
  // Node strips out invalid characters like \n and \t from the string, base64-js does not
  str = str.trim().replace(INVALID_BASE64_RE, '')
  // Node converts strings with length < 2 to ''
  if (str.length < 2) return ''
  // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
  while (str.length % 4 !== 0) {
    str = str + '='
  }
  return str
}

function toHex (n) {
  if (n < 16) return '0' + n.toString(16)
  return n.toString(16)
}

function utf8ToBytes (string, units) {
  units = units || Infinity
  var codePoint
  var length = string.length
  var leadSurrogate = null
  var bytes = []

  for (var i = 0; i < length; ++i) {
    codePoint = string.charCodeAt(i)

    // is surrogate component
    if (codePoint > 0xD7FF && codePoint < 0xE000) {
      // last char was a lead
      if (!leadSurrogate) {
        // no lead yet
        if (codePoint > 0xDBFF) {
          // unexpected trail
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        } else if (i + 1 === length) {
          // unpaired lead
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          continue
        }

        // valid lead
        leadSurrogate = codePoint

        continue
      }

      // 2 leads in a row
      if (codePoint < 0xDC00) {
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
        leadSurrogate = codePoint
        continue
      }

      // valid surrogate pair
      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
    } else if (leadSurrogate) {
      // valid bmp char, but last char was a lead
      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
    }

    leadSurrogate = null

    // encode utf8
    if (codePoint < 0x80) {
      if ((units -= 1) < 0) break
      bytes.push(codePoint)
    } else if (codePoint < 0x800) {
      if ((units -= 2) < 0) break
      bytes.push(
        codePoint >> 0x6 | 0xC0,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x10000) {
      if ((units -= 3) < 0) break
      bytes.push(
        codePoint >> 0xC | 0xE0,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else if (codePoint < 0x110000) {
      if ((units -= 4) < 0) break
      bytes.push(
        codePoint >> 0x12 | 0xF0,
        codePoint >> 0xC & 0x3F | 0x80,
        codePoint >> 0x6 & 0x3F | 0x80,
        codePoint & 0x3F | 0x80
      )
    } else {
      throw new Error('Invalid code point')
    }
  }

  return bytes
}

function asciiToBytes (str) {
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    // Node's code seems to be doing this and not & 0x7F..
    byteArray.push(str.charCodeAt(i) & 0xFF)
  }
  return byteArray
}

function utf16leToBytes (str, units) {
  var c, hi, lo
  var byteArray = []
  for (var i = 0; i < str.length; ++i) {
    if ((units -= 2) < 0) break

    c = str.charCodeAt(i)
    hi = c >> 8
    lo = c % 256
    byteArray.push(lo)
    byteArray.push(hi)
  }

  return byteArray
}

function base64ToBytes (str) {
  return base64.toByteArray(base64clean(str))
}

function blitBuffer (src, dst, offset, length) {
  for (var i = 0; i < length; ++i) {
    if ((i + offset >= dst.length) || (i >= src.length)) break
    dst[i + offset] = src[i]
  }
  return i
}

// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass
// the `instanceof` check but they should be treated as of that type.
// See: https://github.com/feross/buffer/issues/166
function isInstance (obj, type) {
  return obj instanceof type ||
    (obj != null && obj.constructor != null && obj.constructor.name != null &&
      obj.constructor.name === type.name)
}
function numberIsNaN (obj) {
  // For IE11 support
  return obj !== obj // eslint-disable-line no-self-compare
}

}).call(this,require("buffer").Buffer)
},{"base64-js":1,"buffer":3,"ieee754":4}],4:[function(require,module,exports){
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
  var e, m
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var nBits = -7
  var i = isLE ? (nBytes - 1) : 0
  var d = isLE ? -1 : 1
  var s = buffer[offset + i]

  i += d

  e = s & ((1 << (-nBits)) - 1)
  s >>= (-nBits)
  nBits += eLen
  for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  m = e & ((1 << (-nBits)) - 1)
  e >>= (-nBits)
  nBits += mLen
  for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}

  if (e === 0) {
    e = 1 - eBias
  } else if (e === eMax) {
    return m ? NaN : ((s ? -1 : 1) * Infinity)
  } else {
    m = m + Math.pow(2, mLen)
    e = e - eBias
  }
  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
}

exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
  var e, m, c
  var eLen = (nBytes * 8) - mLen - 1
  var eMax = (1 << eLen) - 1
  var eBias = eMax >> 1
  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
  var i = isLE ? 0 : (nBytes - 1)
  var d = isLE ? 1 : -1
  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0

  value = Math.abs(value)

  if (isNaN(value) || value === Infinity) {
    m = isNaN(value) ? 1 : 0
    e = eMax
  } else {
    e = Math.floor(Math.log(value) / Math.LN2)
    if (value * (c = Math.pow(2, -e)) < 1) {
      e--
      c *= 2
    }
    if (e + eBias >= 1) {
      value += rt / c
    } else {
      value += rt * Math.pow(2, 1 - eBias)
    }
    if (value * c >= 2) {
      e++
      c /= 2
    }

    if (e + eBias >= eMax) {
      m = 0
      e = eMax
    } else if (e + eBias >= 1) {
      m = ((value * c) - 1) * Math.pow(2, mLen)
      e = e + eBias
    } else {
      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
      e = 0
    }
  }

  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}

  e = (e << mLen) | m
  eLen += mLen
  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}

  buffer[offset + i - d] |= s * 128
}

},{}],5:[function(require,module,exports){
(function (process){
// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
// backported and transplited with Babel, with backwards-compat fixes

// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
  // if the path tries to go above the root, `up` ends up > 0
  var up = 0;
  for (var i = parts.length - 1; i >= 0; i--) {
    var last = parts[i];
    if (last === '.') {
      parts.splice(i, 1);
    } else if (last === '..') {
      parts.splice(i, 1);
      up++;
    } else if (up) {
      parts.splice(i, 1);
      up--;
    }
  }

  // if the path is allowed to go above the root, restore leading ..s
  if (allowAboveRoot) {
    for (; up--; up) {
      parts.unshift('..');
    }
  }

  return parts;
}

// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
  var resolvedPath = '',
      resolvedAbsolute = false;

  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
    var path = (i >= 0) ? arguments[i] : process.cwd();

    // Skip empty and invalid entries
    if (typeof path !== 'string') {
      throw new TypeError('Arguments to path.resolve must be strings');
    } else if (!path) {
      continue;
    }

    resolvedPath = path + '/' + resolvedPath;
    resolvedAbsolute = path.charAt(0) === '/';
  }

  // At this point the path should be resolved to a full absolute path, but
  // handle relative paths to be safe (might happen when process.cwd() fails)

  // Normalize the path
  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
    return !!p;
  }), !resolvedAbsolute).join('/');

  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};

// path.normalize(path)
// posix version
exports.normalize = function(path) {
  var isAbsolute = exports.isAbsolute(path),
      trailingSlash = substr(path, -1) === '/';

  // Normalize the path
  path = normalizeArray(filter(path.split('/'), function(p) {
    return !!p;
  }), !isAbsolute).join('/');

  if (!path && !isAbsolute) {
    path = '.';
  }
  if (path && trailingSlash) {
    path += '/';
  }

  return (isAbsolute ? '/' : '') + path;
};

// posix version
exports.isAbsolute = function(path) {
  return path.charAt(0) === '/';
};

// posix version
exports.join = function() {
  var paths = Array.prototype.slice.call(arguments, 0);
  return exports.normalize(filter(paths, function(p, index) {
    if (typeof p !== 'string') {
      throw new TypeError('Arguments to path.join must be strings');
    }
    return p;
  }).join('/'));
};


// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
  from = exports.resolve(from).substr(1);
  to = exports.resolve(to).substr(1);

  function trim(arr) {
    var start = 0;
    for (; start < arr.length; start++) {
      if (arr[start] !== '') break;
    }

    var end = arr.length - 1;
    for (; end >= 0; end--) {
      if (arr[end] !== '') break;
    }

    if (start > end) return [];
    return arr.slice(start, end - start + 1);
  }

  var fromParts = trim(from.split('/'));
  var toParts = trim(to.split('/'));

  var length = Math.min(fromParts.length, toParts.length);
  var samePartsLength = length;
  for (var i = 0; i < length; i++) {
    if (fromParts[i] !== toParts[i]) {
      samePartsLength = i;
      break;
    }
  }

  var outputParts = [];
  for (var i = samePartsLength; i < fromParts.length; i++) {
    outputParts.push('..');
  }

  outputParts = outputParts.concat(toParts.slice(samePartsLength));

  return outputParts.join('/');
};

exports.sep = '/';
exports.delimiter = ':';

exports.dirname = function (path) {
  if (typeof path !== 'string') path = path + '';
  if (path.length === 0) return '.';
  var code = path.charCodeAt(0);
  var hasRoot = code === 47 /*/*/;
  var end = -1;
  var matchedSlash = true;
  for (var i = path.length - 1; i >= 1; --i) {
    code = path.charCodeAt(i);
    if (code === 47 /*/*/) {
        if (!matchedSlash) {
          end = i;
          break;
        }
      } else {
      // We saw the first non-path separator
      matchedSlash = false;
    }
  }

  if (end === -1) return hasRoot ? '/' : '.';
  if (hasRoot && end === 1) {
    // return '//';
    // Backwards-compat fix:
    return '/';
  }
  return path.slice(0, end);
};

function basename(path) {
  if (typeof path !== 'string') path = path + '';

  var start = 0;
  var end = -1;
  var matchedSlash = true;
  var i;

  for (i = path.length - 1; i >= 0; --i) {
    if (path.charCodeAt(i) === 47 /*/*/) {
        // If we reached a path separator that was not part of a set of path
        // separators at the end of the string, stop now
        if (!matchedSlash) {
          start = i + 1;
          break;
        }
      } else if (end === -1) {
      // We saw the first non-path separator, mark this as the end of our
      // path component
      matchedSlash = false;
      end = i + 1;
    }
  }

  if (end === -1) return '';
  return path.slice(start, end);
}

// Uses a mixed approach for backwards-compatibility, as ext behavior changed
// in new Node.js versions, so only basename() above is backported here
exports.basename = function (path, ext) {
  var f = basename(path);
  if (ext && f.substr(-1 * ext.length) === ext) {
    f = f.substr(0, f.length - ext.length);
  }
  return f;
};

exports.extname = function (path) {
  if (typeof path !== 'string') path = path + '';
  var startDot = -1;
  var startPart = 0;
  var end = -1;
  var matchedSlash = true;
  // Track the state of characters (if any) we see before our first dot and
  // after any path separator we find
  var preDotState = 0;
  for (var i = path.length - 1; i >= 0; --i) {
    var code = path.charCodeAt(i);
    if (code === 47 /*/*/) {
        // If we reached a path separator that was not part of a set of path
        // separators at the end of the string, stop now
        if (!matchedSlash) {
          startPart = i + 1;
          break;
        }
        continue;
      }
    if (end === -1) {
      // We saw the first non-path separator, mark this as the end of our
      // extension
      matchedSlash = false;
      end = i + 1;
    }
    if (code === 46 /*.*/) {
        // If this is our first dot, mark it as the start of our extension
        if (startDot === -1)
          startDot = i;
        else if (preDotState !== 1)
          preDotState = 1;
    } else if (startDot !== -1) {
      // We saw a non-dot and non-path separator before our dot, so we should
      // have a good chance at having a non-empty extension
      preDotState = -1;
    }
  }

  if (startDot === -1 || end === -1 ||
      // We saw a non-dot character immediately before the dot
      preDotState === 0 ||
      // The (right-most) trimmed path component is exactly '..'
      preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
    return '';
  }
  return path.slice(startDot, end);
};

function filter (xs, f) {
    if (xs.filter) return xs.filter(f);
    var res = [];
    for (var i = 0; i < xs.length; i++) {
        if (f(xs[i], i, xs)) res.push(xs[i]);
    }
    return res;
}

// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b'
    ? function (str, start, len) { return str.substr(start, len) }
    : function (str, start, len) {
        if (start < 0) start = str.length + start;
        return str.substr(start, len);
    }
;

}).call(this,require('_process'))
},{"_process":6}],6:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };

},{}],7:[function(require,module,exports){
(function (global){
/*! https://mths.be/punycode v1.4.1 by @mathias */
;(function(root) {

	/** Detect free variables */
	var freeExports = typeof exports == 'object' && exports &&
		!exports.nodeType && exports;
	var freeModule = typeof module == 'object' && module &&
		!module.nodeType && module;
	var freeGlobal = typeof global == 'object' && global;
	if (
		freeGlobal.global === freeGlobal ||
		freeGlobal.window === freeGlobal ||
		freeGlobal.self === freeGlobal
	) {
		root = freeGlobal;
	}

	/**
	 * The `punycode` object.
	 * @name punycode
	 * @type Object
	 */
	var punycode,

	/** Highest positive signed 32-bit float value */
	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1

	/** Bootstring parameters */
	base = 36,
	tMin = 1,
	tMax = 26,
	skew = 38,
	damp = 700,
	initialBias = 72,
	initialN = 128, // 0x80
	delimiter = '-', // '\x2D'

	/** Regular expressions */
	regexPunycode = /^xn--/,
	regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
	regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators

	/** Error messages */
	errors = {
		'overflow': 'Overflow: input needs wider integers to process',
		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
		'invalid-input': 'Invalid input'
	},

	/** Convenience shortcuts */
	baseMinusTMin = base - tMin,
	floor = Math.floor,
	stringFromCharCode = String.fromCharCode,

	/** Temporary variable */
	key;

	/*--------------------------------------------------------------------------*/

	/**
	 * A generic error utility function.
	 * @private
	 * @param {String} type The error type.
	 * @returns {Error} Throws a `RangeError` with the applicable error message.
	 */
	function error(type) {
		throw new RangeError(errors[type]);
	}

	/**
	 * A generic `Array#map` utility function.
	 * @private
	 * @param {Array} array The array to iterate over.
	 * @param {Function} callback The function that gets called for every array
	 * item.
	 * @returns {Array} A new array of values returned by the callback function.
	 */
	function map(array, fn) {
		var length = array.length;
		var result = [];
		while (length--) {
			result[length] = fn(array[length]);
		}
		return result;
	}

	/**
	 * A simple `Array#map`-like wrapper to work with domain name strings or email
	 * addresses.
	 * @private
	 * @param {String} domain The domain name or email address.
	 * @param {Function} callback The function that gets called for every
	 * character.
	 * @returns {Array} A new string of characters returned by the callback
	 * function.
	 */
	function mapDomain(string, fn) {
		var parts = string.split('@');
		var result = '';
		if (parts.length > 1) {
			// In email addresses, only the domain name should be punycoded. Leave
			// the local part (i.e. everything up to `@`) intact.
			result = parts[0] + '@';
			string = parts[1];
		}
		// Avoid `split(regex)` for IE8 compatibility. See #17.
		string = string.replace(regexSeparators, '\x2E');
		var labels = string.split('.');
		var encoded = map(labels, fn).join('.');
		return result + encoded;
	}

	/**
	 * Creates an array containing the numeric code points of each Unicode
	 * character in the string. While JavaScript uses UCS-2 internally,
	 * this function will convert a pair of surrogate halves (each of which
	 * UCS-2 exposes as separate characters) into a single code point,
	 * matching UTF-16.
	 * @see `punycode.ucs2.encode`
	 * @see <https://mathiasbynens.be/notes/javascript-encoding>
	 * @memberOf punycode.ucs2
	 * @name decode
	 * @param {String} string The Unicode input string (UCS-2).
	 * @returns {Array} The new array of code points.
	 */
	function ucs2decode(string) {
		var output = [],
		    counter = 0,
		    length = string.length,
		    value,
		    extra;
		while (counter < length) {
			value = string.charCodeAt(counter++);
			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
				// high surrogate, and there is a next character
				extra = string.charCodeAt(counter++);
				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
				} else {
					// unmatched surrogate; only append this code unit, in case the next
					// code unit is the high surrogate of a surrogate pair
					output.push(value);
					counter--;
				}
			} else {
				output.push(value);
			}
		}
		return output;
	}

	/**
	 * Creates a string based on an array of numeric code points.
	 * @see `punycode.ucs2.decode`
	 * @memberOf punycode.ucs2
	 * @name encode
	 * @param {Array} codePoints The array of numeric code points.
	 * @returns {String} The new Unicode string (UCS-2).
	 */
	function ucs2encode(array) {
		return map(array, function(value) {
			var output = '';
			if (value > 0xFFFF) {
				value -= 0x10000;
				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
				value = 0xDC00 | value & 0x3FF;
			}
			output += stringFromCharCode(value);
			return output;
		}).join('');
	}

	/**
	 * Converts a basic code point into a digit/integer.
	 * @see `digitToBasic()`
	 * @private
	 * @param {Number} codePoint The basic numeric code point value.
	 * @returns {Number} The numeric value of a basic code point (for use in
	 * representing integers) in the range `0` to `base - 1`, or `base` if
	 * the code point does not represent a value.
	 */
	function basicToDigit(codePoint) {
		if (codePoint - 48 < 10) {
			return codePoint - 22;
		}
		if (codePoint - 65 < 26) {
			return codePoint - 65;
		}
		if (codePoint - 97 < 26) {
			return codePoint - 97;
		}
		return base;
	}

	/**
	 * Converts a digit/integer into a basic code point.
	 * @see `basicToDigit()`
	 * @private
	 * @param {Number} digit The numeric value of a basic code point.
	 * @returns {Number} The basic code point whose value (when used for
	 * representing integers) is `digit`, which needs to be in the range
	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
	 * used; else, the lowercase form is used. The behavior is undefined
	 * if `flag` is non-zero and `digit` has no uppercase form.
	 */
	function digitToBasic(digit, flag) {
		//  0..25 map to ASCII a..z or A..Z
		// 26..35 map to ASCII 0..9
		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
	}

	/**
	 * Bias adaptation function as per section 3.4 of RFC 3492.
	 * https://tools.ietf.org/html/rfc3492#section-3.4
	 * @private
	 */
	function adapt(delta, numPoints, firstTime) {
		var k = 0;
		delta = firstTime ? floor(delta / damp) : delta >> 1;
		delta += floor(delta / numPoints);
		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
			delta = floor(delta / baseMinusTMin);
		}
		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
	}

	/**
	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
	 * symbols.
	 * @memberOf punycode
	 * @param {String} input The Punycode string of ASCII-only symbols.
	 * @returns {String} The resulting string of Unicode symbols.
	 */
	function decode(input) {
		// Don't use UCS-2
		var output = [],
		    inputLength = input.length,
		    out,
		    i = 0,
		    n = initialN,
		    bias = initialBias,
		    basic,
		    j,
		    index,
		    oldi,
		    w,
		    k,
		    digit,
		    t,
		    /** Cached calculation results */
		    baseMinusT;

		// Handle the basic code points: let `basic` be the number of input code
		// points before the last delimiter, or `0` if there is none, then copy
		// the first basic code points to the output.

		basic = input.lastIndexOf(delimiter);
		if (basic < 0) {
			basic = 0;
		}

		for (j = 0; j < basic; ++j) {
			// if it's not a basic code point
			if (input.charCodeAt(j) >= 0x80) {
				error('not-basic');
			}
			output.push(input.charCodeAt(j));
		}

		// Main decoding loop: start just after the last delimiter if any basic code
		// points were copied; start at the beginning otherwise.

		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {

			// `index` is the index of the next character to be consumed.
			// Decode a generalized variable-length integer into `delta`,
			// which gets added to `i`. The overflow checking is easier
			// if we increase `i` as we go, then subtract off its starting
			// value at the end to obtain `delta`.
			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {

				if (index >= inputLength) {
					error('invalid-input');
				}

				digit = basicToDigit(input.charCodeAt(index++));

				if (digit >= base || digit > floor((maxInt - i) / w)) {
					error('overflow');
				}

				i += digit * w;
				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);

				if (digit < t) {
					break;
				}

				baseMinusT = base - t;
				if (w > floor(maxInt / baseMinusT)) {
					error('overflow');
				}

				w *= baseMinusT;

			}

			out = output.length + 1;
			bias = adapt(i - oldi, out, oldi == 0);

			// `i` was supposed to wrap around from `out` to `0`,
			// incrementing `n` each time, so we'll fix that now:
			if (floor(i / out) > maxInt - n) {
				error('overflow');
			}

			n += floor(i / out);
			i %= out;

			// Insert `n` at position `i` of the output
			output.splice(i++, 0, n);

		}

		return ucs2encode(output);
	}

	/**
	 * Converts a string of Unicode symbols (e.g. a domain name label) to a
	 * Punycode string of ASCII-only symbols.
	 * @memberOf punycode
	 * @param {String} input The string of Unicode symbols.
	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
	 */
	function encode(input) {
		var n,
		    delta,
		    handledCPCount,
		    basicLength,
		    bias,
		    j,
		    m,
		    q,
		    k,
		    t,
		    currentValue,
		    output = [],
		    /** `inputLength` will hold the number of code points in `input`. */
		    inputLength,
		    /** Cached calculation results */
		    handledCPCountPlusOne,
		    baseMinusT,
		    qMinusT;

		// Convert the input in UCS-2 to Unicode
		input = ucs2decode(input);

		// Cache the length
		inputLength = input.length;

		// Initialize the state
		n = initialN;
		delta = 0;
		bias = initialBias;

		// Handle the basic code points
		for (j = 0; j < inputLength; ++j) {
			currentValue = input[j];
			if (currentValue < 0x80) {
				output.push(stringFromCharCode(currentValue));
			}
		}

		handledCPCount = basicLength = output.length;

		// `handledCPCount` is the number of code points that have been handled;
		// `basicLength` is the number of basic code points.

		// Finish the basic string - if it is not empty - with a delimiter
		if (basicLength) {
			output.push(delimiter);
		}

		// Main encoding loop:
		while (handledCPCount < inputLength) {

			// All non-basic code points < n have been handled already. Find the next
			// larger one:
			for (m = maxInt, j = 0; j < inputLength; ++j) {
				currentValue = input[j];
				if (currentValue >= n && currentValue < m) {
					m = currentValue;
				}
			}

			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
			// but guard against overflow
			handledCPCountPlusOne = handledCPCount + 1;
			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
				error('overflow');
			}

			delta += (m - n) * handledCPCountPlusOne;
			n = m;

			for (j = 0; j < inputLength; ++j) {
				currentValue = input[j];

				if (currentValue < n && ++delta > maxInt) {
					error('overflow');
				}

				if (currentValue == n) {
					// Represent delta as a generalized variable-length integer
					for (q = delta, k = base; /* no condition */; k += base) {
						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
						if (q < t) {
							break;
						}
						qMinusT = q - t;
						baseMinusT = base - t;
						output.push(
							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
						);
						q = floor(qMinusT / baseMinusT);
					}

					output.push(stringFromCharCode(digitToBasic(q, 0)));
					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
					delta = 0;
					++handledCPCount;
				}
			}

			++delta;
			++n;

		}
		return output.join('');
	}

	/**
	 * Converts a Punycode string representing a domain name or an email address
	 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
	 * it doesn't matter if you call it on a string that has already been
	 * converted to Unicode.
	 * @memberOf punycode
	 * @param {String} input The Punycoded domain name or email address to
	 * convert to Unicode.
	 * @returns {String} The Unicode representation of the given Punycode
	 * string.
	 */
	function toUnicode(input) {
		return mapDomain(input, function(string) {
			return regexPunycode.test(string)
				? decode(string.slice(4).toLowerCase())
				: string;
		});
	}

	/**
	 * Converts a Unicode string representing a domain name or an email address to
	 * Punycode. Only the non-ASCII parts of the domain name will be converted,
	 * i.e. it doesn't matter if you call it with a domain that's already in
	 * ASCII.
	 * @memberOf punycode
	 * @param {String} input The domain name or email address to convert, as a
	 * Unicode string.
	 * @returns {String} The Punycode representation of the given domain name or
	 * email address.
	 */
	function toASCII(input) {
		return mapDomain(input, function(string) {
			return regexNonASCII.test(string)
				? 'xn--' + encode(string)
				: string;
		});
	}

	/*--------------------------------------------------------------------------*/

	/** Define the public API */
	punycode = {
		/**
		 * A string representing the current Punycode.js version number.
		 * @memberOf punycode
		 * @type String
		 */
		'version': '1.4.1',
		/**
		 * An object of methods to convert from JavaScript's internal character
		 * representation (UCS-2) to Unicode code points, and back.
		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
		 * @memberOf punycode
		 * @type Object
		 */
		'ucs2': {
			'decode': ucs2decode,
			'encode': ucs2encode
		},
		'decode': decode,
		'encode': encode,
		'toASCII': toASCII,
		'toUnicode': toUnicode
	};

	/** Expose `punycode` */
	// Some AMD build optimizers, like r.js, check for specific condition patterns
	// like the following:
	if (
		typeof define == 'function' &&
		typeof define.amd == 'object' &&
		define.amd
	) {
		define('punycode', function() {
			return punycode;
		});
	} else if (freeExports && freeModule) {
		if (module.exports == freeExports) {
			// in Node.js, io.js, or RingoJS v0.8.0+
			freeModule.exports = punycode;
		} else {
			// in Narwhal or RingoJS v0.7.0-
			for (key in punycode) {
				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
			}
		}
	} else {
		// in Rhino or a web browser
		root.punycode = punycode;
	}

}(this));

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{}],8:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

// If obj.hasOwnProperty has been overridden, then calling
// obj.hasOwnProperty(prop) will break.
// See: https://github.com/joyent/node/issues/1707
function hasOwnProperty(obj, prop) {
  return Object.prototype.hasOwnProperty.call(obj, prop);
}

module.exports = function(qs, sep, eq, options) {
  sep = sep || '&';
  eq = eq || '=';
  var obj = {};

  if (typeof qs !== 'string' || qs.length === 0) {
    return obj;
  }

  var regexp = /\+/g;
  qs = qs.split(sep);

  var maxKeys = 1000;
  if (options && typeof options.maxKeys === 'number') {
    maxKeys = options.maxKeys;
  }

  var len = qs.length;
  // maxKeys <= 0 means that we should not limit keys count
  if (maxKeys > 0 && len > maxKeys) {
    len = maxKeys;
  }

  for (var i = 0; i < len; ++i) {
    var x = qs[i].replace(regexp, '%20'),
        idx = x.indexOf(eq),
        kstr, vstr, k, v;

    if (idx >= 0) {
      kstr = x.substr(0, idx);
      vstr = x.substr(idx + 1);
    } else {
      kstr = x;
      vstr = '';
    }

    k = decodeURIComponent(kstr);
    v = decodeURIComponent(vstr);

    if (!hasOwnProperty(obj, k)) {
      obj[k] = v;
    } else if (isArray(obj[k])) {
      obj[k].push(v);
    } else {
      obj[k] = [obj[k], v];
    }
  }

  return obj;
};

var isArray = Array.isArray || function (xs) {
  return Object.prototype.toString.call(xs) === '[object Array]';
};

},{}],9:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

var stringifyPrimitive = function(v) {
  switch (typeof v) {
    case 'string':
      return v;

    case 'boolean':
      return v ? 'true' : 'false';

    case 'number':
      return isFinite(v) ? v : '';

    default:
      return '';
  }
};

module.exports = function(obj, sep, eq, name) {
  sep = sep || '&';
  eq = eq || '=';
  if (obj === null) {
    obj = undefined;
  }

  if (typeof obj === 'object') {
    return map(objectKeys(obj), function(k) {
      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
      if (isArray(obj[k])) {
        return map(obj[k], function(v) {
          return ks + encodeURIComponent(stringifyPrimitive(v));
        }).join(sep);
      } else {
        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
      }
    }).join(sep);

  }

  if (!name) return '';
  return encodeURIComponent(stringifyPrimitive(name)) + eq +
         encodeURIComponent(stringifyPrimitive(obj));
};

var isArray = Array.isArray || function (xs) {
  return Object.prototype.toString.call(xs) === '[object Array]';
};

function map (xs, f) {
  if (xs.map) return xs.map(f);
  var res = [];
  for (var i = 0; i < xs.length; i++) {
    res.push(f(xs[i], i));
  }
  return res;
}

var objectKeys = Object.keys || function (obj) {
  var res = [];
  for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
  }
  return res;
};

},{}],10:[function(require,module,exports){
'use strict';

exports.decode = exports.parse = require('./decode');
exports.encode = exports.stringify = require('./encode');

},{"./decode":8,"./encode":9}],11:[function(require,module,exports){
(function (setImmediate,clearImmediate){
var nextTick = require('process/browser.js').nextTick;
var apply = Function.prototype.apply;
var slice = Array.prototype.slice;
var immediateIds = {};
var nextImmediateId = 0;

// DOM APIs, for completeness

exports.setTimeout = function() {
  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
};
exports.setInterval = function() {
  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
};
exports.clearTimeout =
exports.clearInterval = function(timeout) { timeout.close(); };

function Timeout(id, clearFn) {
  this._id = id;
  this._clearFn = clearFn;
}
Timeout.prototype.unref = Timeout.prototype.ref = function() {};
Timeout.prototype.close = function() {
  this._clearFn.call(window, this._id);
};

// Does not start the time, just sets up the members needed.
exports.enroll = function(item, msecs) {
  clearTimeout(item._idleTimeoutId);
  item._idleTimeout = msecs;
};

exports.unenroll = function(item) {
  clearTimeout(item._idleTimeoutId);
  item._idleTimeout = -1;
};

exports._unrefActive = exports.active = function(item) {
  clearTimeout(item._idleTimeoutId);

  var msecs = item._idleTimeout;
  if (msecs >= 0) {
    item._idleTimeoutId = setTimeout(function onTimeout() {
      if (item._onTimeout)
        item._onTimeout();
    }, msecs);
  }
};

// That's not how node.js implements it but the exposed api is the same.
exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) {
  var id = nextImmediateId++;
  var args = arguments.length < 2 ? false : slice.call(arguments, 1);

  immediateIds[id] = true;

  nextTick(function onNextTick() {
    if (immediateIds[id]) {
      // fn.call() is faster so we optimize for the common use-case
      // @see http://jsperf.com/call-apply-segu
      if (args) {
        fn.apply(null, args);
      } else {
        fn.call(null);
      }
      // Prevent ids from leaking
      exports.clearImmediate(id);
    }
  });

  return id;
};

exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) {
  delete immediateIds[id];
};
}).call(this,require("timers").setImmediate,require("timers").clearImmediate)
},{"process/browser.js":6,"timers":11}],12:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

'use strict';

var punycode = require('punycode');
var util = require('./util');

exports.parse = urlParse;
exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;

exports.Url = Url;

function Url() {
  this.protocol = null;
  this.slashes = null;
  this.auth = null;
  this.host = null;
  this.port = null;
  this.hostname = null;
  this.hash = null;
  this.search = null;
  this.query = null;
  this.pathname = null;
  this.path = null;
  this.href = null;
}

// Reference: RFC 3986, RFC 1808, RFC 2396

// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9.+-]+:)/i,
    portPattern = /:[0-9]*$/,

    // Special case for a simple path URL
    simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,

    // RFC 2396: characters reserved for delimiting URLs.
    // We actually just auto-escape these.
    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],

    // RFC 2396: characters not allowed for various reasons.
    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),

    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
    autoEscape = ['\''].concat(unwise),
    // Characters that are never ever allowed in a hostname.
    // Note that any invalid chars are also handled, but these
    // are the ones that are *expected* to be seen, so we fast-path
    // them.
    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
    hostEndingChars = ['/', '?', '#'],
    hostnameMaxLen = 255,
    hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
    hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
    // protocols that can allow "unsafe" and "unwise" chars.
    unsafeProtocol = {
      'javascript': true,
      'javascript:': true
    },
    // protocols that never have a hostname.
    hostlessProtocol = {
      'javascript': true,
      'javascript:': true
    },
    // protocols that always contain a // bit.
    slashedProtocol = {
      'http': true,
      'https': true,
      'ftp': true,
      'gopher': true,
      'file': true,
      'http:': true,
      'https:': true,
      'ftp:': true,
      'gopher:': true,
      'file:': true
    },
    querystring = require('querystring');

function urlParse(url, parseQueryString, slashesDenoteHost) {
  if (url && util.isObject(url) && url instanceof Url) return url;

  var u = new Url;
  u.parse(url, parseQueryString, slashesDenoteHost);
  return u;
}

Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
  if (!util.isString(url)) {
    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
  }

  // Copy chrome, IE, opera backslash-handling behavior.
  // Back slashes before the query string get converted to forward slashes
  // See: https://code.google.com/p/chromium/issues/detail?id=25916
  var queryIndex = url.indexOf('?'),
      splitter =
          (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
      uSplit = url.split(splitter),
      slashRegex = /\\/g;
  uSplit[0] = uSplit[0].replace(slashRegex, '/');
  url = uSplit.join(splitter);

  var rest = url;

  // trim before proceeding.
  // This is to support parse stuff like "  http://foo.com  \n"
  rest = rest.trim();

  if (!slashesDenoteHost && url.split('#').length === 1) {
    // Try fast path regexp
    var simplePath = simplePathPattern.exec(rest);
    if (simplePath) {
      this.path = rest;
      this.href = rest;
      this.pathname = simplePath[1];
      if (simplePath[2]) {
        this.search = simplePath[2];
        if (parseQueryString) {
          this.query = querystring.parse(this.search.substr(1));
        } else {
          this.query = this.search.substr(1);
        }
      } else if (parseQueryString) {
        this.search = '';
        this.query = {};
      }
      return this;
    }
  }

  var proto = protocolPattern.exec(rest);
  if (proto) {
    proto = proto[0];
    var lowerProto = proto.toLowerCase();
    this.protocol = lowerProto;
    rest = rest.substr(proto.length);
  }

  // figure out if it's got a host
  // user@server is *always* interpreted as a hostname, and url
  // resolution will treat //foo/bar as host=foo,path=bar because that's
  // how the browser resolves relative URLs.
  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
    var slashes = rest.substr(0, 2) === '//';
    if (slashes && !(proto && hostlessProtocol[proto])) {
      rest = rest.substr(2);
      this.slashes = true;
    }
  }

  if (!hostlessProtocol[proto] &&
      (slashes || (proto && !slashedProtocol[proto]))) {

    // there's a hostname.
    // the first instance of /, ?, ;, or # ends the host.
    //
    // If there is an @ in the hostname, then non-host chars *are* allowed
    // to the left of the last @ sign, unless some host-ending character
    // comes *before* the @-sign.
    // URLs are obnoxious.
    //
    // ex:
    // http://a@b@c/ => user:a@b host:c
    // http://a@b?@c => user:a host:c path:/?@c

    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
    // Review our test case against browsers more comprehensively.

    // find the first instance of any hostEndingChars
    var hostEnd = -1;
    for (var i = 0; i < hostEndingChars.length; i++) {
      var hec = rest.indexOf(hostEndingChars[i]);
      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
        hostEnd = hec;
    }

    // at this point, either we have an explicit point where the
    // auth portion cannot go past, or the last @ char is the decider.
    var auth, atSign;
    if (hostEnd === -1) {
      // atSign can be anywhere.
      atSign = rest.lastIndexOf('@');
    } else {
      // atSign must be in auth portion.
      // http://a@b/c@d => host:b auth:a path:/c@d
      atSign = rest.lastIndexOf('@', hostEnd);
    }

    // Now we have a portion which is definitely the auth.
    // Pull that off.
    if (atSign !== -1) {
      auth = rest.slice(0, atSign);
      rest = rest.slice(atSign + 1);
      this.auth = decodeURIComponent(auth);
    }

    // the host is the remaining to the left of the first non-host char
    hostEnd = -1;
    for (var i = 0; i < nonHostChars.length; i++) {
      var hec = rest.indexOf(nonHostChars[i]);
      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
        hostEnd = hec;
    }
    // if we still have not hit it, then the entire thing is a host.
    if (hostEnd === -1)
      hostEnd = rest.length;

    this.host = rest.slice(0, hostEnd);
    rest = rest.slice(hostEnd);

    // pull out port.
    this.parseHost();

    // we've indicated that there is a hostname,
    // so even if it's empty, it has to be present.
    this.hostname = this.hostname || '';

    // if hostname begins with [ and ends with ]
    // assume that it's an IPv6 address.
    var ipv6Hostname = this.hostname[0] === '[' &&
        this.hostname[this.hostname.length - 1] === ']';

    // validate a little.
    if (!ipv6Hostname) {
      var hostparts = this.hostname.split(/\./);
      for (var i = 0, l = hostparts.length; i < l; i++) {
        var part = hostparts[i];
        if (!part) continue;
        if (!part.match(hostnamePartPattern)) {
          var newpart = '';
          for (var j = 0, k = part.length; j < k; j++) {
            if (part.charCodeAt(j) > 127) {
              // we replace non-ASCII char with a temporary placeholder
              // we need this to make sure size of hostname is not
              // broken by replacing non-ASCII by nothing
              newpart += 'x';
            } else {
              newpart += part[j];
            }
          }
          // we test again with ASCII char only
          if (!newpart.match(hostnamePartPattern)) {
            var validParts = hostparts.slice(0, i);
            var notHost = hostparts.slice(i + 1);
            var bit = part.match(hostnamePartStart);
            if (bit) {
              validParts.push(bit[1]);
              notHost.unshift(bit[2]);
            }
            if (notHost.length) {
              rest = '/' + notHost.join('.') + rest;
            }
            this.hostname = validParts.join('.');
            break;
          }
        }
      }
    }

    if (this.hostname.length > hostnameMaxLen) {
      this.hostname = '';
    } else {
      // hostnames are always lower case.
      this.hostname = this.hostname.toLowerCase();
    }

    if (!ipv6Hostname) {
      // IDNA Support: Returns a punycoded representation of "domain".
      // It only converts parts of the domain name that
      // have non-ASCII characters, i.e. it doesn't matter if
      // you call it with a domain that already is ASCII-only.
      this.hostname = punycode.toASCII(this.hostname);
    }

    var p = this.port ? ':' + this.port : '';
    var h = this.hostname || '';
    this.host = h + p;
    this.href += this.host;

    // strip [ and ] from the hostname
    // the host field still retains them, though
    if (ipv6Hostname) {
      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
      if (rest[0] !== '/') {
        rest = '/' + rest;
      }
    }
  }

  // now rest is set to the post-host stuff.
  // chop off any delim chars.
  if (!unsafeProtocol[lowerProto]) {

    // First, make 100% sure that any "autoEscape" chars get
    // escaped, even if encodeURIComponent doesn't think they
    // need to be.
    for (var i = 0, l = autoEscape.length; i < l; i++) {
      var ae = autoEscape[i];
      if (rest.indexOf(ae) === -1)
        continue;
      var esc = encodeURIComponent(ae);
      if (esc === ae) {
        esc = escape(ae);
      }
      rest = rest.split(ae).join(esc);
    }
  }


  // chop off from the tail first.
  var hash = rest.indexOf('#');
  if (hash !== -1) {
    // got a fragment string.
    this.hash = rest.substr(hash);
    rest = rest.slice(0, hash);
  }
  var qm = rest.indexOf('?');
  if (qm !== -1) {
    this.search = rest.substr(qm);
    this.query = rest.substr(qm + 1);
    if (parseQueryString) {
      this.query = querystring.parse(this.query);
    }
    rest = rest.slice(0, qm);
  } else if (parseQueryString) {
    // no query string, but parseQueryString still requested
    this.search = '';
    this.query = {};
  }
  if (rest) this.pathname = rest;
  if (slashedProtocol[lowerProto] &&
      this.hostname && !this.pathname) {
    this.pathname = '/';
  }

  //to support http.request
  if (this.pathname || this.search) {
    var p = this.pathname || '';
    var s = this.search || '';
    this.path = p + s;
  }

  // finally, reconstruct the href based on what has been validated.
  this.href = this.format();
  return this;
};

// format a parsed object into a url string
function urlFormat(obj) {
  // ensure it's an object, and not a string url.
  // If it's an obj, this is a no-op.
  // this way, you can call url_format() on strings
  // to clean up potentially wonky urls.
  if (util.isString(obj)) obj = urlParse(obj);
  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
  return obj.format();
}

Url.prototype.format = function() {
  var auth = this.auth || '';
  if (auth) {
    auth = encodeURIComponent(auth);
    auth = auth.replace(/%3A/i, ':');
    auth += '@';
  }

  var protocol = this.protocol || '',
      pathname = this.pathname || '',
      hash = this.hash || '',
      host = false,
      query = '';

  if (this.host) {
    host = auth + this.host;
  } else if (this.hostname) {
    host = auth + (this.hostname.indexOf(':') === -1 ?
        this.hostname :
        '[' + this.hostname + ']');
    if (this.port) {
      host += ':' + this.port;
    }
  }

  if (this.query &&
      util.isObject(this.query) &&
      Object.keys(this.query).length) {
    query = querystring.stringify(this.query);
  }

  var search = this.search || (query && ('?' + query)) || '';

  if (protocol && protocol.substr(-1) !== ':') protocol += ':';

  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
  // unless they had them to begin with.
  if (this.slashes ||
      (!protocol || slashedProtocol[protocol]) && host !== false) {
    host = '//' + (host || '');
    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
  } else if (!host) {
    host = '';
  }

  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
  if (search && search.charAt(0) !== '?') search = '?' + search;

  pathname = pathname.replace(/[?#]/g, function(match) {
    return encodeURIComponent(match);
  });
  search = search.replace('#', '%23');

  return protocol + host + pathname + search + hash;
};

function urlResolve(source, relative) {
  return urlParse(source, false, true).resolve(relative);
}

Url.prototype.resolve = function(relative) {
  return this.resolveObject(urlParse(relative, false, true)).format();
};

function urlResolveObject(source, relative) {
  if (!source) return relative;
  return urlParse(source, false, true).resolveObject(relative);
}

Url.prototype.resolveObject = function(relative) {
  if (util.isString(relative)) {
    var rel = new Url();
    rel.parse(relative, false, true);
    relative = rel;
  }

  var result = new Url();
  var tkeys = Object.keys(this);
  for (var tk = 0; tk < tkeys.length; tk++) {
    var tkey = tkeys[tk];
    result[tkey] = this[tkey];
  }

  // hash is always overridden, no matter what.
  // even href="" will remove it.
  result.hash = relative.hash;

  // if the relative url is empty, then there's nothing left to do here.
  if (relative.href === '') {
    result.href = result.format();
    return result;
  }

  // hrefs like //foo/bar always cut to the protocol.
  if (relative.slashes && !relative.protocol) {
    // take everything except the protocol from relative
    var rkeys = Object.keys(relative);
    for (var rk = 0; rk < rkeys.length; rk++) {
      var rkey = rkeys[rk];
      if (rkey !== 'protocol')
        result[rkey] = relative[rkey];
    }

    //urlParse appends trailing / to urls like http://www.example.com
    if (slashedProtocol[result.protocol] &&
        result.hostname && !result.pathname) {
      result.path = result.pathname = '/';
    }

    result.href = result.format();
    return result;
  }

  if (relative.protocol && relative.protocol !== result.protocol) {
    // if it's a known url protocol, then changing
    // the protocol does weird things
    // first, if it's not file:, then we MUST have a host,
    // and if there was a path
    // to begin with, then we MUST have a path.
    // if it is file:, then the host is dropped,
    // because that's known to be hostless.
    // anything else is assumed to be absolute.
    if (!slashedProtocol[relative.protocol]) {
      var keys = Object.keys(relative);
      for (var v = 0; v < keys.length; v++) {
        var k = keys[v];
        result[k] = relative[k];
      }
      result.href = result.format();
      return result;
    }

    result.protocol = relative.protocol;
    if (!relative.host && !hostlessProtocol[relative.protocol]) {
      var relPath = (relative.pathname || '').split('/');
      while (relPath.length && !(relative.host = relPath.shift()));
      if (!relative.host) relative.host = '';
      if (!relative.hostname) relative.hostname = '';
      if (relPath[0] !== '') relPath.unshift('');
      if (relPath.length < 2) relPath.unshift('');
      result.pathname = relPath.join('/');
    } else {
      result.pathname = relative.pathname;
    }
    result.search = relative.search;
    result.query = relative.query;
    result.host = relative.host || '';
    result.auth = relative.auth;
    result.hostname = relative.hostname || relative.host;
    result.port = relative.port;
    // to support http.request
    if (result.pathname || result.search) {
      var p = result.pathname || '';
      var s = result.search || '';
      result.path = p + s;
    }
    result.slashes = result.slashes || relative.slashes;
    result.href = result.format();
    return result;
  }

  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
      isRelAbs = (
          relative.host ||
          relative.pathname && relative.pathname.charAt(0) === '/'
      ),
      mustEndAbs = (isRelAbs || isSourceAbs ||
                    (result.host && relative.pathname)),
      removeAllDots = mustEndAbs,
      srcPath = result.pathname && result.pathname.split('/') || [],
      relPath = relative.pathname && relative.pathname.split('/') || [],
      psychotic = result.protocol && !slashedProtocol[result.protocol];

  // if the url is a non-slashed url, then relative
  // links like ../.. should be able
  // to crawl up to the hostname, as well.  This is strange.
  // result.protocol has already been set by now.
  // Later on, put the first path part into the host field.
  if (psychotic) {
    result.hostname = '';
    result.port = null;
    if (result.host) {
      if (srcPath[0] === '') srcPath[0] = result.host;
      else srcPath.unshift(result.host);
    }
    result.host = '';
    if (relative.protocol) {
      relative.hostname = null;
      relative.port = null;
      if (relative.host) {
        if (relPath[0] === '') relPath[0] = relative.host;
        else relPath.unshift(relative.host);
      }
      relative.host = null;
    }
    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
  }

  if (isRelAbs) {
    // it's absolute.
    result.host = (relative.host || relative.host === '') ?
                  relative.host : result.host;
    result.hostname = (relative.hostname || relative.hostname === '') ?
                      relative.hostname : result.hostname;
    result.search = relative.search;
    result.query = relative.query;
    srcPath = relPath;
    // fall through to the dot-handling below.
  } else if (relPath.length) {
    // it's relative
    // throw away the existing file, and take the new path instead.
    if (!srcPath) srcPath = [];
    srcPath.pop();
    srcPath = srcPath.concat(relPath);
    result.search = relative.search;
    result.query = relative.query;
  } else if (!util.isNullOrUndefined(relative.search)) {
    // just pull out the search.
    // like href='?foo'.
    // Put this after the other two cases because it simplifies the booleans
    if (psychotic) {
      result.hostname = result.host = srcPath.shift();
      //occationaly the auth can get stuck only in host
      //this especially happens in cases like
      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
      var authInHost = result.host && result.host.indexOf('@') > 0 ?
                       result.host.split('@') : false;
      if (authInHost) {
        result.auth = authInHost.shift();
        result.host = result.hostname = authInHost.shift();
      }
    }
    result.search = relative.search;
    result.query = relative.query;
    //to support http.request
    if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
      result.path = (result.pathname ? result.pathname : '') +
                    (result.search ? result.search : '');
    }
    result.href = result.format();
    return result;
  }

  if (!srcPath.length) {
    // no path at all.  easy.
    // we've already handled the other stuff above.
    result.pathname = null;
    //to support http.request
    if (result.search) {
      result.path = '/' + result.search;
    } else {
      result.path = null;
    }
    result.href = result.format();
    return result;
  }

  // if a url ENDs in . or .., then it must get a trailing slash.
  // however, if it ends in anything else non-slashy,
  // then it must NOT get a trailing slash.
  var last = srcPath.slice(-1)[0];
  var hasTrailingSlash = (
      (result.host || relative.host || srcPath.length > 1) &&
      (last === '.' || last === '..') || last === '');

  // strip single dots, resolve double dots to parent dir
  // if the path tries to go above the root, `up` ends up > 0
  var up = 0;
  for (var i = srcPath.length; i >= 0; i--) {
    last = srcPath[i];
    if (last === '.') {
      srcPath.splice(i, 1);
    } else if (last === '..') {
      srcPath.splice(i, 1);
      up++;
    } else if (up) {
      srcPath.splice(i, 1);
      up--;
    }
  }

  // if the path is allowed to go above the root, restore leading ..s
  if (!mustEndAbs && !removeAllDots) {
    for (; up--; up) {
      srcPath.unshift('..');
    }
  }

  if (mustEndAbs && srcPath[0] !== '' &&
      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
    srcPath.unshift('');
  }

  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
    srcPath.push('');
  }

  var isAbsolute = srcPath[0] === '' ||
      (srcPath[0] && srcPath[0].charAt(0) === '/');

  // put the host back
  if (psychotic) {
    result.hostname = result.host = isAbsolute ? '' :
                                    srcPath.length ? srcPath.shift() : '';
    //occationaly the auth can get stuck only in host
    //this especially happens in cases like
    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
    var authInHost = result.host && result.host.indexOf('@') > 0 ?
                     result.host.split('@') : false;
    if (authInHost) {
      result.auth = authInHost.shift();
      result.host = result.hostname = authInHost.shift();
    }
  }

  mustEndAbs = mustEndAbs || (result.host && srcPath.length);

  if (mustEndAbs && !isAbsolute) {
    srcPath.unshift('');
  }

  if (!srcPath.length) {
    result.pathname = null;
    result.path = null;
  } else {
    result.pathname = srcPath.join('/');
  }

  //to support request.http
  if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
    result.path = (result.pathname ? result.pathname : '') +
                  (result.search ? result.search : '');
  }
  result.auth = relative.auth || result.auth;
  result.slashes = result.slashes || relative.slashes;
  result.href = result.format();
  return result;
};

Url.prototype.parseHost = function() {
  var host = this.host;
  var port = portPattern.exec(host);
  if (port) {
    port = port[0];
    if (port !== ':') {
      this.port = port.substr(1);
    }
    host = host.substr(0, host.length - port.length);
  }
  if (host) this.hostname = host;
};

},{"./util":13,"punycode":7,"querystring":10}],13:[function(require,module,exports){
'use strict';

module.exports = {
  isString: function(arg) {
    return typeof(arg) === 'string';
  },
  isObject: function(arg) {
    return typeof(arg) === 'object' && arg !== null;
  },
  isNull: function(arg) {
    return arg === null;
  },
  isNullOrUndefined: function(arg) {
    return arg == null;
  }
};

},{}],14:[function(require,module,exports){
//This is for browserify to build the required CSS module into something we can use in the browser. 
window.css = require('css');

},{"css":16}],15:[function(require,module,exports){
(function (Buffer){
(function (w) {
  "use strict";

  function findBest(atobNative) {
    // normal window
    if ('function' === typeof atobNative) { return atobNative; }


    // browserify (web worker)
    if ('function' === typeof Buffer) {
      return function atobBrowserify(a) {
        //!! Deliberately using an API that's deprecated in node.js because
        //!! this file is for browsers and we expect them to cope with it.
        //!! Discussion: github.com/node-browser-compat/atob/pull/9
        return new Buffer(a, 'base64').toString('binary');
      };
    }

    // ios web worker with base64js
    if ('object' === typeof w.base64js) {
      // bufferToBinaryString
      // https://git.coolaj86.com/coolaj86/unibabel.js/blob/master/index.js#L50
      return function atobWebWorker_iOS(a) {
        var buf = w.base64js.b64ToByteArray(a);
        return Array.prototype.map.call(buf, function (ch) {
          return String.fromCharCode(ch);
        }).join('');
      };
    }

		return function () {
			// ios web worker without base64js
			throw new Error("You're probably in an old browser or an iOS webworker." +
				" It might help to include beatgammit's base64-js.");
    };
  }

  var atobBest = findBest(w.atob);
  w.atob = atobBest;

  if ((typeof module === 'object') && module && module.exports) {
    module.exports = atobBest;
  }
}(window));

}).call(this,require("buffer").Buffer)
},{"buffer":3}],16:[function(require,module,exports){
exports.parse = require('./lib/parse');
exports.stringify = require('./lib/stringify');

},{"./lib/parse":17,"./lib/stringify":21}],17:[function(require,module,exports){
// http://www.w3.org/TR/CSS21/grammar.html
// https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g

module.exports = function(css, options){
  options = options || {};

  /**
   * Positional.
   */

  var lineno = 1;
  var column = 1;

  /**
   * Update lineno and column based on `str`.
   */

  function updatePosition(str) {
    var lines = str.match(/\n/g);
    if (lines) lineno += lines.length;
    var i = str.lastIndexOf('\n');
    column = ~i ? str.length - i : column + str.length;
  }

  /**
   * Mark position and patch `node.position`.
   */

  function position() {
    var start = { line: lineno, column: column };
    return function(node){
      node.position = new Position(start);
      whitespace();
      return node;
    };
  }

  /**
   * Store position information for a node
   */

  function Position(start) {
    this.start = start;
    this.end = { line: lineno, column: column };
    this.source = options.source;
  }

  /**
   * Non-enumerable source string
   */

  Position.prototype.content = css;

  /**
   * Error `msg`.
   */

  var errorsList = [];

  function error(msg) {
    var err = new Error(options.source + ':' + lineno + ':' + column + ': ' + msg);
    err.reason = msg;
    err.filename = options.source;
    err.line = lineno;
    err.column = column;
    err.source = css;

    if (options.silent) {
      errorsList.push(err);
    } else {
      throw err;
    }
  }

  /**
   * Parse stylesheet.
   */

  function stylesheet() {
    var rulesList = rules();

    return {
      type: 'stylesheet',
      stylesheet: {
        source: options.source,
        rules: rulesList,
        parsingErrors: errorsList
      }
    };
  }

  /**
   * Opening brace.
   */

  function open() {
    return match(/^{\s*/);
  }

  /**
   * Closing brace.
   */

  function close() {
    return match(/^}/);
  }

  /**
   * Parse ruleset.
   */

  function rules() {
    var node;
    var rules = [];
    whitespace();
    comments(rules);
    while (css.length && css.charAt(0) != '}' && (node = atrule() || rule())) {
      if (node !== false) {
        rules.push(node);
        comments(rules);
      }
    }
    return rules;
  }

  /**
   * Match `re` and return captures.
   */

  function match(re) {
    var m = re.exec(css);
    if (!m) return;
    var str = m[0];
    updatePosition(str);
    css = css.slice(str.length);
    return m;
  }

  /**
   * Parse whitespace.
   */

  function whitespace() {
    match(/^\s*/);
  }

  /**
   * Parse comments;
   */

  function comments(rules) {
    var c;
    rules = rules || [];
    while (c = comment()) {
      if (c !== false) {
        rules.push(c);
      }
    }
    return rules;
  }

  /**
   * Parse comment.
   */

  function comment() {
    var pos = position();
    if ('/' != css.charAt(0) || '*' != css.charAt(1)) return;

    var i = 2;
    while ("" != css.charAt(i) && ('*' != css.charAt(i) || '/' != css.charAt(i + 1))) ++i;
    i += 2;

    if ("" === css.charAt(i-1)) {
      return error('End of comment missing');
    }

    var str = css.slice(2, i - 2);
    column += 2;
    updatePosition(str);
    css = css.slice(i);
    column += 2;

    return pos({
      type: 'comment',
      comment: str
    });
  }

  /**
   * Parse selector.
   */

  function selector() {
    var m = match(/^([^{]+)/);
    if (!m) return;
    /* @fix Remove all comments from selectors
     * http://ostermiller.org/findcomment.html */
    return trim(m[0])
      .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
      .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
        return m.replace(/,/g, '\u200C');
      })
      .split(/\s*(?![^(]*\)),\s*/)
      .map(function(s) {
        return s.replace(/\u200C/g, ',');
      });
  }

  /**
   * Parse declaration.
   */

  function declaration() {
    var pos = position();

    // prop
    var prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
    if (!prop) return;
    prop = trim(prop[0]);

    // :
    if (!match(/^:\s*/)) return error("property missing ':'");

    // val
    var val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);

    var ret = pos({
      type: 'declaration',
      property: prop.replace(commentre, ''),
      value: val ? trim(val[0]).replace(commentre, '') : ''
    });

    // ;
    match(/^[;\s]*/);

    return ret;
  }

  /**
   * Parse declarations.
   */

  function declarations() {
    var decls = [];

    if (!open()) return error("missing '{'");
    comments(decls);

    // declarations
    var decl;
    while (decl = declaration()) {
      if (decl !== false) {
        decls.push(decl);
        comments(decls);
      }
    }

    if (!close()) return error("missing '}'");
    return decls;
  }

  /**
   * Parse keyframe.
   */

  function keyframe() {
    var m;
    var vals = [];
    var pos = position();

    while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
      vals.push(m[1]);
      match(/^,\s*/);
    }

    if (!vals.length) return;

    return pos({
      type: 'keyframe',
      values: vals,
      declarations: declarations()
    });
  }

  /**
   * Parse keyframes.
   */

  function atkeyframes() {
    var pos = position();
    var m = match(/^@([-\w]+)?keyframes\s*/);

    if (!m) return;
    var vendor = m[1];

    // identifier
    var m = match(/^([-\w]+)\s*/);
    if (!m) return error("@keyframes missing name");
    var name = m[1];

    if (!open()) return error("@keyframes missing '{'");

    var frame;
    var frames = comments();
    while (frame = keyframe()) {
      frames.push(frame);
      frames = frames.concat(comments());
    }

    if (!close()) return error("@keyframes missing '}'");

    return pos({
      type: 'keyframes',
      name: name,
      vendor: vendor,
      keyframes: frames
    });
  }

  /**
   * Parse supports.
   */

  function atsupports() {
    var pos = position();
    var m = match(/^@supports *([^{]+)/);

    if (!m) return;
    var supports = trim(m[1]);

    if (!open()) return error("@supports missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@supports missing '}'");

    return pos({
      type: 'supports',
      supports: supports,
      rules: style
    });
  }

  /**
   * Parse host.
   */

  function athost() {
    var pos = position();
    var m = match(/^@host\s*/);

    if (!m) return;

    if (!open()) return error("@host missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@host missing '}'");

    return pos({
      type: 'host',
      rules: style
    });
  }

  /**
   * Parse media.
   */

  function atmedia() {
    var pos = position();
    var m = match(/^@media *([^{]+)/);

    if (!m) return;
    var media = trim(m[1]);

    if (!open()) return error("@media missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@media missing '}'");

    return pos({
      type: 'media',
      media: media,
      rules: style
    });
  }


  /**
   * Parse custom-media.
   */

  function atcustommedia() {
    var pos = position();
    var m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
    if (!m) return;

    return pos({
      type: 'custom-media',
      name: trim(m[1]),
      media: trim(m[2])
    });
  }

  /**
   * Parse paged media.
   */

  function atpage() {
    var pos = position();
    var m = match(/^@page */);
    if (!m) return;

    var sel = selector() || [];

    if (!open()) return error("@page missing '{'");
    var decls = comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      decls = decls.concat(comments());
    }

    if (!close()) return error("@page missing '}'");

    return pos({
      type: 'page',
      selectors: sel,
      declarations: decls
    });
  }

  /**
   * Parse document.
   */

  function atdocument() {
    var pos = position();
    var m = match(/^@([-\w]+)?document *([^{]+)/);
    if (!m) return;

    var vendor = trim(m[1]);
    var doc = trim(m[2]);

    if (!open()) return error("@document missing '{'");

    var style = comments().concat(rules());

    if (!close()) return error("@document missing '}'");

    return pos({
      type: 'document',
      document: doc,
      vendor: vendor,
      rules: style
    });
  }

  /**
   * Parse font-face.
   */

  function atfontface() {
    var pos = position();
    var m = match(/^@font-face\s*/);
    if (!m) return;

    if (!open()) return error("@font-face missing '{'");
    var decls = comments();

    // declarations
    var decl;
    while (decl = declaration()) {
      decls.push(decl);
      decls = decls.concat(comments());
    }

    if (!close()) return error("@font-face missing '}'");

    return pos({
      type: 'font-face',
      declarations: decls
    });
  }

  /**
   * Parse import
   */

  var atimport = _compileAtrule('import');

  /**
   * Parse charset
   */

  var atcharset = _compileAtrule('charset');

  /**
   * Parse namespace
   */

  var atnamespace = _compileAtrule('namespace');

  /**
   * Parse non-block at-rules
   */


  function _compileAtrule(name) {
    var re = new RegExp('^@' + name + '\\s*([^;]+);');
    return function() {
      var pos = position();
      var m = match(re);
      if (!m) return;
      var ret = { type: name };
      ret[name] = m[1].trim();
      return pos(ret);
    }
  }

  /**
   * Parse at rule.
   */

  function atrule() {
    if (css[0] != '@') return;

    return atkeyframes()
      || atmedia()
      || atcustommedia()
      || atsupports()
      || atimport()
      || atcharset()
      || atnamespace()
      || atdocument()
      || atpage()
      || athost()
      || atfontface();
  }

  /**
   * Parse rule.
   */

  function rule() {
    var pos = position();
    var sel = selector();

    if (!sel) return error('selector missing');
    comments();

    return pos({
      type: 'rule',
      selectors: sel,
      declarations: declarations()
    });
  }

  return addParent(stylesheet());
};

/**
 * Trim `str`.
 */

function trim(str) {
  return str ? str.replace(/^\s+|\s+$/g, '') : '';
}

/**
 * Adds non-enumerable parent node reference to each node.
 */

function addParent(obj, parent) {
  var isNode = obj && typeof obj.type === 'string';
  var childParent = isNode ? obj : parent;

  for (var k in obj) {
    var value = obj[k];
    if (Array.isArray(value)) {
      value.forEach(function(v) { addParent(v, childParent); });
    } else if (value && typeof value === 'object') {
      addParent(value, childParent);
    }
  }

  if (isNode) {
    Object.defineProperty(obj, 'parent', {
      configurable: true,
      writable: true,
      enumerable: false,
      value: parent || null
    });
  }

  return obj;
}

},{}],18:[function(require,module,exports){

/**
 * Expose `Compiler`.
 */

module.exports = Compiler;

/**
 * Initialize a compiler.
 *
 * @param {Type} name
 * @return {Type}
 * @api public
 */

function Compiler(opts) {
  this.options = opts || {};
}

/**
 * Emit `str`
 */

Compiler.prototype.emit = function(str) {
  return str;
};

/**
 * Visit `node`.
 */

Compiler.prototype.visit = function(node){
  return this[node.type](node);
};

/**
 * Map visit over array of `nodes`, optionally using a `delim`
 */

Compiler.prototype.mapVisit = function(nodes, delim){
  var buf = '';
  delim = delim || '';

  for (var i = 0, length = nodes.length; i < length; i++) {
    buf += this.visit(nodes[i]);
    if (delim && i < length - 1) buf += this.emit(delim);
  }

  return buf;
};

},{}],19:[function(require,module,exports){

/**
 * Module dependencies.
 */

var Base = require('./compiler');
var inherits = require('inherits');

/**
 * Expose compiler.
 */

module.exports = Compiler;

/**
 * Initialize a new `Compiler`.
 */

function Compiler(options) {
  Base.call(this, options);
}

/**
 * Inherit from `Base.prototype`.
 */

inherits(Compiler, Base);

/**
 * Compile `node`.
 */

Compiler.prototype.compile = function(node){
  return node.stylesheet
    .rules.map(this.visit, this)
    .join('');
};

/**
 * Visit comment node.
 */

Compiler.prototype.comment = function(node){
  return this.emit('', node.position);
};

/**
 * Visit import node.
 */

Compiler.prototype.import = function(node){
  return this.emit('@import ' + node.import + ';', node.position);
};

/**
 * Visit media node.
 */

Compiler.prototype.media = function(node){
  return this.emit('@media ' + node.media, node.position)
    + this.emit('{')
    + this.mapVisit(node.rules)
    + this.emit('}');
};

/**
 * Visit document node.
 */

Compiler.prototype.document = function(node){
  var doc = '@' + (node.vendor || '') + 'document ' + node.document;

  return this.emit(doc, node.position)
    + this.emit('{')
    + this.mapVisit(node.rules)
    + this.emit('}');
};

/**
 * Visit charset node.
 */

Compiler.prototype.charset = function(node){
  return this.emit('@charset ' + node.charset + ';', node.position);
};

/**
 * Visit namespace node.
 */

Compiler.prototype.namespace = function(node){
  return this.emit('@namespace ' + node.namespace + ';', node.position);
};

/**
 * Visit supports node.
 */

Compiler.prototype.supports = function(node){
  return this.emit('@supports ' + node.supports, node.position)
    + this.emit('{')
    + this.mapVisit(node.rules)
    + this.emit('}');
};

/**
 * Visit keyframes node.
 */

Compiler.prototype.keyframes = function(node){
  return this.emit('@'
    + (node.vendor || '')
    + 'keyframes '
    + node.name, node.position)
    + this.emit('{')
    + this.mapVisit(node.keyframes)
    + this.emit('}');
};

/**
 * Visit keyframe node.
 */

Compiler.prototype.keyframe = function(node){
  var decls = node.declarations;

  return this.emit(node.values.join(','), node.position)
    + this.emit('{')
    + this.mapVisit(decls)
    + this.emit('}');
};

/**
 * Visit page node.
 */

Compiler.prototype.page = function(node){
  var sel = node.selectors.length
    ? node.selectors.join(', ')
    : '';

  return this.emit('@page ' + sel, node.position)
    + this.emit('{')
    + this.mapVisit(node.declarations)
    + this.emit('}');
};

/**
 * Visit font-face node.
 */

Compiler.prototype['font-face'] = function(node){
  return this.emit('@font-face', node.position)
    + this.emit('{')
    + this.mapVisit(node.declarations)
    + this.emit('}');
};

/**
 * Visit host node.
 */

Compiler.prototype.host = function(node){
  return this.emit('@host', node.position)
    + this.emit('{')
    + this.mapVisit(node.rules)
    + this.emit('}');
};

/**
 * Visit custom-media node.
 */

Compiler.prototype['custom-media'] = function(node){
  return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position);
};

/**
 * Visit rule node.
 */

Compiler.prototype.rule = function(node){
  var decls = node.declarations;
  if (!decls.length) return '';

  return this.emit(node.selectors.join(','), node.position)
    + this.emit('{')
    + this.mapVisit(decls)
    + this.emit('}');
};

/**
 * Visit declaration node.
 */

Compiler.prototype.declaration = function(node){
  return this.emit(node.property + ':' + node.value, node.position) + this.emit(';');
};


},{"./compiler":18,"inherits":24}],20:[function(require,module,exports){

/**
 * Module dependencies.
 */

var Base = require('./compiler');
var inherits = require('inherits');

/**
 * Expose compiler.
 */

module.exports = Compiler;

/**
 * Initialize a new `Compiler`.
 */

function Compiler(options) {
  options = options || {};
  Base.call(this, options);
  this.indentation = options.indent;
}

/**
 * Inherit from `Base.prototype`.
 */

inherits(Compiler, Base);

/**
 * Compile `node`.
 */

Compiler.prototype.compile = function(node){
  return this.stylesheet(node);
};

/**
 * Visit stylesheet node.
 */

Compiler.prototype.stylesheet = function(node){
  return this.mapVisit(node.stylesheet.rules, '\n\n');
};

/**
 * Visit comment node.
 */

Compiler.prototype.comment = function(node){
  return this.emit(this.indent() + '/*' + node.comment + '*/', node.position);
};

/**
 * Visit import node.
 */

Compiler.prototype.import = function(node){
  return this.emit('@import ' + node.import + ';', node.position);
};

/**
 * Visit media node.
 */

Compiler.prototype.media = function(node){
  return this.emit('@media ' + node.media, node.position)
    + this.emit(
        ' {\n'
        + this.indent(1))
    + this.mapVisit(node.rules, '\n\n')
    + this.emit(
        this.indent(-1)
        + '\n}');
};

/**
 * Visit document node.
 */

Compiler.prototype.document = function(node){
  var doc = '@' + (node.vendor || '') + 'document ' + node.document;

  return this.emit(doc, node.position)
    + this.emit(
        ' '
      + ' {\n'
      + this.indent(1))
    + this.mapVisit(node.rules, '\n\n')
    + this.emit(
        this.indent(-1)
        + '\n}');
};

/**
 * Visit charset node.
 */

Compiler.prototype.charset = function(node){
  return this.emit('@charset ' + node.charset + ';', node.position);
};

/**
 * Visit namespace node.
 */

Compiler.prototype.namespace = function(node){
  return this.emit('@namespace ' + node.namespace + ';', node.position);
};

/**
 * Visit supports node.
 */

Compiler.prototype.supports = function(node){
  return this.emit('@supports ' + node.supports, node.position)
    + this.emit(
      ' {\n'
      + this.indent(1))
    + this.mapVisit(node.rules, '\n\n')
    + this.emit(
        this.indent(-1)
        + '\n}');
};

/**
 * Visit keyframes node.
 */

Compiler.prototype.keyframes = function(node){
  return this.emit('@' + (node.vendor || '') + 'keyframes ' + node.name, node.position)
    + this.emit(
      ' {\n'
      + this.indent(1))
    + this.mapVisit(node.keyframes, '\n')
    + this.emit(
        this.indent(-1)
        + '}');
};

/**
 * Visit keyframe node.
 */

Compiler.prototype.keyframe = function(node){
  var decls = node.declarations;

  return this.emit(this.indent())
    + this.emit(node.values.join(', '), node.position)
    + this.emit(
      ' {\n'
      + this.indent(1))
    + this.mapVisit(decls, '\n')
    + this.emit(
      this.indent(-1)
      + '\n'
      + this.indent() + '}\n');
};

/**
 * Visit page node.
 */

Compiler.prototype.page = function(node){
  var sel = node.selectors.length
    ? node.selectors.join(', ') + ' '
    : '';

  return this.emit('@page ' + sel, node.position)
    + this.emit('{\n')
    + this.emit(this.indent(1))
    + this.mapVisit(node.declarations, '\n')
    + this.emit(this.indent(-1))
    + this.emit('\n}');
};

/**
 * Visit font-face node.
 */

Compiler.prototype['font-face'] = function(node){
  return this.emit('@font-face ', node.position)
    + this.emit('{\n')
    + this.emit(this.indent(1))
    + this.mapVisit(node.declarations, '\n')
    + this.emit(this.indent(-1))
    + this.emit('\n}');
};

/**
 * Visit host node.
 */

Compiler.prototype.host = function(node){
  return this.emit('@host', node.position)
    + this.emit(
        ' {\n'
        + this.indent(1))
    + this.mapVisit(node.rules, '\n\n')
    + this.emit(
        this.indent(-1)
        + '\n}');
};

/**
 * Visit custom-media node.
 */

Compiler.prototype['custom-media'] = function(node){
  return this.emit('@custom-media ' + node.name + ' ' + node.media + ';', node.position);
};

/**
 * Visit rule node.
 */

Compiler.prototype.rule = function(node){
  var indent = this.indent();
  var decls = node.declarations;
  if (!decls.length) return '';

  return this.emit(node.selectors.map(function(s){ return indent + s }).join(',\n'), node.position)
    + this.emit(' {\n')
    + this.emit(this.indent(1))
    + this.mapVisit(decls, '\n')
    + this.emit(this.indent(-1))
    + this.emit('\n' + this.indent() + '}');
};

/**
 * Visit declaration node.
 */

Compiler.prototype.declaration = function(node){
  return this.emit(this.indent())
    + this.emit(node.property + ': ' + node.value, node.position)
    + this.emit(';');
};

/**
 * Increase, decrease or return current indentation.
 */

Compiler.prototype.indent = function(level) {
  this.level = this.level || 1;

  if (null != level) {
    this.level += level;
    return '';
  }

  return Array(this.level).join(this.indentation || '  ');
};

},{"./compiler":18,"inherits":24}],21:[function(require,module,exports){

/**
 * Module dependencies.
 */

var Compressed = require('./compress');
var Identity = require('./identity');

/**
 * Stringfy the given AST `node`.
 *
 * Options:
 *
 *  - `compress` space-optimized output
 *  - `sourcemap` return an object with `.code` and `.map`
 *
 * @param {Object} node
 * @param {Object} [options]
 * @return {String}
 * @api public
 */

module.exports = function(node, options){
  options = options || {};

  var compiler = options.compress
    ? new Compressed(options)
    : new Identity(options);

  // source maps
  if (options.sourcemap) {
    var sourcemaps = require('./source-map-support');
    sourcemaps(compiler);

    var code = compiler.compile(node);
    compiler.applySourceMaps();

    var map = options.sourcemap === 'generator'
      ? compiler.map
      : compiler.map.toJSON();

    return { code: code, map: map };
  }

  var code = compiler.compile(node);
  return code;
};

},{"./compress":19,"./identity":20,"./source-map-support":22}],22:[function(require,module,exports){

/**
 * Module dependencies.
 */

var SourceMap = require('source-map').SourceMapGenerator;
var SourceMapConsumer = require('source-map').SourceMapConsumer;
var sourceMapResolve = require('source-map-resolve');
var fs = require('fs');
var path = require('path');

/**
 * Expose `mixin()`.
 */

module.exports = mixin;

/**
 * Ensure Windows-style paths are formatted properly
 */

const makeFriendlyPath = function(aPath) {
  return path.sep === "\\" ? aPath.replace(/\\/g, "/").replace(/^[a-z]:\/?/i, "/") : aPath;
}

/**
 * Mixin source map support into `compiler`.
 *
 * @param {Compiler} compiler
 * @api public
 */

function mixin(compiler) {
  compiler._comment = compiler.comment;
  compiler.map = new SourceMap();
  compiler.position = { line: 1, column: 1 };
  compiler.files = {};
  for (var k in exports) compiler[k] = exports[k];
}

/**
 * Update position.
 *
 * @param {String} str
 * @api private
 */

exports.updatePosition = function(str) {
  var lines = str.match(/\n/g);
  if (lines) this.position.line += lines.length;
  var i = str.lastIndexOf('\n');
  this.position.column = ~i ? str.length - i : this.position.column + str.length;
};

/**
 * Emit `str`.
 *
 * @param {String} str
 * @param {Object} [pos]
 * @return {String}
 * @api private
 */

exports.emit = function(str, pos) {
  if (pos) {
    var sourceFile = makeFriendlyPath(pos.source || 'source.css');

    this.map.addMapping({
      source: sourceFile,
      generated: {
        line: this.position.line,
        column: Math.max(this.position.column - 1, 0)
      },
      original: {
        line: pos.start.line,
        column: pos.start.column - 1
      }
    });

    this.addFile(sourceFile, pos);
  }

  this.updatePosition(str);

  return str;
};

/**
 * Adds a file to the source map output if it has not already been added
 * @param {String} file
 * @param {Object} pos
 */

exports.addFile = function(file, pos) {
  if (typeof pos.content !== 'string') return;
  if (Object.prototype.hasOwnProperty.call(this.files, file)) return;

  this.files[file] = pos.content;
};

/**
 * Applies any original source maps to the output and embeds the source file
 * contents in the source map.
 */

exports.applySourceMaps = function() {
  Object.keys(this.files).forEach(function(file) {
    var content = this.files[file];
    this.map.setSourceContent(file, content);

    if (this.options.inputSourcemaps !== false) {
      var originalMap = sourceMapResolve.resolveSync(
        content, file, fs.readFileSync);
      if (originalMap) {
        var map = new SourceMapConsumer(originalMap.map);
        var relativeTo = originalMap.sourcesRelativeTo;
        this.map.applySourceMap(map, file, makeFriendlyPath(path.dirname(relativeTo)));
      }
    }
  }, this);
};

/**
 * Process comments, drops sourceMap comments.
 * @param {Object} node
 */

exports.comment = function(node) {
  if (/^# sourceMappingURL=/.test(node.comment))
    return this.emit('', node.position);
  else
    return this._comment(node);
};

},{"fs":2,"path":5,"source-map":36,"source-map-resolve":25}],23:[function(require,module,exports){
'use strict';
var token = '%[a-f0-9]{2}';
var singleMatcher = new RegExp(token, 'gi');
var multiMatcher = new RegExp('(' + token + ')+', 'gi');

function decodeComponents(components, split) {
	try {
		// Try to decode the entire string first
		return decodeURIComponent(components.join(''));
	} catch (err) {
		// Do nothing
	}

	if (components.length === 1) {
		return components;
	}

	split = split || 1;

	// Split the array in 2 parts
	var left = components.slice(0, split);
	var right = components.slice(split);

	return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));
}

function decode(input) {
	try {
		return decodeURIComponent(input);
	} catch (err) {
		var tokens = input.match(singleMatcher);

		for (var i = 1; i < tokens.length; i++) {
			input = decodeComponents(tokens, i).join('');

			tokens = input.match(singleMatcher);
		}

		return input;
	}
}

function customDecodeURIComponent(input) {
	// Keep track of all the replacements and prefill the map with the `BOM`
	var replaceMap = {
		'%FE%FF': '\uFFFD\uFFFD',
		'%FF%FE': '\uFFFD\uFFFD'
	};

	var match = multiMatcher.exec(input);
	while (match) {
		try {
			// Decode as big chunks as possible
			replaceMap[match[0]] = decodeURIComponent(match[0]);
		} catch (err) {
			var result = decode(match[0]);

			if (result !== match[0]) {
				replaceMap[match[0]] = result;
			}
		}

		match = multiMatcher.exec(input);
	}

	// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else
	replaceMap['%C2'] = '\uFFFD';

	var entries = Object.keys(replaceMap);

	for (var i = 0; i < entries.length; i++) {
		// Replace all decoded components
		var key = entries[i];
		input = input.replace(new RegExp(key, 'g'), replaceMap[key]);
	}

	return input;
}

module.exports = function (encodedURI) {
	if (typeof encodedURI !== 'string') {
		throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');
	}

	try {
		encodedURI = encodedURI.replace(/\+/g, ' ');

		// Try the built in decoder first
		return decodeURIComponent(encodedURI);
	} catch (err) {
		// Fallback to a more advanced decoder
		return customDecodeURIComponent(encodedURI);
	}
};

},{}],24:[function(require,module,exports){
if (typeof Object.create === 'function') {
  // implementation from standard node.js 'util' module
  module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
      ctor.super_ = superCtor
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      })
    }
  };
} else {
  // old school shim for old browsers
  module.exports = function inherits(ctor, superCtor) {
    if (superCtor) {
      ctor.super_ = superCtor
      var TempCtor = function () {}
      TempCtor.prototype = superCtor.prototype
      ctor.prototype = new TempCtor()
      ctor.prototype.constructor = ctor
    }
  }
}

},{}],25:[function(require,module,exports){
(function (setImmediate){
var atob = require("atob")
var urlLib = require("url")
var pathLib = require("path")
var decodeUriComponentLib = require("decode-uri-component")



function resolveUrl(/* ...urls */) {
  return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) {
    return urlLib.resolve(resolved, nextUrl)
  })
}

function convertWindowsPath(aPath) {
  return pathLib.sep === "\\" ? aPath.replace(/\\/g, "/").replace(/^[a-z]:\/?/i, "/") : aPath
}

function customDecodeUriComponent(string) {
  // `decodeUriComponentLib` turns `+` into ` `, but that's not wanted.
  return decodeUriComponentLib(string.replace(/\+/g, "%2B"))
}

function callbackAsync(callback, error, result) {
  setImmediate(function() { callback(error, result) })
}

function parseMapToJSON(string, data) {
  try {
    return JSON.parse(string.replace(/^\)\]\}'/, ""))
  } catch (error) {
    error.sourceMapData = data
    throw error
  }
}

function readSync(read, url, data) {
  var readUrl = customDecodeUriComponent(url)
  try {
    return String(read(readUrl))
  } catch (error) {
    error.sourceMapData = data
    throw error
  }
}



var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/

var sourceMappingURLRegex = RegExp(
  "(?:" +
    "/\\*" +
    "(?:\\s*\r?\n(?://)?)?" +
    "(?:" + innerRegex.source + ")" +
    "\\s*" +
    "\\*/" +
    "|" +
    "//(?:" + innerRegex.source + ")" +
  ")" +
  "\\s*"
)

function getSourceMappingUrl(code) {
  var match = code.match(sourceMappingURLRegex)
  return match ? match[1] || match[2] || "" : null
}



function resolveSourceMap(code, codeUrl, read, callback) {
  var mapData
  try {
    mapData = resolveSourceMapHelper(code, codeUrl)
  } catch (error) {
    return callbackAsync(callback, error)
  }
  if (!mapData || mapData.map) {
    return callbackAsync(callback, null, mapData)
  }
  var readUrl = customDecodeUriComponent(mapData.url)
  read(readUrl, function(error, result) {
    if (error) {
      error.sourceMapData = mapData
      return callback(error)
    }
    mapData.map = String(result)
    try {
      mapData.map = parseMapToJSON(mapData.map, mapData)
    } catch (error) {
      return callback(error)
    }
    callback(null, mapData)
  })
}

function resolveSourceMapSync(code, codeUrl, read) {
  var mapData = resolveSourceMapHelper(code, codeUrl)
  if (!mapData || mapData.map) {
    return mapData
  }
  mapData.map = readSync(read, mapData.url, mapData)
  mapData.map = parseMapToJSON(mapData.map, mapData)
  return mapData
}

var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/

/**
 * The media type for JSON text is application/json.
 *
 * {@link https://tools.ietf.org/html/rfc8259#section-11 | IANA Considerations }
 *
 * `text/json` is non-standard media type
 */
var jsonMimeTypeRegex = /^(?:application|text)\/json$/

/**
 * JSON text exchanged between systems that are not part of a closed ecosystem
 * MUST be encoded using UTF-8.
 *
 * {@link https://tools.ietf.org/html/rfc8259#section-8.1 | Character Encoding}
 */
var jsonCharacterEncoding = "utf-8"

function base64ToBuf(b64) {
  var binStr = atob(b64)
  var len = binStr.length
  var arr = new Uint8Array(len)
  for (var i = 0; i < len; i++) {
    arr[i] = binStr.charCodeAt(i)
  }
  return arr
}

function decodeBase64String(b64) {
  if (typeof TextDecoder === "undefined" || typeof Uint8Array === "undefined") {
    return atob(b64)
  }
  var buf = base64ToBuf(b64);
  // Note: `decoder.decode` method will throw a `DOMException` with the
  // `"EncodingError"` value when an coding error is found.
  var decoder = new TextDecoder(jsonCharacterEncoding, {fatal: true})
  return decoder.decode(buf);
}

function resolveSourceMapHelper(code, codeUrl) {
  codeUrl = convertWindowsPath(codeUrl)

  var url = getSourceMappingUrl(code)
  if (!url) {
    return null
  }

  var dataUri = url.match(dataUriRegex)
  if (dataUri) {
    var mimeType = dataUri[1] || "text/plain"
    var lastParameter = dataUri[2] || ""
    var encoded = dataUri[3] || ""
    var data = {
      sourceMappingURL: url,
      url: null,
      sourcesRelativeTo: codeUrl,
      map: encoded
    }
    if (!jsonMimeTypeRegex.test(mimeType)) {
      var error = new Error("Unuseful data uri mime type: " + mimeType)
      error.sourceMapData = data
      throw error
    }
    try {
      data.map = parseMapToJSON(
        lastParameter === ";base64" ? decodeBase64String(encoded) : decodeURIComponent(encoded),
        data
      )
    } catch (error) {
      error.sourceMapData = data
      throw error
    }
    return data
  }

  var mapUrl = resolveUrl(codeUrl, url)
  return {
    sourceMappingURL: url,
    url: mapUrl,
    sourcesRelativeTo: mapUrl,
    map: null
  }
}



function resolveSources(map, mapUrl, read, options, callback) {
  if (typeof options === "function") {
    callback = options
    options = {}
  }
  var pending = map.sources ? map.sources.length : 0
  var result = {
    sourcesResolved: [],
    sourcesContent:  []
  }

  if (pending === 0) {
    callbackAsync(callback, null, result)
    return
  }

  var done = function() {
    pending--
    if (pending === 0) {
      callback(null, result)
    }
  }

  resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
    result.sourcesResolved[index] = fullUrl
    if (typeof sourceContent === "string") {
      result.sourcesContent[index] = sourceContent
      callbackAsync(done, null)
    } else {
      var readUrl = customDecodeUriComponent(fullUrl)
      read(readUrl, function(error, source) {
        result.sourcesContent[index] = error ? error : String(source)
        done()
      })
    }
  })
}

function resolveSourcesSync(map, mapUrl, read, options) {
  var result = {
    sourcesResolved: [],
    sourcesContent:  []
  }

  if (!map.sources || map.sources.length === 0) {
    return result
  }

  resolveSourcesHelper(map, mapUrl, options, function(fullUrl, sourceContent, index) {
    result.sourcesResolved[index] = fullUrl
    if (read !== null) {
      if (typeof sourceContent === "string") {
        result.sourcesContent[index] = sourceContent
      } else {
        var readUrl = customDecodeUriComponent(fullUrl)
        try {
          result.sourcesContent[index] = String(read(readUrl))
        } catch (error) {
          result.sourcesContent[index] = error
        }
      }
    }
  })

  return result
}

var endingSlash = /\/?$/

function resolveSourcesHelper(map, mapUrl, options, fn) {
  options = options || {}
  mapUrl = convertWindowsPath(mapUrl)
  var fullUrl
  var sourceContent
  var sourceRoot
  for (var index = 0, len = map.sources.length; index < len; index++) {
    sourceRoot = null
    if (typeof options.sourceRoot === "string") {
      sourceRoot = options.sourceRoot
    } else if (typeof map.sourceRoot === "string" && options.sourceRoot !== false) {
      sourceRoot = map.sourceRoot
    }
    // If the sourceRoot is the empty string, it is equivalent to not setting
    // the property at all.
    if (sourceRoot === null || sourceRoot === '') {
      fullUrl = resolveUrl(mapUrl, map.sources[index])
    } else {
      // Make sure that the sourceRoot ends with a slash, so that `/scripts/subdir` becomes
      // `/scripts/subdir/<source>`, not `/scripts/<source>`. Pointing to a file as source root
      // does not make sense.
      fullUrl = resolveUrl(mapUrl, sourceRoot.replace(endingSlash, "/"), map.sources[index])
    }
    sourceContent = (map.sourcesContent || [])[index]
    fn(fullUrl, sourceContent, index)
  }
}



function resolve(code, codeUrl, read, options, callback) {
  if (typeof options === "function") {
    callback = options
    options = {}
  }
  if (code === null) {
    var mapUrl = codeUrl
    var data = {
      sourceMappingURL: null,
      url: mapUrl,
      sourcesRelativeTo: mapUrl,
      map: null
    }
    var readUrl = customDecodeUriComponent(mapUrl)
    read(readUrl, function(error, result) {
      if (error) {
        error.sourceMapData = data
        return callback(error)
      }
      data.map = String(result)
      try {
        data.map = parseMapToJSON(data.map, data)
      } catch (error) {
        return callback(error)
      }
      _resolveSources(data)
    })
  } else {
    resolveSourceMap(code, codeUrl, read, function(error, mapData) {
      if (error) {
        return callback(error)
      }
      if (!mapData) {
        return callback(null, null)
      }
      _resolveSources(mapData)
    })
  }

  function _resolveSources(mapData) {
    resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) {
      if (error) {
        return callback(error)
      }
      mapData.sourcesResolved = result.sourcesResolved
      mapData.sourcesContent  = result.sourcesContent
      callback(null, mapData)
    })
  }
}

function resolveSync(code, codeUrl, read, options) {
  var mapData
  if (code === null) {
    var mapUrl = codeUrl
    mapData = {
      sourceMappingURL: null,
      url: mapUrl,
      sourcesRelativeTo: mapUrl,
      map: null
    }
    mapData.map = readSync(read, mapUrl, mapData)
    mapData.map = parseMapToJSON(mapData.map, mapData)
  } else {
    mapData = resolveSourceMapSync(code, codeUrl, read)
    if (!mapData) {
      return null
    }
  }
  var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options)
  mapData.sourcesResolved = result.sourcesResolved
  mapData.sourcesContent  = result.sourcesContent
  return mapData
}



module.exports = {
  resolveSourceMap:     resolveSourceMap,
  resolveSourceMapSync: resolveSourceMapSync,
  resolveSources:       resolveSources,
  resolveSourcesSync:   resolveSourcesSync,
  resolve:              resolve,
  resolveSync:          resolveSync,
  parseMapToJSON:       parseMapToJSON
}

}).call(this,require("timers").setImmediate)
},{"atob":15,"decode-uri-component":23,"path":5,"timers":11,"url":12}],26:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var util = require('./util');
var has = Object.prototype.hasOwnProperty;
var hasNativeMap = typeof Map !== "undefined";

/**
 * A data structure which is a combination of an array and a set. Adding a new
 * member is O(1), testing for membership is O(1), and finding the index of an
 * element is O(1). Removing elements from the set is not supported. Only
 * strings are supported for membership.
 */
function ArraySet() {
  this._array = [];
  this._set = hasNativeMap ? new Map() : Object.create(null);
}

/**
 * Static method for creating ArraySet instances from an existing array.
 */
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
  var set = new ArraySet();
  for (var i = 0, len = aArray.length; i < len; i++) {
    set.add(aArray[i], aAllowDuplicates);
  }
  return set;
};

/**
 * Return how many unique items are in this ArraySet. If duplicates have been
 * added, than those do not count towards the size.
 *
 * @returns Number
 */
ArraySet.prototype.size = function ArraySet_size() {
  return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
};

/**
 * Add the given string to this set.
 *
 * @param String aStr
 */
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
  var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
  var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
  var idx = this._array.length;
  if (!isDuplicate || aAllowDuplicates) {
    this._array.push(aStr);
  }
  if (!isDuplicate) {
    if (hasNativeMap) {
      this._set.set(aStr, idx);
    } else {
      this._set[sStr] = idx;
    }
  }
};

/**
 * Is the given string a member of this set?
 *
 * @param String aStr
 */
ArraySet.prototype.has = function ArraySet_has(aStr) {
  if (hasNativeMap) {
    return this._set.has(aStr);
  } else {
    var sStr = util.toSetString(aStr);
    return has.call(this._set, sStr);
  }
};

/**
 * What is the index of the given string in the array?
 *
 * @param String aStr
 */
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
  if (hasNativeMap) {
    var idx = this._set.get(aStr);
    if (idx >= 0) {
        return idx;
    }
  } else {
    var sStr = util.toSetString(aStr);
    if (has.call(this._set, sStr)) {
      return this._set[sStr];
    }
  }

  throw new Error('"' + aStr + '" is not in the set.');
};

/**
 * What is the element at the given index?
 *
 * @param Number aIdx
 */
ArraySet.prototype.at = function ArraySet_at(aIdx) {
  if (aIdx >= 0 && aIdx < this._array.length) {
    return this._array[aIdx];
  }
  throw new Error('No element indexed by ' + aIdx);
};

/**
 * Returns the array representation of this set (which has the proper indices
 * indicated by indexOf). Note that this is a copy of the internal array used
 * for storing the members so that no one can mess with internal state.
 */
ArraySet.prototype.toArray = function ArraySet_toArray() {
  return this._array.slice();
};

exports.ArraySet = ArraySet;

},{"./util":35}],27:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * Based on the Base 64 VLQ implementation in Closure Compiler:
 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
 *
 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *  * Neither the name of Google Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

var base64 = require('./base64');

// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
//   Continuation
//   |    Sign
//   |    |
//   V    V
//   101011

var VLQ_BASE_SHIFT = 5;

// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;

// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;

// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;

/**
 * Converts from a two-complement value to a value where the sign bit is
 * placed in the least significant bit.  For example, as decimals:
 *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
 *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
 */
function toVLQSigned(aValue) {
  return aValue < 0
    ? ((-aValue) << 1) + 1
    : (aValue << 1) + 0;
}

/**
 * Converts to a two-complement value from a value where the sign bit is
 * placed in the least significant bit.  For example, as decimals:
 *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
 *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
 */
function fromVLQSigned(aValue) {
  var isNegative = (aValue & 1) === 1;
  var shifted = aValue >> 1;
  return isNegative
    ? -shifted
    : shifted;
}

/**
 * Returns the base 64 VLQ encoded value.
 */
exports.encode = function base64VLQ_encode(aValue) {
  var encoded = "";
  var digit;

  var vlq = toVLQSigned(aValue);

  do {
    digit = vlq & VLQ_BASE_MASK;
    vlq >>>= VLQ_BASE_SHIFT;
    if (vlq > 0) {
      // There are still more digits in this value, so we must make sure the
      // continuation bit is marked.
      digit |= VLQ_CONTINUATION_BIT;
    }
    encoded += base64.encode(digit);
  } while (vlq > 0);

  return encoded;
};

/**
 * Decodes the next base 64 VLQ value from the given string and returns the
 * value and the rest of the string via the out parameter.
 */
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
  var strLen = aStr.length;
  var result = 0;
  var shift = 0;
  var continuation, digit;

  do {
    if (aIndex >= strLen) {
      throw new Error("Expected more digits in base 64 VLQ value.");
    }

    digit = base64.decode(aStr.charCodeAt(aIndex++));
    if (digit === -1) {
      throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
    }

    continuation = !!(digit & VLQ_CONTINUATION_BIT);
    digit &= VLQ_BASE_MASK;
    result = result + (digit << shift);
    shift += VLQ_BASE_SHIFT;
  } while (continuation);

  aOutParam.value = fromVLQSigned(result);
  aOutParam.rest = aIndex;
};

},{"./base64":28}],28:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');

/**
 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
 */
exports.encode = function (number) {
  if (0 <= number && number < intToCharMap.length) {
    return intToCharMap[number];
  }
  throw new TypeError("Must be between 0 and 63: " + number);
};

/**
 * Decode a single base 64 character code digit to an integer. Returns -1 on
 * failure.
 */
exports.decode = function (charCode) {
  var bigA = 65;     // 'A'
  var bigZ = 90;     // 'Z'

  var littleA = 97;  // 'a'
  var littleZ = 122; // 'z'

  var zero = 48;     // '0'
  var nine = 57;     // '9'

  var plus = 43;     // '+'
  var slash = 47;    // '/'

  var littleOffset = 26;
  var numberOffset = 52;

  // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  if (bigA <= charCode && charCode <= bigZ) {
    return (charCode - bigA);
  }

  // 26 - 51: abcdefghijklmnopqrstuvwxyz
  if (littleA <= charCode && charCode <= littleZ) {
    return (charCode - littleA + littleOffset);
  }

  // 52 - 61: 0123456789
  if (zero <= charCode && charCode <= nine) {
    return (charCode - zero + numberOffset);
  }

  // 62: +
  if (charCode == plus) {
    return 62;
  }

  // 63: /
  if (charCode == slash) {
    return 63;
  }

  // Invalid base64 digit.
  return -1;
};

},{}],29:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

exports.GREATEST_LOWER_BOUND = 1;
exports.LEAST_UPPER_BOUND = 2;

/**
 * Recursive implementation of binary search.
 *
 * @param aLow Indices here and lower do not contain the needle.
 * @param aHigh Indices here and higher do not contain the needle.
 * @param aNeedle The element being searched for.
 * @param aHaystack The non-empty array being searched.
 * @param aCompare Function which takes two elements and returns -1, 0, or 1.
 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 */
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
  // This function terminates when one of the following is true:
  //
  //   1. We find the exact element we are looking for.
  //
  //   2. We did not find the exact element, but we can return the index of
  //      the next-closest element.
  //
  //   3. We did not find the exact element, and there is no next-closest
  //      element than the one we are searching for, so we return -1.
  var mid = Math.floor((aHigh - aLow) / 2) + aLow;
  var cmp = aCompare(aNeedle, aHaystack[mid], true);
  if (cmp === 0) {
    // Found the element we are looking for.
    return mid;
  }
  else if (cmp > 0) {
    // Our needle is greater than aHaystack[mid].
    if (aHigh - mid > 1) {
      // The element is in the upper half.
      return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
    }

    // The exact needle element was not found in this haystack. Determine if
    // we are in termination case (3) or (2) and return the appropriate thing.
    if (aBias == exports.LEAST_UPPER_BOUND) {
      return aHigh < aHaystack.length ? aHigh : -1;
    } else {
      return mid;
    }
  }
  else {
    // Our needle is less than aHaystack[mid].
    if (mid - aLow > 1) {
      // The element is in the lower half.
      return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
    }

    // we are in termination case (3) or (2) and return the appropriate thing.
    if (aBias == exports.LEAST_UPPER_BOUND) {
      return mid;
    } else {
      return aLow < 0 ? -1 : aLow;
    }
  }
}

/**
 * This is an implementation of binary search which will always try and return
 * the index of the closest element if there is no exact hit. This is because
 * mappings between original and generated line/col pairs are single points,
 * and there is an implicit region between each of them, so a miss just means
 * that you aren't on the very start of a region.
 *
 * @param aNeedle The element you are looking for.
 * @param aHaystack The array that is being searched.
 * @param aCompare A function which takes the needle and an element in the
 *     array and returns -1, 0, or 1 depending on whether the needle is less
 *     than, equal to, or greater than the element, respectively.
 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 *     Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
 */
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
  if (aHaystack.length === 0) {
    return -1;
  }

  var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
                              aCompare, aBias || exports.GREATEST_LOWER_BOUND);
  if (index < 0) {
    return -1;
  }

  // We have found either the exact element, or the next-closest element than
  // the one we are searching for. However, there may be more than one such
  // element. Make sure we always return the smallest of these.
  while (index - 1 >= 0) {
    if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
      break;
    }
    --index;
  }

  return index;
};

},{}],30:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2014 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var util = require('./util');

/**
 * Determine whether mappingB is after mappingA with respect to generated
 * position.
 */
function generatedPositionAfter(mappingA, mappingB) {
  // Optimized for most common case
  var lineA = mappingA.generatedLine;
  var lineB = mappingB.generatedLine;
  var columnA = mappingA.generatedColumn;
  var columnB = mappingB.generatedColumn;
  return lineB > lineA || lineB == lineA && columnB >= columnA ||
         util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
}

/**
 * A data structure to provide a sorted view of accumulated mappings in a
 * performance conscious manner. It trades a neglibable overhead in general
 * case for a large speedup in case of mappings being added in order.
 */
function MappingList() {
  this._array = [];
  this._sorted = true;
  // Serves as infimum
  this._last = {generatedLine: -1, generatedColumn: 0};
}

/**
 * Iterate through internal items. This method takes the same arguments that
 * `Array.prototype.forEach` takes.
 *
 * NOTE: The order of the mappings is NOT guaranteed.
 */
MappingList.prototype.unsortedForEach =
  function MappingList_forEach(aCallback, aThisArg) {
    this._array.forEach(aCallback, aThisArg);
  };

/**
 * Add the given source mapping.
 *
 * @param Object aMapping
 */
MappingList.prototype.add = function MappingList_add(aMapping) {
  if (generatedPositionAfter(this._last, aMapping)) {
    this._last = aMapping;
    this._array.push(aMapping);
  } else {
    this._sorted = false;
    this._array.push(aMapping);
  }
};

/**
 * Returns the flat, sorted array of mappings. The mappings are sorted by
 * generated position.
 *
 * WARNING: This method returns internal data without copying, for
 * performance. The return value must NOT be mutated, and should be treated as
 * an immutable borrow. If you want to take ownership, you must make your own
 * copy.
 */
MappingList.prototype.toArray = function MappingList_toArray() {
  if (!this._sorted) {
    this._array.sort(util.compareByGeneratedPositionsInflated);
    this._sorted = true;
  }
  return this._array;
};

exports.MappingList = MappingList;

},{"./util":35}],31:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

// It turns out that some (most?) JavaScript engines don't self-host
// `Array.prototype.sort`. This makes sense because C++ will likely remain
// faster than JS when doing raw CPU-intensive sorting. However, when using a
// custom comparator function, calling back and forth between the VM's C++ and
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
// worse generated code for the comparator function than would be optimal. In
// fact, when sorting with a comparator, these costs outweigh the benefits of
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
// a ~3500ms mean speed-up in `bench/bench.html`.

/**
 * Swap the elements indexed by `x` and `y` in the array `ary`.
 *
 * @param {Array} ary
 *        The array.
 * @param {Number} x
 *        The index of the first item.
 * @param {Number} y
 *        The index of the second item.
 */
function swap(ary, x, y) {
  var temp = ary[x];
  ary[x] = ary[y];
  ary[y] = temp;
}

/**
 * Returns a random integer within the range `low .. high` inclusive.
 *
 * @param {Number} low
 *        The lower bound on the range.
 * @param {Number} high
 *        The upper bound on the range.
 */
function randomIntInRange(low, high) {
  return Math.round(low + (Math.random() * (high - low)));
}

/**
 * The Quick Sort algorithm.
 *
 * @param {Array} ary
 *        An array to sort.
 * @param {function} comparator
 *        Function to use to compare two items.
 * @param {Number} p
 *        Start index of the array
 * @param {Number} r
 *        End index of the array
 */
function doQuickSort(ary, comparator, p, r) {
  // If our lower bound is less than our upper bound, we (1) partition the
  // array into two pieces and (2) recurse on each half. If it is not, this is
  // the empty array and our base case.

  if (p < r) {
    // (1) Partitioning.
    //
    // The partitioning chooses a pivot between `p` and `r` and moves all
    // elements that are less than or equal to the pivot to the before it, and
    // all the elements that are greater than it after it. The effect is that
    // once partition is done, the pivot is in the exact place it will be when
    // the array is put in sorted order, and it will not need to be moved
    // again. This runs in O(n) time.

    // Always choose a random pivot so that an input array which is reverse
    // sorted does not cause O(n^2) running time.
    var pivotIndex = randomIntInRange(p, r);
    var i = p - 1;

    swap(ary, pivotIndex, r);
    var pivot = ary[r];

    // Immediately after `j` is incremented in this loop, the following hold
    // true:
    //
    //   * Every element in `ary[p .. i]` is less than or equal to the pivot.
    //
    //   * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
    for (var j = p; j < r; j++) {
      if (comparator(ary[j], pivot) <= 0) {
        i += 1;
        swap(ary, i, j);
      }
    }

    swap(ary, i + 1, j);
    var q = i + 1;

    // (2) Recurse on each half.

    doQuickSort(ary, comparator, p, q - 1);
    doQuickSort(ary, comparator, q + 1, r);
  }
}

/**
 * Sort the given array in-place with the given comparator function.
 *
 * @param {Array} ary
 *        An array to sort.
 * @param {function} comparator
 *        Function to use to compare two items.
 */
exports.quickSort = function (ary, comparator) {
  doQuickSort(ary, comparator, 0, ary.length - 1);
};

},{}],32:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var util = require('./util');
var binarySearch = require('./binary-search');
var ArraySet = require('./array-set').ArraySet;
var base64VLQ = require('./base64-vlq');
var quickSort = require('./quick-sort').quickSort;

function SourceMapConsumer(aSourceMap, aSourceMapURL) {
  var sourceMap = aSourceMap;
  if (typeof aSourceMap === 'string') {
    sourceMap = util.parseSourceMapInput(aSourceMap);
  }

  return sourceMap.sections != null
    ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
    : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
}

SourceMapConsumer.fromSourceMap = function(aSourceMap, aSourceMapURL) {
  return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
}

/**
 * The version of the source mapping spec that we are consuming.
 */
SourceMapConsumer.prototype._version = 3;

// `__generatedMappings` and `__originalMappings` are arrays that hold the
// parsed mapping coordinates from the source map's "mappings" attribute. They
// are lazily instantiated, accessed via the `_generatedMappings` and
// `_originalMappings` getters respectively, and we only parse the mappings
// and create these arrays once queried for a source location. We jump through
// these hoops because there can be many thousands of mappings, and parsing
// them is expensive, so we only want to do it if we must.
//
// Each object in the arrays is of the form:
//
//     {
//       generatedLine: The line number in the generated code,
//       generatedColumn: The column number in the generated code,
//       source: The path to the original source file that generated this
//               chunk of code,
//       originalLine: The line number in the original source that
//                     corresponds to this chunk of generated code,
//       originalColumn: The column number in the original source that
//                       corresponds to this chunk of generated code,
//       name: The name of the original symbol which generated this chunk of
//             code.
//     }
//
// All properties except for `generatedLine` and `generatedColumn` can be
// `null`.
//
// `_generatedMappings` is ordered by the generated positions.
//
// `_originalMappings` is ordered by the original positions.

SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
  configurable: true,
  enumerable: true,
  get: function () {
    if (!this.__generatedMappings) {
      this._parseMappings(this._mappings, this.sourceRoot);
    }

    return this.__generatedMappings;
  }
});

SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
  configurable: true,
  enumerable: true,
  get: function () {
    if (!this.__originalMappings) {
      this._parseMappings(this._mappings, this.sourceRoot);
    }

    return this.__originalMappings;
  }
});

SourceMapConsumer.prototype._charIsMappingSeparator =
  function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
    var c = aStr.charAt(index);
    return c === ";" || c === ",";
  };

/**
 * Parse the mappings in a string in to a data structure which we can easily
 * query (the ordered arrays in the `this.__generatedMappings` and
 * `this.__originalMappings` properties).
 */
SourceMapConsumer.prototype._parseMappings =
  function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
    throw new Error("Subclasses must implement _parseMappings");
  };

SourceMapConsumer.GENERATED_ORDER = 1;
SourceMapConsumer.ORIGINAL_ORDER = 2;

SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
SourceMapConsumer.LEAST_UPPER_BOUND = 2;

/**
 * Iterate over each mapping between an original source/line/column and a
 * generated line/column in this source map.
 *
 * @param Function aCallback
 *        The function that is called with each mapping.
 * @param Object aContext
 *        Optional. If specified, this object will be the value of `this` every
 *        time that `aCallback` is called.
 * @param aOrder
 *        Either `SourceMapConsumer.GENERATED_ORDER` or
 *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
 *        iterate over the mappings sorted by the generated file's line/column
 *        order or the original's source/line/column order, respectively. Defaults to
 *        `SourceMapConsumer.GENERATED_ORDER`.
 */
SourceMapConsumer.prototype.eachMapping =
  function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
    var context = aContext || null;
    var order = aOrder || SourceMapConsumer.GENERATED_ORDER;

    var mappings;
    switch (order) {
    case SourceMapConsumer.GENERATED_ORDER:
      mappings = this._generatedMappings;
      break;
    case SourceMapConsumer.ORIGINAL_ORDER:
      mappings = this._originalMappings;
      break;
    default:
      throw new Error("Unknown order of iteration.");
    }

    var sourceRoot = this.sourceRoot;
    mappings.map(function (mapping) {
      var source = mapping.source === null ? null : this._sources.at(mapping.source);
      source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
      return {
        source: source,
        generatedLine: mapping.generatedLine,
        generatedColumn: mapping.generatedColumn,
        originalLine: mapping.originalLine,
        originalColumn: mapping.originalColumn,
        name: mapping.name === null ? null : this._names.at(mapping.name)
      };
    }, this).forEach(aCallback, context);
  };

/**
 * Returns all generated line and column information for the original source,
 * line, and column provided. If no column is provided, returns all mappings
 * corresponding to a either the line we are searching for or the next
 * closest line that has any mappings. Otherwise, returns all mappings
 * corresponding to the given line and either the column we are searching for
 * or the next closest column that has any offsets.
 *
 * The only argument is an object with the following properties:
 *
 *   - source: The filename of the original source.
 *   - line: The line number in the original source.  The line number is 1-based.
 *   - column: Optional. the column number in the original source.
 *    The column number is 0-based.
 *
 * and an array of objects is returned, each with the following properties:
 *
 *   - line: The line number in the generated source, or null.  The
 *    line number is 1-based.
 *   - column: The column number in the generated source, or null.
 *    The column number is 0-based.
 */
SourceMapConsumer.prototype.allGeneratedPositionsFor =
  function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
    var line = util.getArg(aArgs, 'line');

    // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
    // returns the index of the closest mapping less than the needle. By
    // setting needle.originalColumn to 0, we thus find the last mapping for
    // the given line, provided such a mapping exists.
    var needle = {
      source: util.getArg(aArgs, 'source'),
      originalLine: line,
      originalColumn: util.getArg(aArgs, 'column', 0)
    };

    needle.source = this._findSourceIndex(needle.source);
    if (needle.source < 0) {
      return [];
    }

    var mappings = [];

    var index = this._findMapping(needle,
                                  this._originalMappings,
                                  "originalLine",
                                  "originalColumn",
                                  util.compareByOriginalPositions,
                                  binarySearch.LEAST_UPPER_BOUND);
    if (index >= 0) {
      var mapping = this._originalMappings[index];

      if (aArgs.column === undefined) {
        var originalLine = mapping.originalLine;

        // Iterate until either we run out of mappings, or we run into
        // a mapping for a different line than the one we found. Since
        // mappings are sorted, this is guaranteed to find all mappings for
        // the line we found.
        while (mapping && mapping.originalLine === originalLine) {
          mappings.push({
            line: util.getArg(mapping, 'generatedLine', null),
            column: util.getArg(mapping, 'generatedColumn', null),
            lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
          });

          mapping = this._originalMappings[++index];
        }
      } else {
        var originalColumn = mapping.originalColumn;

        // Iterate until either we run out of mappings, or we run into
        // a mapping for a different line than the one we were searching for.
        // Since mappings are sorted, this is guaranteed to find all mappings for
        // the line we are searching for.
        while (mapping &&
               mapping.originalLine === line &&
               mapping.originalColumn == originalColumn) {
          mappings.push({
            line: util.getArg(mapping, 'generatedLine', null),
            column: util.getArg(mapping, 'generatedColumn', null),
            lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
          });

          mapping = this._originalMappings[++index];
        }
      }
    }

    return mappings;
  };

exports.SourceMapConsumer = SourceMapConsumer;

/**
 * A BasicSourceMapConsumer instance represents a parsed source map which we can
 * query for information about the original file positions by giving it a file
 * position in the generated source.
 *
 * The first parameter is the raw source map (either as a JSON string, or
 * already parsed to an object). According to the spec, source maps have the
 * following attributes:
 *
 *   - version: Which version of the source map spec this map is following.
 *   - sources: An array of URLs to the original source files.
 *   - names: An array of identifiers which can be referrenced by individual mappings.
 *   - sourceRoot: Optional. The URL root from which all sources are relative.
 *   - sourcesContent: Optional. An array of contents of the original source files.
 *   - mappings: A string of base64 VLQs which contain the actual mappings.
 *   - file: Optional. The generated file this source map is associated with.
 *
 * Here is an example source map, taken from the source map spec[0]:
 *
 *     {
 *       version : 3,
 *       file: "out.js",
 *       sourceRoot : "",
 *       sources: ["foo.js", "bar.js"],
 *       names: ["src", "maps", "are", "fun"],
 *       mappings: "AA,AB;;ABCDE;"
 *     }
 *
 * The second parameter, if given, is a string whose value is the URL
 * at which the source map was found.  This URL is used to compute the
 * sources array.
 *
 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
 */
function BasicSourceMapConsumer(aSourceMap, aSourceMapURL) {
  var sourceMap = aSourceMap;
  if (typeof aSourceMap === 'string') {
    sourceMap = util.parseSourceMapInput(aSourceMap);
  }

  var version = util.getArg(sourceMap, 'version');
  var sources = util.getArg(sourceMap, 'sources');
  // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
  // requires the array) to play nice here.
  var names = util.getArg(sourceMap, 'names', []);
  var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
  var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
  var mappings = util.getArg(sourceMap, 'mappings');
  var file = util.getArg(sourceMap, 'file', null);

  // Once again, Sass deviates from the spec and supplies the version as a
  // string rather than a number, so we use loose equality checking here.
  if (version != this._version) {
    throw new Error('Unsupported version: ' + version);
  }

  if (sourceRoot) {
    sourceRoot = util.normalize(sourceRoot);
  }

  sources = sources
    .map(String)
    // Some source maps produce relative source paths like "./foo.js" instead of
    // "foo.js".  Normalize these first so that future comparisons will succeed.
    // See bugzil.la/1090768.
    .map(util.normalize)
    // Always ensure that absolute sources are internally stored relative to
    // the source root, if the source root is absolute. Not doing this would
    // be particularly problematic when the source root is a prefix of the
    // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
    .map(function (source) {
      return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
        ? util.relative(sourceRoot, source)
        : source;
    });

  // Pass `true` below to allow duplicate names and sources. While source maps
  // are intended to be compressed and deduplicated, the TypeScript compiler
  // sometimes generates source maps with duplicates in them. See Github issue
  // #72 and bugzil.la/889492.
  this._names = ArraySet.fromArray(names.map(String), true);
  this._sources = ArraySet.fromArray(sources, true);

  this._absoluteSources = this._sources.toArray().map(function (s) {
    return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
  });

  this.sourceRoot = sourceRoot;
  this.sourcesContent = sourcesContent;
  this._mappings = mappings;
  this._sourceMapURL = aSourceMapURL;
  this.file = file;
}

BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;

/**
 * Utility function to find the index of a source.  Returns -1 if not
 * found.
 */
BasicSourceMapConsumer.prototype._findSourceIndex = function(aSource) {
  var relativeSource = aSource;
  if (this.sourceRoot != null) {
    relativeSource = util.relative(this.sourceRoot, relativeSource);
  }

  if (this._sources.has(relativeSource)) {
    return this._sources.indexOf(relativeSource);
  }

  // Maybe aSource is an absolute URL as returned by |sources|.  In
  // this case we can't simply undo the transform.
  var i;
  for (i = 0; i < this._absoluteSources.length; ++i) {
    if (this._absoluteSources[i] == aSource) {
      return i;
    }
  }

  return -1;
};

/**
 * Create a BasicSourceMapConsumer from a SourceMapGenerator.
 *
 * @param SourceMapGenerator aSourceMap
 *        The source map that will be consumed.
 * @param String aSourceMapURL
 *        The URL at which the source map can be found (optional)
 * @returns BasicSourceMapConsumer
 */
BasicSourceMapConsumer.fromSourceMap =
  function SourceMapConsumer_fromSourceMap(aSourceMap, aSourceMapURL) {
    var smc = Object.create(BasicSourceMapConsumer.prototype);

    var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
    var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
    smc.sourceRoot = aSourceMap._sourceRoot;
    smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
                                                            smc.sourceRoot);
    smc.file = aSourceMap._file;
    smc._sourceMapURL = aSourceMapURL;
    smc._absoluteSources = smc._sources.toArray().map(function (s) {
      return util.computeSourceURL(smc.sourceRoot, s, aSourceMapURL);
    });

    // Because we are modifying the entries (by converting string sources and
    // names to indices into the sources and names ArraySets), we have to make
    // a copy of the entry or else bad things happen. Shared mutable state
    // strikes again! See github issue #191.

    var generatedMappings = aSourceMap._mappings.toArray().slice();
    var destGeneratedMappings = smc.__generatedMappings = [];
    var destOriginalMappings = smc.__originalMappings = [];

    for (var i = 0, length = generatedMappings.length; i < length; i++) {
      var srcMapping = generatedMappings[i];
      var destMapping = new Mapping;
      destMapping.generatedLine = srcMapping.generatedLine;
      destMapping.generatedColumn = srcMapping.generatedColumn;

      if (srcMapping.source) {
        destMapping.source = sources.indexOf(srcMapping.source);
        destMapping.originalLine = srcMapping.originalLine;
        destMapping.originalColumn = srcMapping.originalColumn;

        if (srcMapping.name) {
          destMapping.name = names.indexOf(srcMapping.name);
        }

        destOriginalMappings.push(destMapping);
      }

      destGeneratedMappings.push(destMapping);
    }

    quickSort(smc.__originalMappings, util.compareByOriginalPositions);

    return smc;
  };

/**
 * The version of the source mapping spec that we are consuming.
 */
BasicSourceMapConsumer.prototype._version = 3;

/**
 * The list of original sources.
 */
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
  get: function () {
    return this._absoluteSources.slice();
  }
});

/**
 * Provide the JIT with a nice shape / hidden class.
 */
function Mapping() {
  this.generatedLine = 0;
  this.generatedColumn = 0;
  this.source = null;
  this.originalLine = null;
  this.originalColumn = null;
  this.name = null;
}

/**
 * Parse the mappings in a string in to a data structure which we can easily
 * query (the ordered arrays in the `this.__generatedMappings` and
 * `this.__originalMappings` properties).
 */
BasicSourceMapConsumer.prototype._parseMappings =
  function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
    var generatedLine = 1;
    var previousGeneratedColumn = 0;
    var previousOriginalLine = 0;
    var previousOriginalColumn = 0;
    var previousSource = 0;
    var previousName = 0;
    var length = aStr.length;
    var index = 0;
    var cachedSegments = {};
    var temp = {};
    var originalMappings = [];
    var generatedMappings = [];
    var mapping, str, segment, end, value;

    while (index < length) {
      if (aStr.charAt(index) === ';') {
        generatedLine++;
        index++;
        previousGeneratedColumn = 0;
      }
      else if (aStr.charAt(index) === ',') {
        index++;
      }
      else {
        mapping = new Mapping();
        mapping.generatedLine = generatedLine;

        // Because each offset is encoded relative to the previous one,
        // many segments often have the same encoding. We can exploit this
        // fact by caching the parsed variable length fields of each segment,
        // allowing us to avoid a second parse if we encounter the same
        // segment again.
        for (end = index; end < length; end++) {
          if (this._charIsMappingSeparator(aStr, end)) {
            break;
          }
        }
        str = aStr.slice(index, end);

        segment = cachedSegments[str];
        if (segment) {
          index += str.length;
        } else {
          segment = [];
          while (index < end) {
            base64VLQ.decode(aStr, index, temp);
            value = temp.value;
            index = temp.rest;
            segment.push(value);
          }

          if (segment.length === 2) {
            throw new Error('Found a source, but no line and column');
          }

          if (segment.length === 3) {
            throw new Error('Found a source and line, but no column');
          }

          cachedSegments[str] = segment;
        }

        // Generated column.
        mapping.generatedColumn = previousGeneratedColumn + segment[0];
        previousGeneratedColumn = mapping.generatedColumn;

        if (segment.length > 1) {
          // Original source.
          mapping.source = previousSource + segment[1];
          previousSource += segment[1];

          // Original line.
          mapping.originalLine = previousOriginalLine + segment[2];
          previousOriginalLine = mapping.originalLine;
          // Lines are stored 0-based
          mapping.originalLine += 1;

          // Original column.
          mapping.originalColumn = previousOriginalColumn + segment[3];
          previousOriginalColumn = mapping.originalColumn;

          if (segment.length > 4) {
            // Original name.
            mapping.name = previousName + segment[4];
            previousName += segment[4];
          }
        }

        generatedMappings.push(mapping);
        if (typeof mapping.originalLine === 'number') {
          originalMappings.push(mapping);
        }
      }
    }

    quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
    this.__generatedMappings = generatedMappings;

    quickSort(originalMappings, util.compareByOriginalPositions);
    this.__originalMappings = originalMappings;
  };

/**
 * Find the mapping that best matches the hypothetical "needle" mapping that
 * we are searching for in the given "haystack" of mappings.
 */
BasicSourceMapConsumer.prototype._findMapping =
  function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
                                         aColumnName, aComparator, aBias) {
    // To return the position we are searching for, we must first find the
    // mapping for the given position and then return the opposite position it
    // points to. Because the mappings are sorted, we can use binary search to
    // find the best mapping.

    if (aNeedle[aLineName] <= 0) {
      throw new TypeError('Line must be greater than or equal to 1, got '
                          + aNeedle[aLineName]);
    }
    if (aNeedle[aColumnName] < 0) {
      throw new TypeError('Column must be greater than or equal to 0, got '
                          + aNeedle[aColumnName]);
    }

    return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
  };

/**
 * Compute the last column for each generated mapping. The last column is
 * inclusive.
 */
BasicSourceMapConsumer.prototype.computeColumnSpans =
  function SourceMapConsumer_computeColumnSpans() {
    for (var index = 0; index < this._generatedMappings.length; ++index) {
      var mapping = this._generatedMappings[index];

      // Mappings do not contain a field for the last generated columnt. We
      // can come up with an optimistic estimate, however, by assuming that
      // mappings are contiguous (i.e. given two consecutive mappings, the
      // first mapping ends where the second one starts).
      if (index + 1 < this._generatedMappings.length) {
        var nextMapping = this._generatedMappings[index + 1];

        if (mapping.generatedLine === nextMapping.generatedLine) {
          mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
          continue;
        }
      }

      // The last mapping for each line spans the entire line.
      mapping.lastGeneratedColumn = Infinity;
    }
  };

/**
 * Returns the original source, line, and column information for the generated
 * source's line and column positions provided. The only argument is an object
 * with the following properties:
 *
 *   - line: The line number in the generated source.  The line number
 *     is 1-based.
 *   - column: The column number in the generated source.  The column
 *     number is 0-based.
 *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
 *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
 *
 * and an object is returned with the following properties:
 *
 *   - source: The original source file, or null.
 *   - line: The line number in the original source, or null.  The
 *     line number is 1-based.
 *   - column: The column number in the original source, or null.  The
 *     column number is 0-based.
 *   - name: The original identifier, or null.
 */
BasicSourceMapConsumer.prototype.originalPositionFor =
  function SourceMapConsumer_originalPositionFor(aArgs) {
    var needle = {
      generatedLine: util.getArg(aArgs, 'line'),
      generatedColumn: util.getArg(aArgs, 'column')
    };

    var index = this._findMapping(
      needle,
      this._generatedMappings,
      "generatedLine",
      "generatedColumn",
      util.compareByGeneratedPositionsDeflated,
      util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
    );

    if (index >= 0) {
      var mapping = this._generatedMappings[index];

      if (mapping.generatedLine === needle.generatedLine) {
        var source = util.getArg(mapping, 'source', null);
        if (source !== null) {
          source = this._sources.at(source);
          source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
        }
        var name = util.getArg(mapping, 'name', null);
        if (name !== null) {
          name = this._names.at(name);
        }
        return {
          source: source,
          line: util.getArg(mapping, 'originalLine', null),
          column: util.getArg(mapping, 'originalColumn', null),
          name: name
        };
      }
    }

    return {
      source: null,
      line: null,
      column: null,
      name: null
    };
  };

/**
 * Return true if we have the source content for every source in the source
 * map, false otherwise.
 */
BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
  function BasicSourceMapConsumer_hasContentsOfAllSources() {
    if (!this.sourcesContent) {
      return false;
    }
    return this.sourcesContent.length >= this._sources.size() &&
      !this.sourcesContent.some(function (sc) { return sc == null; });
  };

/**
 * Returns the original source content. The only argument is the url of the
 * original source file. Returns null if no original source content is
 * available.
 */
BasicSourceMapConsumer.prototype.sourceContentFor =
  function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
    if (!this.sourcesContent) {
      return null;
    }

    var index = this._findSourceIndex(aSource);
    if (index >= 0) {
      return this.sourcesContent[index];
    }

    var relativeSource = aSource;
    if (this.sourceRoot != null) {
      relativeSource = util.relative(this.sourceRoot, relativeSource);
    }

    var url;
    if (this.sourceRoot != null
        && (url = util.urlParse(this.sourceRoot))) {
      // XXX: file:// URIs and absolute paths lead to unexpected behavior for
      // many users. We can help them out when they expect file:// URIs to
      // behave like it would if they were running a local HTTP server. See
      // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
      var fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
      if (url.scheme == "file"
          && this._sources.has(fileUriAbsPath)) {
        return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
      }

      if ((!url.path || url.path == "/")
          && this._sources.has("/" + relativeSource)) {
        return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
      }
    }

    // This function is used recursively from
    // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
    // don't want to throw if we can't find the source - we just want to
    // return null, so we provide a flag to exit gracefully.
    if (nullOnMissing) {
      return null;
    }
    else {
      throw new Error('"' + relativeSource + '" is not in the SourceMap.');
    }
  };

/**
 * Returns the generated line and column information for the original source,
 * line, and column positions provided. The only argument is an object with
 * the following properties:
 *
 *   - source: The filename of the original source.
 *   - line: The line number in the original source.  The line number
 *     is 1-based.
 *   - column: The column number in the original source.  The column
 *     number is 0-based.
 *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
 *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
 *
 * and an object is returned with the following properties:
 *
 *   - line: The line number in the generated source, or null.  The
 *     line number is 1-based.
 *   - column: The column number in the generated source, or null.
 *     The column number is 0-based.
 */
BasicSourceMapConsumer.prototype.generatedPositionFor =
  function SourceMapConsumer_generatedPositionFor(aArgs) {
    var source = util.getArg(aArgs, 'source');
    source = this._findSourceIndex(source);
    if (source < 0) {
      return {
        line: null,
        column: null,
        lastColumn: null
      };
    }

    var needle = {
      source: source,
      originalLine: util.getArg(aArgs, 'line'),
      originalColumn: util.getArg(aArgs, 'column')
    };

    var index = this._findMapping(
      needle,
      this._originalMappings,
      "originalLine",
      "originalColumn",
      util.compareByOriginalPositions,
      util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
    );

    if (index >= 0) {
      var mapping = this._originalMappings[index];

      if (mapping.source === needle.source) {
        return {
          line: util.getArg(mapping, 'generatedLine', null),
          column: util.getArg(mapping, 'generatedColumn', null),
          lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
        };
      }
    }

    return {
      line: null,
      column: null,
      lastColumn: null
    };
  };

exports.BasicSourceMapConsumer = BasicSourceMapConsumer;

/**
 * An IndexedSourceMapConsumer instance represents a parsed source map which
 * we can query for information. It differs from BasicSourceMapConsumer in
 * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
 * input.
 *
 * The first parameter is a raw source map (either as a JSON string, or already
 * parsed to an object). According to the spec for indexed source maps, they
 * have the following attributes:
 *
 *   - version: Which version of the source map spec this map is following.
 *   - file: Optional. The generated file this source map is associated with.
 *   - sections: A list of section definitions.
 *
 * Each value under the "sections" field has two fields:
 *   - offset: The offset into the original specified at which this section
 *       begins to apply, defined as an object with a "line" and "column"
 *       field.
 *   - map: A source map definition. This source map could also be indexed,
 *       but doesn't have to be.
 *
 * Instead of the "map" field, it's also possible to have a "url" field
 * specifying a URL to retrieve a source map from, but that's currently
 * unsupported.
 *
 * Here's an example source map, taken from the source map spec[0], but
 * modified to omit a section which uses the "url" field.
 *
 *  {
 *    version : 3,
 *    file: "app.js",
 *    sections: [{
 *      offset: {line:100, column:10},
 *      map: {
 *        version : 3,
 *        file: "section.js",
 *        sources: ["foo.js", "bar.js"],
 *        names: ["src", "maps", "are", "fun"],
 *        mappings: "AAAA,E;;ABCDE;"
 *      }
 *    }],
 *  }
 *
 * The second parameter, if given, is a string whose value is the URL
 * at which the source map was found.  This URL is used to compute the
 * sources array.
 *
 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
 */
function IndexedSourceMapConsumer(aSourceMap, aSourceMapURL) {
  var sourceMap = aSourceMap;
  if (typeof aSourceMap === 'string') {
    sourceMap = util.parseSourceMapInput(aSourceMap);
  }

  var version = util.getArg(sourceMap, 'version');
  var sections = util.getArg(sourceMap, 'sections');

  if (version != this._version) {
    throw new Error('Unsupported version: ' + version);
  }

  this._sources = new ArraySet();
  this._names = new ArraySet();

  var lastOffset = {
    line: -1,
    column: 0
  };
  this._sections = sections.map(function (s) {
    if (s.url) {
      // The url field will require support for asynchronicity.
      // See https://github.com/mozilla/source-map/issues/16
      throw new Error('Support for url field in sections not implemented.');
    }
    var offset = util.getArg(s, 'offset');
    var offsetLine = util.getArg(offset, 'line');
    var offsetColumn = util.getArg(offset, 'column');

    if (offsetLine < lastOffset.line ||
        (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
      throw new Error('Section offsets must be ordered and non-overlapping.');
    }
    lastOffset = offset;

    return {
      generatedOffset: {
        // The offset fields are 0-based, but we use 1-based indices when
        // encoding/decoding from VLQ.
        generatedLine: offsetLine + 1,
        generatedColumn: offsetColumn + 1
      },
      consumer: new SourceMapConsumer(util.getArg(s, 'map'), aSourceMapURL)
    }
  });
}

IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;

/**
 * The version of the source mapping spec that we are consuming.
 */
IndexedSourceMapConsumer.prototype._version = 3;

/**
 * The list of original sources.
 */
Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
  get: function () {
    var sources = [];
    for (var i = 0; i < this._sections.length; i++) {
      for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
        sources.push(this._sections[i].consumer.sources[j]);
      }
    }
    return sources;
  }
});

/**
 * Returns the original source, line, and column information for the generated
 * source's line and column positions provided. The only argument is an object
 * with the following properties:
 *
 *   - line: The line number in the generated source.  The line number
 *     is 1-based.
 *   - column: The column number in the generated source.  The column
 *     number is 0-based.
 *
 * and an object is returned with the following properties:
 *
 *   - source: The original source file, or null.
 *   - line: The line number in the original source, or null.  The
 *     line number is 1-based.
 *   - column: The column number in the original source, or null.  The
 *     column number is 0-based.
 *   - name: The original identifier, or null.
 */
IndexedSourceMapConsumer.prototype.originalPositionFor =
  function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
    var needle = {
      generatedLine: util.getArg(aArgs, 'line'),
      generatedColumn: util.getArg(aArgs, 'column')
    };

    // Find the section containing the generated position we're trying to map
    // to an original position.
    var sectionIndex = binarySearch.search(needle, this._sections,
      function(needle, section) {
        var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
        if (cmp) {
          return cmp;
        }

        return (needle.generatedColumn -
                section.generatedOffset.generatedColumn);
      });
    var section = this._sections[sectionIndex];

    if (!section) {
      return {
        source: null,
        line: null,
        column: null,
        name: null
      };
    }

    return section.consumer.originalPositionFor({
      line: needle.generatedLine -
        (section.generatedOffset.generatedLine - 1),
      column: needle.generatedColumn -
        (section.generatedOffset.generatedLine === needle.generatedLine
         ? section.generatedOffset.generatedColumn - 1
         : 0),
      bias: aArgs.bias
    });
  };

/**
 * Return true if we have the source content for every source in the source
 * map, false otherwise.
 */
IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
  function IndexedSourceMapConsumer_hasContentsOfAllSources() {
    return this._sections.every(function (s) {
      return s.consumer.hasContentsOfAllSources();
    });
  };

/**
 * Returns the original source content. The only argument is the url of the
 * original source file. Returns null if no original source content is
 * available.
 */
IndexedSourceMapConsumer.prototype.sourceContentFor =
  function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
    for (var i = 0; i < this._sections.length; i++) {
      var section = this._sections[i];

      var content = section.consumer.sourceContentFor(aSource, true);
      if (content) {
        return content;
      }
    }
    if (nullOnMissing) {
      return null;
    }
    else {
      throw new Error('"' + aSource + '" is not in the SourceMap.');
    }
  };

/**
 * Returns the generated line and column information for the original source,
 * line, and column positions provided. The only argument is an object with
 * the following properties:
 *
 *   - source: The filename of the original source.
 *   - line: The line number in the original source.  The line number
 *     is 1-based.
 *   - column: The column number in the original source.  The column
 *     number is 0-based.
 *
 * and an object is returned with the following properties:
 *
 *   - line: The line number in the generated source, or null.  The
 *     line number is 1-based. 
 *   - column: The column number in the generated source, or null.
 *     The column number is 0-based.
 */
IndexedSourceMapConsumer.prototype.generatedPositionFor =
  function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
    for (var i = 0; i < this._sections.length; i++) {
      var section = this._sections[i];

      // Only consider this section if the requested source is in the list of
      // sources of the consumer.
      if (section.consumer._findSourceIndex(util.getArg(aArgs, 'source')) === -1) {
        continue;
      }
      var generatedPosition = section.consumer.generatedPositionFor(aArgs);
      if (generatedPosition) {
        var ret = {
          line: generatedPosition.line +
            (section.generatedOffset.generatedLine - 1),
          column: generatedPosition.column +
            (section.generatedOffset.generatedLine === generatedPosition.line
             ? section.generatedOffset.generatedColumn - 1
             : 0)
        };
        return ret;
      }
    }

    return {
      line: null,
      column: null
    };
  };

/**
 * Parse the mappings in a string in to a data structure which we can easily
 * query (the ordered arrays in the `this.__generatedMappings` and
 * `this.__originalMappings` properties).
 */
IndexedSourceMapConsumer.prototype._parseMappings =
  function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
    this.__generatedMappings = [];
    this.__originalMappings = [];
    for (var i = 0; i < this._sections.length; i++) {
      var section = this._sections[i];
      var sectionMappings = section.consumer._generatedMappings;
      for (var j = 0; j < sectionMappings.length; j++) {
        var mapping = sectionMappings[j];

        var source = section.consumer._sources.at(mapping.source);
        source = util.computeSourceURL(section.consumer.sourceRoot, source, this._sourceMapURL);
        this._sources.add(source);
        source = this._sources.indexOf(source);

        var name = null;
        if (mapping.name) {
          name = section.consumer._names.at(mapping.name);
          this._names.add(name);
          name = this._names.indexOf(name);
        }

        // The mappings coming from the consumer for the section have
        // generated positions relative to the start of the section, so we
        // need to offset them to be relative to the start of the concatenated
        // generated file.
        var adjustedMapping = {
          source: source,
          generatedLine: mapping.generatedLine +
            (section.generatedOffset.generatedLine - 1),
          generatedColumn: mapping.generatedColumn +
            (section.generatedOffset.generatedLine === mapping.generatedLine
            ? section.generatedOffset.generatedColumn - 1
            : 0),
          originalLine: mapping.originalLine,
          originalColumn: mapping.originalColumn,
          name: name
        };

        this.__generatedMappings.push(adjustedMapping);
        if (typeof adjustedMapping.originalLine === 'number') {
          this.__originalMappings.push(adjustedMapping);
        }
      }
    }

    quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
    quickSort(this.__originalMappings, util.compareByOriginalPositions);
  };

exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;

},{"./array-set":26,"./base64-vlq":27,"./binary-search":29,"./quick-sort":31,"./util":35}],33:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var base64VLQ = require('./base64-vlq');
var util = require('./util');
var ArraySet = require('./array-set').ArraySet;
var MappingList = require('./mapping-list').MappingList;

/**
 * An instance of the SourceMapGenerator represents a source map which is
 * being built incrementally. You may pass an object with the following
 * properties:
 *
 *   - file: The filename of the generated source.
 *   - sourceRoot: A root for all relative URLs in this source map.
 */
function SourceMapGenerator(aArgs) {
  if (!aArgs) {
    aArgs = {};
  }
  this._file = util.getArg(aArgs, 'file', null);
  this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
  this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
  this._sources = new ArraySet();
  this._names = new ArraySet();
  this._mappings = new MappingList();
  this._sourcesContents = null;
}

SourceMapGenerator.prototype._version = 3;

/**
 * Creates a new SourceMapGenerator based on a SourceMapConsumer
 *
 * @param aSourceMapConsumer The SourceMap.
 */
SourceMapGenerator.fromSourceMap =
  function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
    var sourceRoot = aSourceMapConsumer.sourceRoot;
    var generator = new SourceMapGenerator({
      file: aSourceMapConsumer.file,
      sourceRoot: sourceRoot
    });
    aSourceMapConsumer.eachMapping(function (mapping) {
      var newMapping = {
        generated: {
          line: mapping.generatedLine,
          column: mapping.generatedColumn
        }
      };

      if (mapping.source != null) {
        newMapping.source = mapping.source;
        if (sourceRoot != null) {
          newMapping.source = util.relative(sourceRoot, newMapping.source);
        }

        newMapping.original = {
          line: mapping.originalLine,
          column: mapping.originalColumn
        };

        if (mapping.name != null) {
          newMapping.name = mapping.name;
        }
      }

      generator.addMapping(newMapping);
    });
    aSourceMapConsumer.sources.forEach(function (sourceFile) {
      var sourceRelative = sourceFile;
      if (sourceRoot !== null) {
        sourceRelative = util.relative(sourceRoot, sourceFile);
      }

      if (!generator._sources.has(sourceRelative)) {
        generator._sources.add(sourceRelative);
      }

      var content = aSourceMapConsumer.sourceContentFor(sourceFile);
      if (content != null) {
        generator.setSourceContent(sourceFile, content);
      }
    });
    return generator;
  };

/**
 * Add a single mapping from original source line and column to the generated
 * source's line and column for this source map being created. The mapping
 * object should have the following properties:
 *
 *   - generated: An object with the generated line and column positions.
 *   - original: An object with the original line and column positions.
 *   - source: The original source file (relative to the sourceRoot).
 *   - name: An optional original token name for this mapping.
 */
SourceMapGenerator.prototype.addMapping =
  function SourceMapGenerator_addMapping(aArgs) {
    var generated = util.getArg(aArgs, 'generated');
    var original = util.getArg(aArgs, 'original', null);
    var source = util.getArg(aArgs, 'source', null);
    var name = util.getArg(aArgs, 'name', null);

    if (!this._skipValidation) {
      this._validateMapping(generated, original, source, name);
    }

    if (source != null) {
      source = String(source);
      if (!this._sources.has(source)) {
        this._sources.add(source);
      }
    }

    if (name != null) {
      name = String(name);
      if (!this._names.has(name)) {
        this._names.add(name);
      }
    }

    this._mappings.add({
      generatedLine: generated.line,
      generatedColumn: generated.column,
      originalLine: original != null && original.line,
      originalColumn: original != null && original.column,
      source: source,
      name: name
    });
  };

/**
 * Set the source content for a source file.
 */
SourceMapGenerator.prototype.setSourceContent =
  function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
    var source = aSourceFile;
    if (this._sourceRoot != null) {
      source = util.relative(this._sourceRoot, source);
    }

    if (aSourceContent != null) {
      // Add the source content to the _sourcesContents map.
      // Create a new _sourcesContents map if the property is null.
      if (!this._sourcesContents) {
        this._sourcesContents = Object.create(null);
      }
      this._sourcesContents[util.toSetString(source)] = aSourceContent;
    } else if (this._sourcesContents) {
      // Remove the source file from the _sourcesContents map.
      // If the _sourcesContents map is empty, set the property to null.
      delete this._sourcesContents[util.toSetString(source)];
      if (Object.keys(this._sourcesContents).length === 0) {
        this._sourcesContents = null;
      }
    }
  };

/**
 * Applies the mappings of a sub-source-map for a specific source file to the
 * source map being generated. Each mapping to the supplied source file is
 * rewritten using the supplied source map. Note: The resolution for the
 * resulting mappings is the minimium of this map and the supplied map.
 *
 * @param aSourceMapConsumer The source map to be applied.
 * @param aSourceFile Optional. The filename of the source file.
 *        If omitted, SourceMapConsumer's file property will be used.
 * @param aSourceMapPath Optional. The dirname of the path to the source map
 *        to be applied. If relative, it is relative to the SourceMapConsumer.
 *        This parameter is needed when the two source maps aren't in the same
 *        directory, and the source map to be applied contains relative source
 *        paths. If so, those relative source paths need to be rewritten
 *        relative to the SourceMapGenerator.
 */
SourceMapGenerator.prototype.applySourceMap =
  function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
    var sourceFile = aSourceFile;
    // If aSourceFile is omitted, we will use the file property of the SourceMap
    if (aSourceFile == null) {
      if (aSourceMapConsumer.file == null) {
        throw new Error(
          'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
          'or the source map\'s "file" property. Both were omitted.'
        );
      }
      sourceFile = aSourceMapConsumer.file;
    }
    var sourceRoot = this._sourceRoot;
    // Make "sourceFile" relative if an absolute Url is passed.
    if (sourceRoot != null) {
      sourceFile = util.relative(sourceRoot, sourceFile);
    }
    // Applying the SourceMap can add and remove items from the sources and
    // the names array.
    var newSources = new ArraySet();
    var newNames = new ArraySet();

    // Find mappings for the "sourceFile"
    this._mappings.unsortedForEach(function (mapping) {
      if (mapping.source === sourceFile && mapping.originalLine != null) {
        // Check if it can be mapped by the source map, then update the mapping.
        var original = aSourceMapConsumer.originalPositionFor({
          line: mapping.originalLine,
          column: mapping.originalColumn
        });
        if (original.source != null) {
          // Copy mapping
          mapping.source = original.source;
          if (aSourceMapPath != null) {
            mapping.source = util.join(aSourceMapPath, mapping.source)
          }
          if (sourceRoot != null) {
            mapping.source = util.relative(sourceRoot, mapping.source);
          }
          mapping.originalLine = original.line;
          mapping.originalColumn = original.column;
          if (original.name != null) {
            mapping.name = original.name;
          }
        }
      }

      var source = mapping.source;
      if (source != null && !newSources.has(source)) {
        newSources.add(source);
      }

      var name = mapping.name;
      if (name != null && !newNames.has(name)) {
        newNames.add(name);
      }

    }, this);
    this._sources = newSources;
    this._names = newNames;

    // Copy sourcesContents of applied map.
    aSourceMapConsumer.sources.forEach(function (sourceFile) {
      var content = aSourceMapConsumer.sourceContentFor(sourceFile);
      if (content != null) {
        if (aSourceMapPath != null) {
          sourceFile = util.join(aSourceMapPath, sourceFile);
        }
        if (sourceRoot != null) {
          sourceFile = util.relative(sourceRoot, sourceFile);
        }
        this.setSourceContent(sourceFile, content);
      }
    }, this);
  };

/**
 * A mapping can have one of the three levels of data:
 *
 *   1. Just the generated position.
 *   2. The Generated position, original position, and original source.
 *   3. Generated and original position, original source, as well as a name
 *      token.
 *
 * To maintain consistency, we validate that any new mapping being added falls
 * in to one of these categories.
 */
SourceMapGenerator.prototype._validateMapping =
  function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
                                              aName) {
    // When aOriginal is truthy but has empty values for .line and .column,
    // it is most likely a programmer error. In this case we throw a very
    // specific error message to try to guide them the right way.
    // For example: https://github.com/Polymer/polymer-bundler/pull/519
    if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
        throw new Error(
            'original.line and original.column are not numbers -- you probably meant to omit ' +
            'the original mapping entirely and only map the generated position. If so, pass ' +
            'null for the original mapping instead of an object with empty or null values.'
        );
    }

    if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
        && aGenerated.line > 0 && aGenerated.column >= 0
        && !aOriginal && !aSource && !aName) {
      // Case 1.
      return;
    }
    else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
             && aOriginal && 'line' in aOriginal && 'column' in aOriginal
             && aGenerated.line > 0 && aGenerated.column >= 0
             && aOriginal.line > 0 && aOriginal.column >= 0
             && aSource) {
      // Cases 2 and 3.
      return;
    }
    else {
      throw new Error('Invalid mapping: ' + JSON.stringify({
        generated: aGenerated,
        source: aSource,
        original: aOriginal,
        name: aName
      }));
    }
  };

/**
 * Serialize the accumulated mappings in to the stream of base 64 VLQs
 * specified by the source map format.
 */
SourceMapGenerator.prototype._serializeMappings =
  function SourceMapGenerator_serializeMappings() {
    var previousGeneratedColumn = 0;
    var previousGeneratedLine = 1;
    var previousOriginalColumn = 0;
    var previousOriginalLine = 0;
    var previousName = 0;
    var previousSource = 0;
    var result = '';
    var next;
    var mapping;
    var nameIdx;
    var sourceIdx;

    var mappings = this._mappings.toArray();
    for (var i = 0, len = mappings.length; i < len; i++) {
      mapping = mappings[i];
      next = ''

      if (mapping.generatedLine !== previousGeneratedLine) {
        previousGeneratedColumn = 0;
        while (mapping.generatedLine !== previousGeneratedLine) {
          next += ';';
          previousGeneratedLine++;
        }
      }
      else {
        if (i > 0) {
          if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
            continue;
          }
          next += ',';
        }
      }

      next += base64VLQ.encode(mapping.generatedColumn
                                 - previousGeneratedColumn);
      previousGeneratedColumn = mapping.generatedColumn;

      if (mapping.source != null) {
        sourceIdx = this._sources.indexOf(mapping.source);
        next += base64VLQ.encode(sourceIdx - previousSource);
        previousSource = sourceIdx;

        // lines are stored 0-based in SourceMap spec version 3
        next += base64VLQ.encode(mapping.originalLine - 1
                                   - previousOriginalLine);
        previousOriginalLine = mapping.originalLine - 1;

        next += base64VLQ.encode(mapping.originalColumn
                                   - previousOriginalColumn);
        previousOriginalColumn = mapping.originalColumn;

        if (mapping.name != null) {
          nameIdx = this._names.indexOf(mapping.name);
          next += base64VLQ.encode(nameIdx - previousName);
          previousName = nameIdx;
        }
      }

      result += next;
    }

    return result;
  };

SourceMapGenerator.prototype._generateSourcesContent =
  function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
    return aSources.map(function (source) {
      if (!this._sourcesContents) {
        return null;
      }
      if (aSourceRoot != null) {
        source = util.relative(aSourceRoot, source);
      }
      var key = util.toSetString(source);
      return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
        ? this._sourcesContents[key]
        : null;
    }, this);
  };

/**
 * Externalize the source map.
 */
SourceMapGenerator.prototype.toJSON =
  function SourceMapGenerator_toJSON() {
    var map = {
      version: this._version,
      sources: this._sources.toArray(),
      names: this._names.toArray(),
      mappings: this._serializeMappings()
    };
    if (this._file != null) {
      map.file = this._file;
    }
    if (this._sourceRoot != null) {
      map.sourceRoot = this._sourceRoot;
    }
    if (this._sourcesContents) {
      map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
    }

    return map;
  };

/**
 * Render the source map being generated to a string.
 */
SourceMapGenerator.prototype.toString =
  function SourceMapGenerator_toString() {
    return JSON.stringify(this.toJSON());
  };

exports.SourceMapGenerator = SourceMapGenerator;

},{"./array-set":26,"./base64-vlq":27,"./mapping-list":30,"./util":35}],34:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');

// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
var REGEX_NEWLINE = /(\r?\n)/;

// Newline character code for charCodeAt() comparisons
var NEWLINE_CODE = 10;

// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
var isSourceNode = "$$$isSourceNode$$$";

/**
 * SourceNodes provide a way to abstract over interpolating/concatenating
 * snippets of generated JavaScript source code while maintaining the line and
 * column information associated with the original source code.
 *
 * @param aLine The original line number.
 * @param aColumn The original column number.
 * @param aSource The original source's filename.
 * @param aChunks Optional. An array of strings which are snippets of
 *        generated JS, or other SourceNodes.
 * @param aName The original identifier.
 */
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
  this.children = [];
  this.sourceContents = {};
  this.line = aLine == null ? null : aLine;
  this.column = aColumn == null ? null : aColumn;
  this.source = aSource == null ? null : aSource;
  this.name = aName == null ? null : aName;
  this[isSourceNode] = true;
  if (aChunks != null) this.add(aChunks);
}

/**
 * Creates a SourceNode from generated code and a SourceMapConsumer.
 *
 * @param aGeneratedCode The generated code
 * @param aSourceMapConsumer The SourceMap for the generated code
 * @param aRelativePath Optional. The path that relative sources in the
 *        SourceMapConsumer should be relative to.
 */
SourceNode.fromStringWithSourceMap =
  function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
    // The SourceNode we want to fill with the generated code
    // and the SourceMap
    var node = new SourceNode();

    // All even indices of this array are one line of the generated code,
    // while all odd indices are the newlines between two adjacent lines
    // (since `REGEX_NEWLINE` captures its match).
    // Processed fragments are accessed by calling `shiftNextLine`.
    var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
    var remainingLinesIndex = 0;
    var shiftNextLine = function() {
      var lineContents = getNextLine();
      // The last line of a file might not have a newline.
      var newLine = getNextLine() || "";
      return lineContents + newLine;

      function getNextLine() {
        return remainingLinesIndex < remainingLines.length ?
            remainingLines[remainingLinesIndex++] : undefined;
      }
    };

    // We need to remember the position of "remainingLines"
    var lastGeneratedLine = 1, lastGeneratedColumn = 0;

    // The generate SourceNodes we need a code range.
    // To extract it current and last mapping is used.
    // Here we store the last mapping.
    var lastMapping = null;

    aSourceMapConsumer.eachMapping(function (mapping) {
      if (lastMapping !== null) {
        // We add the code from "lastMapping" to "mapping":
        // First check if there is a new line in between.
        if (lastGeneratedLine < mapping.generatedLine) {
          // Associate first line with "lastMapping"
          addMappingWithCode(lastMapping, shiftNextLine());
          lastGeneratedLine++;
          lastGeneratedColumn = 0;
          // The remaining code is added without mapping
        } else {
          // There is no new line in between.
          // Associate the code between "lastGeneratedColumn" and
          // "mapping.generatedColumn" with "lastMapping"
          var nextLine = remainingLines[remainingLinesIndex] || '';
          var code = nextLine.substr(0, mapping.generatedColumn -
                                        lastGeneratedColumn);
          remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
                                              lastGeneratedColumn);
          lastGeneratedColumn = mapping.generatedColumn;
          addMappingWithCode(lastMapping, code);
          // No more remaining code, continue
          lastMapping = mapping;
          return;
        }
      }
      // We add the generated code until the first mapping
      // to the SourceNode without any mapping.
      // Each line is added as separate string.
      while (lastGeneratedLine < mapping.generatedLine) {
        node.add(shiftNextLine());
        lastGeneratedLine++;
      }
      if (lastGeneratedColumn < mapping.generatedColumn) {
        var nextLine = remainingLines[remainingLinesIndex] || '';
        node.add(nextLine.substr(0, mapping.generatedColumn));
        remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
        lastGeneratedColumn = mapping.generatedColumn;
      }
      lastMapping = mapping;
    }, this);
    // We have processed all mappings.
    if (remainingLinesIndex < remainingLines.length) {
      if (lastMapping) {
        // Associate the remaining code in the current line with "lastMapping"
        addMappingWithCode(lastMapping, shiftNextLine());
      }
      // and add the remaining lines without any mapping
      node.add(remainingLines.splice(remainingLinesIndex).join(""));
    }

    // Copy sourcesContent into SourceNode
    aSourceMapConsumer.sources.forEach(function (sourceFile) {
      var content = aSourceMapConsumer.sourceContentFor(sourceFile);
      if (content != null) {
        if (aRelativePath != null) {
          sourceFile = util.join(aRelativePath, sourceFile);
        }
        node.setSourceContent(sourceFile, content);
      }
    });

    return node;

    function addMappingWithCode(mapping, code) {
      if (mapping === null || mapping.source === undefined) {
        node.add(code);
      } else {
        var source = aRelativePath
          ? util.join(aRelativePath, mapping.source)
          : mapping.source;
        node.add(new SourceNode(mapping.originalLine,
                                mapping.originalColumn,
                                source,
                                code,
                                mapping.name));
      }
    }
  };

/**
 * Add a chunk of generated JS to this source node.
 *
 * @param aChunk A string snippet of generated JS code, another instance of
 *        SourceNode, or an array where each member is one of those things.
 */
SourceNode.prototype.add = function SourceNode_add(aChunk) {
  if (Array.isArray(aChunk)) {
    aChunk.forEach(function (chunk) {
      this.add(chunk);
    }, this);
  }
  else if (aChunk[isSourceNode] || typeof aChunk === "string") {
    if (aChunk) {
      this.children.push(aChunk);
    }
  }
  else {
    throw new TypeError(
      "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
    );
  }
  return this;
};

/**
 * Add a chunk of generated JS to the beginning of this source node.
 *
 * @param aChunk A string snippet of generated JS code, another instance of
 *        SourceNode, or an array where each member is one of those things.
 */
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
  if (Array.isArray(aChunk)) {
    for (var i = aChunk.length-1; i >= 0; i--) {
      this.prepend(aChunk[i]);
    }
  }
  else if (aChunk[isSourceNode] || typeof aChunk === "string") {
    this.children.unshift(aChunk);
  }
  else {
    throw new TypeError(
      "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
    );
  }
  return this;
};

/**
 * Walk over the tree of JS snippets in this node and its children. The
 * walking function is called once for each snippet of JS and is passed that
 * snippet and the its original associated source's line/column location.
 *
 * @param aFn The traversal function.
 */
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
  var chunk;
  for (var i = 0, len = this.children.length; i < len; i++) {
    chunk = this.children[i];
    if (chunk[isSourceNode]) {
      chunk.walk(aFn);
    }
    else {
      if (chunk !== '') {
        aFn(chunk, { source: this.source,
                     line: this.line,
                     column: this.column,
                     name: this.name });
      }
    }
  }
};

/**
 * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
 * each of `this.children`.
 *
 * @param aSep The separator.
 */
SourceNode.prototype.join = function SourceNode_join(aSep) {
  var newChildren;
  var i;
  var len = this.children.length;
  if (len > 0) {
    newChildren = [];
    for (i = 0; i < len-1; i++) {
      newChildren.push(this.children[i]);
      newChildren.push(aSep);
    }
    newChildren.push(this.children[i]);
    this.children = newChildren;
  }
  return this;
};

/**
 * Call String.prototype.replace on the very right-most source snippet. Useful
 * for trimming whitespace from the end of a source node, etc.
 *
 * @param aPattern The pattern to replace.
 * @param aReplacement The thing to replace the pattern with.
 */
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
  var lastChild = this.children[this.children.length - 1];
  if (lastChild[isSourceNode]) {
    lastChild.replaceRight(aPattern, aReplacement);
  }
  else if (typeof lastChild === 'string') {
    this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
  }
  else {
    this.children.push(''.replace(aPattern, aReplacement));
  }
  return this;
};

/**
 * Set the source content for a source file. This will be added to the SourceMapGenerator
 * in the sourcesContent field.
 *
 * @param aSourceFile The filename of the source file
 * @param aSourceContent The content of the source file
 */
SourceNode.prototype.setSourceContent =
  function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
    this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
  };

/**
 * Walk over the tree of SourceNodes. The walking function is called for each
 * source file content and is passed the filename and source content.
 *
 * @param aFn The traversal function.
 */
SourceNode.prototype.walkSourceContents =
  function SourceNode_walkSourceContents(aFn) {
    for (var i = 0, len = this.children.length; i < len; i++) {
      if (this.children[i][isSourceNode]) {
        this.children[i].walkSourceContents(aFn);
      }
    }

    var sources = Object.keys(this.sourceContents);
    for (var i = 0, len = sources.length; i < len; i++) {
      aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
    }
  };

/**
 * Return the string representation of this source node. Walks over the tree
 * and concatenates all the various snippets together to one string.
 */
SourceNode.prototype.toString = function SourceNode_toString() {
  var str = "";
  this.walk(function (chunk) {
    str += chunk;
  });
  return str;
};

/**
 * Returns the string representation of this source node along with a source
 * map.
 */
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
  var generated = {
    code: "",
    line: 1,
    column: 0
  };
  var map = new SourceMapGenerator(aArgs);
  var sourceMappingActive = false;
  var lastOriginalSource = null;
  var lastOriginalLine = null;
  var lastOriginalColumn = null;
  var lastOriginalName = null;
  this.walk(function (chunk, original) {
    generated.code += chunk;
    if (original.source !== null
        && original.line !== null
        && original.column !== null) {
      if(lastOriginalSource !== original.source
         || lastOriginalLine !== original.line
         || lastOriginalColumn !== original.column
         || lastOriginalName !== original.name) {
        map.addMapping({
          source: original.source,
          original: {
            line: original.line,
            column: original.column
          },
          generated: {
            line: generated.line,
            column: generated.column
          },
          name: original.name
        });
      }
      lastOriginalSource = original.source;
      lastOriginalLine = original.line;
      lastOriginalColumn = original.column;
      lastOriginalName = original.name;
      sourceMappingActive = true;
    } else if (sourceMappingActive) {
      map.addMapping({
        generated: {
          line: generated.line,
          column: generated.column
        }
      });
      lastOriginalSource = null;
      sourceMappingActive = false;
    }
    for (var idx = 0, length = chunk.length; idx < length; idx++) {
      if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
        generated.line++;
        generated.column = 0;
        // Mappings end at eol
        if (idx + 1 === length) {
          lastOriginalSource = null;
          sourceMappingActive = false;
        } else if (sourceMappingActive) {
          map.addMapping({
            source: original.source,
            original: {
              line: original.line,
              column: original.column
            },
            generated: {
              line: generated.line,
              column: generated.column
            },
            name: original.name
          });
        }
      } else {
        generated.column++;
      }
    }
  });
  this.walkSourceContents(function (sourceFile, sourceContent) {
    map.setSourceContent(sourceFile, sourceContent);
  });

  return { code: generated.code, map: map };
};

exports.SourceNode = SourceNode;

},{"./source-map-generator":33,"./util":35}],35:[function(require,module,exports){
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

/**
 * This is a helper function for getting values from parameter/options
 * objects.
 *
 * @param args The object we are extracting values from
 * @param name The name of the property we are getting.
 * @param defaultValue An optional value to return if the property is missing
 * from the object. If this is not specified and the property is missing, an
 * error will be thrown.
 */
function getArg(aArgs, aName, aDefaultValue) {
  if (aName in aArgs) {
    return aArgs[aName];
  } else if (arguments.length === 3) {
    return aDefaultValue;
  } else {
    throw new Error('"' + aName + '" is a required argument.');
  }
}
exports.getArg = getArg;

var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
var dataUrlRegexp = /^data:.+\,.+$/;

function urlParse(aUrl) {
  var match = aUrl.match(urlRegexp);
  if (!match) {
    return null;
  }
  return {
    scheme: match[1],
    auth: match[2],
    host: match[3],
    port: match[4],
    path: match[5]
  };
}
exports.urlParse = urlParse;

function urlGenerate(aParsedUrl) {
  var url = '';
  if (aParsedUrl.scheme) {
    url += aParsedUrl.scheme + ':';
  }
  url += '//';
  if (aParsedUrl.auth) {
    url += aParsedUrl.auth + '@';
  }
  if (aParsedUrl.host) {
    url += aParsedUrl.host;
  }
  if (aParsedUrl.port) {
    url += ":" + aParsedUrl.port
  }
  if (aParsedUrl.path) {
    url += aParsedUrl.path;
  }
  return url;
}
exports.urlGenerate = urlGenerate;

/**
 * Normalizes a path, or the path portion of a URL:
 *
 * - Replaces consecutive slashes with one slash.
 * - Removes unnecessary '.' parts.
 * - Removes unnecessary '<dir>/..' parts.
 *
 * Based on code in the Node.js 'path' core module.
 *
 * @param aPath The path or url to normalize.
 */
function normalize(aPath) {
  var path = aPath;
  var url = urlParse(aPath);
  if (url) {
    if (!url.path) {
      return aPath;
    }
    path = url.path;
  }
  var isAbsolute = exports.isAbsolute(path);

  var parts = path.split(/\/+/);
  for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
    part = parts[i];
    if (part === '.') {
      parts.splice(i, 1);
    } else if (part === '..') {
      up++;
    } else if (up > 0) {
      if (part === '') {
        // The first part is blank if the path is absolute. Trying to go
        // above the root is a no-op. Therefore we can remove all '..' parts
        // directly after the root.
        parts.splice(i + 1, up);
        up = 0;
      } else {
        parts.splice(i, 2);
        up--;
      }
    }
  }
  path = parts.join('/');

  if (path === '') {
    path = isAbsolute ? '/' : '.';
  }

  if (url) {
    url.path = path;
    return urlGenerate(url);
  }
  return path;
}
exports.normalize = normalize;

/**
 * Joins two paths/URLs.
 *
 * @param aRoot The root path or URL.
 * @param aPath The path or URL to be joined with the root.
 *
 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
 *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended
 *   first.
 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
 *   is updated with the result and aRoot is returned. Otherwise the result
 *   is returned.
 *   - If aPath is absolute, the result is aPath.
 *   - Otherwise the two paths are joined with a slash.
 * - Joining for example 'http://' and 'www.example.com' is also supported.
 */
function join(aRoot, aPath) {
  if (aRoot === "") {
    aRoot = ".";
  }
  if (aPath === "") {
    aPath = ".";
  }
  var aPathUrl = urlParse(aPath);
  var aRootUrl = urlParse(aRoot);
  if (aRootUrl) {
    aRoot = aRootUrl.path || '/';
  }

  // `join(foo, '//www.example.org')`
  if (aPathUrl && !aPathUrl.scheme) {
    if (aRootUrl) {
      aPathUrl.scheme = aRootUrl.scheme;
    }
    return urlGenerate(aPathUrl);
  }

  if (aPathUrl || aPath.match(dataUrlRegexp)) {
    return aPath;
  }

  // `join('http://', 'www.example.com')`
  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
    aRootUrl.host = aPath;
    return urlGenerate(aRootUrl);
  }

  var joined = aPath.charAt(0) === '/'
    ? aPath
    : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);

  if (aRootUrl) {
    aRootUrl.path = joined;
    return urlGenerate(aRootUrl);
  }
  return joined;
}
exports.join = join;

exports.isAbsolute = function (aPath) {
  return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
};

/**
 * Make a path relative to a URL or another path.
 *
 * @param aRoot The root path or URL.
 * @param aPath The path or URL to be made relative to aRoot.
 */
function relative(aRoot, aPath) {
  if (aRoot === "") {
    aRoot = ".";
  }

  aRoot = aRoot.replace(/\/$/, '');

  // It is possible for the path to be above the root. In this case, simply
  // checking whether the root is a prefix of the path won't work. Instead, we
  // need to remove components from the root one by one, until either we find
  // a prefix that fits, or we run out of components to remove.
  var level = 0;
  while (aPath.indexOf(aRoot + '/') !== 0) {
    var index = aRoot.lastIndexOf("/");
    if (index < 0) {
      return aPath;
    }

    // If the only part of the root that is left is the scheme (i.e. http://,
    // file:///, etc.), one or more slashes (/), or simply nothing at all, we
    // have exhausted all components, so the path is not relative to the root.
    aRoot = aRoot.slice(0, index);
    if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
      return aPath;
    }

    ++level;
  }

  // Make sure we add a "../" for each component we removed from the root.
  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
}
exports.relative = relative;

var supportsNullProto = (function () {
  var obj = Object.create(null);
  return !('__proto__' in obj);
}());

function identity (s) {
  return s;
}

/**
 * Because behavior goes wacky when you set `__proto__` on objects, we
 * have to prefix all the strings in our set with an arbitrary character.
 *
 * See https://github.com/mozilla/source-map/pull/31 and
 * https://github.com/mozilla/source-map/issues/30
 *
 * @param String aStr
 */
function toSetString(aStr) {
  if (isProtoString(aStr)) {
    return '$' + aStr;
  }

  return aStr;
}
exports.toSetString = supportsNullProto ? identity : toSetString;

function fromSetString(aStr) {
  if (isProtoString(aStr)) {
    return aStr.slice(1);
  }

  return aStr;
}
exports.fromSetString = supportsNullProto ? identity : fromSetString;

function isProtoString(s) {
  if (!s) {
    return false;
  }

  var length = s.length;

  if (length < 9 /* "__proto__".length */) {
    return false;
  }

  if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||
      s.charCodeAt(length - 2) !== 95  /* '_' */ ||
      s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
      s.charCodeAt(length - 4) !== 116 /* 't' */ ||
      s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
      s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
      s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
      s.charCodeAt(length - 8) !== 95  /* '_' */ ||
      s.charCodeAt(length - 9) !== 95  /* '_' */) {
    return false;
  }

  for (var i = length - 10; i >= 0; i--) {
    if (s.charCodeAt(i) !== 36 /* '$' */) {
      return false;
    }
  }

  return true;
}

/**
 * Comparator between two mappings where the original positions are compared.
 *
 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
 * mappings with the same original source/line/column, but different generated
 * line and column the same. Useful when searching for a mapping with a
 * stubbed out mapping.
 */
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
  var cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0 || onlyCompareOriginal) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;

/**
 * Comparator between two mappings with deflated source and name indices where
 * the generated positions are compared.
 *
 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
 * mappings with the same generated line and column, but different
 * source/name/original line and column the same. Useful when searching for a
 * mapping with a stubbed out mapping.
 */
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
  var cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0 || onlyCompareGenerated) {
    return cmp;
  }

  cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;

function strcmp(aStr1, aStr2) {
  if (aStr1 === aStr2) {
    return 0;
  }

  if (aStr1 === null) {
    return 1; // aStr2 !== null
  }

  if (aStr2 === null) {
    return -1; // aStr1 !== null
  }

  if (aStr1 > aStr2) {
    return 1;
  }

  return -1;
}

/**
 * Comparator between two mappings with inflated source and name strings where
 * the generated positions are compared.
 */
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
  var cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;

/**
 * Strip any JSON XSSI avoidance prefix from the string (as documented
 * in the source maps specification), and then parse the string as
 * JSON.
 */
function parseSourceMapInput(str) {
  return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
}
exports.parseSourceMapInput = parseSourceMapInput;

/**
 * Compute the URL of a source given the the source root, the source's
 * URL, and the source map's URL.
 */
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
  sourceURL = sourceURL || '';

  if (sourceRoot) {
    // This follows what Chrome does.
    if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
      sourceRoot += '/';
    }
    // The spec says:
    //   Line 4: An optional source root, useful for relocating source
    //   files on a server or removing repeated values in the
    //   “sources” entry.  This value is prepended to the individual
    //   entries in the “source” field.
    sourceURL = sourceRoot + sourceURL;
  }

  // Historically, SourceMapConsumer did not take the sourceMapURL as
  // a parameter.  This mode is still somewhat supported, which is why
  // this code block is conditional.  However, it's preferable to pass
  // the source map URL to SourceMapConsumer, so that this function
  // can implement the source URL resolution algorithm as outlined in
  // the spec.  This block is basically the equivalent of:
  //    new URL(sourceURL, sourceMapURL).toString()
  // ... except it avoids using URL, which wasn't available in the
  // older releases of node still supported by this library.
  //
  // The spec says:
  //   If the sources are not absolute URLs after prepending of the
  //   “sourceRoot”, the sources are resolved relative to the
  //   SourceMap (like resolving script src in a html document).
  if (sourceMapURL) {
    var parsed = urlParse(sourceMapURL);
    if (!parsed) {
      throw new Error("sourceMapURL could not be parsed");
    }
    if (parsed.path) {
      // Strip the last path component, but keep the "/".
      var index = parsed.path.lastIndexOf('/');
      if (index >= 0) {
        parsed.path = parsed.path.substring(0, index + 1);
      }
    }
    sourceURL = join(urlGenerate(parsed), sourceURL);
  }

  return normalize(sourceURL);
}
exports.computeSourceURL = computeSourceURL;

},{}],36:[function(require,module,exports){
/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./lib/source-node').SourceNode;

},{"./lib/source-map-consumer":32,"./lib/source-map-generator":33,"./lib/source-node":34}]},{},[14]);
var SPECIFICITY=function(){var t,e;return t=function(t){var r,n,i,c,a=[];for(i=0,c=(r=t.split(",")).length;i<c;i+=1)(n=r[i]).length>0&&a.push(e(n));return a},e=function(t){var e,r,n=t,i={a:0,b:0,c:0},c=[];return e=function(t,e){var r,a,g,l,o,s;if(t.test(n))for(a=0,g=(r=n.match(t)).length;a<g;a+=1)i[e]+=1,l=r[a],o=n.indexOf(l),s=l.length,c.push({selector:l,type:e,index:o,length:s}),n=n.replace(l,Array(s+1).join(" "))},(r=/:not\(([^\)]*)\)/g).test(n)&&(n=n.replace(r,"     $1 ")),function(){var t,e,r,i,c=/{[^]*/gm;if(c.test(n))for(e=0,r=(t=n.match(c)).length;e<r;e+=1)i=t[e],n=n.replace(i,Array(i.length+1).join(" "))}(),e(/(\[[^\]]+\])/g,"b"),e(/(#[^\s\+>~\.\[:]+)/g,"a"),e(/(\.[^\s\+>~\.\[:]+)/g,"b"),e(/(::[^\s\+>~\.\[:]+|:first-line|:first-letter|:before|:after)/gi,"c"),e(/(:[\w-]+\([^\)]*\))/gi,"b"),e(/(:[^\s\+>~\.\[:]+)/g,"b"),n=(n=n.replace(/[\*\s\+>~]/g," ")).replace(/[#\.]/g," "),e(/([^\s\+>~\.\[:]+)/g,"c"),c.sort((function(t,e){return t.index-e.index})),{selector:t,specificity:"0,"+i.a.toString()+","+i.b.toString()+","+i.c.toString(),parts:c}},{calculate:t}}();/*!
 * URI.js - Mutating URLs
 *
 * Version: 1.18.1
 *
 * Author: Rodney Rehm
 * Web: http://medialize.github.io/URI.js/
 *
 * Licensed under
 *   MIT License http://www.opensource.org/licenses/mit-license
 *
 */
(function (root, factory) {
  'use strict';
  // Browser globals (root is window)
  root.URI = factory(root.punycode, root.IPv6, root.SecondLevelDomains, root);
}(this, function (punycode, IPv6, SLD, root) {
  'use strict';
  /*global location, escape, unescape */
  // FIXME: v2.0.0 renamce non-camelCase properties to uppercase
  /*jshint camelcase: false */

  // save current URI variable, if any
  var _URI = root && root.URI;

  function URI(url, base) {
    var _urlSupplied = arguments.length >= 1;
    var _baseSupplied = arguments.length >= 2;

    // Allow instantiation without the 'new' keyword
    if (!(this instanceof URI)) {
      if (_urlSupplied) {
        if (_baseSupplied) {
          return new URI(url, base);
        }

        return new URI(url);
      }

      return new URI();
    }

    if (url === undefined) {
      if (_urlSupplied) {
        throw new TypeError('undefined is not a valid argument for URI');
      }

      if (typeof location !== 'undefined') {
        url = location.href + '';
      } else {
        url = '';
      }
    }

    this.href(url);

    // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor
    if (base !== undefined) {
      return this.absoluteTo(base);
    }

    return this;
  }

  URI.version = '1.18.1';

  var p = URI.prototype;
  var hasOwn = Object.prototype.hasOwnProperty;

  function escapeRegEx(string) {
    // https://github.com/medialize/URI.js/commit/85ac21783c11f8ccab06106dba9735a31a86924d#commitcomment-821963
    return string.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
  }

  function getType(value) {
    // IE8 doesn't return [Object Undefined] but [Object Object] for undefined value
    if (value === undefined) {
      return 'Undefined';
    }

    return String(Object.prototype.toString.call(value)).slice(8, -1);
  }

  function isArray(obj) {
    return getType(obj) === 'Array';
  }

  function filterArrayValues(data, value) {
    var lookup = {};
    var i, length;

    if (getType(value) === 'RegExp') {
      lookup = null;
    } else if (isArray(value)) {
      for (i = 0, length = value.length; i < length; i++) {
        lookup[value[i]] = true;
      }
    } else {
      lookup[value] = true;
    }

    for (i = 0, length = data.length; i < length; i++) {
      /*jshint laxbreak: true */
      var _match = lookup && lookup[data[i]] !== undefined
        || !lookup && value.test(data[i]);
      /*jshint laxbreak: false */
      if (_match) {
        data.splice(i, 1);
        length--;
        i--;
      }
    }

    return data;
  }

  function arrayContains(list, value) {
    var i, length;

    // value may be string, number, array, regexp
    if (isArray(value)) {
      // Note: this can be optimized to O(n) (instead of current O(m * n))
      for (i = 0, length = value.length; i < length; i++) {
        if (!arrayContains(list, value[i])) {
          return false;
        }
      }

      return true;
    }

    var _type = getType(value);
    for (i = 0, length = list.length; i < length; i++) {
      if (_type === 'RegExp') {
        if (typeof list[i] === 'string' && list[i].match(value)) {
          return true;
        }
      } else if (list[i] === value) {
        return true;
      }
    }

    return false;
  }

  function arraysEqual(one, two) {
    if (!isArray(one) || !isArray(two)) {
      return false;
    }

    // arrays can't be equal if they have different amount of content
    if (one.length !== two.length) {
      return false;
    }

    one.sort();
    two.sort();

    for (var i = 0, l = one.length; i < l; i++) {
      if (one[i] !== two[i]) {
        return false;
      }
    }

    return true;
  }

  function trimSlashes(text) {
    var trim_expression = /^\/+|\/+$/g;
    return text.replace(trim_expression, '');
  }

  URI._parts = function() {
    return {
      protocol: null,
      username: null,
      password: null,
      hostname: null,
      urn: null,
      port: null,
      path: null,
      query: null,
      fragment: null,
      // state
      duplicateQueryParameters: URI.duplicateQueryParameters,
      escapeQuerySpace: URI.escapeQuerySpace
    };
  };
  // state: allow duplicate query parameters (a=1&a=1)
  URI.duplicateQueryParameters = false;
  // state: replaces + with %20 (space in query strings)
  URI.escapeQuerySpace = true;
  // static properties
  URI.protocol_expression = /^[a-z][a-z0-9.+-]*$/i;
  URI.idn_expression = /[^a-z0-9\.-]/i;
  URI.punycode_expression = /(xn--)/i;
  // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care?
  URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
  // credits to Rich Brown
  // source: http://forums.intermapper.com/viewtopic.php?p=1096#1096
  // specification: http://www.ietf.org/rfc/rfc4291.txt
  URI.ip6_expression = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;
  // expression used is "gruber revised" (@gruber v2) determined to be the
  // best solution in a regex-golf we did a couple of ages ago at
  // * http://mathiasbynens.be/demo/url-regex
  // * http://rodneyrehm.de/t/url-regex.html
  URI.find_uri_expression = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig;
  URI.findUri = {
    // valid "scheme://" or "www."
    start: /\b(?:([a-z][a-z0-9.+-]*:\/\/)|www\.)/gi,
    // everything up to the next whitespace
    end: /[\s\r\n]|$/,
    // trim trailing punctuation captured by end RegExp
    trim: /[`!()\[\]{};:'".,<>?«»“”„‘’]+$/
  };
  // http://www.iana.org/assignments/uri-schemes.html
  // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports
  URI.defaultPorts = {
    http: '80',
    https: '443',
    ftp: '21',
    gopher: '70',
    ws: '80',
    wss: '443'
  };
  // allowed hostname characters according to RFC 3986
  // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded
  // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . -
  URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/;
  // map DOM Elements to their URI attribute
  URI.domAttributes = {
    'a': 'href',
    'blockquote': 'cite',
    'link': 'href',
    'base': 'href',
    'script': 'src',
    'form': 'action',
    'img': 'src',
    'area': 'href',
    'iframe': 'src',
    'embed': 'src',
    'source': 'src',
    'track': 'src',
    'input': 'src', // but only if type="image"
    'audio': 'src',
    'video': 'src'
  };
  URI.getDomAttribute = function(node) {
    if (!node || !node.nodeName) {
      return undefined;
    }

    var nodeName = node.nodeName.toLowerCase();
    // <input> should only expose src for type="image"
    if (nodeName === 'input' && node.type !== 'image') {
      return undefined;
    }

    return URI.domAttributes[nodeName];
  };

  function escapeForDumbFirefox36(value) {
    // https://github.com/medialize/URI.js/issues/91
    return escape(value);
  }

  // encoding / decoding according to RFC3986
  function strictEncodeURIComponent(string) {
    // see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent
    return encodeURIComponent(string)
      .replace(/[!'()*]/g, escapeForDumbFirefox36)
      .replace(/\*/g, '%2A');
  }
  URI.encode = strictEncodeURIComponent;
  URI.decode = decodeURIComponent;
  URI.iso8859 = function() {
    URI.encode = escape;
    URI.decode = unescape;
  };
  URI.unicode = function() {
    URI.encode = strictEncodeURIComponent;
    URI.decode = decodeURIComponent;
  };
  URI.characters = {
    pathname: {
      encode: {
        // RFC3986 2.1: For consistency, URI producers and normalizers should
        // use uppercase hexadecimal digits for all percent-encodings.
        expression: /%(24|26|2B|2C|3B|3D|3A|40)/ig,
        map: {
          // -._~!'()*
          '%24': '$',
          '%26': '&',
          '%2B': '+',
          '%2C': ',',
          '%3B': ';',
          '%3D': '=',
          '%3A': ':',
          '%40': '@'
        }
      },
      decode: {
        expression: /[\/\?#]/g,
        map: {
          '/': '%2F',
          '?': '%3F',
          '#': '%23'
        }
      }
    },
    reserved: {
      encode: {
        // RFC3986 2.1: For consistency, URI producers and normalizers should
        // use uppercase hexadecimal digits for all percent-encodings.
        expression: /%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig,
        map: {
          // gen-delims
          '%3A': ':',
          '%2F': '/',
          '%3F': '?',
          '%23': '#',
          '%5B': '[',
          '%5D': ']',
          '%40': '@',
          // sub-delims
          '%21': '!',
          '%24': '$',
          '%26': '&',
          '%27': '\'',
          '%28': '(',
          '%29': ')',
          '%2A': '*',
          '%2B': '+',
          '%2C': ',',
          '%3B': ';',
          '%3D': '='
        }
      }
    },
    urnpath: {
      // The characters under `encode` are the characters called out by RFC 2141 as being acceptable
      // for usage in a URN. RFC2141 also calls out "-", ".", and "_" as acceptable characters, but
      // these aren't encoded by encodeURIComponent, so we don't have to call them out here. Also
      // note that the colon character is not featured in the encoding map; this is because URI.js
      // gives the colons in URNs semantic meaning as the delimiters of path segements, and so it
      // should not appear unencoded in a segment itself.
      // See also the note above about RFC3986 and capitalalized hex digits.
      encode: {
        expression: /%(21|24|27|28|29|2A|2B|2C|3B|3D|40)/ig,
        map: {
          '%21': '!',
          '%24': '$',
          '%27': '\'',
          '%28': '(',
          '%29': ')',
          '%2A': '*',
          '%2B': '+',
          '%2C': ',',
          '%3B': ';',
          '%3D': '=',
          '%40': '@'
        }
      },
      // These characters are the characters called out by RFC2141 as "reserved" characters that
      // should never appear in a URN, plus the colon character (see note above).
      decode: {
        expression: /[\/\?#:]/g,
        map: {
          '/': '%2F',
          '?': '%3F',
          '#': '%23',
          ':': '%3A'
        }
      }
    }
  };
  URI.encodeQuery = function(string, escapeQuerySpace) {
    var escaped = URI.encode(string + '');
    if (escapeQuerySpace === undefined) {
      escapeQuerySpace = URI.escapeQuerySpace;
    }

    return escapeQuerySpace ? escaped.replace(/%20/g, '+') : escaped;
  };
  URI.decodeQuery = function(string, escapeQuerySpace) {
    string += '';
    if (escapeQuerySpace === undefined) {
      escapeQuerySpace = URI.escapeQuerySpace;
    }

    try {
      return URI.decode(escapeQuerySpace ? string.replace(/\+/g, '%20') : string);
    } catch(e) {
      // we're not going to mess with weird encodings,
      // give up and return the undecoded original string
      // see https://github.com/medialize/URI.js/issues/87
      // see https://github.com/medialize/URI.js/issues/92
      return string;
    }
  };
  // generate encode/decode path functions
  var _parts = {'encode':'encode', 'decode':'decode'};
  var _part;
  var generateAccessor = function(_group, _part) {
    return function(string) {
      try {
        return URI[_part](string + '').replace(URI.characters[_group][_part].expression, function(c) {
          return URI.characters[_group][_part].map[c];
        });
      } catch (e) {
        // we're not going to mess with weird encodings,
        // give up and return the undecoded original string
        // see https://github.com/medialize/URI.js/issues/87
        // see https://github.com/medialize/URI.js/issues/92
        return string;
      }
    };
  };

  for (_part in _parts) {
    URI[_part + 'PathSegment'] = generateAccessor('pathname', _parts[_part]);
    URI[_part + 'UrnPathSegment'] = generateAccessor('urnpath', _parts[_part]);
  }

  var generateSegmentedPathFunction = function(_sep, _codingFuncName, _innerCodingFuncName) {
    return function(string) {
      // Why pass in names of functions, rather than the function objects themselves? The
      // definitions of some functions (but in particular, URI.decode) will occasionally change due
      // to URI.js having ISO8859 and Unicode modes. Passing in the name and getting it will ensure
      // that the functions we use here are "fresh".
      var actualCodingFunc;
      if (!_innerCodingFuncName) {
        actualCodingFunc = URI[_codingFuncName];
      } else {
        actualCodingFunc = function(string) {
          return URI[_codingFuncName](URI[_innerCodingFuncName](string));
        };
      }

      var segments = (string + '').split(_sep);

      for (var i = 0, length = segments.length; i < length; i++) {
        segments[i] = actualCodingFunc(segments[i]);
      }

      return segments.join(_sep);
    };
  };

  // This takes place outside the above loop because we don't want, e.g., encodeUrnPath functions.
  URI.decodePath = generateSegmentedPathFunction('/', 'decodePathSegment');
  URI.decodeUrnPath = generateSegmentedPathFunction(':', 'decodeUrnPathSegment');
  URI.recodePath = generateSegmentedPathFunction('/', 'encodePathSegment', 'decode');
  URI.recodeUrnPath = generateSegmentedPathFunction(':', 'encodeUrnPathSegment', 'decode');

  URI.encodeReserved = generateAccessor('reserved', 'encode');

  URI.parse = function(string, parts) {
    var pos;
    if (!parts) {
      parts = {};
    }
    // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment]

    // extract fragment
    pos = string.indexOf('#');
    if (pos > -1) {
      // escaping?
      parts.fragment = string.substring(pos + 1) || null;
      string = string.substring(0, pos);
    }

    // extract query
    pos = string.indexOf('?');
    if (pos > -1) {
      // escaping?
      parts.query = string.substring(pos + 1) || null;
      string = string.substring(0, pos);
    }

    // extract protocol
    if (string.substring(0, 2) === '//') {
      // relative-scheme
      parts.protocol = null;
      string = string.substring(2);
      // extract "user:pass@host:port"
      string = URI.parseAuthority(string, parts);
    } else {
      pos = string.indexOf(':');
      if (pos > -1) {
        parts.protocol = string.substring(0, pos) || null;
        if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) {
          // : may be within the path
          parts.protocol = undefined;
        } else if (string.substring(pos + 1, pos + 3) === '//') {
          string = string.substring(pos + 3);

          // extract "user:pass@host:port"
          string = URI.parseAuthority(string, parts);
        } else {
          string = string.substring(pos + 1);
          parts.urn = true;
        }
      }
    }

    // what's left must be the path
    parts.path = string;

    // and we're done
    return parts;
  };
  URI.parseHost = function(string, parts) {
    // Copy chrome, IE, opera backslash-handling behavior.
    // Back slashes before the query string get converted to forward slashes
    // See: https://github.com/joyent/node/blob/386fd24f49b0e9d1a8a076592a404168faeecc34/lib/url.js#L115-L124
    // See: https://code.google.com/p/chromium/issues/detail?id=25916
    // https://github.com/medialize/URI.js/pull/233
    string = string.replace(/\\/g, '/');

    // extract host:port
    var pos = string.indexOf('/');
    var bracketPos;
    var t;

    if (pos === -1) {
      pos = string.length;
    }

    if (string.charAt(0) === '[') {
      // IPv6 host - http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04#section-6
      // I claim most client software breaks on IPv6 anyways. To simplify things, URI only accepts
      // IPv6+port in the format [2001:db8::1]:80 (for the time being)
      bracketPos = string.indexOf(']');
      parts.hostname = string.substring(1, bracketPos) || null;
      parts.port = string.substring(bracketPos + 2, pos) || null;
      if (parts.port === '/') {
        parts.port = null;
      }
    } else {
      var firstColon = string.indexOf(':');
      var firstSlash = string.indexOf('/');
      var nextColon = string.indexOf(':', firstColon + 1);
      if (nextColon !== -1 && (firstSlash === -1 || nextColon < firstSlash)) {
        // IPv6 host contains multiple colons - but no port
        // this notation is actually not allowed by RFC 3986, but we're a liberal parser
        parts.hostname = string.substring(0, pos) || null;
        parts.port = null;
      } else {
        t = string.substring(0, pos).split(':');
        parts.hostname = t[0] || null;
        parts.port = t[1] || null;
      }
    }

    if (parts.hostname && string.substring(pos).charAt(0) !== '/') {
      pos++;
      string = '/' + string;
    }

    return string.substring(pos) || '/';
  };
  URI.parseAuthority = function(string, parts) {
    string = URI.parseUserinfo(string, parts);
    return URI.parseHost(string, parts);
  };
  URI.parseUserinfo = function(string, parts) {
    // extract username:password
    var firstSlash = string.indexOf('/');
    var pos = string.lastIndexOf('@', firstSlash > -1 ? firstSlash : string.length - 1);
    var t;

    // authority@ must come before /path
    if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) {
      t = string.substring(0, pos).split(':');
      parts.username = t[0] ? URI.decode(t[0]) : null;
      t.shift();
      parts.password = t[0] ? URI.decode(t.join(':')) : null;
      string = string.substring(pos + 1);
    } else {
      parts.username = null;
      parts.password = null;
    }

    return string;
  };
  URI.parseQuery = function(string, escapeQuerySpace) {
    if (!string) {
      return {};
    }

    // throw out the funky business - "?"[name"="value"&"]+
    string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, '');

    if (!string) {
      return {};
    }

    var items = {};
    var splits = string.split('&');
    var length = splits.length;
    var v, name, value;

    for (var i = 0; i < length; i++) {
      v = splits[i].split('=');
      name = URI.decodeQuery(v.shift(), escapeQuerySpace);
      // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters
      value = v.length ? URI.decodeQuery(v.join('='), escapeQuerySpace) : null;

      if (hasOwn.call(items, name)) {
        if (typeof items[name] === 'string' || items[name] === null) {
          items[name] = [items[name]];
        }

        items[name].push(value);
      } else {
        items[name] = value;
      }
    }

    return items;
  };

  URI.build = function(parts) {
    var t = '';

    if (parts.protocol) {
      t += parts.protocol + ':';
    }

    if (!parts.urn && (t || parts.hostname)) {
      t += '//';
    }

    t += (URI.buildAuthority(parts) || '');

    if (typeof parts.path === 'string') {
      if (parts.path.charAt(0) !== '/' && typeof parts.hostname === 'string') {
        t += '/';
      }

      t += parts.path;
    }

    if (typeof parts.query === 'string' && parts.query) {
      t += '?' + parts.query;
    }

    if (typeof parts.fragment === 'string' && parts.fragment) {
      t += '#' + parts.fragment;
    }
    return t;
  };
  URI.buildHost = function(parts) {
    var t = '';

    if (!parts.hostname) {
      return '';
    } else if (URI.ip6_expression.test(parts.hostname)) {
      t += '[' + parts.hostname + ']';
    } else {
      t += parts.hostname;
    }

    if (parts.port) {
      t += ':' + parts.port;
    }

    return t;
  };
  URI.buildAuthority = function(parts) {
    return URI.buildUserinfo(parts) + URI.buildHost(parts);
  };
  URI.buildUserinfo = function(parts) {
    var t = '';

    if (parts.username) {
      t += URI.encode(parts.username);
    }

    if (parts.password) {
      t += ':' + URI.encode(parts.password);
    }

    if (t) {
      t += '@';
    }

    return t;
  };
  URI.buildQuery = function(data, duplicateQueryParameters, escapeQuerySpace) {
    // according to http://tools.ietf.org/html/rfc3986 or http://labs.apache.org/webarch/uri/rfc/rfc3986.html
    // being »-._~!$&'()*+,;=:@/?« %HEX and alnum are allowed
    // the RFC explicitly states ?/foo being a valid use case, no mention of parameter syntax!
    // URI.js treats the query string as being application/x-www-form-urlencoded
    // see http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type

    var t = '';
    var unique, key, i, length;
    for (key in data) {
      if (hasOwn.call(data, key) && key) {
        if (isArray(data[key])) {
          unique = {};
          for (i = 0, length = data[key].length; i < length; i++) {
            if (data[key][i] !== undefined && unique[data[key][i] + ''] === undefined) {
              t += '&' + URI.buildQueryParameter(key, data[key][i], escapeQuerySpace);
              if (duplicateQueryParameters !== true) {
                unique[data[key][i] + ''] = true;
              }
            }
          }
        } else if (data[key] !== undefined) {
          t += '&' + URI.buildQueryParameter(key, data[key], escapeQuerySpace);
        }
      }
    }

    return t.substring(1);
  };
  URI.buildQueryParameter = function(name, value, escapeQuerySpace) {
    // http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type -- application/x-www-form-urlencoded
    // don't append "=" for null values, according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#url-parameter-serialization
    return URI.encodeQuery(name, escapeQuerySpace) + (value !== null ? '=' + URI.encodeQuery(value, escapeQuerySpace) : '');
  };

  URI.addQuery = function(data, name, value) {
    if (typeof name === 'object') {
      for (var key in name) {
        if (hasOwn.call(name, key)) {
          URI.addQuery(data, key, name[key]);
        }
      }
    } else if (typeof name === 'string') {
      if (data[name] === undefined) {
        data[name] = value;
        return;
      } else if (typeof data[name] === 'string') {
        data[name] = [data[name]];
      }

      if (!isArray(value)) {
        value = [value];
      }

      data[name] = (data[name] || []).concat(value);
    } else {
      throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
    }
  };
  URI.removeQuery = function(data, name, value) {
    var i, length, key;

    if (isArray(name)) {
      for (i = 0, length = name.length; i < length; i++) {
        data[name[i]] = undefined;
      }
    } else if (getType(name) === 'RegExp') {
      for (key in data) {
        if (name.test(key)) {
          data[key] = undefined;
        }
      }
    } else if (typeof name === 'object') {
      for (key in name) {
        if (hasOwn.call(name, key)) {
          URI.removeQuery(data, key, name[key]);
        }
      }
    } else if (typeof name === 'string') {
      if (value !== undefined) {
        if (getType(value) === 'RegExp') {
          if (!isArray(data[name]) && value.test(data[name])) {
            data[name] = undefined;
          } else {
            data[name] = filterArrayValues(data[name], value);
          }
        } else if (data[name] === String(value) && (!isArray(value) || value.length === 1)) {
          data[name] = undefined;
        } else if (isArray(data[name])) {
          data[name] = filterArrayValues(data[name], value);
        }
      } else {
        data[name] = undefined;
      }
    } else {
      throw new TypeError('URI.removeQuery() accepts an object, string, RegExp as the first parameter');
    }
  };
  URI.hasQuery = function(data, name, value, withinArray) {
    switch (getType(name)) {
      case 'String':
        // Nothing to do here
        break;

      case 'RegExp':
        for (var key in data) {
          if (hasOwn.call(data, key)) {
            if (name.test(key) && (value === undefined || URI.hasQuery(data, key, value))) {
              return true;
            }
          }
        }

        return false;

      case 'Object':
        for (var _key in name) {
          if (hasOwn.call(name, _key)) {
            if (!URI.hasQuery(data, _key, name[_key])) {
              return false;
            }
          }
        }

        return true;

      default:
        throw new TypeError('URI.hasQuery() accepts a string, regular expression or object as the name parameter');
    }

    switch (getType(value)) {
      case 'Undefined':
        // true if exists (but may be empty)
        return name in data; // data[name] !== undefined;

      case 'Boolean':
        // true if exists and non-empty
        var _booly = Boolean(isArray(data[name]) ? data[name].length : data[name]);
        return value === _booly;

      case 'Function':
        // allow complex comparison
        return !!value(data[name], name, data);

      case 'Array':
        if (!isArray(data[name])) {
          return false;
        }

        var op = withinArray ? arrayContains : arraysEqual;
        return op(data[name], value);

      case 'RegExp':
        if (!isArray(data[name])) {
          return Boolean(data[name] && data[name].match(value));
        }

        if (!withinArray) {
          return false;
        }

        return arrayContains(data[name], value);

      case 'Number':
        value = String(value);
        /* falls through */
      case 'String':
        if (!isArray(data[name])) {
          return data[name] === value;
        }

        if (!withinArray) {
          return false;
        }

        return arrayContains(data[name], value);

      default:
        throw new TypeError('URI.hasQuery() accepts undefined, boolean, string, number, RegExp, Function as the value parameter');
    }
  };


  URI.joinPaths = function() {
    var input = [];
    var segments = [];
    var nonEmptySegments = 0;

    for (var i = 0; i < arguments.length; i++) {
      var url = new URI(arguments[i]);
      input.push(url);
      var _segments = url.segment();
      for (var s = 0; s < _segments.length; s++) {
        if (typeof _segments[s] === 'string') {
          segments.push(_segments[s]);
        }

        if (_segments[s]) {
          nonEmptySegments++;
        }
      }
    }

    if (!segments.length || !nonEmptySegments) {
      return new URI('');
    }

    var uri = new URI('').segment(segments);

    if (input[0].path() === '' || input[0].path().slice(0, 1) === '/') {
      uri.path('/' + uri.path());
    }

    return uri.normalize();
  };

  URI.commonPath = function(one, two) {
    var length = Math.min(one.length, two.length);
    var pos;

    // find first non-matching character
    for (pos = 0; pos < length; pos++) {
      if (one.charAt(pos) !== two.charAt(pos)) {
        pos--;
        break;
      }
    }

    if (pos < 1) {
      return one.charAt(0) === two.charAt(0) && one.charAt(0) === '/' ? '/' : '';
    }

    // revert to last /
    if (one.charAt(pos) !== '/' || two.charAt(pos) !== '/') {
      pos = one.substring(0, pos).lastIndexOf('/');
    }

    return one.substring(0, pos + 1);
  };

  URI.withinString = function(string, callback, options) {
    options || (options = {});
    var _start = options.start || URI.findUri.start;
    var _end = options.end || URI.findUri.end;
    var _trim = options.trim || URI.findUri.trim;
    var _attributeOpen = /[a-z0-9-]=["']?$/i;

    _start.lastIndex = 0;
    while (true) {
      var match = _start.exec(string);
      if (!match) {
        break;
      }

      var start = match.index;
      if (options.ignoreHtml) {
        // attribut(e=["']?$)
        var attributeOpen = string.slice(Math.max(start - 3, 0), start);
        if (attributeOpen && _attributeOpen.test(attributeOpen)) {
          continue;
        }
      }

      var end = start + string.slice(start).search(_end);
      var slice = string.slice(start, end).replace(_trim, '');
      if (options.ignore && options.ignore.test(slice)) {
        continue;
      }

      end = start + slice.length;
      var result = callback(slice, start, end, string);
      string = string.slice(0, start) + result + string.slice(end);
      _start.lastIndex = start + result.length;
    }

    _start.lastIndex = 0;
    return string;
  };

  URI.ensureValidHostname = function(v) {
    // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986)
    // they are not part of DNS and therefore ignored by URI.js

    if (v.match(URI.invalid_hostname_characters)) {
      // test punycode
      if (!punycode) {
        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-] and Punycode.js is not available');
      }

      if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) {
        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
      }
    }
  };

  // noConflict
  URI.noConflict = function(removeAll) {
    if (removeAll) {
      var unconflicted = {
        URI: this.noConflict()
      };

      if (root.URITemplate && typeof root.URITemplate.noConflict === 'function') {
        unconflicted.URITemplate = root.URITemplate.noConflict();
      }

      if (root.IPv6 && typeof root.IPv6.noConflict === 'function') {
        unconflicted.IPv6 = root.IPv6.noConflict();
      }

      if (root.SecondLevelDomains && typeof root.SecondLevelDomains.noConflict === 'function') {
        unconflicted.SecondLevelDomains = root.SecondLevelDomains.noConflict();
      }

      return unconflicted;
    } else if (root.URI === this) {
      root.URI = _URI;
    }

    return this;
  };

  p.build = function(deferBuild) {
    if (deferBuild === true) {
      this._deferred_build = true;
    } else if (deferBuild === undefined || this._deferred_build) {
      this._string = URI.build(this._parts);
      this._deferred_build = false;
    }

    return this;
  };

  p.clone = function() {
    return new URI(this);
  };

  p.valueOf = p.toString = function() {
    return this.build(false)._string;
  };


  function generateSimpleAccessor(_part){
    return function(v, build) {
      if (v === undefined) {
        return this._parts[_part] || '';
      } else {
        this._parts[_part] = v || null;
        this.build(!build);
        return this;
      }
    };
  }

  function generatePrefixAccessor(_part, _key){
    return function(v, build) {
      if (v === undefined) {
        return this._parts[_part] || '';
      } else {
        if (v !== null) {
          v = v + '';
          if (v.charAt(0) === _key) {
            v = v.substring(1);
          }
        }

        this._parts[_part] = v;
        this.build(!build);
        return this;
      }
    };
  }

  p.protocol = generateSimpleAccessor('protocol');
  p.username = generateSimpleAccessor('username');
  p.password = generateSimpleAccessor('password');
  p.hostname = generateSimpleAccessor('hostname');
  p.port = generateSimpleAccessor('port');
  p.query = generatePrefixAccessor('query', '?');
  p.fragment = generatePrefixAccessor('fragment', '#');

  p.search = function(v, build) {
    var t = this.query(v, build);
    return typeof t === 'string' && t.length ? ('?' + t) : t;
  };
  p.hash = function(v, build) {
    var t = this.fragment(v, build);
    return typeof t === 'string' && t.length ? ('#' + t) : t;
  };

  p.pathname = function(v, build) {
    if (v === undefined || v === true) {
      var res = this._parts.path || (this._parts.hostname ? '/' : '');
      return v ? (this._parts.urn ? URI.decodeUrnPath : URI.decodePath)(res) : res;
    } else {
      if (this._parts.urn) {
        this._parts.path = v ? URI.recodeUrnPath(v) : '';
      } else {
        this._parts.path = v ? URI.recodePath(v) : '/';
      }
      this.build(!build);
      return this;
    }
  };
  p.path = p.pathname;
  p.href = function(href, build) {
    var key;

    if (href === undefined) {
      return this.toString();
    }

    this._string = '';
    this._parts = URI._parts();

    var _URI = href instanceof URI;
    var _object = typeof href === 'object' && (href.hostname || href.path || href.pathname);
    if (href.nodeName) {
      var attribute = URI.getDomAttribute(href);
      href = href[attribute] || '';
      _object = false;
    }

    // window.location is reported to be an object, but it's not the sort
    // of object we're looking for:
    // * location.protocol ends with a colon
    // * location.query != object.search
    // * location.hash != object.fragment
    // simply serializing the unknown object should do the trick
    // (for location, not for everything...)
    if (!_URI && _object && href.pathname !== undefined) {
      href = href.toString();
    }

    if (typeof href === 'string' || href instanceof String) {
      this._parts = URI.parse(String(href), this._parts);
    } else if (_URI || _object) {
      var src = _URI ? href._parts : href;
      for (key in src) {
        if (hasOwn.call(this._parts, key)) {
          this._parts[key] = src[key];
        }
      }
    } else {
      throw new TypeError('invalid input');
    }

    this.build(!build);
    return this;
  };

  // identification accessors
  p.is = function(what) {
    var ip = false;
    var ip4 = false;
    var ip6 = false;
    var name = false;
    var sld = false;
    var idn = false;
    var punycode = false;
    var relative = !this._parts.urn;

    if (this._parts.hostname) {
      relative = false;
      ip4 = URI.ip4_expression.test(this._parts.hostname);
      ip6 = URI.ip6_expression.test(this._parts.hostname);
      ip = ip4 || ip6;
      name = !ip;
      sld = name && SLD && SLD.has(this._parts.hostname);
      idn = name && URI.idn_expression.test(this._parts.hostname);
      punycode = name && URI.punycode_expression.test(this._parts.hostname);
    }

    switch (what.toLowerCase()) {
      case 'relative':
        return relative;

      case 'absolute':
        return !relative;

      // hostname identification
      case 'domain':
      case 'name':
        return name;

      case 'sld':
        return sld;

      case 'ip':
        return ip;

      case 'ip4':
      case 'ipv4':
      case 'inet4':
        return ip4;

      case 'ip6':
      case 'ipv6':
      case 'inet6':
        return ip6;

      case 'idn':
        return idn;

      case 'url':
        return !this._parts.urn;

      case 'urn':
        return !!this._parts.urn;

      case 'punycode':
        return punycode;
    }

    return null;
  };

  // component specific input validation
  var _protocol = p.protocol;
  var _port = p.port;
  var _hostname = p.hostname;

  p.protocol = function(v, build) {
    if (v !== undefined) {
      if (v) {
        // accept trailing ://
        v = v.replace(/:(\/\/)?$/, '');

        if (!v.match(URI.protocol_expression)) {
          throw new TypeError('Protocol "' + v + '" contains characters other than [A-Z0-9.+-] or doesn\'t start with [A-Z]');
        }
      }
    }
    return _protocol.call(this, v, build);
  };
  p.scheme = p.protocol;
  p.port = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v !== undefined) {
      if (v === 0) {
        v = null;
      }

      if (v) {
        v += '';
        if (v.charAt(0) === ':') {
          v = v.substring(1);
        }

        if (v.match(/[^0-9]/)) {
          throw new TypeError('Port "' + v + '" contains characters other than [0-9]');
        }
      }
    }
    return _port.call(this, v, build);
  };
  p.hostname = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v !== undefined) {
      var x = {};
      var res = URI.parseHost(v, x);
      if (res !== '/') {
        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
      }

      v = x.hostname;
    }
    return _hostname.call(this, v, build);
  };

  // compound accessors
  p.origin = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined) {
      var protocol = this.protocol();
      var authority = this.authority();
      if (!authority) {
        return '';
      }

      return (protocol ? protocol + '://' : '') + this.authority();
    } else {
      var origin = URI(v);
      this
        .protocol(origin.protocol())
        .authority(origin.authority())
        .build(!build);
      return this;
    }
  };
  p.host = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined) {
      return this._parts.hostname ? URI.buildHost(this._parts) : '';
    } else {
      var res = URI.parseHost(v, this._parts);
      if (res !== '/') {
        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
      }

      this.build(!build);
      return this;
    }
  };
  p.authority = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined) {
      return this._parts.hostname ? URI.buildAuthority(this._parts) : '';
    } else {
      var res = URI.parseAuthority(v, this._parts);
      if (res !== '/') {
        throw new TypeError('Hostname "' + v + '" contains characters other than [A-Z0-9.-]');
      }

      this.build(!build);
      return this;
    }
  };
  p.userinfo = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined) {
      var t = URI.buildUserinfo(this._parts);
      return t ? t.substring(0, t.length -1) : t;
    } else {
      if (v[v.length-1] !== '@') {
        v += '@';
      }

      URI.parseUserinfo(v, this._parts);
      this.build(!build);
      return this;
    }
  };
  p.resource = function(v, build) {
    var parts;

    if (v === undefined) {
      return this.path() + this.search() + this.hash();
    }

    parts = URI.parse(v);
    this._parts.path = parts.path;
    this._parts.query = parts.query;
    this._parts.fragment = parts.fragment;
    this.build(!build);
    return this;
  };

  // fraction accessors
  p.subdomain = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    // convenience, return "www" from "www.example.org"
    if (v === undefined) {
      if (!this._parts.hostname || this.is('IP')) {
        return '';
      }

      // grab domain and add another segment
      var end = this._parts.hostname.length - this.domain().length - 1;
      return this._parts.hostname.substring(0, end) || '';
    } else {
      var e = this._parts.hostname.length - this.domain().length;
      var sub = this._parts.hostname.substring(0, e);
      var replace = new RegExp('^' + escapeRegEx(sub));

      if (v && v.charAt(v.length - 1) !== '.') {
        v += '.';
      }

      if (v) {
        URI.ensureValidHostname(v);
      }

      this._parts.hostname = this._parts.hostname.replace(replace, v);
      this.build(!build);
      return this;
    }
  };
  p.domain = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (typeof v === 'boolean') {
      build = v;
      v = undefined;
    }

    // convenience, return "example.org" from "www.example.org"
    if (v === undefined) {
      if (!this._parts.hostname || this.is('IP')) {
        return '';
      }

      // if hostname consists of 1 or 2 segments, it must be the domain
      var t = this._parts.hostname.match(/\./g);
      if (t && t.length < 2) {
        return this._parts.hostname;
      }

      // grab tld and add another segment
      var end = this._parts.hostname.length - this.tld(build).length - 1;
      end = this._parts.hostname.lastIndexOf('.', end -1) + 1;
      return this._parts.hostname.substring(end) || '';
    } else {
      if (!v) {
        throw new TypeError('cannot set domain empty');
      }

      URI.ensureValidHostname(v);

      if (!this._parts.hostname || this.is('IP')) {
        this._parts.hostname = v;
      } else {
        var replace = new RegExp(escapeRegEx(this.domain()) + '$');
        this._parts.hostname = this._parts.hostname.replace(replace, v);
      }

      this.build(!build);
      return this;
    }
  };
  p.tld = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (typeof v === 'boolean') {
      build = v;
      v = undefined;
    }

    // return "org" from "www.example.org"
    if (v === undefined) {
      if (!this._parts.hostname || this.is('IP')) {
        return '';
      }

      var pos = this._parts.hostname.lastIndexOf('.');
      var tld = this._parts.hostname.substring(pos + 1);

      if (build !== true && SLD && SLD.list[tld.toLowerCase()]) {
        return SLD.get(this._parts.hostname) || tld;
      }

      return tld;
    } else {
      var replace;

      if (!v) {
        throw new TypeError('cannot set TLD empty');
      } else if (v.match(/[^a-zA-Z0-9-]/)) {
        if (SLD && SLD.is(v)) {
          replace = new RegExp(escapeRegEx(this.tld()) + '$');
          this._parts.hostname = this._parts.hostname.replace(replace, v);
        } else {
          throw new TypeError('TLD "' + v + '" contains characters other than [A-Z0-9]');
        }
      } else if (!this._parts.hostname || this.is('IP')) {
        throw new ReferenceError('cannot set TLD on non-domain host');
      } else {
        replace = new RegExp(escapeRegEx(this.tld()) + '$');
        this._parts.hostname = this._parts.hostname.replace(replace, v);
      }

      this.build(!build);
      return this;
    }
  };
  p.directory = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined || v === true) {
      if (!this._parts.path && !this._parts.hostname) {
        return '';
      }

      if (this._parts.path === '/') {
        return '/';
      }

      var end = this._parts.path.length - this.filename().length - 1;
      var res = this._parts.path.substring(0, end) || (this._parts.hostname ? '/' : '');

      return v ? URI.decodePath(res) : res;

    } else {
      var e = this._parts.path.length - this.filename().length;
      var directory = this._parts.path.substring(0, e);
      var replace = new RegExp('^' + escapeRegEx(directory));

      // fully qualifier directories begin with a slash
      if (!this.is('relative')) {
        if (!v) {
          v = '/';
        }

        if (v.charAt(0) !== '/') {
          v = '/' + v;
        }
      }

      // directories always end with a slash
      if (v && v.charAt(v.length - 1) !== '/') {
        v += '/';
      }

      v = URI.recodePath(v);
      this._parts.path = this._parts.path.replace(replace, v);
      this.build(!build);
      return this;
    }
  };
  p.filename = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined || v === true) {
      if (!this._parts.path || this._parts.path === '/') {
        return '';
      }

      var pos = this._parts.path.lastIndexOf('/');
      var res = this._parts.path.substring(pos+1);

      return v ? URI.decodePathSegment(res) : res;
    } else {
      var mutatedDirectory = false;

      if (v.charAt(0) === '/') {
        v = v.substring(1);
      }

      if (v.match(/\.?\//)) {
        mutatedDirectory = true;
      }

      var replace = new RegExp(escapeRegEx(this.filename()) + '$');
      v = URI.recodePath(v);
      this._parts.path = this._parts.path.replace(replace, v);

      if (mutatedDirectory) {
        this.normalizePath(build);
      } else {
        this.build(!build);
      }

      return this;
    }
  };
  p.suffix = function(v, build) {
    if (this._parts.urn) {
      return v === undefined ? '' : this;
    }

    if (v === undefined || v === true) {
      if (!this._parts.path || this._parts.path === '/') {
        return '';
      }

      var filename = this.filename();
      var pos = filename.lastIndexOf('.');
      var s, res;

      if (pos === -1) {
        return '';
      }

      // suffix may only contain alnum characters (yup, I made this up.)
      s = filename.substring(pos+1);
      res = (/^[a-z0-9%]+$/i).test(s) ? s : '';
      return v ? URI.decodePathSegment(res) : res;
    } else {
      if (v.charAt(0) === '.') {
        v = v.substring(1);
      }

      var suffix = this.suffix();
      var replace;

      if (!suffix) {
        if (!v) {
          return this;
        }

        this._parts.path += '.' + URI.recodePath(v);
      } else if (!v) {
        replace = new RegExp(escapeRegEx('.' + suffix) + '$');
      } else {
        replace = new RegExp(escapeRegEx(suffix) + '$');
      }

      if (replace) {
        v = URI.recodePath(v);
        this._parts.path = this._parts.path.replace(replace, v);
      }

      this.build(!build);
      return this;
    }
  };
  p.segment = function(segment, v, build) {
    var separator = this._parts.urn ? ':' : '/';
    var path = this.path();
    var absolute = path.substring(0, 1) === '/';
    var segments = path.split(separator);

    if (segment !== undefined && typeof segment !== 'number') {
      build = v;
      v = segment;
      segment = undefined;
    }

    if (segment !== undefined && typeof segment !== 'number') {
      throw new Error('Bad segment "' + segment + '", must be 0-based integer');
    }

    if (absolute) {
      segments.shift();
    }

    if (segment < 0) {
      // allow negative indexes to address from the end
      segment = Math.max(segments.length + segment, 0);
    }

    if (v === undefined) {
      /*jshint laxbreak: true */
      return segment === undefined
        ? segments
        : segments[segment];
      /*jshint laxbreak: false */
    } else if (segment === null || segments[segment] === undefined) {
      if (isArray(v)) {
        segments = [];
        // collapse empty elements within array
        for (var i=0, l=v.length; i < l; i++) {
          if (!v[i].length && (!segments.length || !segments[segments.length -1].length)) {
            continue;
          }

          if (segments.length && !segments[segments.length -1].length) {
            segments.pop();
          }

          segments.push(trimSlashes(v[i]));
        }
      } else if (v || typeof v === 'string') {
        v = trimSlashes(v);
        if (segments[segments.length -1] === '') {
          // empty trailing elements have to be overwritten
          // to prevent results such as /foo//bar
          segments[segments.length -1] = v;
        } else {
          segments.push(v);
        }
      }
    } else {
      if (v) {
        segments[segment] = trimSlashes(v);
      } else {
        segments.splice(segment, 1);
      }
    }

    if (absolute) {
      segments.unshift('');
    }

    return this.path(segments.join(separator), build);
  };
  p.segmentCoded = function(segment, v, build) {
    var segments, i, l;

    if (typeof segment !== 'number') {
      build = v;
      v = segment;
      segment = undefined;
    }

    if (v === undefined) {
      segments = this.segment(segment, v, build);
      if (!isArray(segments)) {
        segments = segments !== undefined ? URI.decode(segments) : undefined;
      } else {
        for (i = 0, l = segments.length; i < l; i++) {
          segments[i] = URI.decode(segments[i]);
        }
      }

      return segments;
    }

    if (!isArray(v)) {
      v = (typeof v === 'string' || v instanceof String) ? URI.encode(v) : v;
    } else {
      for (i = 0, l = v.length; i < l; i++) {
        v[i] = URI.encode(v[i]);
      }
    }

    return this.segment(segment, v, build);
  };

  // mutating query string
  var q = p.query;
  p.query = function(v, build) {
    if (v === true) {
      return URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
    } else if (typeof v === 'function') {
      var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
      var result = v.call(this, data);
      this._parts.query = URI.buildQuery(result || data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
      this.build(!build);
      return this;
    } else if (v !== undefined && typeof v !== 'string') {
      this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
      this.build(!build);
      return this;
    } else {
      return q.call(this, v, build);
    }
  };
  p.setQuery = function(name, value, build) {
    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);

    if (typeof name === 'string' || name instanceof String) {
      data[name] = value !== undefined ? value : null;
    } else if (typeof name === 'object') {
      for (var key in name) {
        if (hasOwn.call(name, key)) {
          data[key] = name[key];
        }
      }
    } else {
      throw new TypeError('URI.addQuery() accepts an object, string as the name parameter');
    }

    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
    if (typeof name !== 'string') {
      build = value;
    }

    this.build(!build);
    return this;
  };
  p.addQuery = function(name, value, build) {
    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
    URI.addQuery(data, name, value === undefined ? null : value);
    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
    if (typeof name !== 'string') {
      build = value;
    }

    this.build(!build);
    return this;
  };
  p.removeQuery = function(name, value, build) {
    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
    URI.removeQuery(data, name, value);
    this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters, this._parts.escapeQuerySpace);
    if (typeof name !== 'string') {
      build = value;
    }

    this.build(!build);
    return this;
  };
  p.hasQuery = function(name, value, withinArray) {
    var data = URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace);
    return URI.hasQuery(data, name, value, withinArray);
  };
  p.setSearch = p.setQuery;
  p.addSearch = p.addQuery;
  p.removeSearch = p.removeQuery;
  p.hasSearch = p.hasQuery;

  // sanitizing URLs
  p.normalize = function() {
    if (this._parts.urn) {
      return this
        .normalizeProtocol(false)
        .normalizePath(false)
        .normalizeQuery(false)
        .normalizeFragment(false)
        .build();
    }

    return this
      .normalizeProtocol(false)
      .normalizeHostname(false)
      .normalizePort(false)
      .normalizePath(false)
      .normalizeQuery(false)
      .normalizeFragment(false)
      .build();
  };
  p.normalizeProtocol = function(build) {
    if (typeof this._parts.protocol === 'string') {
      this._parts.protocol = this._parts.protocol.toLowerCase();
      this.build(!build);
    }

    return this;
  };
  p.normalizeHostname = function(build) {
    if (this._parts.hostname) {
      if (this.is('IDN') && punycode) {
        this._parts.hostname = punycode.toASCII(this._parts.hostname);
      } else if (this.is('IPv6') && IPv6) {
        this._parts.hostname = IPv6.best(this._parts.hostname);
      }

      this._parts.hostname = this._parts.hostname.toLowerCase();
      this.build(!build);
    }

    return this;
  };
  p.normalizePort = function(build) {
    // remove port of it's the protocol's default
    if (typeof this._parts.protocol === 'string' && this._parts.port === URI.defaultPorts[this._parts.protocol]) {
      this._parts.port = null;
      this.build(!build);
    }

    return this;
  };
  p.normalizePath = function(build) {
    var _path = this._parts.path;
    if (!_path) {
      return this;
    }

    if (this._parts.urn) {
      this._parts.path = URI.recodeUrnPath(this._parts.path);
      this.build(!build);
      return this;
    }

    if (this._parts.path === '/') {
      return this;
    }

    _path = URI.recodePath(_path);

    var _was_relative;
    var _leadingParents = '';
    var _parent, _pos;

    // handle relative paths
    if (_path.charAt(0) !== '/') {
      _was_relative = true;
      _path = '/' + _path;
    }

    // handle relative files (as opposed to directories)
    if (_path.slice(-3) === '/..' || _path.slice(-2) === '/.') {
      _path += '/';
    }

    // resolve simples
    _path = _path
      .replace(/(\/(\.\/)+)|(\/\.$)/g, '/')
      .replace(/\/{2,}/g, '/');

    // remember leading parents
    if (_was_relative) {
      _leadingParents = _path.substring(1).match(/^(\.\.\/)+/) || '';
      if (_leadingParents) {
        _leadingParents = _leadingParents[0];
      }
    }

    // resolve parents
    while (true) {
      _parent = _path.search(/\/\.\.(\/|$)/);
      if (_parent === -1) {
        // no more ../ to resolve
        break;
      } else if (_parent === 0) {
        // top level cannot be relative, skip it
        _path = _path.substring(3);
        continue;
      }

      _pos = _path.substring(0, _parent).lastIndexOf('/');
      if (_pos === -1) {
        _pos = _parent;
      }
      _path = _path.substring(0, _pos) + _path.substring(_parent + 3);
    }

    // revert to relative
    if (_was_relative && this.is('relative')) {
      _path = _leadingParents + _path.substring(1);
    }

    this._parts.path = _path;
    this.build(!build);
    return this;
  };
  p.normalizePathname = p.normalizePath;
  p.normalizeQuery = function(build) {
    if (typeof this._parts.query === 'string') {
      if (!this._parts.query.length) {
        this._parts.query = null;
      } else {
        this.query(URI.parseQuery(this._parts.query, this._parts.escapeQuerySpace));
      }

      this.build(!build);
    }

    return this;
  };
  p.normalizeFragment = function(build) {
    if (!this._parts.fragment) {
      this._parts.fragment = null;
      this.build(!build);
    }

    return this;
  };
  p.normalizeSearch = p.normalizeQuery;
  p.normalizeHash = p.normalizeFragment;

  p.iso8859 = function() {
    // expect unicode input, iso8859 output
    var e = URI.encode;
    var d = URI.decode;

    URI.encode = escape;
    URI.decode = decodeURIComponent;
    try {
      this.normalize();
    } finally {
      URI.encode = e;
      URI.decode = d;
    }
    return this;
  };

  p.unicode = function() {
    // expect iso8859 input, unicode output
    var e = URI.encode;
    var d = URI.decode;

    URI.encode = strictEncodeURIComponent;
    URI.decode = unescape;
    try {
      this.normalize();
    } finally {
      URI.encode = e;
      URI.decode = d;
    }
    return this;
  };

  p.readable = function() {
    var uri = this.clone();
    // removing username, password, because they shouldn't be displayed according to RFC 3986
    uri.username('').password('').normalize();
    var t = '';
    if (uri._parts.protocol) {
      t += uri._parts.protocol + '://';
    }

    if (uri._parts.hostname) {
      if (uri.is('punycode') && punycode) {
        t += punycode.toUnicode(uri._parts.hostname);
        if (uri._parts.port) {
          t += ':' + uri._parts.port;
        }
      } else {
        t += uri.host();
      }
    }

    if (uri._parts.hostname && uri._parts.path && uri._parts.path.charAt(0) !== '/') {
      t += '/';
    }

    t += uri.path(true);
    if (uri._parts.query) {
      var q = '';
      for (var i = 0, qp = uri._parts.query.split('&'), l = qp.length; i < l; i++) {
        var kv = (qp[i] || '').split('=');
        q += '&' + URI.decodeQuery(kv[0], this._parts.escapeQuerySpace)
          .replace(/&/g, '%26');

        if (kv[1] !== undefined) {
          q += '=' + URI.decodeQuery(kv[1], this._parts.escapeQuerySpace)
            .replace(/&/g, '%26');
        }
      }
      t += '?' + q.substring(1);
    }

    t += URI.decodeQuery(uri.hash(), true);
    return t;
  };

  // resolving relative and absolute URLs
  p.absoluteTo = function(base) {
    var resolved = this.clone();
    var properties = ['protocol', 'username', 'password', 'hostname', 'port'];
    var basedir, i, p;

    if (this._parts.urn) {
      throw new Error('URNs do not have any generally defined hierarchical components');
    }

    if (!(base instanceof URI)) {
      base = new URI(base);
    }

    if (!resolved._parts.protocol) {
      resolved._parts.protocol = base._parts.protocol;
    }

    if (this._parts.hostname) {
      return resolved;
    }

    for (i = 0; (p = properties[i]); i++) {
      resolved._parts[p] = base._parts[p];
    }

    if (!resolved._parts.path) {
      resolved._parts.path = base._parts.path;
      if (!resolved._parts.query) {
        resolved._parts.query = base._parts.query;
      }
    } else if (resolved._parts.path.substring(-2) === '..') {
      resolved._parts.path += '/';
    }

    if (resolved.path().charAt(0) !== '/') {
      basedir = base.directory();
      basedir = basedir ? basedir : base.path().indexOf('/') === 0 ? '/' : '';
      resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path;
      resolved.normalizePath();
    }

    resolved.build();
    return resolved;
  };
  p.relativeTo = function(base) {
    var relative = this.clone().normalize();
    var relativeParts, baseParts, common, relativePath, basePath;

    if (relative._parts.urn) {
      throw new Error('URNs do not have any generally defined hierarchical components');
    }

    base = new URI(base).normalize();
    relativeParts = relative._parts;
    baseParts = base._parts;
    relativePath = relative.path();
    basePath = base.path();

    if (relativePath.charAt(0) !== '/') {
      throw new Error('URI is already relative');
    }

    if (basePath.charAt(0) !== '/') {
      throw new Error('Cannot calculate a URI relative to another relative URI');
    }

    if (relativeParts.protocol === baseParts.protocol) {
      relativeParts.protocol = null;
    }

    if (relativeParts.username !== baseParts.username || relativeParts.password !== baseParts.password) {
      return relative.build();
    }

    if (relativeParts.protocol !== null || relativeParts.username !== null || relativeParts.password !== null) {
      return relative.build();
    }

    if (relativeParts.hostname === baseParts.hostname && relativeParts.port === baseParts.port) {
      relativeParts.hostname = null;
      relativeParts.port = null;
    } else {
      return relative.build();
    }

    if (relativePath === basePath) {
      relativeParts.path = '';
      return relative.build();
    }

    // determine common sub path
    common = URI.commonPath(relativePath, basePath);

    // If the paths have nothing in common, return a relative URL with the absolute path.
    if (!common) {
      return relative.build();
    }

    var parents = baseParts.path
      .substring(common.length)
      .replace(/[^\/]*$/, '')
      .replace(/.*?\//g, '../');

    relativeParts.path = (parents + relativeParts.path.substring(common.length)) || './';

    return relative.build();
  };

  // comparing URIs
  p.equals = function(uri) {
    var one = this.clone();
    var two = new URI(uri);
    var one_map = {};
    var two_map = {};
    var checked = {};
    var one_query, two_query, key;

    one.normalize();
    two.normalize();

    // exact match
    if (one.toString() === two.toString()) {
      return true;
    }

    // extract query string
    one_query = one.query();
    two_query = two.query();
    one.query('');
    two.query('');

    // definitely not equal if not even non-query parts match
    if (one.toString() !== two.toString()) {
      return false;
    }

    // query parameters have the same length, even if they're permuted
    if (one_query.length !== two_query.length) {
      return false;
    }

    one_map = URI.parseQuery(one_query, this._parts.escapeQuerySpace);
    two_map = URI.parseQuery(two_query, this._parts.escapeQuerySpace);

    for (key in one_map) {
      if (hasOwn.call(one_map, key)) {
        if (!isArray(one_map[key])) {
          if (one_map[key] !== two_map[key]) {
            return false;
          }
        } else if (!arraysEqual(one_map[key], two_map[key])) {
          return false;
        }

        checked[key] = true;
      }
    }

    for (key in two_map) {
      if (hasOwn.call(two_map, key)) {
        if (!checked[key]) {
          // two contains a parameter not present in one
          return false;
        }
      }
    }

    return true;
  };

  // state
  p.duplicateQueryParameters = function(v) {
    this._parts.duplicateQueryParameters = !!v;
    return this;
  };

  p.escapeQuerySpace = function(v) {
    this._parts.escapeQuerySpace = !!v;
    return this;
  };

  return URI;
}));
/*!
CSSLint v1.0.3
Copyright (c) 2016 Nicole Sullivan and Nicholas C. Zakas. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the 'Software'), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/
var CSSLint=function(){var e,t=t||{},r=(e=function t(r,n,i){function o(s,l){if(!n[s]){if(!r[s]){var c="function"==typeof e&&e;if(!l&&c)return c(s,!0);if(a)return a(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=n[s]={exports:{}};r[s][0].call(d.exports,(function(e){var t=r[s][1][e];return o(t||e)}),d,d.exports,t,r,n,i)}return n[s].exports}for(var a="function"==typeof e&&e,s=0;s<i.length;s++)o(i[s]);return o}({1:[function(e,t,r){"use strict";t.exports={__proto__:null,aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",currentColor:"The value of the 'color' property.",activeBorder:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface.",background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box.",graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",greytext:"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control.",inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption.",inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls.",infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus.",scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows."}},{}],2:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r){n.call(this,e,t,r,i.COMBINATOR_TYPE),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":">"===e?this.type="child":"+"===e?this.type="adjacent-sibling":"~"===e&&(this.type="sibling")}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],3:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/StringReader"),i=e("../util/SyntaxError");function o(e,t){this.match=function(t){var r;return t.mark(),(r=e(t))?t.drop():t.restore(),r},this.toString="function"==typeof t?t:function(){return t}}o.prec={MOD:5,SEQ:4,ANDAND:3,OROR:2,ALT:1},o.parse=function(e){var t,r,a,s,l,c,u,d,h;if(t=new n(e),r=function(e){var r=t.readMatch(e);if(null===r)throw new i("Expected "+e,t.getLine(),t.getCol());return r},a=function(){for(var e=[s()];null!==t.readMatch(" | ");)e.push(s());return 1===e.length?e[0]:o.alt.apply(o,e)},s=function(){for(var e=[l()];null!==t.readMatch(" || ");)e.push(l());return 1===e.length?e[0]:o.oror.apply(o,e)},l=function(){for(var e=[c()];null!==t.readMatch(" && ");)e.push(c());return 1===e.length?e[0]:o.andand.apply(o,e)},c=function(){for(var e=[u()];null!==t.readMatch(/^ (?![&|\]])/);)e.push(u());return 1===e.length?e[0]:o.seq.apply(o,e)},u=function(){var e=d();if(null!==t.readMatch("?"))return e.question();if(null!==t.readMatch("*"))return e.star();if(null!==t.readMatch("+"))return e.plus();if(null!==t.readMatch("#"))return e.hash();if(null!==t.readMatch(/^\{\s*/)){var n=r(/^\d+/);r(/^\s*,\s*/);var i=r(/^\d+/);return r(/^\s*\}/),e.braces(+n,+i)}return e},d=function(){if(null!==t.readMatch("[ ")){var e=a();return r(" ]"),e}return o.fromType(r(/^[^ ?*+#{]+/))},h=a(),!t.eof())throw new i("Expected end of string",t.getLine(),t.getCol());return h},o.cast=function(e){return e instanceof o?e:o.parse(e)},o.fromType=function(t){var r=e("./ValidationTypes");return new o((function(e){return e.hasNext()&&r.isType(e,t)}),t)},o.seq=function(){var e=Array.prototype.slice.call(arguments).map(o.cast);return 1===e.length?e[0]:new o((function(t){var r,n=!0;for(r=0;n&&r<e.length;r++)n=e[r].match(t);return n}),(function(t){var r=o.prec.SEQ,n=e.map((function(e){return e.toString(r)})).join(" ");return t>r&&(n="[ "+n+" ]"),n}))},o.alt=function(){var e=Array.prototype.slice.call(arguments).map(o.cast);return 1===e.length?e[0]:new o((function(t){var r,n=!1;for(r=0;!n&&r<e.length;r++)n=e[r].match(t);return n}),(function(t){var r=o.prec.ALT,n=e.map((function(e){return e.toString(r)})).join(" | ");return t>r&&(n="[ "+n+" ]"),n}))},o.many=function(t){var r=Array.prototype.slice.call(arguments,1).reduce((function(t,r){if(r.expand){var n=e("./ValidationTypes");t.push.apply(t,n.complex[r.expand].options)}else t.push(o.cast(r));return t}),[]);!0===t&&(t=r.map((function(){return!0})));var n=new o((function(e){var n=[],i=0,o=0,a=function(s){for(var l=0;l<r.length;l++)if(!n[l])if(e.mark(),r[l].match(e)){if(n[l]=!0,a(s+(!1===t||t[l]?1:0)))return e.drop(),!0;e.restore(),n[l]=!1}else e.drop();return function(e){return 0===o?(i=Math.max(e,i),e===r.length):e===i}(s)};if(a(0)||(o++,a(0)),!1===t)return i>0;for(var s=0;s<r.length;s++)if(t[s]&&!n[s])return!1;return!0}),(function(e){var n=!1===t?o.prec.OROR:o.prec.ANDAND,i=r.map((function(e,r){return!1===t||t[r]?e.toString(n):e.toString(o.prec.MOD)+"?"})).join(!1===t?" || ":" && ");return e>n&&(i="[ "+i+" ]"),i}));return n.options=r,n},o.andand=function(){var e=Array.prototype.slice.call(arguments);return e.unshift(!0),o.many.apply(o,e)},o.oror=function(){var e=Array.prototype.slice.call(arguments);return e.unshift(!1),o.many.apply(o,e)},o.prototype={constructor:o,match:function(){throw new Error("unimplemented")},toString:function(){throw new Error("unimplemented")},func:function(){return this.match.bind(this)},then:function(e){return o.seq(this,e)},or:function(e){return o.alt(this,e)},andand:function(e){return o.many(!0,this,e)},oror:function(e){return o.many(!1,this,e)},star:function(){return this.braces(0,1/0,"*")},plus:function(){return this.braces(1,1/0,"+")},question:function(){return this.braces(0,1,"?")},hash:function(){return this.braces(1,1/0,"#",o.cast(","))},braces:function(e,t,r,n){var i=this,a=n?n.then(this):this;return r||(r="{"+e+","+t+"}"),new o((function(r){var o;for(o=0;o<t&&(o>0&&n?a.match(r):i.match(r));o++);return o>=e}),(function(){return i.toString(o.prec.MOD)+r}))}}},{"../util/StringReader":24,"../util/SyntaxError":25,"./ValidationTypes":21}],4:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t){n.call(this,"("+e+(null!==t?":"+t:"")+")",e.startLine,e.startCol,i.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],5:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r,o,a){n.call(this,(e?e+" ":"")+(t||"")+(t&&r.length>0?" and ":"")+r.join(" and "),o,a,i.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=r}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],6:[function(e,t,r){"use strict";t.exports=k;var n=e("../util/EventTarget"),i=e("../util/SyntaxError"),o=e("../util/SyntaxUnit"),a=e("./Combinator"),s=e("./MediaFeature"),l=e("./MediaQuery"),c=e("./PropertyName"),u=e("./PropertyValue"),d=e("./PropertyValuePart"),h=e("./Selector"),p=e("./SelectorPart"),f=e("./SelectorSubPart"),m=e("./TokenStream"),g=e("./Tokens"),b=e("./Validation");function k(e){n.call(this),this.options=e||{},this._tokenStream=null}k.DEFAULT_TYPE=0,k.COMBINATOR_TYPE=1,k.MEDIA_FEATURE_TYPE=2,k.MEDIA_QUERY_TYPE=3,k.PROPERTY_NAME_TYPE=4,k.PROPERTY_VALUE_TYPE=5,k.PROPERTY_VALUE_PART_TYPE=6,k.SELECTOR_TYPE=7,k.SELECTOR_PART_TYPE=8,k.SELECTOR_SUB_PART_TYPE=9,k.prototype=function(){var e,t=new n,r={__proto__:null,constructor:k,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e,t,r,n=this._tokenStream;for(this.fire("startstylesheet"),this._charset(),this._skipCruft();n.peek()===g.IMPORT_SYM;)this._import(),this._skipCruft();for(;n.peek()===g.NAMESPACE_SYM;)this._namespace(),this._skipCruft();for(r=n.peek();r>g.EOF;){try{switch(r){case g.MEDIA_SYM:this._media(),this._skipCruft();break;case g.PAGE_SYM:this._page(),this._skipCruft();break;case g.FONT_FACE_SYM:this._font_face(),this._skipCruft();break;case g.KEYFRAMES_SYM:this._keyframes(),this._skipCruft();break;case g.VIEWPORT_SYM:this._viewport(),this._skipCruft();break;case g.DOCUMENT_SYM:this._document(),this._skipCruft();break;case g.SUPPORTS_SYM:this._supports(),this._skipCruft();break;case g.UNKNOWN_SYM:if(n.get(),this.options.strict)throw new i("Unknown @ rule.",n.LT(0).startLine,n.LT(0).startCol);for(this.fire({type:"error",error:null,message:"Unknown @ rule: "+n.LT(0).value+".",line:n.LT(0).startLine,col:n.LT(0).startCol}),e=0;n.advance([g.LBRACE,g.RBRACE])===g.LBRACE;)e++;for(;e;)n.advance([g.RBRACE]),e--;break;case g.S:this._readWhitespace();break;default:if(!this._ruleset())switch(r){case g.CHARSET_SYM:throw t=n.LT(1),this._charset(!1),new i("@charset not allowed here.",t.startLine,t.startCol);case g.IMPORT_SYM:throw t=n.LT(1),this._import(!1),new i("@import not allowed here.",t.startLine,t.startCol);case g.NAMESPACE_SYM:throw t=n.LT(1),this._namespace(!1),new i("@namespace not allowed here.",t.startLine,t.startCol);default:n.get(),this._unexpectedToken(n.token())}}}catch(e){if(!(e instanceof i)||this.options.strict)throw e;this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col})}r=n.peek()}r!==g.EOF&&this._unexpectedToken(n.token()),this.fire("endstylesheet")},_charset:function(e){var t,r,n,i=this._tokenStream;i.match(g.CHARSET_SYM)&&(r=i.token().startLine,n=i.token().startCol,this._readWhitespace(),i.mustMatch(g.STRING),t=i.token().value,this._readWhitespace(),i.mustMatch(g.SEMICOLON),!1!==e&&this.fire({type:"charset",charset:t,line:r,col:n}))},_import:function(e){var t,r,n,i=this._tokenStream;i.mustMatch(g.IMPORT_SYM),r=i.token(),this._readWhitespace(),i.mustMatch([g.STRING,g.URI]),t=i.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/,"$1"),this._readWhitespace(),n=this._media_query_list(),i.mustMatch(g.SEMICOLON),this._readWhitespace(),!1!==e&&this.fire({type:"import",uri:t,media:n,line:r.startLine,col:r.startCol})},_namespace:function(e){var t,r,n,i,o=this._tokenStream;o.mustMatch(g.NAMESPACE_SYM),t=o.token().startLine,r=o.token().startCol,this._readWhitespace(),o.match(g.IDENT)&&(n=o.token().value,this._readWhitespace()),o.mustMatch([g.STRING,g.URI]),i=o.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),o.mustMatch(g.SEMICOLON),this._readWhitespace(),!1!==e&&this.fire({type:"namespace",prefix:n,uri:i,line:t,col:r})},_supports:function(e){var t,r,n=this._tokenStream;if(n.match(g.SUPPORTS_SYM)){for(t=n.token().startLine,r=n.token().startCol,this._readWhitespace(),this._supports_condition(),this._readWhitespace(),n.mustMatch(g.LBRACE),this._readWhitespace(),!1!==e&&this.fire({type:"startsupports",line:t,col:r});this._ruleset(););n.mustMatch(g.RBRACE),this._readWhitespace(),this.fire({type:"endsupports",line:t,col:r})}},_supports_condition:function(){var e,t=this._tokenStream;if(t.match(g.IDENT))"not"===(e=t.token().value.toLowerCase())?(t.mustMatch(g.S),this._supports_condition_in_parens()):t.unget();else for(this._supports_condition_in_parens(),this._readWhitespace();t.peek()===g.IDENT;)"and"!==(e=t.LT(1).value.toLowerCase())&&"or"!==e||(t.mustMatch(g.IDENT),this._readWhitespace(),this._supports_condition_in_parens(),this._readWhitespace())},_supports_condition_in_parens:function(){var e=this._tokenStream;e.match(g.LPAREN)?(this._readWhitespace(),e.match(g.IDENT)?"not"===e.token().value.toLowerCase()?(this._readWhitespace(),this._supports_condition(),this._readWhitespace(),e.mustMatch(g.RPAREN)):(e.unget(),this._supports_declaration_condition(!1)):(this._supports_condition(),this._readWhitespace(),e.mustMatch(g.RPAREN))):this._supports_declaration_condition()},_supports_declaration_condition:function(e){var t=this._tokenStream;!1!==e&&t.mustMatch(g.LPAREN),this._readWhitespace(),this._declaration(),t.mustMatch(g.RPAREN)},_media:function(){var e,t,r,n=this._tokenStream;for(n.mustMatch(g.MEDIA_SYM),e=n.token().startLine,t=n.token().startCol,this._readWhitespace(),r=this._media_query_list(),n.mustMatch(g.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line:e,col:t});;)if(n.peek()===g.PAGE_SYM)this._page();else if(n.peek()===g.FONT_FACE_SYM)this._font_face();else if(n.peek()===g.VIEWPORT_SYM)this._viewport();else if(n.peek()===g.DOCUMENT_SYM)this._document();else if(n.peek()===g.SUPPORTS_SYM)this._supports();else if(!this._ruleset())break;n.mustMatch(g.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:e,col:t})},_media_query_list:function(){var e=this._tokenStream,t=[];for(this._readWhitespace(),e.peek()!==g.IDENT&&e.peek()!==g.LPAREN||t.push(this._media_query());e.match(g.COMMA);)this._readWhitespace(),t.push(this._media_query());return t},_media_query:function(){var e=this._tokenStream,t=null,r=null,n=null,i=[];if(e.match(g.IDENT)&&("only"!==(r=e.token().value.toLowerCase())&&"not"!==r?(e.unget(),r=null):n=e.token()),this._readWhitespace(),e.peek()===g.IDENT?(t=this._media_type(),null===n&&(n=e.token())):e.peek()===g.LPAREN&&(null===n&&(n=e.LT(1)),i.push(this._media_expression())),null===t&&0===i.length)return null;for(this._readWhitespace();e.match(g.IDENT);)"and"!==e.token().value.toLowerCase()&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression());return new l(r,t,i,n.startLine,n.startCol)},_media_type:function(){return this._media_feature()},_media_expression:function(){var e,t,r=this._tokenStream,n=null;return r.mustMatch(g.LPAREN),e=this._media_feature(),this._readWhitespace(),r.match(g.COLON)&&(this._readWhitespace(),t=r.LT(1),n=this._expression()),r.mustMatch(g.RPAREN),this._readWhitespace(),new s(e,n?new o(n,t.startLine,t.startCol):null)},_media_feature:function(){var e=this._tokenStream;return this._readWhitespace(),e.mustMatch(g.IDENT),o.fromToken(e.token())},_page:function(){var e,t,r=this._tokenStream,n=null,i=null;r.mustMatch(g.PAGE_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),r.match(g.IDENT)&&"auto"===(n=r.token().value).toLowerCase()&&this._unexpectedToken(r.token()),r.peek()===g.COLON&&(i=this._pseudo_page()),this._readWhitespace(),this.fire({type:"startpage",id:n,pseudo:i,line:e,col:t}),this._readDeclarations(!0,!0),this.fire({type:"endpage",id:n,pseudo:i,line:e,col:t})},_margin:function(){var e,t,r=this._tokenStream,n=this._margin_sym();return!!n&&(e=r.token().startLine,t=r.token().startCol,this.fire({type:"startpagemargin",margin:n,line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:n,line:e,col:t}),!0)},_margin_sym:function(){var e=this._tokenStream;return e.match([g.TOPLEFTCORNER_SYM,g.TOPLEFT_SYM,g.TOPCENTER_SYM,g.TOPRIGHT_SYM,g.TOPRIGHTCORNER_SYM,g.BOTTOMLEFTCORNER_SYM,g.BOTTOMLEFT_SYM,g.BOTTOMCENTER_SYM,g.BOTTOMRIGHT_SYM,g.BOTTOMRIGHTCORNER_SYM,g.LEFTTOP_SYM,g.LEFTMIDDLE_SYM,g.LEFTBOTTOM_SYM,g.RIGHTTOP_SYM,g.RIGHTMIDDLE_SYM,g.RIGHTBOTTOM_SYM])?o.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream;return e.mustMatch(g.COLON),e.mustMatch(g.IDENT),e.token().value},_font_face:function(){var e,t,r=this._tokenStream;r.mustMatch(g.FONT_FACE_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),this.fire({type:"startfontface",line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endfontface",line:e,col:t})},_viewport:function(){var e,t,r=this._tokenStream;r.mustMatch(g.VIEWPORT_SYM),e=r.token().startLine,t=r.token().startCol,this._readWhitespace(),this.fire({type:"startviewport",line:e,col:t}),this._readDeclarations(!0),this.fire({type:"endviewport",line:e,col:t})},_document:function(){var e,t=this._tokenStream,r=[],n="";for(t.mustMatch(g.DOCUMENT_SYM),e=t.token(),/^@\-([^\-]+)\-/.test(e.value)&&(n=RegExp.$1),this._readWhitespace(),r.push(this._document_function());t.match(g.COMMA);)this._readWhitespace(),r.push(this._document_function());t.mustMatch(g.LBRACE),this._readWhitespace(),this.fire({type:"startdocument",functions:r,prefix:n,line:e.startLine,col:e.startCol});for(var i=!0;i;)switch(t.peek()){case g.PAGE_SYM:this._page();break;case g.FONT_FACE_SYM:this._font_face();break;case g.VIEWPORT_SYM:this._viewport();break;case g.MEDIA_SYM:this._media();break;case g.KEYFRAMES_SYM:this._keyframes();break;case g.DOCUMENT_SYM:this._document();break;default:i=Boolean(this._ruleset())}t.mustMatch(g.RBRACE),e=t.token(),this._readWhitespace(),this.fire({type:"enddocument",functions:r,prefix:n,line:e.startLine,col:e.startCol})},_document_function:function(){var e,t=this._tokenStream;return t.match(g.URI)?(e=t.token().value,this._readWhitespace()):e=this._function(),e},_operator:function(e){var t=this._tokenStream,r=null;return(t.match([g.SLASH,g.COMMA])||e&&t.match([g.PLUS,g.STAR,g.MINUS]))&&(r=t.token(),this._readWhitespace()),r?d.fromToken(r):null},_combinator:function(){var e,t=this._tokenStream,r=null;return t.match([g.PLUS,g.GREATER,g.TILDE])&&(e=t.token(),r=new a(e.value,e.startLine,e.startCol),this._readWhitespace()),r},_unary_operator:function(){var e=this._tokenStream;return e.match([g.MINUS,g.PLUS])?e.token().value:null},_property:function(){var e,t,r,n,i=this._tokenStream,o=null,a=null;return i.peek()===g.STAR&&this.options.starHack&&(i.get(),a=(t=i.token()).value,r=t.startLine,n=t.startCol),i.match(g.IDENT)&&("_"===(e=(t=i.token()).value).charAt(0)&&this.options.underscoreHack&&(a="_",e=e.substring(1)),o=new c(e,a,r||t.startLine,n||t.startCol),this._readWhitespace()),o},_ruleset:function(){var e,t=this._tokenStream;try{e=this._selectors_group()}catch(e){if(!(e instanceof i)||this.options.strict)throw e;if(this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col}),t.advance([g.RBRACE])!==g.RBRACE)throw e;return!0}return e&&(this.fire({type:"startrule",selectors:e,line:e[0].line,col:e[0].col}),this._readDeclarations(!0),this.fire({type:"endrule",selectors:e,line:e[0].line,col:e[0].col})),e},_selectors_group:function(){var e,t=this._tokenStream,r=[];if(null!==(e=this._selector()))for(r.push(e);t.match(g.COMMA);)this._readWhitespace(),null!==(e=this._selector())?r.push(e):this._unexpectedToken(t.LT(1));return r.length?r:null},_selector:function(){var e=this._tokenStream,t=[],r=null,n=null,i=null;if(null===(r=this._simple_selector_sequence()))return null;for(t.push(r);;)if(null!==(n=this._combinator()))t.push(n),null===(r=this._simple_selector_sequence())?this._unexpectedToken(e.LT(1)):t.push(r);else{if(!this._readWhitespace())break;i=new a(e.token().value,e.token().startLine,e.token().startCol),n=this._combinator(),null===(r=this._simple_selector_sequence())?null!==n&&this._unexpectedToken(e.LT(1)):(null!==n?t.push(n):t.push(i),t.push(r))}return new h(t,t[0].line,t[0].col)},_simple_selector_sequence:function(){var e,t,r=this._tokenStream,n=null,i=[],o="",a=[function(){return r.match(g.HASH)?new f(r.token().value,"id",r.token().startLine,r.token().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,l=a.length,c=null;for(e=r.LT(1).startLine,t=r.LT(1).startCol,(n=this._type_selector())||(n=this._universal()),null!==n&&(o+=n);r.peek()!==g.S;){for(;s<l&&null===c;)c=a[s++].call(this);if(null===c){if(""===o)return null;break}s=0,i.push(c),o+=c.toString(),c=null}return""!==o?new p(n,i,o,e,t):null},_type_selector:function(){var e=this._tokenStream,t=this._namespace_prefix(),r=this._element_name();return r?(t&&(r.text=t+r.text,r.col-=t.length),r):(t&&(e.unget(),t.length>1&&e.unget()),null)},_class:function(){var e,t=this._tokenStream;return t.match(g.DOT)?(t.mustMatch(g.IDENT),e=t.token(),new f("."+e.value,"class",e.startLine,e.startCol-1)):null},_element_name:function(){var e,t=this._tokenStream;return t.match(g.IDENT)?(e=t.token(),new f(e.value,"elementName",e.startLine,e.startCol)):null},_namespace_prefix:function(){var e=this._tokenStream,t="";return e.LA(1)!==g.PIPE&&e.LA(2)!==g.PIPE||(e.match([g.IDENT,g.STAR])&&(t+=e.token().value),e.mustMatch(g.PIPE),t+="|"),t.length?t:null},_universal:function(){var e,t=this._tokenStream,r="";return(e=this._namespace_prefix())&&(r+=e),t.match(g.STAR)&&(r+="*"),r.length?r:null},_attrib:function(){var e,t,r=this._tokenStream,n=null;return r.match(g.LBRACKET)?(n=(t=r.token()).value,n+=this._readWhitespace(),(e=this._namespace_prefix())&&(n+=e),r.mustMatch(g.IDENT),n+=r.token().value,n+=this._readWhitespace(),r.match([g.PREFIXMATCH,g.SUFFIXMATCH,g.SUBSTRINGMATCH,g.EQUALS,g.INCLUDES,g.DASHMATCH])&&(n+=r.token().value,n+=this._readWhitespace(),r.mustMatch([g.IDENT,g.STRING]),n+=r.token().value,n+=this._readWhitespace()),r.mustMatch(g.RBRACKET),new f(n+"]","attribute",t.startLine,t.startCol)):null},_pseudo:function(){var e,t,r=this._tokenStream,n=null,o=":";if(r.match(g.COLON)){if(r.match(g.COLON)&&(o+=":"),r.match(g.IDENT)?(n=r.token().value,e=r.token().startLine,t=r.token().startCol-o.length):r.peek()===g.FUNCTION&&(e=r.LT(1).startLine,t=r.LT(1).startCol-o.length,n=this._functional_pseudo()),!n){var a=r.LT(1).startLine,s=r.LT(0).startCol;throw new i("Expected a `FUNCTION` or `IDENT` after colon at line "+a+", col "+s+".",a,s)}n=new f(o+n,"pseudo",e,t)}return n},_functional_pseudo:function(){var e=this._tokenStream,t=null;return e.match(g.FUNCTION)&&(t=e.token().value,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(g.RPAREN),t+=")"),t},_expression:function(){for(var e=this._tokenStream,t="";e.match([g.PLUS,g.MINUS,g.DIMENSION,g.NUMBER,g.STRING,g.IDENT,g.LENGTH,g.FREQ,g.ANGLE,g.TIME,g.RESOLUTION,g.SLASH]);)t+=e.token().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){var e,t,r,n=this._tokenStream,i="",o=null;return n.match(g.NOT)&&(i=n.token().value,e=n.token().startLine,t=n.token().startCol,i+=this._readWhitespace(),i+=r=this._negation_arg(),i+=this._readWhitespace(),n.match(g.RPAREN),i+=n.token().value,(o=new f(i,"not",e,t)).args.push(r)),o},_negation_arg:function(){var e,t,r=this._tokenStream,n=[this._type_selector,this._universal,function(){return r.match(g.HASH)?new f(r.token().value,"id",r.token().startLine,r.token().startCol):null},this._class,this._attrib,this._pseudo],i=null,o=0,a=n.length;for(e=r.LT(1).startLine,t=r.LT(1).startCol;o<a&&null===i;)i=n[o].call(this),o++;return null===i&&this._unexpectedToken(r.LT(1)),"elementName"===i.type?new p(i,[],i.toString(),e,t):new p(null,[i],i.toString(),e,t)},_declaration:function(){var e=this._tokenStream,t=null,r=null,n=null,i=null,o="";if(null!==(t=this._property())){e.mustMatch(g.COLON),this._readWhitespace(),(r=this._expr())&&0!==r.length||this._unexpectedToken(e.LT(1)),n=this._prio(),o=t.toString(),(this.options.starHack&&"*"===t.hack||this.options.underscoreHack&&"_"===t.hack)&&(o=t.text);try{this._validateProperty(o,r)}catch(e){i=e}return this.fire({type:"property",property:t,value:r,important:n,line:t.line,col:t.col,invalid:i}),!0}return!1},_prio:function(){var e=this._tokenStream.match(g.IMPORTANT_SYM);return this._readWhitespace(),e},_expr:function(e){var t=[],r=null,n=null;if(null!==(r=this._term(e)))for(t.push(r);(n=this._operator(e))&&t.push(n),null!==(r=this._term(e));)t.push(r);return t.length>0?new u(t,t[0].line,t[0].col):null},_term:function(e){var t,r,n,i,o=this._tokenStream,a=null,s=null,l=null;return null!==(t=this._unary_operator())&&(n=o.token().startLine,i=o.token().startCol),o.peek()===g.IE_FUNCTION&&this.options.ieFilters?(a=this._ie_function(),null===t&&(n=o.token().startLine,i=o.token().startCol)):e&&o.match([g.LPAREN,g.LBRACE,g.LBRACKET])?(s=(r=o.token()).endChar,a=r.value+this._expr(e).text,null===t&&(n=o.token().startLine,i=o.token().startCol),o.mustMatch(g.type(s)),a+=s,this._readWhitespace()):o.match([g.NUMBER,g.PERCENTAGE,g.LENGTH,g.ANGLE,g.TIME,g.FREQ,g.STRING,g.IDENT,g.URI,g.UNICODE_RANGE])?(a=o.token().value,null===t&&(n=o.token().startLine,i=o.token().startCol,l=d.fromToken(o.token())),this._readWhitespace()):null===(r=this._hexcolor())?(null===t&&(n=o.LT(1).startLine,i=o.LT(1).startCol),null===a&&(a=o.LA(3)===g.EQUALS&&this.options.ieFilters?this._ie_function():this._function())):(a=r.value,null===t&&(n=r.startLine,i=r.startCol)),null!==l?l:null!==a?new d(null!==t?t+a:a,n,i):null},_function:function(){var e,t=this._tokenStream,r=null;if(t.match(g.FUNCTION)){if(r=t.token().value,this._readWhitespace(),r+=this._expr(!0),this.options.ieFilters&&t.peek()===g.EQUALS)do{for(this._readWhitespace()&&(r+=t.token().value),t.LA(0)===g.COMMA&&(r+=t.token().value),t.match(g.IDENT),r+=t.token().value,t.match(g.EQUALS),r+=t.token().value,e=t.peek();e!==g.COMMA&&e!==g.S&&e!==g.RPAREN;)t.get(),r+=t.token().value,e=t.peek()}while(t.match([g.COMMA,g.S]));t.match(g.RPAREN),r+=")",this._readWhitespace()}return r},_ie_function:function(){var e,t=this._tokenStream,r=null;if(t.match([g.IE_FUNCTION,g.FUNCTION])){r=t.token().value;do{for(this._readWhitespace()&&(r+=t.token().value),t.LA(0)===g.COMMA&&(r+=t.token().value),t.match(g.IDENT),r+=t.token().value,t.match(g.EQUALS),r+=t.token().value,e=t.peek();e!==g.COMMA&&e!==g.S&&e!==g.RPAREN;)t.get(),r+=t.token().value,e=t.peek()}while(t.match([g.COMMA,g.S]));t.match(g.RPAREN),r+=")",this._readWhitespace()}return r},_hexcolor:function(){var e,t=this._tokenStream,r=null;if(t.match(g.HASH)){if(e=(r=t.token()).value,!/#[a-f0-9]{3,6}/i.test(e))throw new i("Expected a hex color but found '"+e+"' at line "+r.startLine+", col "+r.startCol+".",r.startLine,r.startCol);this._readWhitespace()}return r},_keyframes:function(){var e,t,r,n=this._tokenStream,i="";for(n.mustMatch(g.KEYFRAMES_SYM),e=n.token(),/^@\-([^\-]+)\-/.test(e.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name(),this._readWhitespace(),n.mustMatch(g.LBRACE),this.fire({type:"startkeyframes",name:r,prefix:i,line:e.startLine,col:e.startCol}),this._readWhitespace(),t=n.peek();t===g.IDENT||t===g.PERCENTAGE;)this._keyframe_rule(),this._readWhitespace(),t=n.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:e.startLine,col:e.startCol}),this._readWhitespace(),n.mustMatch(g.RBRACE),this._readWhitespace()},_keyframe_name:function(){var e=this._tokenStream;return e.mustMatch([g.IDENT,g.STRING]),o.fromToken(e.token())},_keyframe_rule:function(){var e=this._key_list();this.fire({type:"startkeyframerule",keys:e,line:e[0].line,col:e[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys:e,line:e[0].line,col:e[0].col})},_key_list:function(){var e=this._tokenStream,t=[];for(t.push(this._key()),this._readWhitespace();e.match(g.COMMA);)this._readWhitespace(),t.push(this._key()),this._readWhitespace();return t},_key:function(){var e,t=this._tokenStream;if(t.match(g.PERCENTAGE))return o.fromToken(t.token());if(t.match(g.IDENT)){if(e=t.token(),/from|to/i.test(e.value))return o.fromToken(e);t.unget()}this._unexpectedToken(t.LT(1))},_skipCruft:function(){for(;this._tokenStream.match([g.S,g.CDO,g.CDC]););},_readDeclarations:function(e,t){var r,n=this._tokenStream;this._readWhitespace(),e&&n.mustMatch(g.LBRACE),this._readWhitespace();try{for(;;){if(n.match(g.SEMICOLON)||t&&this._margin());else{if(!this._declaration())break;if(!n.match(g.SEMICOLON))break}this._readWhitespace()}n.mustMatch(g.RBRACE),this._readWhitespace()}catch(e){if(!(e instanceof i)||this.options.strict)throw e;if(this.fire({type:"error",error:e,message:e.message,line:e.line,col:e.col}),(r=n.advance([g.SEMICOLON,g.RBRACE]))===g.SEMICOLON)this._readDeclarations(!1,t);else if(r!==g.RBRACE)throw e}},_readWhitespace:function(){for(var e=this._tokenStream,t="";e.match(g.S);)t+=e.token().value;return t},_unexpectedToken:function(e){throw new i("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!==g.EOF&&this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){b.validate(e,t)},parse:function(e){this._tokenStream=new m(e,g),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery:function(e){this._tokenStream=new m(e,g);var t=this._media_query();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._expr();return this._readWhitespace(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._ruleset();return this._readWhitespace(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new m(e,g),this._readWhitespace();var t=this._selector();return this._readWhitespace(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new m(e,g),this._readDeclarations()}};for(e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e]);return t}()},{"../util/EventTarget":23,"../util/SyntaxError":25,"../util/SyntaxUnit":26,"./Combinator":2,"./MediaFeature":4,"./MediaQuery":5,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./TokenStream":17,"./Tokens":18,"./Validation":19}],7:[function(e,t,r){"use strict";t.exports={__proto__:null,"align-items":"flex-start | flex-end | center | baseline | stretch","align-content":"flex-start | flex-end | center | space-between | space-around | stretch","align-self":"auto | flex-start | flex-end | center | baseline | stretch","-webkit-align-items":"flex-start | flex-end | center | baseline | stretch","-webkit-align-content":"flex-start | flex-end | center | space-between | space-around | stretch","-webkit-align-self":"auto | flex-start | flex-end | center | baseline | stretch","alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>","alignment-baseline":"auto | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",animation:1,"animation-delay":"<time>#","animation-direction":"<single-animation-direction>#","animation-duration":"<time>#","animation-fill-mode":"[ none | forwards | backwards | both ]#","animation-iteration-count":"[ <number> | infinite ]#","animation-name":"[ none | <single-animation-name> ]#","animation-play-state":"[ running | paused ]#","animation-timing-function":1,"-moz-animation-delay":"<time>#","-moz-animation-direction":"[ normal | alternate ]#","-moz-animation-duration":"<time>#","-moz-animation-iteration-count":"[ <number> | infinite ]#","-moz-animation-name":"[ none | <single-animation-name> ]#","-moz-animation-play-state":"[ running | paused ]#","-ms-animation-delay":"<time>#","-ms-animation-direction":"[ normal | alternate ]#","-ms-animation-duration":"<time>#","-ms-animation-iteration-count":"[ <number> | infinite ]#","-ms-animation-name":"[ none | <single-animation-name> ]#","-ms-animation-play-state":"[ running | paused ]#","-webkit-animation-delay":"<time>#","-webkit-animation-direction":"[ normal | alternate ]#","-webkit-animation-duration":"<time>#","-webkit-animation-fill-mode":"[ none | forwards | backwards | both ]#","-webkit-animation-iteration-count":"[ <number> | infinite ]#","-webkit-animation-name":"[ none | <single-animation-name> ]#","-webkit-animation-play-state":"[ running | paused ]#","-o-animation-delay":"<time>#","-o-animation-direction":"[ normal | alternate ]#","-o-animation-duration":"<time>#","-o-animation-iteration-count":"[ <number> | infinite ]#","-o-animation-name":"[ none | <single-animation-name> ]#","-o-animation-play-state":"[ running | paused ]#",appearance:"icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none",azimuth:"<azimuth>","backface-visibility":"visible | hidden",background:1,"background-attachment":"<attachment>#","background-clip":"<box>#","background-color":"<color>","background-image":"<bg-image>#","background-origin":"<box>#","background-position":"<bg-position>","background-repeat":"<repeat-style>#","background-size":"<bg-size>#","baseline-shift":"baseline | sub | super | <percentage> | <length>",behavior:1,binding:1,bleed:"<length>","bookmark-label":"<content> | <attr> | <string>","bookmark-level":"none | <integer>","bookmark-state":"open | closed","bookmark-target":"none | <uri> | <attr>",border:"<border-width> || <border-style> || <color>","border-bottom":"<border-width> || <border-style> || <color>","border-bottom-color":"<color>","border-bottom-left-radius":"<x-one-radius>","border-bottom-right-radius":"<x-one-radius>","border-bottom-style":"<border-style>","border-bottom-width":"<border-width>","border-collapse":"collapse | separate","border-color":"<color>{1,4}","border-image":1,"border-image-outset":"[ <length> | <number> ]{1,4}","border-image-repeat":"[ stretch | repeat | round ]{1,2}","border-image-slice":"<border-image-slice>","border-image-source":"<image> | none","border-image-width":"[ <length> | <percentage> | <number> | auto ]{1,4}","border-left":"<border-width> || <border-style> || <color>","border-left-color":"<color>","border-left-style":"<border-style>","border-left-width":"<border-width>","border-radius":"<border-radius>","border-right":"<border-width> || <border-style> || <color>","border-right-color":"<color>","border-right-style":"<border-style>","border-right-width":"<border-width>","border-spacing":"<length>{1,2}","border-style":"<border-style>{1,4}","border-top":"<border-width> || <border-style> || <color>","border-top-color":"<color>","border-top-left-radius":"<x-one-radius>","border-top-right-radius":"<x-one-radius>","border-top-style":"<border-style>","border-top-width":"<border-width>","border-width":"<border-width>{1,4}",bottom:"<margin-width>","-moz-box-align":"start | end | center | baseline | stretch","-moz-box-decoration-break":"slice | clone","-moz-box-direction":"normal | reverse","-moz-box-flex":"<number>","-moz-box-flex-group":"<integer>","-moz-box-lines":"single | multiple","-moz-box-ordinal-group":"<integer>","-moz-box-orient":"horizontal | vertical | inline-axis | block-axis","-moz-box-pack":"start | end | center | justify","-o-box-decoration-break":"slice | clone","-webkit-box-align":"start | end | center | baseline | stretch","-webkit-box-decoration-break":"slice | clone","-webkit-box-direction":"normal | reverse","-webkit-box-flex":"<number>","-webkit-box-flex-group":"<integer>","-webkit-box-lines":"single | multiple","-webkit-box-ordinal-group":"<integer>","-webkit-box-orient":"horizontal | vertical | inline-axis | block-axis","-webkit-box-pack":"start | end | center | justify","box-decoration-break":"slice | clone","box-shadow":"<box-shadow>","box-sizing":"content-box | border-box","break-after":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-before":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-inside":"auto | avoid | avoid-page | avoid-column","caption-side":"top | bottom",clear:"none | right | left | both",clip:"<shape> | auto","-webkit-clip-path":"<clip-source> | <clip-path> | none","clip-path":"<clip-source> | <clip-path> | none","clip-rule":"nonzero | evenodd",color:"<color>","color-interpolation":"auto | sRGB | linearRGB","color-interpolation-filters":"auto | sRGB | linearRGB","color-profile":1,"color-rendering":"auto | optimizeSpeed | optimizeQuality","column-count":"<integer> | auto","column-fill":"auto | balance","column-gap":"<length> | normal","column-rule":"<border-width> || <border-style> || <color>","column-rule-color":"<color>","column-rule-style":"<border-style>","column-rule-width":"<border-width>","column-span":"none | all","column-width":"<length> | auto",columns:1,content:1,"counter-increment":1,"counter-reset":1,crop:"<shape> | auto",cue:"cue-after | cue-before","cue-after":1,"cue-before":1,cursor:1,direction:"ltr | rtl",display:"inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | run-in | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | contents | none | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex","dominant-baseline":"auto | use-script | no-change | reset-size | ideographic | alphabetic | hanging | mathematical | central | middle | text-after-edge | text-before-edge","drop-initial-after-adjust":"central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>","drop-initial-after-align":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-before-adjust":"before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>","drop-initial-before-align":"caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-size":"auto | line | <length> | <percentage>","drop-initial-value":"<integer>",elevation:"<angle> | below | level | above | higher | lower","empty-cells":"show | hide","enable-background":1,fill:"<paint>","fill-opacity":"<opacity-value>","fill-rule":"nonzero | evenodd",filter:"<filter-function-list> | none",fit:"fill | hidden | meet | slice","fit-position":1,flex:"<flex>","flex-basis":"<width>","flex-direction":"row | row-reverse | column | column-reverse","flex-flow":"<flex-direction> || <flex-wrap>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap | wrap | wrap-reverse","-webkit-flex":"<flex>","-webkit-flex-basis":"<width>","-webkit-flex-direction":"row | row-reverse | column | column-reverse","-webkit-flex-flow":"<flex-direction> || <flex-wrap>","-webkit-flex-grow":"<number>","-webkit-flex-shrink":"<number>","-webkit-flex-wrap":"nowrap | wrap | wrap-reverse","-ms-flex":"<flex>","-ms-flex-align":"start | end | center | stretch | baseline","-ms-flex-direction":"row | row-reverse | column | column-reverse","-ms-flex-order":"<number>","-ms-flex-pack":"start | end | center | justify","-ms-flex-wrap":"nowrap | wrap | wrap-reverse",float:"left | right | none","float-offset":1,"flood-color":1,"flood-opacity":"<opacity-value>",font:"<font-shorthand> | caption | icon | menu | message-box | small-caption | status-bar","font-family":"<font-family>","font-feature-settings":"<feature-tag-value> | normal","font-kerning":"auto | normal | none","font-size":"<font-size>","font-size-adjust":"<number> | none","font-stretch":"<font-stretch>","font-style":"<font-style>","font-variant":"<font-variant> | normal | none","font-variant-alternates":"<font-variant-alternates> | normal","font-variant-caps":"<font-variant-caps> | normal","font-variant-east-asian":"<font-variant-east-asian> | normal","font-variant-ligatures":"<font-variant-ligatures> | normal | none","font-variant-numeric":"<font-variant-numeric> | normal","font-variant-position":"normal | sub | super","font-weight":"<font-weight>","glyph-orientation-horizontal":"<glyph-angle>","glyph-orientation-vertical":"auto | <glyph-angle>",grid:1,"grid-area":1,"grid-auto-columns":1,"grid-auto-flow":1,"grid-auto-position":1,"grid-auto-rows":1,"grid-cell-stacking":"columns | rows | layer","grid-column":1,"grid-columns":1,"grid-column-align":"start | end | center | stretch","grid-column-sizing":1,"grid-column-start":1,"grid-column-end":1,"grid-column-span":"<integer>","grid-flow":"none | rows | columns","grid-layer":"<integer>","grid-row":1,"grid-rows":1,"grid-row-align":"start | end | center | stretch","grid-row-start":1,"grid-row-end":1,"grid-row-span":"<integer>","grid-row-sizing":1,"grid-template":1,"grid-template-areas":1,"grid-template-columns":1,"grid-template-rows":1,"hanging-punctuation":1,height:"<margin-width> | <content-sizing>","hyphenate-after":"<integer> | auto","hyphenate-before":"<integer> | auto","hyphenate-character":"<string> | auto","hyphenate-lines":"no-limit | <integer>","hyphenate-resource":1,hyphens:"none | manual | auto",icon:1,"image-orientation":"angle | auto","image-rendering":"auto | optimizeSpeed | optimizeQuality","image-resolution":1,"ime-mode":"auto | normal | active | inactive | disabled","inline-box-align":"last | <integer>","justify-content":"flex-start | flex-end | center | space-between | space-around","-webkit-justify-content":"flex-start | flex-end | center | space-between | space-around",kerning:"auto | <length>",left:"<margin-width>","letter-spacing":"<length> | normal","line-height":"<line-height>","line-break":"auto | loose | normal | strict","line-stacking":1,"line-stacking-ruby":"exclude-ruby | include-ruby","line-stacking-shift":"consider-shifts | disregard-shifts","line-stacking-strategy":"inline-line-height | block-line-height | max-height | grid-height","list-style":1,"list-style-image":"<uri> | none","list-style-position":"inside | outside","list-style-type":"disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none",margin:"<margin-width>{1,4}","margin-bottom":"<margin-width>","margin-left":"<margin-width>","margin-right":"<margin-width>","margin-top":"<margin-width>",mark:1,"mark-after":1,"mark-before":1,marker:1,"marker-end":1,"marker-mid":1,"marker-start":1,marks:1,"marquee-direction":1,"marquee-play-count":1,"marquee-speed":1,"marquee-style":1,mask:1,"max-height":"<length> | <percentage> | <content-sizing> | none","max-width":"<length> | <percentage> | <content-sizing> | none","min-height":"<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats","min-width":"<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats","move-to":1,"nav-down":1,"nav-index":1,"nav-left":1,"nav-right":1,"nav-up":1,"object-fit":"fill | contain | cover | none | scale-down","object-position":"<position>",opacity:"<opacity-value>",order:"<integer>","-webkit-order":"<integer>",orphans:"<integer>",outline:1,"outline-color":"<color> | invert","outline-offset":1,"outline-style":"<border-style>","outline-width":"<border-width>",overflow:"visible | hidden | scroll | auto","overflow-style":1,"overflow-wrap":"normal | break-word","overflow-x":1,"overflow-y":1,padding:"<padding-width>{1,4}","padding-bottom":"<padding-width>","padding-left":"<padding-width>","padding-right":"<padding-width>","padding-top":"<padding-width>",page:1,"page-break-after":"auto | always | avoid | left | right","page-break-before":"auto | always | avoid | left | right","page-break-inside":"auto | avoid","page-policy":1,pause:1,"pause-after":1,"pause-before":1,perspective:1,"perspective-origin":1,phonemes:1,pitch:1,"pitch-range":1,"play-during":1,"pointer-events":"auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all",position:"static | relative | absolute | fixed","presentation-level":1,"punctuation-trim":1,quotes:1,"rendering-intent":1,resize:1,rest:1,"rest-after":1,"rest-before":1,richness:1,right:"<margin-width>",rotation:1,"rotation-point":1,"ruby-align":1,"ruby-overhang":1,"ruby-position":1,"ruby-span":1,"shape-rendering":"auto | optimizeSpeed | crispEdges | geometricPrecision",size:1,speak:"normal | none | spell-out","speak-header":"once | always","speak-numeral":"digits | continuous","speak-punctuation":"code | none","speech-rate":1,src:1,"stop-color":1,"stop-opacity":"<opacity-value>",stress:1,"string-set":1,stroke:"<paint>","stroke-dasharray":"none | <dasharray>","stroke-dashoffset":"<percentage> | <length>","stroke-linecap":"butt | round | square","stroke-linejoin":"miter | round | bevel","stroke-miterlimit":"<miterlimit>","stroke-opacity":"<opacity-value>","stroke-width":"<percentage> | <length>","table-layout":"auto | fixed","tab-size":"<integer> | <length>",target:1,"target-name":1,"target-new":1,"target-position":1,"text-align":"left | right | center | justify | match-parent | start | end","text-align-last":1,"text-anchor":"start | middle | end","text-decoration":"<text-decoration>","text-emphasis":1,"text-height":1,"text-indent":"<length> | <percentage>","text-justify":"auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida","text-outline":1,"text-overflow":1,"text-rendering":"auto | optimizeSpeed | optimizeLegibility | geometricPrecision","text-shadow":1,"text-transform":"capitalize | uppercase | lowercase | none","text-wrap":"normal | none | avoid",top:"<margin-width>","-ms-touch-action":"auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation","touch-action":"auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation",transform:1,"transform-origin":1,"transform-style":1,transition:1,"transition-delay":1,"transition-duration":1,"transition-property":1,"transition-timing-function":1,"unicode-bidi":"normal | embed | isolate | bidi-override | isolate-override | plaintext","user-modify":"read-only | read-write | write-only","user-select":"none | text | toggle | element | elements | all","vertical-align":"auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length>",visibility:"visible | hidden | collapse","voice-balance":1,"voice-duration":1,"voice-family":1,"voice-pitch":1,"voice-pitch-range":1,"voice-rate":1,"voice-stress":1,"voice-volume":1,volume:1,"white-space":"normal | pre | nowrap | pre-wrap | pre-line | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap","white-space-collapse":1,widows:"<integer>",width:"<length> | <percentage> | <content-sizing> | auto","will-change":"<will-change>","word-break":"normal | keep-all | break-all","word-spacing":"<length> | normal","word-wrap":"normal | break-word","writing-mode":"horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb","z-index":"<integer> | auto",zoom:"<number> | <percentage> | normal"}},{}],8:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r,o){n.call(this,e,r,o,i.PROPERTY_NAME_TYPE),this.hack=t}o.prototype=new n,o.prototype.constructor=o,o.prototype.toString=function(){return(this.hack?this.hack:"")+this.text}},{"../util/SyntaxUnit":26,"./Parser":6}],9:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r){n.call(this,e.join(" "),t,r,i.PROPERTY_VALUE_TYPE),this.parts=e}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],10:[function(e,t,r){"use strict";function n(e){this._i=0,this._parts=e.parts,this._marks=[],this.value=e}t.exports=n,n.prototype.count=function(){return this._parts.length},n.prototype.isFirst=function(){return 0===this._i},n.prototype.hasNext=function(){return this._i<this._parts.length},n.prototype.mark=function(){this._marks.push(this._i)},n.prototype.peek=function(e){return this.hasNext()?this._parts[this._i+(e||0)]:null},n.prototype.next=function(){return this.hasNext()?this._parts[this._i++]:null},n.prototype.previous=function(){return this._i>0?this._parts[--this._i]:null},n.prototype.restore=function(){this._marks.length&&(this._i=this._marks.pop())},n.prototype.drop=function(){this._marks.pop()}},{}],11:[function(e,t,r){"use strict";t.exports=s;var n=e("../util/SyntaxUnit"),i=e("./Colors"),o=e("./Parser"),a=e("./Tokens");function s(e,t,r,a){var l,c=a||{};if(n.call(this,e,t,r,o.PROPERTY_VALUE_PART_TYPE),this.type="unknown",/^([+\-]?[\d\.]+)([a-z]+)$/i.test(e))switch(this.type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2,this.units.toLowerCase()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc":case"ch":case"vh":case"vw":case"vmax":case"vmin":this.type="length";break;case"fr":this.type="grid";break;case"deg":case"rad":case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz":case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution"}else/^([+\-]?[\d\.]+)%$/i.test(e)?(this.type="percentage",this.value=+RegExp.$1):/^([+\-]?\d+)$/i.test(e)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i.test(e)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test(e)?(this.type="color",3===(l=RegExp.$1).length?(this.red=parseInt(l.charAt(0)+l.charAt(0),16),this.green=parseInt(l.charAt(1)+l.charAt(1),16),this.blue=parseInt(l.charAt(2)+l.charAt(2),16)):(this.red=parseInt(l.substring(0,2),16),this.green=parseInt(l.substring(2,4),16),this.blue=parseInt(l.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(e)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(e)?(this.type="color",this.red=255*+RegExp.$1/100,this.green=255*+RegExp.$2/100,this.blue=255*+RegExp.$3/100):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(e)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(e)?(this.type="color",this.red=255*+RegExp.$1/100,this.green=255*+RegExp.$2/100,this.blue=255*+RegExp.$3/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(e)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(e)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(("([^\\"]|\\.)*")\)/i.test(e)?(this.type="uri",this.uri=s.parseString(RegExp.$1)):/^([^\(]+)\(/i.test(e)?(this.type="function",this.name=RegExp.$1,this.value=e):/^"([^\n\r\f\\"]|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*"/i.test(e)?(this.type="string",this.value=s.parseString(e)):/^'([^\n\r\f\\']|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*'/i.test(e)?(this.type="string",this.value=s.parseString(e)):i[e.toLowerCase()]?(this.type="color",l=i[e.toLowerCase()].substring(1),this.red=parseInt(l.substring(0,2),16),this.green=parseInt(l.substring(2,4),16),this.blue=parseInt(l.substring(4,6),16)):/^[,\/]$/.test(e)?(this.type="operator",this.value=e):/^-?[a-z_\u00A0-\uFFFF][a-z0-9\-_\u00A0-\uFFFF]*$/i.test(e)&&(this.type="identifier",this.value=e);this.wasIdent=Boolean(c.ident)}s.prototype=new n,s.prototype.constructor=s,s.parseString=function(e){return(e=e.slice(1,-1)).replace(/\\(\r\n|[^\r0-9a-f]|[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)/gi,(function(e,t){if(/^(\n|\r\n|\r|\f)$/.test(t))return"";var r=/^[0-9a-f]{1,6}/i.exec(t);if(r){var n=parseInt(r[0],16);return String.fromCodePoint?String.fromCodePoint(n):String.fromCharCode(n)}return t}))},s.serializeString=function(e){return'"'+e.replace(/["\r\n\f]/g,(function(e,t){return'"'===t?"\\"+t:"\\"+(String.codePointAt?String.codePointAt(0):String.charCodeAt(0)).toString(16)+" "}))+'"'},s.fromToken=function(e){return new s(e.value,e.startLine,e.startCol,{ident:e.type===a.IDENT})}},{"../util/SyntaxUnit":26,"./Colors":1,"./Parser":6,"./Tokens":18}],12:[function(e,t,r){"use strict";var n=t.exports={__proto__:null,":first-letter":1,":first-line":1,":before":1,":after":1};n.ELEMENT=1,n.CLASS=2,n.isElement=function(e){return 0===e.indexOf("::")||n[e.toLowerCase()]===n.ELEMENT}},{}],13:[function(e,t,r){"use strict";t.exports=a;var n=e("../util/SyntaxUnit"),i=e("./Parser"),o=e("./Specificity");function a(e,t,r){n.call(this,e.join(" "),t,r,i.SELECTOR_TYPE),this.parts=e,this.specificity=o.calculate(this)}a.prototype=new n,a.prototype.constructor=a},{"../util/SyntaxUnit":26,"./Parser":6,"./Specificity":16}],14:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r,o,a){n.call(this,r,o,a,i.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],15:[function(e,t,r){"use strict";t.exports=o;var n=e("../util/SyntaxUnit"),i=e("./Parser");function o(e,t,r,o){n.call(this,e,r,o,i.SELECTOR_SUB_PART_TYPE),this.type=t,this.args=[]}o.prototype=new n,o.prototype.constructor=o},{"../util/SyntaxUnit":26,"./Parser":6}],16:[function(e,t,r){"use strict";t.exports=o;var n=e("./Pseudos"),i=e("./SelectorPart");function o(e,t,r,n){this.a=e,this.b=t,this.c=r,this.d=n}o.prototype={constructor:o,compare:function(e){var t,r,n=["a","b","c","d"];for(t=0,r=n.length;t<r;t++){if(this[n[t]]<e[n[t]])return-1;if(this[n[t]]>e[n[t]])return 1}return 0},valueOf:function(){return 1e3*this.a+100*this.b+10*this.c+this.d},toString:function(){return this.a+","+this.b+","+this.c+","+this.d}},o.calculate=function(e){var t,r,a,s=0,l=0,c=0;function u(e){var t,r,i,o,a,d=e.elementName?e.elementName.text:"";for(d&&"*"!==d.charAt(d.length-1)&&c++,t=0,i=e.modifiers.length;t<i;t++)switch((a=e.modifiers[t]).type){case"class":case"attribute":l++;break;case"id":s++;break;case"pseudo":n.isElement(a.text)?c++:l++;break;case"not":for(r=0,o=a.args.length;r<o;r++)u(a.args[r])}}for(t=0,r=e.parts.length;t<r;t++)(a=e.parts[t])instanceof i&&u(a);return new o(0,s,l,c)}},{"./Pseudos":12,"./SelectorPart":14}],17:[function(e,t,r){"use strict";t.exports=b;var n=e("../util/TokenStreamBase"),i=e("./PropertyValuePart"),o=e("./Tokens"),a=/^[0-9a-fA-F]$/,s=/^[\u00A0-\uFFFF]$/,l=/\n|\r\n|\r|\f/,c=/\u0009|\u000a|\u000c|\u000d|\u0020/;function u(e){return null!==e&&a.test(e)}function d(e){return null!==e&&/\d/.test(e)}function h(e){return null!==e&&c.test(e)}function p(e){return null!==e&&l.test(e)}function f(e){return null!==e&&/[a-z_\u00A0-\uFFFF\\]/i.test(e)}function m(e){return null!==e&&(f(e)||/[0-9\-\\]/.test(e))}function g(e){return null!==e&&(f(e)||/\-\\/.test(e))}function b(e){n.call(this,e,o)}b.prototype=function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}(new n,{_getToken:function(){var e,t=this._reader,r=null,n=t.getLine(),i=t.getCol();for(e=t.read();e;){switch(e){case"/":r="*"===t.peek()?this.commentToken(e,n,i):this.charToken(e,n,i);break;case"|":case"~":case"^":case"$":case"*":r="="===t.peek()?this.comparisonToken(e,n,i):this.charToken(e,n,i);break;case'"':case"'":r=this.stringToken(e,n,i);break;case"#":r=m(t.peek())?this.hashToken(e,n,i):this.charToken(e,n,i);break;case".":r=d(t.peek())?this.numberToken(e,n,i):this.charToken(e,n,i);break;case"-":r="-"===t.peek()?this.htmlCommentEndToken(e,n,i):f(t.peek())?this.identOrFunctionToken(e,n,i):this.charToken(e,n,i);break;case"!":r=this.importantToken(e,n,i);break;case"@":r=this.atRuleToken(e,n,i);break;case":":r=this.notToken(e,n,i);break;case"<":r=this.htmlCommentStartToken(e,n,i);break;case"\\":r=/[^\r\n\f]/.test(t.peek())?this.identOrFunctionToken(this.readEscape(e,!0),n,i):this.charToken(e,n,i);break;case"U":case"u":if("+"===t.peek()){r=this.unicodeRangeToken(e,n,i);break}default:r=d(e)?this.numberToken(e,n,i):h(e)?this.whitespaceToken(e,n,i):g(e)?this.identOrFunctionToken(e,n,i):this.charToken(e,n,i)}break}return r||null!==e||(r=this.createToken(o.EOF,null,n,i)),r},createToken:function(e,t,r,n,i){var o=this._reader;return{value:t,type:e,channel:(i=i||{}).channel,endChar:i.endChar,hide:i.hide||!1,startLine:r,startCol:n,endLine:o.getLine(),endCol:o.getCol()}},atRuleToken:function(e,t,r){var n=e,i=this._reader,a=o.CHAR;return i.mark(),n=e+this.readName(),(a=o.type(n.toLowerCase()))!==o.CHAR&&a!==o.UNKNOWN||(n.length>1?a=o.UNKNOWN_SYM:(a=o.CHAR,n=e,i.reset())),this.createToken(a,n,t,r)},charToken:function(e,t,r){var n=o.type(e),i={};return-1===n?n=o.CHAR:i.endChar=o[n].endChar,this.createToken(n,e,t,r,i)},commentToken:function(e,t,r){var n=this.readComment(e);return this.createToken(o.COMMENT,n,t,r)},comparisonToken:function(e,t,r){var n=e+this._reader.read(),i=o.type(n)||o.CHAR;return this.createToken(i,n,t,r)},hashToken:function(e,t,r){var n=this.readName(e);return this.createToken(o.HASH,n,t,r)},htmlCommentStartToken:function(e,t,r){var n=this._reader,i=e;return n.mark(),"\x3c!--"===(i+=n.readCount(3))?this.createToken(o.CDO,i,t,r):(n.reset(),this.charToken(e,t,r))},htmlCommentEndToken:function(e,t,r){var n=this._reader,i=e;return n.mark(),"--\x3e"===(i+=n.readCount(2))?this.createToken(o.CDC,i,t,r):(n.reset(),this.charToken(e,t,r))},identOrFunctionToken:function(e,t,r){var n,i=this._reader,a=this.readName(e),s=o.IDENT;return"("===i.peek()?(a+=i.read(),["url(","url-prefix(","domain("].indexOf(a.toLowerCase())>-1?(i.mark(),null===(n=this.readURI(a))?(i.reset(),s=o.FUNCTION):(s=o.URI,a=n)):s=o.FUNCTION):":"===i.peek()&&"progid"===a.toLowerCase()&&(a+=i.readTo("("),s=o.IE_FUNCTION),this.createToken(s,a,t,r)},importantToken:function(e,t,r){var n,i,a=this._reader,s=e,l=o.CHAR;for(a.mark(),i=a.read();i;){if("/"===i){if("*"!==a.peek())break;if(""===(n=this.readComment(i)))break}else{if(!h(i)){if(/i/i.test(i)){n=a.readCount(8),/mportant/i.test(n)&&(s+=i+n,l=o.IMPORTANT_SYM);break}break}s+=i+this.readWhitespace()}i=a.read()}return l===o.CHAR?(a.reset(),this.charToken(e,t,r)):this.createToken(l,s,t,r)},notToken:function(e,t,r){var n=this._reader,i=e;return n.mark(),":not("===(i+=n.readCount(4)).toLowerCase()?this.createToken(o.NOT,i,t,r):(n.reset(),this.charToken(e,t,r))},numberToken:function(e,t,r){var n,i=this._reader,a=this.readNumber(e),s=o.NUMBER,l=i.peek();return g(l)?(a+=n=this.readName(i.read()),s=/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(n)?o.LENGTH:/^deg|^rad$|^grad$/i.test(n)?o.ANGLE:/^ms$|^s$/i.test(n)?o.TIME:/^hz$|^khz$/i.test(n)?o.FREQ:/^dpi$|^dpcm$/i.test(n)?o.RESOLUTION:o.DIMENSION):"%"===l&&(a+=i.read(),s=o.PERCENTAGE),this.createToken(s,a,t,r)},stringToken:function(e,t,r){for(var n,i=e,a=e,s=this._reader,l=o.STRING,c=s.read();c;){if(a+=c,"\\"===c){if(null===(c=s.read()))break;if(/[^\r\n\f0-9a-f]/i.test(c))a+=c;else{for(n=0;u(c)&&n<6;n++)a+=c,c=s.read();if("\r"===c&&"\n"===s.peek()&&(a+=c,c=s.read()),!h(c))continue;a+=c}}else{if(c===i)break;if(p(s.peek())){l=o.INVALID;break}}c=s.read()}return null===c&&(l=o.INVALID),this.createToken(l,a,t,r)},unicodeRangeToken:function(e,t,r){var n,i=this._reader,a=e,s=o.CHAR;return"+"===i.peek()&&(i.mark(),a+=i.read(),2===(a+=this.readUnicodeRangePart(!0)).length?i.reset():(s=o.UNICODE_RANGE,-1===a.indexOf("?")&&"-"===i.peek()&&(i.mark(),n=i.read(),1===(n+=this.readUnicodeRangePart(!1)).length?i.reset():a+=n))),this.createToken(s,a,t,r)},whitespaceToken:function(e,t,r){var n=e+this.readWhitespace();return this.createToken(o.S,n,t,r)},readUnicodeRangePart:function(e){for(var t=this._reader,r="",n=t.peek();u(n)&&r.length<6;)t.read(),r+=n,n=t.peek();if(e)for(;"?"===n&&r.length<6;)t.read(),r+=n,n=t.peek();return r},readWhitespace:function(){for(var e=this._reader,t="",r=e.peek();h(r);)e.read(),t+=r,r=e.peek();return t},readNumber:function(e){for(var t=this._reader,r=e,n="."===e,i=t.peek();i;){if(d(i))r+=t.read();else{if("."!==i)break;if(n)break;n=!0,r+=t.read()}i=t.peek()}return r},readString:function(){var e=this.stringToken(this._reader.read(),0,0);return e.type===o.INVALID?null:e.value},readURI:function(e){for(var t=this._reader,r=e,n="",o=t.peek();o&&h(o);)t.read(),o=t.peek();for("'"===o||'"'===o?null!==(n=this.readString())&&(n=i.parseString(n)):n=this.readUnquotedURL(),o=t.peek();o&&h(o);)t.read(),o=t.peek();return null===n||")"!==o?r=null:r+=i.serializeString(n)+t.read(),r},readUnquotedURL:function(e){var t,r=this._reader,n=e||"";for(t=r.peek();t;t=r.peek())if(s.test(t)||/^[\-!#$%&*-\[\]-~]$/.test(t))n+=t,r.read();else{if("\\"!==t)break;if(!/^[^\r\n\f]$/.test(r.peek(2)))break;n+=this.readEscape(r.read(),!0)}return n},readName:function(e){var t,r=this._reader,n=e||"";for(t=r.peek();t;t=r.peek())if("\\"===t){if(!/^[^\r\n\f]$/.test(r.peek(2)))break;n+=this.readEscape(r.read(),!0)}else{if(!m(t))break;n+=r.read()}return n},readEscape:function(e,t){var r=this._reader,n=e||"",i=0,o=r.peek();if(u(o))do{n+=r.read(),o=r.peek()}while(o&&u(o)&&++i<6);if(1===n.length){if(!/^[^\r\n\f0-9a-f]$/.test(o))throw new Error("Bad escape sequence.");if(r.read(),t)return o}else"\r"===o?(r.read(),"\n"===r.peek()&&(o+=r.read())):/^[ \t\n\f]$/.test(o)?r.read():o="";if(t){var a=parseInt(n.slice(e.length),16);return String.fromCodePoint?String.fromCodePoint(a):String.fromCharCode(a)}return n+o},readComment:function(e){var t=this._reader,r=e||"",n=t.read();if("*"===n){for(;n;){if((r+=n).length>2&&"*"===n&&"/"===t.peek()){r+=t.read();break}n=t.read()}return r}return""}})},{"../util/TokenStreamBase":27,"./PropertyValuePart":11,"./Tokens":18}],18:[function(e,t,r){"use strict";var n=t.exports=[{name:"CDO"},{name:"CDC"},{name:"S",whitespace:!0},{name:"COMMENT",comment:!0,hide:!0,channel:"comment"},{name:"INCLUDES",text:"~="},{name:"DASHMATCH",text:"|="},{name:"PREFIXMATCH",text:"^="},{name:"SUFFIXMATCH",text:"$="},{name:"SUBSTRINGMATCH",text:"*="},{name:"STRING"},{name:"IDENT"},{name:"HASH"},{name:"IMPORT_SYM",text:"@import"},{name:"PAGE_SYM",text:"@page"},{name:"MEDIA_SYM",text:"@media"},{name:"FONT_FACE_SYM",text:"@font-face"},{name:"CHARSET_SYM",text:"@charset"},{name:"NAMESPACE_SYM",text:"@namespace"},{name:"SUPPORTS_SYM",text:"@supports"},{name:"VIEWPORT_SYM",text:["@viewport","@-ms-viewport","@-o-viewport"]},{name:"DOCUMENT_SYM",text:["@document","@-moz-document"]},{name:"UNKNOWN_SYM"},{name:"KEYFRAMES_SYM",text:["@keyframes","@-webkit-keyframes","@-moz-keyframes","@-o-keyframes"]},{name:"IMPORTANT_SYM"},{name:"LENGTH"},{name:"ANGLE"},{name:"TIME"},{name:"FREQ"},{name:"DIMENSION"},{name:"PERCENTAGE"},{name:"NUMBER"},{name:"URI"},{name:"FUNCTION"},{name:"UNICODE_RANGE"},{name:"INVALID"},{name:"PLUS",text:"+"},{name:"GREATER",text:">"},{name:"COMMA",text:","},{name:"TILDE",text:"~"},{name:"NOT"},{name:"TOPLEFTCORNER_SYM",text:"@top-left-corner"},{name:"TOPLEFT_SYM",text:"@top-left"},{name:"TOPCENTER_SYM",text:"@top-center"},{name:"TOPRIGHT_SYM",text:"@top-right"},{name:"TOPRIGHTCORNER_SYM",text:"@top-right-corner"},{name:"BOTTOMLEFTCORNER_SYM",text:"@bottom-left-corner"},{name:"BOTTOMLEFT_SYM",text:"@bottom-left"},{name:"BOTTOMCENTER_SYM",text:"@bottom-center"},{name:"BOTTOMRIGHT_SYM",text:"@bottom-right"},{name:"BOTTOMRIGHTCORNER_SYM",text:"@bottom-right-corner"},{name:"LEFTTOP_SYM",text:"@left-top"},{name:"LEFTMIDDLE_SYM",text:"@left-middle"},{name:"LEFTBOTTOM_SYM",text:"@left-bottom"},{name:"RIGHTTOP_SYM",text:"@right-top"},{name:"RIGHTMIDDLE_SYM",text:"@right-middle"},{name:"RIGHTBOTTOM_SYM",text:"@right-bottom"},{name:"RESOLUTION",state:"media"},{name:"IE_FUNCTION"},{name:"CHAR"},{name:"PIPE",text:"|"},{name:"SLASH",text:"/"},{name:"MINUS",text:"-"},{name:"STAR",text:"*"},{name:"LBRACE",endChar:"}",text:"{"},{name:"RBRACE",text:"}"},{name:"LBRACKET",endChar:"]",text:"["},{name:"RBRACKET",text:"]"},{name:"EQUALS",text:"="},{name:"COLON",text:":"},{name:"SEMICOLON",text:";"},{name:"LPAREN",endChar:")",text:"("},{name:"RPAREN",text:")"},{name:"DOT",text:"."}];!function(){var e=[],t=Object.create(null);n.UNKNOWN=-1,n.unshift({name:"EOF"});for(var r=0,i=n.length;r<i;r++)if(e.push(n[r].name),n[n[r].name]=r,n[r].text)if(n[r].text instanceof Array)for(var o=0;o<n[r].text.length;o++)t[n[r].text[o]]=r;else t[n[r].text]=r;n.name=function(t){return e[t]},n.type=function(e){return t[e]||-1}}()},{}],19:[function(e,t,r){"use strict";var n=e("./Matcher"),i=e("./Properties"),o=e("./ValidationTypes"),a=e("./ValidationError"),s=e("./PropertyValueIterator");t.exports={validate:function(e,t){var r,n=e.toString().toLowerCase(),l=new s(t),c=i[n];if(c){if("number"!=typeof c){if(o.isAny(l,"inherit | initial | unset")){if(l.hasNext())throw r=l.next(),new a("Expected end of value but found '"+r+"'.",r.line,r.col);return}this.singleProperty(c,l)}}else if(0!==n.indexOf("-"))throw new a("Unknown property '"+e+"'.",e.line,e.col)},singleProperty:function(e,t){var r,i=t.value;if(!n.parse(e).match(t))throw t.hasNext()&&!t.isFirst()?(r=t.peek(),new a("Expected end of value but found '"+r+"'.",r.line,r.col)):new a("Expected ("+o.describe(e)+") but found '"+i+"'.",i.line,i.col);if(t.hasNext())throw r=t.next(),new a("Expected end of value but found '"+r+"'.",r.line,r.col)}}},{"./Matcher":3,"./Properties":7,"./PropertyValueIterator":10,"./ValidationError":20,"./ValidationTypes":21}],20:[function(e,t,r){"use strict";function n(e,t,r){this.col=r,this.line=t,this.message=e}t.exports=n,n.prototype=new Error},{}],21:[function(e,t,r){"use strict";var n,i,o=t.exports,a=e("./Matcher");n=o,i={isLiteral:function(e,t){var r,n,i=e.text.toString().toLowerCase(),o=t.split(" | "),a=!1;for(r=0,n=o.length;r<n&&!a;r++)"<"===o[r].charAt(0)?a=this.simple[o[r]](e):"()"===o[r].slice(-2)?a="function"===e.type&&e.name===o[r].slice(0,-2):i===o[r].toLowerCase()&&(a=!0);return a},isSimple:function(e){return Boolean(this.simple[e])},isComplex:function(e){return Boolean(this.complex[e])},describe:function(e){return this.complex[e]instanceof a?this.complex[e].toString(0):e},isAny:function(e,t){var r,n,i=t.split(" | "),o=!1;for(r=0,n=i.length;r<n&&!o&&e.hasNext();r++)o=this.isType(e,i[r]);return o},isAnyOfGroup:function(e,t){var r,n,i=t.split(" || "),o=!1;for(r=0,n=i.length;r<n&&!o;r++)o=this.isType(e,i[r]);return!!o&&i[r-1]},isType:function(e,t){var r=e.peek(),n=!1;return"<"!==t.charAt(0)?(n=this.isLiteral(r,t))&&e.next():this.simple[t]?(n=this.simple[t](r))&&e.next():n=this.complex[t]instanceof a?this.complex[t].match(e):this.complex[t](e),n},simple:{__proto__:null,"<absolute-size>":"xx-small | x-small | small | medium | large | x-large | xx-large","<animateable-feature>":"scroll-position | contents | <animateable-feature-name>","<animateable-feature-name>":function(e){return this["<ident>"](e)&&!/^(unset|initial|inherit|will-change|auto|scroll-position|contents)$/i.test(e)},"<angle>":function(e){return"angle"===e.type},"<attachment>":"scroll | fixed | local","<attr>":"attr()","<basic-shape>":"inset() | circle() | ellipse() | polygon()","<bg-image>":"<image> | <gradient> | none","<border-style>":"none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset","<border-width>":"<length> | thin | medium | thick","<box>":"padding-box | border-box | content-box","<clip-source>":"<uri>","<color>":function(e){return"color"===e.type||"transparent"===String(e)||"currentColor"===String(e)},"<color-svg>":function(e){return"color"===e.type},"<content>":"content()","<content-sizing>":"fill-available | -moz-available | -webkit-fill-available | max-content | -moz-max-content | -webkit-max-content | min-content | -moz-min-content | -webkit-min-content | fit-content | -moz-fit-content | -webkit-fit-content","<feature-tag-value>":function(e){return"function"===e.type&&/^[A-Z0-9]{4}$/i.test(e)},"<filter-function>":"blur() | brightness() | contrast() | custom() | drop-shadow() | grayscale() | hue-rotate() | invert() | opacity() | saturate() | sepia()","<flex-basis>":"<width>","<flex-direction>":"row | row-reverse | column | column-reverse","<flex-grow>":"<number>","<flex-shrink>":"<number>","<flex-wrap>":"nowrap | wrap | wrap-reverse","<font-size>":"<absolute-size> | <relative-size> | <length> | <percentage>","<font-stretch>":"normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded","<font-style>":"normal | italic | oblique","<font-variant-caps>":"small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps","<font-variant-css21>":"normal | small-caps","<font-weight>":"normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900","<generic-family>":"serif | sans-serif | cursive | fantasy | monospace","<geometry-box>":"<shape-box> | fill-box | stroke-box | view-box","<glyph-angle>":function(e){return"angle"===e.type&&"deg"===e.units},"<gradient>":function(e){return"function"===e.type&&/^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(e)},"<icccolor>":"cielab() | cielch() | cielchab() | icc-color() | icc-named-color()","<ident>":function(e){return"identifier"===e.type||e.wasIdent},"<ident-not-generic-family>":function(e){return this["<ident>"](e)&&!this["<generic-family>"](e)},"<image>":"<uri>","<integer>":function(e){return"integer"===e.type},"<length>":function(e){return!("function"!==e.type||!/^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(e))||"length"===e.type||"number"===e.type||"integer"===e.type||"0"===String(e)},"<line>":function(e){return"integer"===e.type},"<line-height>":"<number> | <length> | <percentage> | normal","<margin-width>":"<length> | <percentage> | auto","<miterlimit>":function(e){return this["<number>"](e)&&e.value>=1},"<nonnegative-length-or-percentage>":function(e){return(this["<length>"](e)||this["<percentage>"](e))&&("0"===String(e)||"function"===e.type||e.value>=0)},"<nonnegative-number-or-percentage>":function(e){return(this["<number>"](e)||this["<percentage>"](e))&&("0"===String(e)||"function"===e.type||e.value>=0)},"<number>":function(e){return"number"===e.type||this["<integer>"](e)},"<opacity-value>":function(e){return this["<number>"](e)&&e.value>=0&&e.value<=1},"<padding-width>":"<nonnegative-length-or-percentage>","<percentage>":function(e){return"percentage"===e.type||"0"===String(e)},"<relative-size>":"smaller | larger","<shape>":"rect() | inset-rect()","<shape-box>":"<box> | margin-box","<single-animation-direction>":"normal | reverse | alternate | alternate-reverse","<single-animation-name>":function(e){return this["<ident>"](e)&&/^-?[a-z_][-a-z0-9_]+$/i.test(e)&&!/^(none|unset|initial|inherit)$/i.test(e)},"<string>":function(e){return"string"===e.type},"<time>":function(e){return"time"===e.type},"<uri>":function(e){return"uri"===e.type},"<width>":"<margin-width>"},complex:{__proto__:null,"<azimuth>":"<angle> | [ [ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards","<bg-position>":"<position>#","<bg-size>":"[ <length> | <percentage> | auto ]{1,2} | cover | contain","<border-image-slice>":a.many([!0],a.cast("<nonnegative-number-or-percentage>"),a.cast("<nonnegative-number-or-percentage>"),a.cast("<nonnegative-number-or-percentage>"),a.cast("<nonnegative-number-or-percentage>"),"fill"),"<border-radius>":"<nonnegative-length-or-percentage>{1,4} [ / <nonnegative-length-or-percentage>{1,4} ]?","<box-shadow>":"none | <shadow>#","<clip-path>":"<basic-shape> || <geometry-box>","<dasharray>":a.cast("<nonnegative-length-or-percentage>").braces(1,1/0,"#",a.cast(",").question()),"<family-name>":"<string> | <ident-not-generic-family> <ident>*","<filter-function-list>":"[ <filter-function> | <uri> ]+","<flex>":"none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]","<font-family>":"[ <generic-family> | <family-name> ]#","<font-shorthand>":"[ <font-style> || <font-variant-css21> || <font-weight> || <font-stretch> ]? <font-size> [ / <line-height> ]? <font-family>","<font-variant-alternates>":"stylistic() || historical-forms || styleset() || character-variant() || swash() || ornaments() || annotation()","<font-variant-ligatures>":"[ common-ligatures | no-common-ligatures ] || [ discretionary-ligatures | no-discretionary-ligatures ] || [ historical-ligatures | no-historical-ligatures ] || [ contextual | no-contextual ]","<font-variant-numeric>":"[ lining-nums | oldstyle-nums ] || [ proportional-nums | tabular-nums ] || [ diagonal-fractions | stacked-fractions ] || ordinal || slashed-zero","<font-variant-east-asian>":"[ jis78 | jis83 | jis90 | jis04 | simplified | traditional ] || [ full-width | proportional-width ] || ruby","<paint>":"<paint-basic> | <uri> <paint-basic>?","<paint-basic>":"none | currentColor | <color-svg> <icccolor>?","<position>":"[ center | [ left | right ] [ <percentage> | <length> ]? ] && [ center | [ top | bottom ] [ <percentage> | <length> ]? ] | [ left | center | right | <percentage> | <length> ] [ top | center | bottom | <percentage> | <length> ] | [ left | center | right | top | bottom | <percentage> | <length> ]","<repeat-style>":"repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2}","<shadow>":a.many([!0],a.cast("<length>").braces(2,4),"inset","<color>"),"<text-decoration>":"none | [ underline || overline || line-through || blink ]","<will-change>":"auto | <animateable-feature>#","<x-one-radius>":"[ <length> | <percentage> ]{1,2}"}},Object.keys(i).forEach((function(e){n[e]=i[e]})),Object.keys(o.simple).forEach((function(e){var t=o.simple[e];"string"==typeof t&&(o.simple[e]=function(e){return o.isLiteral(e,t)})})),Object.keys(o.complex).forEach((function(e){var t=o.complex[e];"string"==typeof t&&(o.complex[e]=a.parse(t))})),o.complex["<font-variant>"]=a.oror({expand:"<font-variant-ligatures>"},{expand:"<font-variant-alternates>"},"<font-variant-caps>",{expand:"<font-variant-numeric>"},{expand:"<font-variant-east-asian>"})},{"./Matcher":3}],22:[function(e,t,r){"use strict";t.exports={Colors:e("./Colors"),Combinator:e("./Combinator"),Parser:e("./Parser"),PropertyName:e("./PropertyName"),PropertyValue:e("./PropertyValue"),PropertyValuePart:e("./PropertyValuePart"),Matcher:e("./Matcher"),MediaFeature:e("./MediaFeature"),MediaQuery:e("./MediaQuery"),Selector:e("./Selector"),SelectorPart:e("./SelectorPart"),SelectorSubPart:e("./SelectorSubPart"),Specificity:e("./Specificity"),TokenStream:e("./TokenStream"),Tokens:e("./Tokens"),ValidationError:e("./ValidationError")}},{"./Colors":1,"./Combinator":2,"./Matcher":3,"./MediaFeature":4,"./MediaQuery":5,"./Parser":6,"./PropertyName":8,"./PropertyValue":9,"./PropertyValuePart":11,"./Selector":13,"./SelectorPart":14,"./SelectorSubPart":15,"./Specificity":16,"./TokenStream":17,"./Tokens":18,"./ValidationError":20}],23:[function(e,t,r){"use strict";function n(){this._listeners=Object.create(null)}t.exports=n,n.prototype={constructor:n,addListener:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t)},fire:function(e){if("string"==typeof e&&(e={type:e}),void 0!==e.target&&(e.target=this),void 0===e.type)throw new Error("Event object missing 'type' property.");if(this._listeners[e.type])for(var t=this._listeners[e.type].concat(),r=0,n=t.length;r<n;r++)t[r].call(this,e)},removeListener:function(e,t){if(this._listeners[e])for(var r=this._listeners[e],n=0,i=r.length;n<i;n++)if(r[n]===t){r.splice(n,1);break}}}},{}],24:[function(e,t,r){"use strict";function n(e){this._input=e.replace(/(\r\n?|\n)/g,"\n"),this._line=1,this._col=1,this._cursor=0}t.exports=n,n.prototype={constructor:n,getCol:function(){return this._col},getLine:function(){return this._line},eof:function(){return this._cursor===this._input.length},peek:function(e){var t=null;return e=void 0===e?1:e,this._cursor<this._input.length&&(t=this._input.charAt(this._cursor+e-1)),t},read:function(){var e=null;return this._cursor<this._input.length&&("\n"===this._input.charAt(this._cursor)?(this._line++,this._col=1):this._col++,e=this._input.charAt(this._cursor++)),e},mark:function(){this._bookmark={cursor:this._cursor,line:this._line,col:this._col}},reset:function(){this._bookmark&&(this._cursor=this._bookmark.cursor,this._line=this._bookmark.line,this._col=this._bookmark.col,delete this._bookmark)},readTo:function(e){for(var t,r="";r.length<e.length||r.lastIndexOf(e)!==r.length-e.length;){if(!(t=this.read()))throw new Error('Expected "'+e+'" at line '+this._line+", col "+this._col+".");r+=t}return r},readWhile:function(e){for(var t="",r=this.peek();null!==r&&e(r);)t+=this.read(),r=this.peek();return t},readMatch:function(e){var t=this._input.substring(this._cursor),r=null;return"string"==typeof e?t.slice(0,e.length)===e&&(r=this.readCount(e.length)):e instanceof RegExp&&e.test(t)&&(r=this.readCount(RegExp.lastMatch.length)),r},readCount:function(e){for(var t="";e--;)t+=this.read();return t}}},{}],25:[function(e,t,r){"use strict";function n(e,t,r){Error.call(this),this.name=this.constructor.name,this.col=r,this.line=t,this.message=e}t.exports=n,n.prototype=Object.create(Error.prototype),n.prototype.constructor=n},{}],26:[function(e,t,r){"use strict";function n(e,t,r,n){this.col=r,this.line=t,this.text=e,this.type=n}t.exports=n,n.fromToken=function(e){return new n(e.value,e.startLine,e.startCol)},n.prototype={constructor:n,valueOf:function(){return this.toString()},toString:function(){return this.text}}},{}],27:[function(e,t,r){"use strict";t.exports=o;var n=e("./StringReader"),i=e("./SyntaxError");function o(e,t){this._reader=new n(e?e.toString():""),this._token=null,this._tokenData=t,this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}o.createTokenData=function(e){var t=[],r=Object.create(null),n=e.concat([]),i=0,o=n.length+1;for(n.UNKNOWN=-1,n.unshift({name:"EOF"});i<o;i++)t.push(n[i].name),n[n[i].name]=i,n[i].text&&(r[n[i].text]=i);return n.name=function(e){return t[e]},n.type=function(e){return r[e]},n},o.prototype={constructor:o,match:function(e,t){e instanceof Array||(e=[e]);for(var r=this.get(t),n=0,i=e.length;n<i;)if(r===e[n++])return!0;return this.unget(),!1},mustMatch:function(e){var t;if(e instanceof Array||(e=[e]),!this.match.apply(this,arguments))throw t=this.LT(1),new i("Expected "+this._tokenData[e[0]].name+" at line "+t.startLine+", col "+t.startCol+".",t.startLine,t.startCol)},advance:function(e,t){for(;0!==this.LA(0)&&!this.match(e,t);)this.get();return this.LA(0)},get:function(e){var t,r,n=this._tokenData,i=0;if(this._lt.length&&this._ltIndex>=0&&this._ltIndex<this._lt.length){for(i++,this._token=this._lt[this._ltIndex++],r=n[this._token.type];void 0!==r.channel&&e!==r.channel&&this._ltIndex<this._lt.length;)this._token=this._lt[this._ltIndex++],r=n[this._token.type],i++;if((void 0===r.channel||e===r.channel)&&this._ltIndex<=this._lt.length)return this._ltIndexCache.push(i),this._token.type}return(t=this._getToken()).type>-1&&!n[t.type].hide&&(t.channel=n[t.type].channel,this._token=t,this._lt.push(t),this._ltIndexCache.push(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),(r=n[t.type])&&(r.hide||void 0!==r.channel&&e!==r.channel)?this.get(e):t.type},LA:function(e){var t,r=e;if(e>0){if(e>5)throw new Error("Too much lookahead.");for(;r;)t=this.get(),r--;for(;r<e;)this.unget(),r++}else if(e<0){if(!this._lt[this._ltIndex+e])throw new Error("Too much lookbehind.");t=this._lt[this._ltIndex+e].type}else t=this._token.type;return t},LT:function(e){return this.LA(e),this._lt[this._ltIndex+e-1]},peek:function(){return this.LA(1)},token:function(){return this._token},tokenName:function(e){return e<0||e>this._tokenData.length?"UNKNOWN_TOKEN":this._tokenData[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-=this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}}},{"./StringReader":24,"./SyntaxError":25}],28:[function(e,t,r){"use strict";t.exports={StringReader:e("./StringReader"),SyntaxError:e("./SyntaxError"),SyntaxUnit:e("./SyntaxUnit"),EventTarget:e("./EventTarget"),TokenStreamBase:e("./TokenStreamBase")}},{"./EventTarget":23,"./StringReader":24,"./SyntaxError":25,"./SyntaxUnit":26,"./TokenStreamBase":27}],parserlib:[function(e,t,r){"use strict";t.exports={css:e("./css"),util:e("./util")}},{"./css":22,"./util":28}]},{},[]))("parserlib"),n=function(){"use strict";function e(t,n,i,o){"object"==typeof n&&(i=n.depth,o=n.prototype,n.filter,n=n.circular);var a=[],s=[],l="undefined"!=typeof Buffer;return void 0===n&&(n=!0),void 0===i&&(i=1/0),function t(i,c){if(null===i)return null;if(0==c)return i;var u,d;if("object"!=typeof i)return i;if(e.__isArray(i))u=[];else if(e.__isRegExp(i))u=new RegExp(i.source,r(i)),i.lastIndex&&(u.lastIndex=i.lastIndex);else if(e.__isDate(i))u=new Date(i.getTime());else{if(l&&Buffer.isBuffer(i))return u=new Buffer(i.length),i.copy(u),u;void 0===o?(d=Object.getPrototypeOf(i),u=Object.create(d)):(u=Object.create(o),d=o)}if(n){var h=a.indexOf(i);if(-1!=h)return s[h];a.push(i),s.push(u)}for(var p in i){var f;d&&(f=Object.getOwnPropertyDescriptor(d,p)),f&&null==f.set||(u[p]=t(i[p],c-1))}return u}(t,i)}function t(e){return Object.prototype.toString.call(e)}function r(e){var t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),t}return e.clonePrototype=function(e){if(null===e)return null;var t=function(){};return t.prototype=e,new t},e.__objToStr=t,e.__isDate=function(e){return"object"==typeof e&&"[object Date]"===t(e)},e.__isArray=function(e){return"object"==typeof e&&"[object Array]"===t(e)},e.__isRegExp=function(e){return"object"==typeof e&&"[object RegExp]"===t(e)},e.__getRegExpFlags=r,e}();
/*!
Parser-Lib
Copyright (c) 2009-2016 Nicholas C. Zakas. All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/"object"==typeof t&&t.exports&&(t.exports=n);var i=function(){"use strict";var e=[],t=[],a=/\/\*\s*csslint([^\*]*)\*\//,s=new r.util.EventTarget;return s.version="1.0.3",s.addRule=function(t){e.push(t),e[t.id]=t},s.clearRules=function(){e=[]},s.getRules=function(){return[].concat(e).sort((function(e,t){return e.id>t.id?1:0}))},s.getRuleset=function(){for(var t={},r=0,n=e.length;r<n;)t[e[r++].id]=1;return t},s.addFormatter=function(e){t[e.id]=e},s.getFormatter=function(e){return t[e]},s.format=function(e,t,r,n){var i=this.getFormatter(r),o=null;return i&&(o=i.startFormat(),o+=i.formatResults(e,t,n||{}),o+=i.endFormat()),o},s.hasFormat=function(e){return t.hasOwnProperty(e)},s.verify=function(t,s){var l,c,u,d=0,h={},p=[],f=new r.css.Parser({starHack:!0,ieFilters:!0,underscoreHack:!0,strict:!1});c=t.replace(/\n\r?/g,"$split$").split("$split$"),i.Util.forEach(c,(function(e,t){var r=e&&e.match(/\/\*[ \t]*csslint[ \t]+allow:[ \t]*([^\*]*)\*\//i),n=r&&r[1],i={};n&&(n.toLowerCase().split(",").forEach((function(e){i[e.trim()]=!0})),Object.keys(i).length>0&&(h[t+1]=i))}));var m=null,g=null;for(d in i.Util.forEach(c,(function(e,t){null===m&&e.match(/\/\*[ \t]*csslint[ \t]+ignore:start[ \t]*\*\//i)&&(m=t),e.match(/\/\*[ \t]*csslint[ \t]+ignore:end[ \t]*\*\//i)&&(g=t),null!==m&&null!==g&&(p.push([m,g]),m=g=null)})),null!==m&&p.push([m,c.length]),s||(s=this.getRuleset()),a.test(t)&&(s=function(e,t){var r,n=e&&e.match(a),i=n&&n[1];return i&&(r={true:2,"":1,false:0,2:2,1:1,0:0},i.toLowerCase().split(",").forEach((function(e){var n=e.split(":"),i=n[0]||"",o=n[1]||"";t[i.trim()]=r[o.trim()]}))),t}(t,s=n(s))),l=new o(c,s,h,p),s.errors=2,s)s.hasOwnProperty(d)&&s[d]&&e[d]&&e[d].init(f,l);try{f.parse(t)}catch(e){l.error("Fatal error, cannot continue: "+e.message,e.line,e.col,{})}return(u={messages:l.messages,stats:l.stats,ruleset:l.ruleset,allow:l.allow,ignore:l.ignore}).messages.sort((function(e,t){return e.rollup&&!t.rollup?1:!e.rollup&&t.rollup?-1:e.line-t.line})),u},s}();function o(e,t,r,n){"use strict";this.messages=[],this.stats=[],this.lines=e,this.ruleset=t,this.allow=r,this.allow||(this.allow={}),this.ignore=n,this.ignore||(this.ignore=[])}return o.prototype={constructor:o,error:function(e,t,r,n){"use strict";this.messages.push({type:"error",line:t,col:r,message:e,evidence:this.lines[t-1],rule:n||{}})},warn:function(e,t,r,n){"use strict";this.report(e,t,r,n)},report:function(e,t,r,n){"use strict";if(!this.allow.hasOwnProperty(t)||!this.allow[t].hasOwnProperty(n.id)){var o=!1;i.Util.forEach(this.ignore,(function(e){e[0]<=t&&t<=e[1]&&(o=!0)})),o||this.messages.push({type:2===this.ruleset[n.id]?"error":"warning",line:t,col:r,message:e,evidence:this.lines[t-1],rule:n})}},info:function(e,t,r,n){"use strict";this.messages.push({type:"info",line:t,col:r,message:e,evidence:this.lines[t-1],rule:n})},rollupError:function(e,t){"use strict";this.messages.push({type:"error",rollup:!0,message:e,rule:t})},rollupWarn:function(e,t){"use strict";this.messages.push({type:"warning",rollup:!0,message:e,rule:t})},stat:function(e,t){"use strict";this.stats[e]=t}},i._Reporter=o,i.Util={mix:function(e,t){"use strict";var r;for(r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return r},indexOf:function(e,t){"use strict";if(e.indexOf)return e.indexOf(t);for(var r=0,n=e.length;r<n;r++)if(e[r]===t)return r;return-1},forEach:function(e,t){"use strict";if(e.forEach)return e.forEach(t);for(var r=0,n=e.length;r<n;r++)t(e[r],r,e)}},i.addRule({id:"adjoining-classes",name:"Disallow adjoining classes",desc:"Don't use adjoining classes.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-adjoining-classes",browsers:"IE6",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(n){var i,o,a,s,l,c,u=n.selectors;for(s=0;s<u.length;s++)for(i=u[s],l=0;l<i.parts.length;l++)if((o=i.parts[l]).type===e.SELECTOR_PART_TYPE)for(a=0,c=0;c<o.modifiers.length;c++)"class"===o.modifiers[c].type&&a++,a>1&&t.report("Adjoining classes: "+u[s].text,o.line,o.col,r)}))}}),i.addRule({id:"box-model",name:"Beware of broken box size",desc:"Don't use width or height when using padding or border.",url:"https://github.com/CSSLint/csslint/wiki/Beware-of-box-model-size",browsers:"All",init:function(e,t){"use strict";var r,n=this,i={border:1,"border-left":1,"border-right":1,padding:1,"padding-left":1,"padding-right":1},o={border:1,"border-bottom":1,"border-top":1,padding:1,"padding-bottom":1,"padding-top":1},a=!1;function s(){r={},a=!1}function l(){var e,s;if(!a){if(r.height)for(e in o)o.hasOwnProperty(e)&&r[e]&&(s=r[e].value,"padding"===e&&2===s.parts.length&&0===s.parts[0].value||t.report("Using height with "+e+" can sometimes make elements larger than you expect.",r[e].line,r[e].col,n));if(r.width)for(e in i)i.hasOwnProperty(e)&&r[e]&&(s=r[e].value,"padding"===e&&2===s.parts.length&&0===s.parts[1].value||t.report("Using width with "+e+" can sometimes make elements larger than you expect.",r[e].line,r[e].col,n))}}e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("startpage",s),e.addListener("startpagemargin",s),e.addListener("startkeyframerule",s),e.addListener("startviewport",s),e.addListener("property",(function(e){var t=e.property.text.toLowerCase();o[t]||i[t]?/^0\S*$/.test(e.value)||"border"===t&&"none"===e.value.toString()||(r[t]={line:e.property.line,col:e.property.col,value:e.value}):/^(width|height)/i.test(t)&&/^(length|percentage)/.test(e.value.parts[0].type)?r[t]=1:"box-sizing"===t&&(a=!0)})),e.addListener("endrule",l),e.addListener("endfontface",l),e.addListener("endpage",l),e.addListener("endpagemargin",l),e.addListener("endkeyframerule",l),e.addListener("endviewport",l)}}),i.addRule({id:"box-sizing",name:"Disallow use of box-sizing",desc:"The box-sizing properties isn't supported in IE6 and IE7.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-box-sizing",browsers:"IE6, IE7",tags:["Compatibility"],init:function(e,t){"use strict";var r=this;e.addListener("property",(function(e){"box-sizing"===e.property.text.toLowerCase()&&t.report("The box-sizing property isn't supported in IE6 and IE7.",e.line,e.col,r)}))}}),i.addRule({id:"bulletproof-font-face",name:"Use the bulletproof @font-face syntax",desc:"Use the bulletproof @font-face syntax to avoid 404's in old IE (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax).",url:"https://github.com/CSSLint/csslint/wiki/Bulletproof-font-face",browsers:"All",init:function(e,t){"use strict";var r,n,i=this,o=!1,a=!0,s=!1;e.addListener("startfontface",(function(){o=!0})),e.addListener("property",(function(e){if(o){var t=e.property.toString().toLowerCase(),i=e.value.toString();if(r=e.line,n=e.col,"src"===t){var l=/^\s?url\(['"].+\.eot\?.*['"]\)\s*format\(['"]embedded-opentype['"]\).*$/i;!i.match(l)&&a?(s=!0,a=!1):i.match(l)&&!a&&(s=!1)}}})),e.addListener("endfontface",(function(){o=!1,s&&t.report("@font-face declaration doesn't follow the fontspring bulletproof syntax.",r,n,i)}))}}),i.addRule({id:"compatible-vendor-prefixes",name:"Require compatible vendor prefixes",desc:"Include all compatible vendor prefixes to reach a wider range of users.",url:"https://github.com/CSSLint/csslint/wiki/Require-compatible-vendor-prefixes",browsers:"All",init:function(e,t){"use strict";var r,n,o,a,s,l,c,u=this,d=!1,h=Array.prototype.push,p=[];for(o in r={animation:"webkit","animation-delay":"webkit","animation-direction":"webkit","animation-duration":"webkit","animation-fill-mode":"webkit","animation-iteration-count":"webkit","animation-name":"webkit","animation-play-state":"webkit","animation-timing-function":"webkit",appearance:"webkit moz","border-end":"webkit moz","border-end-color":"webkit moz","border-end-style":"webkit moz","border-end-width":"webkit moz","border-image":"webkit moz o","border-radius":"webkit","border-start":"webkit moz","border-start-color":"webkit moz","border-start-style":"webkit moz","border-start-width":"webkit moz","box-align":"webkit moz ms","box-direction":"webkit moz ms","box-flex":"webkit moz ms","box-lines":"webkit ms","box-ordinal-group":"webkit moz ms","box-orient":"webkit moz ms","box-pack":"webkit moz ms","box-sizing":"","box-shadow":"","column-count":"webkit moz ms","column-gap":"webkit moz ms","column-rule":"webkit moz ms","column-rule-color":"webkit moz ms","column-rule-style":"webkit moz ms","column-rule-width":"webkit moz ms","column-width":"webkit moz ms",hyphens:"epub moz","line-break":"webkit ms","margin-end":"webkit moz","margin-start":"webkit moz","marquee-speed":"webkit wap","marquee-style":"webkit wap","padding-end":"webkit moz","padding-start":"webkit moz","tab-size":"moz o","text-size-adjust":"webkit ms",transform:"webkit ms","transform-origin":"webkit ms",transition:"","transition-delay":"","transition-duration":"","transition-property":"","transition-timing-function":"","user-modify":"webkit moz","user-select":"webkit moz ms","word-break":"epub ms","writing-mode":"epub ms"})if(r.hasOwnProperty(o)){for(a=[],l=0,c=(s=r[o].split(" ")).length;l<c;l++)a.push("-"+s[l]+"-"+o);r[o]=a,h.apply(p,a)}e.addListener("startrule",(function(){n=[]})),e.addListener("startkeyframes",(function(e){d=e.prefix||!0})),e.addListener("endkeyframes",(function(){d=!1})),e.addListener("property",(function(e){var t=e.property;i.Util.indexOf(p,t.text)>-1&&(d&&"string"==typeof d&&0===t.text.indexOf("-"+d+"-")||n.push(t))})),e.addListener("endrule",(function(){if(n.length){var e,o,a,s,l,c,d,h,p,f,m={};for(e=0,o=n.length;e<o;e++)for(s in a=n[e],r)r.hasOwnProperty(s)&&(l=r[s],i.Util.indexOf(l,a.text)>-1&&(m[s]||(m[s]={full:l.slice(0),actual:[],actualNodes:[]}),-1===i.Util.indexOf(m[s].actual,a.text)&&(m[s].actual.push(a.text),m[s].actualNodes.push(a))));for(s in m)if(m.hasOwnProperty(s)&&(d=(c=m[s]).full,h=c.actual,d.length>h.length))for(e=0,o=d.length;e<o;e++)p=d[e],-1===i.Util.indexOf(h,p)&&(f=1===h.length?h[0]:2===h.length?h.join(" and "):h.join(", "),t.report("The property "+p+" is compatible with "+f+" and should be included as well.",c.actualNodes[0].line,c.actualNodes[0].col,u))}}))}}),i.addRule({id:"display-property-grouping",name:"Require properties appropriate for display",desc:"Certain properties shouldn't be used with certain display property values.",url:"https://github.com/CSSLint/csslint/wiki/Require-properties-appropriate-for-display",browsers:"All",init:function(e,t){"use strict";var r,n=this,i={display:1,float:"none",height:1,width:1,margin:1,"margin-left":1,"margin-right":1,"margin-bottom":1,"margin-top":1,padding:1,"padding-left":1,"padding-right":1,"padding-bottom":1,"padding-top":1,"vertical-align":1};function o(e,o,a){r[e]&&("string"==typeof i[e]&&r[e].value.toLowerCase()===i[e]||t.report(a||e+" can't be used with display: "+o+".",r[e].line,r[e].col,n))}function a(){r={}}function s(){var e=r.display?r.display.value:null;if(e)switch(e){case"inline":o("height",e),o("width",e),o("margin",e),o("margin-top",e),o("margin-bottom",e),o("float",e,"display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");break;case"block":o("vertical-align",e);break;case"inline-block":o("float",e);break;default:0===e.indexOf("table-")&&(o("margin",e),o("margin-left",e),o("margin-right",e),o("margin-top",e),o("margin-bottom",e),o("float",e))}}e.addListener("startrule",a),e.addListener("startfontface",a),e.addListener("startkeyframerule",a),e.addListener("startpagemargin",a),e.addListener("startpage",a),e.addListener("startviewport",a),e.addListener("property",(function(e){var t=e.property.text.toLowerCase();i[t]&&(r[t]={value:e.value.text,line:e.property.line,col:e.property.col})})),e.addListener("endrule",s),e.addListener("endfontface",s),e.addListener("endkeyframerule",s),e.addListener("endpagemargin",s),e.addListener("endpage",s),e.addListener("endviewport",s)}}),i.addRule({id:"duplicate-background-images",name:"Disallow duplicate background images",desc:"Every background-image should be unique. Use a common class for e.g. sprites.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-background-images",browsers:"All",init:function(e,t){"use strict";var r=this,n={};e.addListener("property",(function(e){var i,o,a=e.property.text,s=e.value;if(a.match(/background/i))for(i=0,o=s.parts.length;i<o;i++)"uri"===s.parts[i].type&&(void 0===n[s.parts[i].uri]?n[s.parts[i].uri]=e:t.report("Background image '"+s.parts[i].uri+"' was used multiple times, first declared at line "+n[s.parts[i].uri].line+", col "+n[s.parts[i].uri].col+".",e.line,e.col,r))}))}}),i.addRule({id:"duplicate-properties",name:"Disallow duplicate properties",desc:"Duplicate properties must appear one after the other.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-duplicate-properties",browsers:"All",init:function(e,t){"use strict";var r,n,i=this;function o(){r={}}e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("startviewport",o),e.addListener("property",(function(e){var o=e.property.text.toLowerCase();!r[o]||n===o&&r[o]!==e.value.text||t.report("Duplicate property '"+e.property+"' found.",e.line,e.col,i),r[o]=e.value.text,n=o}))}}),i.addRule({id:"empty-rules",name:"Disallow empty rules",desc:"Rules without any properties specified should be removed.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-empty-rules",browsers:"All",init:function(e,t){"use strict";var r=this,n=0;e.addListener("startrule",(function(){n=0})),e.addListener("property",(function(){n++})),e.addListener("endrule",(function(e){var i=e.selectors;0===n&&t.report("Rule is empty.",i[0].line,i[0].col,r)}))}}),i.addRule({id:"errors",name:"Parsing Errors",desc:"This rule looks for recoverable syntax errors.",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("error",(function(e){t.error(e.message,e.line,e.col,r)}))}}),i.addRule({id:"fallback-colors",name:"Require fallback colors",desc:"For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",url:"https://github.com/CSSLint/csslint/wiki/Require-fallback-colors",browsers:"IE6,IE7,IE8",init:function(e,t){"use strict";var r,n=this,i={color:1,background:1,"border-color":1,"border-top-color":1,"border-right-color":1,"border-bottom-color":1,"border-left-color":1,border:1,"border-top":1,"border-right":1,"border-bottom":1,"border-left":1,"background-color":1};function o(){r=null}e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("startviewport",o),e.addListener("property",(function(e){var o=e.property.text.toLowerCase(),a=e.value.parts,s=0,l="",c=a.length;if(i[o])for(;s<c;)"color"===a[s].type&&("alpha"in a[s]||"hue"in a[s]?(/([^\)]+)\(/.test(a[s])&&(l=RegExp.$1.toUpperCase()),r&&r.property.text.toLowerCase()===o&&"compat"===r.colorType||t.report("Fallback "+o+" (hex or RGB) should precede "+l+" "+o+".",e.line,e.col,n)):e.colorType="compat"),s++;r=e}))}}),i.addRule({id:"floats",name:"Disallow too many floats",desc:"This rule tests if the float property is used too many times",url:"https://github.com/CSSLint/csslint/wiki/Disallow-too-many-floats",browsers:"All",init:function(e,t){"use strict";var r=this,n=0;e.addListener("property",(function(e){"float"===e.property.text.toLowerCase()&&"none"!==e.value.text.toLowerCase()&&n++})),e.addListener("endstylesheet",(function(){t.stat("floats",n),n>=10&&t.rollupWarn("Too many floats ("+n+"), you're probably using them for layout. Consider using a grid system instead.",r)}))}}),i.addRule({id:"font-faces",name:"Don't use too many web fonts",desc:"Too many different web fonts in the same stylesheet.",url:"https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-web-fonts",browsers:"All",init:function(e,t){"use strict";var r=this,n=0;e.addListener("startfontface",(function(){n++})),e.addListener("endstylesheet",(function(){n>5&&t.rollupWarn("Too many @font-face declarations ("+n+").",r)}))}}),i.addRule({id:"font-sizes",name:"Disallow too many font sizes",desc:"Checks the number of font-size declarations.",url:"https://github.com/CSSLint/csslint/wiki/Don%27t-use-too-many-font-size-declarations",browsers:"All",init:function(e,t){"use strict";var r=this,n=0;e.addListener("property",(function(e){"font-size"===e.property.toString()&&n++})),e.addListener("endstylesheet",(function(){t.stat("font-sizes",n),n>=10&&t.rollupWarn("Too many font-size declarations ("+n+"), abstraction needed.",r)}))}}),i.addRule({id:"gradients",name:"Require all gradient definitions",desc:"When using a vendor-prefixed gradient, make sure to use them all.",url:"https://github.com/CSSLint/csslint/wiki/Require-all-gradient-definitions",browsers:"All",init:function(e,t){"use strict";var r,n=this;e.addListener("startrule",(function(){r={moz:0,webkit:0,oldWebkit:0,o:0}})),e.addListener("property",(function(e){/\-(moz|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(e.value)?r[RegExp.$1]=1:/\-webkit\-gradient/i.test(e.value)&&(r.oldWebkit=1)})),e.addListener("endrule",(function(e){var i=[];r.moz||i.push("Firefox 3.6+"),r.webkit||i.push("Webkit (Safari 5+, Chrome)"),r.oldWebkit||i.push("Old Webkit (Safari 4+, Chrome)"),r.o||i.push("Opera 11.1+"),i.length&&i.length<4&&t.report("Missing vendor-prefixed CSS gradients for "+i.join(", ")+".",e.selectors[0].line,e.selectors[0].col,n)}))}}),i.addRule({id:"ids",name:"Disallow IDs in selectors",desc:"Selectors should not contain IDs.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-IDs-in-selectors",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(n){var i,o,a,s,l,c,u=n.selectors;for(s=0;s<u.length;s++){for(i=u[s],a=0,l=0;l<i.parts.length;l++)if((o=i.parts[l]).type===e.SELECTOR_PART_TYPE)for(c=0;c<o.modifiers.length;c++)"id"===o.modifiers[c].type&&a++;1===a?t.report("Don't use IDs in selectors.",i.line,i.col,r):a>1&&t.report(a+" IDs in the selector, really?",i.line,i.col,r)}}))}}),i.addRule({id:"import-ie-limit",name:"@import limit on IE6-IE9",desc:"IE6-9 supports up to 31 @import per stylesheet",browsers:"IE6, IE7, IE8, IE9",init:function(e,t){"use strict";var r=this,n=0;e.addListener("startpage",(function(){n=0})),e.addListener("import",(function(){n++})),e.addListener("endstylesheet",(function(){n>31&&t.rollupError("Too many @import rules ("+n+"). IE6-9 supports up to 31 import per stylesheet.",r)}))}}),i.addRule({id:"import",name:"Disallow @import",desc:"Don't use @import, use <link> instead.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-%40import",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("import",(function(e){t.report("@import prevents parallel downloads, use <link> instead.",e.line,e.col,r)}))}}),i.addRule({id:"important",name:"Disallow !important",desc:"Be careful when using !important declaration",url:"https://github.com/CSSLint/csslint/wiki/Disallow-%21important",browsers:"All",init:function(e,t){"use strict";var r=this,n=0;e.addListener("property",(function(e){!0===e.important&&(n++,t.report("Use of !important",e.line,e.col,r))})),e.addListener("endstylesheet",(function(){t.stat("important",n),n>=10&&t.rollupWarn("Too many !important declarations ("+n+"), try to use less than 10 to avoid specificity issues.",r)}))}}),i.addRule({id:"known-properties",name:"Require use of known properties",desc:"Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",url:"https://github.com/CSSLint/csslint/wiki/Require-use-of-known-properties",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("property",(function(e){e.invalid&&t.report(e.invalid.message,e.line,e.col,r)}))}}),i.addRule({id:"order-alphabetical",name:"Alphabetical order",desc:"Assure properties are in alphabetical order",browsers:"All",init:function(e,t){"use strict";var r,n=this,i=function(){r=[]},o=function(e){r.join(",")!==r.sort().join(",")&&t.report("Rule doesn't have all its properties in alphabetical order.",e.line,e.col,n)};e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("startviewport",i),e.addListener("property",(function(e){var t=e.property.text.toLowerCase().replace(/^-.*?-/,"");r.push(t)})),e.addListener("endrule",o),e.addListener("endfontface",o),e.addListener("endpage",o),e.addListener("endpagemargin",o),e.addListener("endkeyframerule",o),e.addListener("endviewport",o)}}),i.addRule({id:"outline-none",name:"Disallow outline: none",desc:"Use of outline: none or outline: 0 should be limited to :focus rules.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-outline%3Anone",browsers:"All",tags:["Accessibility"],init:function(e,t){"use strict";var r,n=this;function i(e){r=e.selectors?{line:e.line,col:e.col,selectors:e.selectors,propCount:0,outline:!1}:null}function o(){r&&r.outline&&(-1===r.selectors.toString().toLowerCase().indexOf(":focus")?t.report("Outlines should only be modified using :focus.",r.line,r.col,n):1===r.propCount&&t.report("Outlines shouldn't be hidden unless other visual changes are made.",r.line,r.col,n))}e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("startviewport",i),e.addListener("property",(function(e){var t=e.property.text.toLowerCase(),n=e.value;r&&(r.propCount++,"outline"!==t||"none"!==n.toString()&&"0"!==n.toString()||(r.outline=!0))})),e.addListener("endrule",o),e.addListener("endfontface",o),e.addListener("endpage",o),e.addListener("endpagemargin",o),e.addListener("endkeyframerule",o),e.addListener("endviewport",o)}}),i.addRule({id:"overqualified-elements",name:"Disallow overqualified elements",desc:"Don't use classes or IDs with elements (a.foo or a#foo).",url:"https://github.com/CSSLint/csslint/wiki/Disallow-overqualified-elements",browsers:"All",init:function(e,t){"use strict";var r=this,n={};e.addListener("startrule",(function(i){var o,a,s,l,c,u,d=i.selectors;for(l=0;l<d.length;l++)for(o=d[l],c=0;c<o.parts.length;c++)if((a=o.parts[c]).type===e.SELECTOR_PART_TYPE)for(u=0;u<a.modifiers.length;u++)s=a.modifiers[u],a.elementName&&"id"===s.type?t.report("Element ("+a+") is overqualified, just use "+s+" without element name.",a.line,a.col,r):"class"===s.type&&(n[s]||(n[s]=[]),n[s].push({modifier:s,part:a}))})),e.addListener("endstylesheet",(function(){var e;for(e in n)n.hasOwnProperty(e)&&1===n[e].length&&n[e][0].part.elementName&&t.report("Element ("+n[e][0].part+") is overqualified, just use "+n[e][0].modifier+" without element name.",n[e][0].part.line,n[e][0].part.col,r)}))}}),i.addRule({id:"qualified-headings",name:"Disallow qualified headings",desc:"Headings should not be qualified (namespaced).",url:"https://github.com/CSSLint/csslint/wiki/Disallow-qualified-headings",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(n){var i,o,a,s,l=n.selectors;for(a=0;a<l.length;a++)for(i=l[a],s=0;s<i.parts.length;s++)(o=i.parts[s]).type===e.SELECTOR_PART_TYPE&&o.elementName&&/h[1-6]/.test(o.elementName.toString())&&s>0&&t.report("Heading ("+o.elementName+") should not be qualified.",o.line,o.col,r)}))}}),i.addRule({id:"regex-selectors",name:"Disallow selectors that look like regexs",desc:"Selectors that look like regular expressions are slow and should be avoided.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-selectors-that-look-like-regular-expressions",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(n){var i,o,a,s,l,c,u=n.selectors;for(s=0;s<u.length;s++)for(i=u[s],l=0;l<i.parts.length;l++)if((o=i.parts[l]).type===e.SELECTOR_PART_TYPE)for(c=0;c<o.modifiers.length;c++)"attribute"===(a=o.modifiers[c]).type&&/([~\|\^\$\*]=)/.test(a)&&t.report("Attribute selectors with "+RegExp.$1+" are slow!",a.line,a.col,r)}))}}),i.addRule({id:"rules-count",name:"Rules Count",desc:"Track how many rules there are.",browsers:"All",init:function(e,t){"use strict";var r=0;e.addListener("startrule",(function(){r++})),e.addListener("endstylesheet",(function(){t.stat("rule-count",r)}))}}),i.addRule({id:"selector-max-approaching",name:"Warn when approaching the 4095 selector limit for IE",desc:"Will warn when selector count is >= 3800 selectors.",browsers:"IE",init:function(e,t){"use strict";var r=this,n=0;e.addListener("startrule",(function(e){n+=e.selectors.length})),e.addListener("endstylesheet",(function(){n>=3800&&t.report("You have "+n+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,r)}))}}),i.addRule({id:"selector-max",name:"Error when past the 4095 selector limit for IE",desc:"Will error when selector count is > 4095.",browsers:"IE",init:function(e,t){"use strict";var r=this,n=0;e.addListener("startrule",(function(e){n+=e.selectors.length})),e.addListener("endstylesheet",(function(){n>4095&&t.report("You have "+n+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,r)}))}}),i.addRule({id:"selector-newline",name:"Disallow new-line characters in selectors",desc:"New-line characters in selectors are usually a forgotten comma and not a descendant combinator.",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(e){var n,i,o,a,s,l,c,u,d,h,p,f=e.selectors;for(n=0,i=f.length;n<i;n++)for(a=0,l=(o=f[n]).parts.length;a<l;a++)for(s=a+1;s<l;s++)c=o.parts[a],u=o.parts[s],d=c.type,h=c.line,p=u.line,"descendant"===d&&p>h&&t.report("newline character found in selector (forgot a comma?)",h,f[n].parts[0].col,r)}))}}),i.addRule({id:"shorthand",name:"Require shorthand properties",desc:"Use shorthand properties where possible.",url:"https://github.com/CSSLint/csslint/wiki/Require-shorthand-properties",browsers:"All",init:function(e,t){"use strict";var r,n,i,o,a=this,s={},l={margin:["margin-top","margin-bottom","margin-left","margin-right"],padding:["padding-top","padding-bottom","padding-left","padding-right"]};for(r in l)if(l.hasOwnProperty(r))for(n=0,i=l[r].length;n<i;n++)s[l[r][n]]=r;function c(){o={}}function u(e){var r,n,i,s;for(r in l)if(l.hasOwnProperty(r)){for(s=0,n=0,i=l[r].length;n<i;n++)s+=o[l[r][n]]?1:0;s===l[r].length&&t.report("The properties "+l[r].join(", ")+" can be replaced by "+r+".",e.line,e.col,a)}}e.addListener("startrule",c),e.addListener("startfontface",c),e.addListener("property",(function(e){var t=e.property.toString().toLowerCase();s[t]&&(o[t]=1)})),e.addListener("endrule",u),e.addListener("endfontface",u)}}),i.addRule({id:"star-property-hack",name:"Disallow properties with a star prefix",desc:"Checks for the star property hack (targets IE6/7)",url:"https://github.com/CSSLint/csslint/wiki/Disallow-star-hack",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("property",(function(e){"*"===e.property.hack&&t.report("Property with star prefix found.",e.property.line,e.property.col,r)}))}}),i.addRule({id:"text-indent",name:"Disallow negative text-indent",desc:"Checks for text indent less than -99px",url:"https://github.com/CSSLint/csslint/wiki/Disallow-negative-text-indent",browsers:"All",init:function(e,t){"use strict";var r,n,i=this;function o(){r=!1,n="inherit"}function a(){r&&"ltr"!==n&&t.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.",r.line,r.col,i)}e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("property",(function(e){var t=e.property.toString().toLowerCase(),i=e.value;"text-indent"===t&&i.parts[0].value<-99?r=e.property:"direction"===t&&"ltr"===i.toString()&&(n="ltr")})),e.addListener("endrule",a),e.addListener("endfontface",a)}}),i.addRule({id:"underscore-property-hack",name:"Disallow properties with an underscore prefix",desc:"Checks for the underscore property hack (targets IE6)",url:"https://github.com/CSSLint/csslint/wiki/Disallow-underscore-hack",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("property",(function(e){"_"===e.property.hack&&t.report("Property with underscore prefix found.",e.property.line,e.property.col,r)}))}}),i.addRule({id:"unique-headings",name:"Headings should only be defined once",desc:"Headings should be defined only once.",url:"https://github.com/CSSLint/csslint/wiki/Headings-should-only-be-defined-once",browsers:"All",init:function(e,t){"use strict";var r=this,n={h1:0,h2:0,h3:0,h4:0,h5:0,h6:0};e.addListener("startrule",(function(e){var i,o,a,s,l,c=e.selectors;for(s=0;s<c.length;s++)if((o=(i=c[s]).parts[i.parts.length-1]).elementName&&/(h[1-6])/i.test(o.elementName.toString())){for(l=0;l<o.modifiers.length;l++)if("pseudo"===o.modifiers[l].type){a=!0;break}a||(n[RegExp.$1]++,n[RegExp.$1]>1&&t.report("Heading ("+o.elementName+") has already been defined.",o.line,o.col,r))}})),e.addListener("endstylesheet",(function(){var e,i=[];for(e in n)n.hasOwnProperty(e)&&n[e]>1&&i.push(n[e]+" "+e+"s");i.length&&t.rollupWarn("You have "+i.join(", ")+" defined in this stylesheet.",r)}))}}),i.addRule({id:"universal-selector",name:"Disallow universal selector",desc:"The universal selector (*) is known to be slow.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-universal-selector",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(e){var n,i,o,a=e.selectors;for(o=0;o<a.length;o++)"*"===(i=(n=a[o]).parts[n.parts.length-1]).elementName&&t.report(r.desc,i.line,i.col,r)}))}}),i.addRule({id:"unqualified-attributes",name:"Disallow unqualified attribute selectors",desc:"Unqualified attribute selectors are known to be slow.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-unqualified-attribute-selectors",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("startrule",(function(n){var i,o,a,s,l,c=n.selectors,u=!1;for(s=0;s<c.length;s++)if((o=(i=c[s]).parts[i.parts.length-1]).type===e.SELECTOR_PART_TYPE){for(l=0;l<o.modifiers.length;l++)if("class"===(a=o.modifiers[l]).type||"id"===a.type){u=!0;break}if(!u)for(l=0;l<o.modifiers.length;l++)"attribute"!==(a=o.modifiers[l]).type||o.elementName&&"*"!==o.elementName||t.report(r.desc,o.line,o.col,r)}}))}}),i.addRule({id:"vendor-prefix",name:"Require standard property with vendor prefix",desc:"When using a vendor-prefixed property, make sure to include the standard one.",url:"https://github.com/CSSLint/csslint/wiki/Require-standard-property-with-vendor-prefix",browsers:"All",init:function(e,t){"use strict";var r,n,i=this,o={"-webkit-border-radius":"border-radius","-webkit-border-top-left-radius":"border-top-left-radius","-webkit-border-top-right-radius":"border-top-right-radius","-webkit-border-bottom-left-radius":"border-bottom-left-radius","-webkit-border-bottom-right-radius":"border-bottom-right-radius","-o-border-radius":"border-radius","-o-border-top-left-radius":"border-top-left-radius","-o-border-top-right-radius":"border-top-right-radius","-o-border-bottom-left-radius":"border-bottom-left-radius","-o-border-bottom-right-radius":"border-bottom-right-radius","-moz-border-radius":"border-radius","-moz-border-radius-topleft":"border-top-left-radius","-moz-border-radius-topright":"border-top-right-radius","-moz-border-radius-bottomleft":"border-bottom-left-radius","-moz-border-radius-bottomright":"border-bottom-right-radius","-moz-column-count":"column-count","-webkit-column-count":"column-count","-moz-column-gap":"column-gap","-webkit-column-gap":"column-gap","-moz-column-rule":"column-rule","-webkit-column-rule":"column-rule","-moz-column-rule-style":"column-rule-style","-webkit-column-rule-style":"column-rule-style","-moz-column-rule-color":"column-rule-color","-webkit-column-rule-color":"column-rule-color","-moz-column-rule-width":"column-rule-width","-webkit-column-rule-width":"column-rule-width","-moz-column-width":"column-width","-webkit-column-width":"column-width","-webkit-column-span":"column-span","-webkit-columns":"columns","-moz-box-shadow":"box-shadow","-webkit-box-shadow":"box-shadow","-moz-transform":"transform","-webkit-transform":"transform","-o-transform":"transform","-ms-transform":"transform","-moz-transform-origin":"transform-origin","-webkit-transform-origin":"transform-origin","-o-transform-origin":"transform-origin","-ms-transform-origin":"transform-origin","-moz-box-sizing":"box-sizing","-webkit-box-sizing":"box-sizing"};function a(){r={},n=1}function s(){var e,n,a,s,l,c=[];for(e in r)o[e]&&c.push({actual:e,needed:o[e]});for(n=0,a=c.length;n<a;n++)s=c[n].needed,l=c[n].actual,r[s]?r[s][0].pos<r[l][0].pos&&t.report("Standard property '"+s+"' should come after vendor-prefixed property '"+l+"'.",r[l][0].name.line,r[l][0].name.col,i):t.report("Missing standard property '"+s+"' to go along with '"+l+"'.",r[l][0].name.line,r[l][0].name.col,i)}e.addListener("startrule",a),e.addListener("startfontface",a),e.addListener("startpage",a),e.addListener("startpagemargin",a),e.addListener("startkeyframerule",a),e.addListener("startviewport",a),e.addListener("property",(function(e){var t=e.property.text.toLowerCase();r[t]||(r[t]=[]),r[t].push({name:e.property,value:e.value,pos:n++})})),e.addListener("endrule",s),e.addListener("endfontface",s),e.addListener("endpage",s),e.addListener("endpagemargin",s),e.addListener("endkeyframerule",s),e.addListener("endviewport",s)}}),i.addRule({id:"zero-units",name:"Disallow units for 0 values",desc:"You don't need to specify units when a value is 0.",url:"https://github.com/CSSLint/csslint/wiki/Disallow-units-for-zero-values",browsers:"All",init:function(e,t){"use strict";var r=this;e.addListener("property",(function(e){for(var n=e.value.parts,i=0,o=n.length;i<o;)!n[i].units&&"percentage"!==n[i].type||0!==n[i].value||"time"===n[i].type||t.report("Values of 0 shouldn't have units specified.",n[i].line,n[i].col,r),i++}))}}),function(){"use strict";var e=function(e){return e&&e.constructor===String?e.replace(/["&><]/g,(function(e){switch(e){case'"':return"&quot;";case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;"}})):""};i.addFormatter({id:"checkstyle-xml",name:"Checkstyle XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><checkstyle>'},endFormat:function(){return"</checkstyle>"},readError:function(t,r){return'<file name="'+e(t)+'"><error line="0" column="0" severty="error" message="'+e(r)+'"></error></file>'},formatResults:function(t,r){var n=t.messages,o=[];return n.length>0&&(o.push('<file name="'+r+'">'),i.Util.forEach(n,(function(t){var r;t.rollup||o.push('<error line="'+t.line+'" column="'+t.col+'" severity="'+t.type+'" message="'+e(t.message)+'" source="'+((r=t.rule)&&"name"in r?"net.csslint."+r.name.replace(/\s/g,""):"")+'"/>')})),o.push("</file>")),o.join("")}})}(),i.addFormatter({id:"compact",name:"Compact, 'porcelain' format",startFormat:function(){"use strict";return""},endFormat:function(){"use strict";return""},formatResults:function(e,t,r){"use strict";var n=e.messages,o="";r=r||{};var a=function(e){return e.charAt(0).toUpperCase()+e.slice(1)};return 0===n.length?r.quiet?"":t+": Lint Free!":(i.Util.forEach(n,(function(e){e.rollup?o+=t+": "+a(e.type)+" - "+e.message+" ("+e.rule.id+")\n":o+=t+": line "+e.line+", col "+e.col+", "+a(e.type)+" - "+e.message+" ("+e.rule.id+")\n"})),o)}}),i.addFormatter({id:"csslint-xml",name:"CSSLint XML format",startFormat:function(){"use strict";return'<?xml version="1.0" encoding="utf-8"?><csslint>'},endFormat:function(){"use strict";return"</csslint>"},formatResults:function(e,t){"use strict";var r=e.messages,n=[],o=function(e){return e&&e.constructor===String?e.replace(/"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):""};return r.length>0&&(n.push('<file name="'+t+'">'),i.Util.forEach(r,(function(e){e.rollup?n.push('<issue severity="'+e.type+'" reason="'+o(e.message)+'" evidence="'+o(e.evidence)+'"/>'):n.push('<issue line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'" reason="'+o(e.message)+'" evidence="'+o(e.evidence)+'"/>')})),n.push("</file>")),n.join("")}}),i.addFormatter({id:"json",name:"JSON",startFormat:function(){"use strict";return this.json=[],""},endFormat:function(){"use strict";var e="";return this.json.length>0&&(e=1===this.json.length?JSON.stringify(this.json[0]):JSON.stringify(this.json)),e},formatResults:function(e,t,r){"use strict";return(e.messages.length>0||!r.quiet)&&this.json.push({filename:t,messages:e.messages,stats:e.stats}),""}}),i.addFormatter({id:"junit-xml",name:"JUNIT XML format",startFormat:function(){"use strict";return'<?xml version="1.0" encoding="utf-8"?><testsuites>'},endFormat:function(){"use strict";return"</testsuites>"},formatResults:function(e,t){"use strict";var r=e.messages,n=[],i={error:0,failure:0},o=function(e){return e&&e.constructor===String?e.replace(/"/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;"):""};return r.length>0&&(r.forEach((function(e){var t,r="warning"===e.type?"error":e.type;e.rollup||(n.push('<testcase time="0" name="'+((t=e.rule)&&"name"in t?"net.csslint."+t.name.replace(/\s/g,""):"")+'">'),n.push("<"+r+' message="'+o(e.message)+'"><![CDATA['+e.line+":"+e.col+":"+o(e.evidence)+"]]></"+r+">"),n.push("</testcase>"),i[r]+=1)})),n.unshift('<testsuite time="0" tests="'+r.length+'" skipped="0" errors="'+i.error+'" failures="'+i.failure+'" package="net.csslint" name="'+t+'">'),n.push("</testsuite>")),n.join("")}}),i.addFormatter({id:"lint-xml",name:"Lint XML format",startFormat:function(){"use strict";return'<?xml version="1.0" encoding="utf-8"?><lint>'},endFormat:function(){"use strict";return"</lint>"},formatResults:function(e,t){"use strict";var r=e.messages,n=[],o=function(e){return e&&e.constructor===String?e.replace(/"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):""};return r.length>0&&(n.push('<file name="'+t+'">'),i.Util.forEach(r,(function(e){if(e.rollup)n.push('<issue severity="'+e.type+'" reason="'+o(e.message)+'" evidence="'+o(e.evidence)+'"/>');else{var t="";e.rule&&e.rule.id&&(t='rule="'+o(e.rule.id)+'" '),n.push("<issue "+t+'line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'" reason="'+o(e.message)+'" evidence="'+o(e.evidence)+'"/>')}})),n.push("</file>")),n.join("")}}),i.addFormatter({id:"text",name:"Plain Text",startFormat:function(){"use strict";return""},endFormat:function(){"use strict";return""},formatResults:function(e,t,r){"use strict";var n=e.messages,o="";if(r=r||{},0===n.length)return r.quiet?"":"\n\ncsslint: No errors in "+t+".";o="\n\ncsslint: There ",1===n.length?o+="is 1 problem":o+="are "+n.length+" problems",o+=" in "+t+".";var a=t.lastIndexOf("/"),s=t;return-1===a&&(a=t.lastIndexOf("\\")),a>-1&&(s=t.substring(a+1)),i.Util.forEach(n,(function(e,t){o=o+"\n\n"+s,e.rollup?(o+="\n"+(t+1)+": "+e.type,o+="\n"+e.message):(o+="\n"+(t+1)+": "+e.type+" at line "+e.line+", col "+e.col,o+="\n"+e.message,o+="\n"+e.evidence)})),o}}),i}();<script type="text/template" id="template-snippet-browser">
	<div class="snippet-browser-overlay">

	</div>

	<div class="snippet-browser-dialog">
		<div class="toolbar">
			<h1><?php esc_html_e( 'CSS Snippets', 'so-css' ); ?></h1>
			<span href="#" class="close">
				<span class="icon"></span>
			</span>
		</div>
		<div class="sidebar">
			<input type="text" class="snippet-search" placeholder="<?php esc_attr_e( 'Search Snippets', 'so-css' ); ?>" />
			<ul class="snippets">
			</ul>
		</div>
		<div class="main">
			<div class="snippet-view">
				<h2 class="snippet-title"></h2>
				<p class="snippet-description"></p>
				<pre class="snippet-code"></pre>
			</div>
		</div>
		<div class="buttons">
			<input type="button" class="insert-snippet button-primary" value="<?php esc_attr_e( 'Insert Snippet', 'so-css' ); ?>" />
		</div>
	</div>
</script>

<script type="text/template" id="template-sides-field">
	<div class="spacing-field">

		<ul class="select-tabs side-tabs" data-type="box">
			<li class="select-tab side-tab" data-direction="all"><div class="spacing-all"></div></li>
			<li class="select-tab side-tab" data-direction="top"><div class="spacing-top"></div></li>
			<li class="select-tab side-tab" data-direction="right"><div class="spacing-right"></div></li>
			<li class="select-tab side-tab" data-direction="bottom"><div class="spacing-bottom"></div></li>
			<li class="select-tab side-tab" data-direction="left"><div class="spacing-left"></div></li>
		</ul>

		<ul class="select-tabs side-tabs" data-type="radius">
			<li class="select-tab side-tab" data-direction="all"><div class="spacing-all"></div></li>
			<li class="select-tab side-tab" data-direction="top-right"><div class="spacing-top spacing-right"></div></li>
			<li class="select-tab side-tab" data-direction="bottom-right"><div class="spacing-bottom spacing-right"></div></li>
			<li class="select-tab side-tab" data-direction="bottom-left"><div class="spacing-bottom spacing-left"></div></li>
			<li class="select-tab side-tab" data-direction="top-left"><div class="spacing-top spacing-left"></div></li>
		</ul>

		<ul class="sides">

		</ul>

	</div>
</script>

<script type="text/template" id="template-preview-window">
	<div id="preview-navigator">
		<input type="text" data-invalid-uri="<?php esc_attr_e( "Invalid URI. Please make sure you're using a URL from the same site.", 'so-css' ); ?>" />
	</div>
	<iframe id="preview-iframe" seamless="seamless"></iframe>
</script>

<script type="text/template" id="template-webfont-teaser">
	<input type="text" value="" class="socss-property-controller-input"/>
	<small style="color: #888">
		<?php
		printf(
			esc_html__( 'Get a %sGoogle Font%s selector.', 'so-css' ),
			'<a href="https://siteorigin.com/downloads/premium/?featured_addon=plugin/web-font-selector" target="_blank">',
			'</a>'
		);
		?>
	</small>
</script>
<div id="socss-inspector-interface" class="socss-element">

	<div class="socss-link">
		<?php esc_html_e( 'Navigate To: ', 'so-css' ); ?>: <a href="#"></a>
	</div>

	<div class="socss-toolbar">
		<div class="socss-enable-inspector dashicons dashicons-search"></div>
		<div class="socss-hierarchy"></div>
	</div>

	<div class="socss-selectors-window">

	</div>

	<div class="socss-properties-window">

	</div>

</div>

<script type="text/template" id="socss-template-hover">
	<div class="socss-inspector-hover socss-element">

		<div class="socss-guide socss-guide-margin socss-guide-top"></div>
		<div class="socss-guide socss-guide-margin socss-guide-bottom"></div>
		<div class="socss-guide socss-guide-margin socss-guide-left"></div>
		<div class="socss-guide socss-guide-margin socss-guide-right"></div>

		<div class="socss-guide socss-guide-padding socss-guide-top"></div>
		<div class="socss-guide socss-guide-padding socss-guide-bottom"></div>
		<div class="socss-guide socss-guide-padding socss-guide-left"></div>
		<div class="socss-guide socss-guide-padding socss-guide-right"></div>

	</div>
</script>
<?php
/**
 * @var $page_title string The title of the page. Includes the post title if a post was selected.
 * @var $custom_css string The custom CSS string to be edited.
 * @var $current_revision int If the CSS to be edited is a revision, this will contain the timestamp of the revision.
 * @var $custom_css_revisions array Saved revisions for the current theme.
 * @var $editor_description string Description to provide context for the CSS being edited.
 * @var $socss_post_id int ID of the post for which we're editing CSS.
 * @var $save_button_label string Label of the save button depending on whether a post or revision has been selected.
 * @var $form_save_url string URL to use when saving the CSS.
 */
$snippets = SiteOrigin_CSS::single()->get_snippets();
$user = wp_get_current_user();

if ( ! empty( $current_revision ) ) {
	$revision_date = date( 'j F Y @ H:i:s', $current_revision + get_option( 'gmt_offset' ) * 60 * 60 );
}
?>

<div class="wrap" id="siteorigin-custom-css">
	<h2>
		<img src="<?php echo plugin_dir_url( __FILE__ ) . '../css/images/icon.png'; ?>" class="icon" />
		<?php echo esc_html( $page_title ); ?>
	</h2>


	<?php if ( isset( $_POST['siteorigin_custom_css'] ) ) { ?>
		<div class="notice notice-success"><p><?php esc_html_e( 'Site design updated.', 'so-css' ); ?></p></div>
	<?php } ?>

	<?php if ( ! empty( $current_revision ) ) { ?>
		<div class="notice notice-warning">
			<p><?php printf( esc_html__( 'Editing revision dated %s. Click %sRevert to this revision%s to keep using it.', 'so-css' ), $revision_date, '<em>', '</em>' ); ?></p>
		</div>
	<?php } ?>

	<div id="poststuff">
		<form action="<?php echo esc_url( $form_save_url ); ?>" method="POST">

			<div id="so-custom-css-info">
				<p class="so-custom-css-submit">
					<input type="submit" name="siteorigin_custom_css_save" class="button-primary" value="<?php esc_attr_e( $save_button_label ); ?>" />
				</p>

				<?php if ( $this->display_teaser() ) { ?>
					<div class="postbox">
						<h3 class="hndle"><span><?php esc_html_e( 'Get The Full Experience', 'so-css' ); ?></span></h3>
						<div class="inside">
							<?php printf( wp_kses_post( __( '%sSiteOrigin Premium%s adds a <strong>Google Web Font</strong> selector to SiteOrigin CSS so you can easily change any font.', 'so-css' ) ), '<a href="https://siteorigin.com/downloads/premium/?featured_addon=plugin/web-font-selector" target="_blank">', '</a>' ); ?>
						</div>
					</div>
				<?php } ?>

				<?php if ( ! get_user_meta( $user->ID, 'socss_hide_gs' ) ) { ?>
					<div class="postbox" id="so-custom-css-getting-started">
						<h3 class="hndle">
							<span><?php esc_html_e( 'Getting Started Video', 'so-css' ); ?></span>
							<a href="<?php echo wp_nonce_url( admin_url( 'admin-ajax.php?action=socss_hide_getting_started' ), 'hide' ); ?>" class="hide"><?php esc_html_e( 'Dismiss', 'so-css' ); ?></a>
						</h3>
						<div class="inside">
							<a href="https://siteorigin.com/css/getting-started/" target="_blank"><img src="<?php echo plugin_dir_url( __FILE__ ) . '../css/images/video.jpg'; ?>" /></a>
						</div>
					</div>
				<?php } ?>

				<div class="postbox" id="so-custom-css-revisions">
					<h3 class="hndle"><span><?php esc_html_e( 'CSS Revisions', 'so-css' ); ?></span></h3>
					<div class="inside">
						<ol class="custom-revisions-list" data-confirm="<?php esc_attr_e( 'Are you sure you want to load this revision?', 'so-css' ); ?>">
							<?php $this->custom_css_revisions_list( $theme, $socss_post_id, $current_revision ); ?>
						</ol>
					</div>
				</div>

				<div class="postbox" id="so-custom-css-editor-theme">
					<h3 class="hndle"><span><?php esc_html_e( 'Editor Theme', 'so-css' ); ?></span></h3>
					<div class="inside">
						<select name="so_css_editor_theme" id="so_css_editor_theme">
							<option value="neat" <?php selected( 'neat', $editor_theme ); ?>><?php esc_attr_e( 'Light', 'so-css' ); ?></option>
							<option value="ambiance" <?php selected( 'ambiance', $editor_theme ); ?>><?php esc_attr_e( 'Dark', 'so-css' ); ?></option>
						</select>
					</div>
				</div>

					<div class="color-theme">
					</div>

			</div>

			<div id="so-custom-css-form">

				<div class="custom-css-toolbar">
					<div class="toolbar-function-buttons">
						<div class="toolbar-functions-dropdown">
							<span class="dashicons dashicons-menu"></span>
						</div>
						
						<ul class="toolbar-buttons">
						</ul>
					</div>

					<div class="toolbar-action-buttons">
						<a href="#expand" class="editor-expand socss-button" title="<?php esc_attr_e( 'Open Expanded Mode', 'so-css' ); ?>">
							<span class="so-css-icon so-css-icon-expand" title="<?php esc_attr_e( 'Open Expanded Mode', 'so-css' ); ?>"></span>
							<span class="so-css-icon so-css-icon-compress" title="<?php esc_attr_e( 'Close Expanded Mode', 'so-css' ); ?>"></span>
						</a>

						<a href="#visual" class="editor-visual socss-button" title="<?php esc_attr_e( 'Open Visual Mode', 'so-css' ); ?>">
							<span class="so-css-icon so-css-icon-eye"></span>
						</a>

						<span class="save socss-button button-primary" title="<?php esc_attr_e( 'Save CSS', 'so-css' ); ?>">
							<span class="so-css-icon so-css-icon-save"></span>
						</span>
					</div>
				</div>

				<div class="custom-css-container">
					<textarea
						name="siteorigin_custom_css" id="custom-css-textarea" data-theme="<?php echo esc_attr( $editor_theme ); ?>" class="css-editor" rows="<?php echo max( 10, substr_count( $custom_css, "\n" ) + 1 ); ?>"><?php echo esc_textarea( $custom_css ); ?></textarea>
					<?php wp_nonce_field( 'custom_css', '_sononce' ); ?>
				</div>
				<div class="so-css-footer">
					<p class="description">
						<?php esc_html_e( $editor_description ); ?>
					</p>
				</div>
				<?php
				if (
					! class_exists( 'SiteOrigin_Panels' ) &&
					! class_exists( 'SiteOrigin_Widgets_Bundle' ) &&
					! class_exists( 'SiteOrigin_Premium' )
				) {
					?>
					<div class="installer">
						<a href="#" class="installer-link">
							<?php _e( 'Other Settings', 'so-css' ); ?>
						</a>

						<div class="installer-container" style="display: none;">
							<label>
								<?php echo __( 'Enable SiteOrigin Installer: ', 'so-css' ); ?>
								<input
									type="checkbox"
									name="installer_status"
									class="installer_status"
									<?php checked( get_option( 'siteorigin_installer', false ), 1 ); ?>
									data-nonce="<?php echo wp_create_nonce( 'siteorigin_installer_status' ); ?>"
								>
							</label>
						</div>
					</div>
				<?php } ?>

				<div class="custom-css-preview"></div>

				<div class="decoration"></div>

			</div>

			<div id="so-custom-css-properties">

				<div class="toolbar">
					<select></select>
					<div class="close socss-button" title="<?php esc_attr_e( 'Close', 'so-css' ); ?>">
						<span class="so-css-icon so-css-icon-check"></span>
					</div>
					<div class="save socss-button button-primary" title="<?php esc_attr_e( 'Save CSS', 'so-css' ); ?>">
						<span class="so-css-icon so-css-icon-save"></span>
					</div>
				</div>

				<ul class="section-tabs"></ul>

				<div class="sections"></div>

			</div>

		</form>

	</div>

	<div class="clear"></div>

</div>
                    GNU GENERAL PUBLIC LICENSE
                       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

                    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

                            NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    {description}
    Copyright (C) {year}  {fullname}

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  {signature of Ty Coon}, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

<?php
/*
Plugin Name: SiteOrigin CSS
Description: An advanced CSS editor from SiteOrigin.
Version: 1.5.10
Author: SiteOrigin
Author URI: https://siteorigin.com
Plugin URI: https://siteorigin.com/css/
License: GPL3
License URI: https://www.gnu.org/licenses/gpl-3.0.txt
Text Domain: so-css
*/

// Handle the legacy CSS editor that came with SiteOrigin themes
include plugin_dir_path( __FILE__ ) . 'inc/legacy.php';

define( 'SOCSS_VERSION', '1.5.10' );
define( 'SOCSS_JS_SUFFIX', '.min' );

/**
 * Class SiteOrigin_CSS The main class for the SiteOrigin CSS Editor
 */
class SiteOrigin_CSS {

	private $theme;
	private $snippet_paths;
	private $css_file;

	public function __construct() {
		$this->theme = basename( get_template_directory() );
		$this->snippet_paths = array();

		// Main header actions
		add_action( 'plugins_loaded', array( $this, 'set_plugin_textdomain' ) );

		global $wp_filesystem;

		if ( ! class_exists( 'wp_filesystem' ) ) {
			require_once ABSPATH . '/wp-admin/includes/file.php';
			WP_Filesystem();
		}

		// Priority 20 is necessary to ensure our CSS takes precedence.
		add_action( 'wp_head', array( $this, 'enqueue_css' ), 20 );

		// All the admin actions
		add_action( 'admin_menu', array( $this, 'action_admin_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ), 20 );
		add_action( 'admin_enqueue_scripts', array( $this, 'dequeue_admin_scripts' ), 19 );
		add_action( 'load-appearance_page_so_custom_css', array( $this, 'add_help_tab' ) );

		// Add the action links.
		add_action( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );

		// The request to hide the getting started video
		add_action( 'wp_ajax_socss_hide_getting_started', array( $this, 'admin_action_hide_getting_started' ) );

		add_action( 'wp_ajax_socss_get_post_css', array( $this, 'admin_action_get_post_css' ) );
		add_action( 'wp_ajax_socss_get_revisions_list', array( $this, 'admin_action_get_revisions_list' ) );
		add_action( 'wp_ajax_socss_save_css', array( $this, 'admin_action_save_css' ) );

		if ( ! is_admin() ) {
			if ( isset( $_GET['so_css_preview'] )  ) {
				add_action( 'plugins_loaded', array( $this, 'disable_ngg_resource_manager' ) );
				add_filter( 'show_admin_bar', '__return_false' );
				add_filter( 'wp_enqueue_scripts', array( $this, 'enqueue_inspector_scripts' ) );
				add_filter( 'wp_footer', array( $this, 'inspector_templates' ) );

				// We'll be grabbing all the enqueued scripts and outputting them
				add_action( 'wp_enqueue_scripts', array( $this, 'inline_inspector_scripts' ), 100 );
			}
		} elseif ( ! class_exists( 'SiteOrigin_Installer' ) ) {
			include plugin_dir_path( __FILE__ ) . 'inc/installer/siteorigin-installer.php';
			if (
				! class_exists( 'SiteOrigin_Panels' ) &&
				! class_exists( 'SiteOrigin_Widgets_Bundle' ) &&
				! class_exists( 'SiteOrigin_Premium' )
			) {
				add_filter( 'siteorigin_add_installer', array( $this, 'manage_installer' ) );
			}
		}
	}

	/**
	 * Get a singleton of the SiteOrigin CSS.
	 *
	 * @return SiteOrigin_CSS
	 */
	public static function single() {
		static $single;

		if ( empty( $single ) ) {
			$single = new SiteOrigin_CSS();
		}

		return $single;
	}

	public function manage_installer( $status ) {
		// If the user hasn't enabled/disabled the installer, disable it by default.
		if ( empty( get_option( 'siteorigin_installer' ) ) ) {
				$status = false;
		}
		return $status;
	}

	/**
	 * Retrieve the current custom CSS for a given theme and post id combination.
	 *
	 * @param $theme string The name of the theme for which to retrieve custom CSS.
	 * @param $post_id int The ID of the specific post for which to retrieve custom CSS.
	 *
	 * @return string The custom CSS for the theme and post ID combination.
	 */
	public function get_custom_css( $theme, $post_id = null ) {
		$css_key = 'siteorigin_custom_css[' . $theme . ']';

		if ( empty( $post_id ) && WP_Filesystem() ) {
			$custom_css_file = apply_filters( 'siteorigin_custom_css_file', false );

			if (
				! empty( $custom_css_file ) &&
				! empty( $custom_css_file['file'] )
			) {
				// Did we previously load the CSS file? If not, load it.
				if ( empty( $this->css_file ) || isset( $_POST['siteorigin_custom_css'] ) ) {
					global $wp_filesystem;

					// If custom file doesn't exist, create it.
					if ( ! $wp_filesystem->exists( $custom_css_file['file'] ) ) {
						$wp_filesystem->touch( $custom_css_file['file'] );
					}

					if ( empty( get_option( 'siteorigin_custom_file' ) ) ) {
						update_option( 'siteorigin_custom_file', true, true );
					}

					if ( $wp_filesystem->is_writable( $custom_css_file['file'] ) ) {
						$this->css_file = $wp_filesystem->get_contents( $custom_css_file['file'] );
					}
				}

				return $this->css_file;
			} elseif ( ! empty( get_option( 'siteorigin_custom_file' ) ) ) {
				// If the custom file filter was previously active we need to
				// generate the global CSS file to avoid no CSS outputting
				// without modification.
				delete_option( 'siteorigin_custom_file', true );
				$css_file_path = $this->get_css_file_name( $theme );

				global $wp_filesystem;
				$wp_filesystem->put_contents(
					$css_file_path,
					get_option( $css_key, '' )
				);
			}
		}

		if ( ! empty( $post_id ) ) {
			return get_post_meta( $post_id, $css_key, true );
		}

		return get_option( $css_key, '' );
	}

	/**
	 * Save custom CSS for a given theme and post id combination.
	 *
	 * @param $custom_css string The custom CSS to save.
	 * @param $theme string The name of the theme for which to save custom CSS.
	 * @param $post_id int The ID of the specific post for which to save custom CSS.
	 *
	 * @return bool Whether or not saving the custom CSS was successful.
	 */
	public function save_custom_css( $custom_css, $theme, $post_id = null ) {
		$css_key = 'siteorigin_custom_css[' . $theme . ']';

		if ( empty( $post_id ) ) {
			$current = get_option( $css_key );

			if ( $current === false ) {
				return add_option( $css_key, $custom_css, '', 'no' );
			} else {
				return update_option( $css_key, $custom_css );
			}
		}

		if ( metadata_exists( 'post', $post_id, $css_key ) ) {
			return update_post_meta( $post_id, $css_key, $custom_css );
		}

		return add_post_meta( $post_id, $css_key, $custom_css );
	}

	/**
	 * Returns the file name of the CSS file we're editing.
	 *
	 * @param null $post_id
	 */
	public function get_css_file_name( $theme, $post_id = null ) {
		global $wp_filesystem;
		$upload_dir = wp_upload_dir();
		$upload_dir_path = $upload_dir['basedir'] . '/so-css/';

		if ( ! $wp_filesystem->is_dir( $upload_dir_path ) ) {
			$wp_filesystem->mkdir( $upload_dir_path );
		}

		$css_file_name = 'so-css-' . $theme . ( ! empty( $post_id ) ? '_' . $post_id : '' );

		return $upload_dir_path . $css_file_name . '.css';
	}

	/**
	 * Save custom CSS for a given theme and post id combination to a file in the uploads directory to allow for caching.
	 *
	 * @param null $post_id
	 */
	public function save_custom_css_file( $custom_css, $theme, $post_id = null ) {
		if ( WP_Filesystem() ) {
			global $wp_filesystem;
			$css_file_path = apply_filters( 'siteorigin_custom_css_file', false );

			if (
				empty( $css_file_path ) ||
				empty( $css_file_path['file'] ) ||
				! $wp_filesystem->is_writable( $css_file_path['file'] )
			) {
				$css_file_path = $this->get_css_file_name( $theme, $post_id );

				if ( file_exists( $css_file_path ) ) {
					$wp_filesystem->delete( $css_file_path );
				}
			} else {
				$css_file_path = $css_file_path['file'];
				$this->css_file = $custom_css;
			}

			$wp_filesystem->put_contents(
				$css_file_path,
				$custom_css
			);
		}
	}

	/**
	 * Retrieve the previous revisions of custom CSS for a given theme and post id combination.
	 *
	 * @param $theme string The name of the theme for which to retrieve custom CSS revisions.
	 * @param $post_id int The ID of the specific post for which to retrieve custom CSS revisions.
	 *
	 * @return array The custom CSS revisions for the theme and post ID combination.
	 */
	public function get_custom_css_revisions( $theme, $post_id = null ) {
		$css_key = 'siteorigin_custom_css_revisions[' . $theme . ']';

		if ( empty( $post_id ) ) {
			return get_option( $css_key, '' );
		}

		return get_post_meta( $post_id, $css_key, true );
	}

	/**
	 * Adds a custom CSS revision for a given theme and post id combination.
	 *
	 * @param $custom_css string The custom CSS to add as a revision.
	 * @param $theme string The name of the theme for which to save custom CSS.
	 * @param $post_id int The ID of the specific post for which to save custom CSS.
	 *
	 * @return bool Whether or not adding the custom CSS revision was successful.
	 */
	public function add_custom_css_revision( $custom_css, $theme, $post_id = null ) {
		$revisions = $this->get_custom_css_revisions( $this->theme, $post_id );

		$css_key = 'siteorigin_custom_css_revisions[' . $theme . ']';

		if ( empty( $revisions ) ) {
			$revisions = array();

			if ( empty( $post_id ) ) {
				add_option( $css_key, $revisions, '', 'no' );
			} else {
				add_post_meta( $post_id, $css_key, $revisions );
			}
		}
		$revisions[ time() ] = $custom_css;

		// Sort the revisions and cut off any old ones.
		krsort( $revisions );
		$revisions = array_slice( $revisions, 0, 15, true );

		if ( empty( $post_id ) ) {
			return update_option( $css_key, $revisions );
		}

		return update_post_meta( $post_id, $css_key, $revisions );
	}

	/**
	 * Enqueue or print inline CSS.
	 */
	public function enqueue_css() {
		$this->enqueue_custom_css( $this->theme );

		if ( is_singular() ) {
			$this->enqueue_custom_css( $this->theme, get_the_ID() );
		}
	}

	/**
	 * Enqueue the custom CSS for the given theme and post id combination.
	 *
	 * @param $theme string The name of the theme for which to enqueue custom CSS.
	 * @param $post_id int The ID of the specific post for which to enqueue custom CSS.
	 */
	public function enqueue_custom_css( $theme, $post_id = null ) {
		$css_id = $theme . ( ! empty( $post_id ) ? '_' . $post_id : '' );

		if (
			empty( $_GET['so_css_preview'] ) &&
			! is_admin() &&
			apply_filters( 'siteorigin_css_enqueue_css', true )
		) {
			$custom_css_file = apply_filters( 'siteorigin_custom_css_file', array() );

			if ( ! empty( $post_id ) || empty( $custom_css_file ) ) {
				$upload_dir = wp_upload_dir();
				$upload_dir_path = $upload_dir['basedir'] . '/so-css/';
				$css_file_name = 'so-css-' . $css_id;
				$css_file_path = $upload_dir_path . $css_file_name . '.css';
				$css_file_url = $upload_dir['baseurl'] . '/so-css/' . $css_file_name . '.css';
			} elseif ( isset( $custom_css_file['url'] ) ) {
				$css_file_path = $custom_css_file['file'];
				$css_file_url = $custom_css_file['url'];
			}

			if ( ! empty( $css_file_path ) && file_exists( $css_file_path ) ) {
				wp_enqueue_style(
					'so-css-' . $css_id,
					set_url_scheme( $css_file_url ),
					array(),
					$this->get_latest_revision_timestamp()
				);
			}
		} else {
			$custom_css = $this->get_custom_css( $theme, $post_id );
			// We just need to enqueue a dummy style
			if ( ! empty( $custom_css ) ) {
				echo "<style id='" . sanitize_html_class( $css_id ) . "-custom-css' class='siteorigin-custom-css' type='text/css'>\n";
				echo self::sanitize_css( $custom_css ) . "\n";
				echo "</style>\n";
			}
		}
	}

	public function set_plugin_textdomain() {
		load_plugin_textdomain( 'so-css', false, plugin_dir_path( __FILE__ ) . 'lang/' );
	}

	/**
	 * Action to run on the admin action.
	 */
	public function action_admin_menu() {
		add_theme_page( esc_html__( 'Custom CSS', 'so-css' ), esc_html__( 'Custom CSS', 'so-css' ), 'edit_theme_options', 'so_custom_css', array(
			$this,
			'display_admin_page',
		) );

		if ( current_user_can( 'edit_theme_options' ) && isset( $_POST['siteorigin_custom_css'] ) ) {
			check_admin_referer( 'custom_css', '_sononce' );

			// Sanitize CSS input. Should keep most tags, apart from script and style tags.
			$custom_css = self::sanitize_css( filter_input( INPUT_POST, 'siteorigin_custom_css' ) );
			$socss_post_id = filter_input( INPUT_GET, 'socss_post_id', FILTER_VALIDATE_INT );

			if ( empty( $this->css_file ) ) {
				$current = $this->get_custom_css( $this->theme, $socss_post_id );
				$this->save_custom_css( $custom_css, $this->theme, $socss_post_id );
			} else {
				$current = $this->css_file;
			}

			// If this has changed, then add a revision.
			if ( $current != $custom_css ) {
				$this->add_custom_css_revision( $custom_css, $this->theme, $socss_post_id );

				$this->save_custom_css_file( $custom_css, $this->theme, $socss_post_id );
			}

			// Update Editor Theme.
			if (
				$_POST['so_css_editor_theme'] == 'neat' ||
				$_POST['so_css_editor_theme'] == 'ambiance'
			) {
				update_option( 'so_css_editor_theme', $_POST['so_css_editor_theme'] );
			}
		}
	}

	/**
	 * Display the help tab
	 */
	public function add_help_tab() {
		$screen = get_current_screen();
		$screen->add_help_tab( array(
			'id'      => 'custom-css',
			'title'   => esc_html__( 'Custom CSS', 'so-css' ),
			'content' => '<p>'
						 . sprintf( esc_html__( "SiteOrigin CSS adds any custom CSS you enter here into your site's header. ", 'so-css' ) )
						 . esc_html__( "These changes will persist across updates so it's best to make all your changes here. ", 'so-css' )
						 . '</p>',
		) );
	}

	public function enqueue_admin_scripts( $page ) {
		if ( $page != 'appearance_page_so_custom_css' ) {
			return;
		}

		// Core WordPress stuff that we use
		wp_enqueue_media();

		global $wp_version;

		if ( version_compare( $wp_version, '4.9', '>=' ) && wp_get_current_user()->syntax_highlighting ) {
			wp_enqueue_code_editor(
				array(
					'type' => 'css',
					'codemirror' => array(
						'lint' => true,
					),
				)
			);
		} else {
			$this->enqueue_fallback_codemirror();
		}
		wp_enqueue_style( 'socss-codemirror-theme-neat', plugin_dir_url( __FILE__ ) . 'lib/codemirror/theme/neat.css', array(), SOCSS_VERSION );
		wp_enqueue_style( 'socss-codemirror-theme-ambiance', plugin_dir_url( __FILE__ ) . 'lib/codemirror/theme/ambiance.css', array(), SOCSS_VERSION );

		// Enqueue the scripts for theme CSS processing
		wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url( __FILE__ ) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );

		// There are conflicts between CSS linting and the built in WordPress color picker, so use something else
		wp_enqueue_style( 'siteorigin-custom-css-minicolors', plugin_dir_url( __FILE__ ) . 'lib/minicolors/jquery.minicolors.css', array(), '2.1.7' );
		wp_enqueue_script( 'siteorigin-custom-css-minicolors', plugin_dir_url( __FILE__ ) . 'lib/minicolors/jquery.minicolors' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), '2.1.7' );

		// URI parsing for preview navigation
		wp_enqueue_script( 'siteorigin-uri', plugin_dir_url( __FILE__ ) . 'js/URI' . SOCSS_JS_SUFFIX . '.js', array(), SOCSS_VERSION, true );

		// All the custom SiteOrigin CSS stuff
		wp_enqueue_script( 'siteorigin-custom-css', plugin_dir_url( __FILE__ ) . 'js/editor' . SOCSS_JS_SUFFIX . '.js', array( 'jquery', 'underscore', 'backbone' ), SOCSS_VERSION, true );
		wp_enqueue_style( 'siteorigin-custom-css', plugin_dir_url( __FILE__ ) . 'css/admin.css', array( ), SOCSS_VERSION );

		// Pretty confusing, but it seems we should be using `home_url` and NOT `site_url`
		// as described here => https://wordpress.stackexchange.com/a/50605
		$init_url = home_url();

		if ( ! empty( $socss_post_id ) && is_int( $socss_post_id ) ) {
			$init_url = set_url_scheme( get_permalink( $socss_post_id ) );
		}

		$open_visual_editor = ! empty( $_REQUEST['open_visual_editor'] );

		$home_url = add_query_arg( 'so_css_preview', '1', $init_url );

		wp_localize_script( 'siteorigin-custom-css', 'socssOptions', array(
			'homeURL' => $home_url,
			'postCssUrlRoot' => wp_nonce_url( admin_url( 'admin-ajax.php?action=socss_get_post_css' ), 'get_post_css' ),
			'getRevisionsListAjaxUrl' => wp_nonce_url( admin_url( 'admin-ajax.php?action=socss_get_revisions_list' ), 'get_revisions_list' ),
			'ajaxurl' => wp_nonce_url( admin_url( 'admin-ajax.php' ), 'so-css-ajax' ),
			'openVisualEditor' => $open_visual_editor,

			'propertyControllers' => apply_filters( 'siteorigin_css_property_controllers', $this->get_property_controllers() ),

			'loc' => array(
				'unchanged'    => esc_html__( 'Unchanged', 'so-css' ),
				'select'       => esc_html__( 'Select', 'so-css' ),
				'select_image' => esc_html__( 'Select Image', 'so-css' ),
				'leave'        => esc_html__( 'Are you sure you want to leave without saving?', 'so-css' ),
			),
		) );

		// This is for the templates required by the CSS editor. Ideally this would be out in the footer, but we need
		// it earlier for dependent scripts.
		include plugin_dir_path( __FILE__ ) . 'tpl/js-templates.php';
	}

	// Handles loading the fallback version of CodeMirror.
	public function enqueue_fallback_codemirror() {
		// Enqueue the codemirror scripts. Call Underscore and Backbone dependencies so they're enqueued first to prevent conflicts.
		wp_enqueue_script( 'socss-codemirror', plugin_dir_url( __FILE__ ) . 'lib/codemirror/lib/codemirror' . SOCSS_JS_SUFFIX . '.js', array( 'underscore', 'backbone' ), '5.2.0' );
		wp_enqueue_script( 'socss-codemirror-mode-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/mode/css/css' . SOCSS_JS_SUFFIX . '.js', array(), '5.2.0' );

		// Add in all the linting libs
		wp_enqueue_script( 'socss-codemirror-lint', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/lint' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror' ), '5.2.0' );
		wp_enqueue_script( 'socss-codemirror-lint-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/css-lint' . SOCSS_JS_SUFFIX . '.js', array(
			'socss-codemirror',
			'socss-codemirror-lint-css-lib',
		), '5.2.0' );
		wp_enqueue_script( 'socss-codemirror-lint-css-lib', plugin_dir_url( __FILE__ ) . 'js/csslint' . SOCSS_JS_SUFFIX . '.js', array(), '0.10.0' );

		// The CodeMirror autocomplete library
		wp_enqueue_script( 'socss-codemirror-show-hint', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/hint/show-hint' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror' ), '5.2.0' );

		// CodeMirror search and dialog addons
		wp_enqueue_script( 'socss-codemirror-dialog', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/dialog/dialog' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror' ), '5.2.0' );

		wp_enqueue_script( 'socss-codemirror-search', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/search' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror' ), '5.37.0' );
		wp_enqueue_script( 'socss-codemirror-search-searchcursor', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/searchcursor' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror', 'socss-codemirror-search' ), '5.37.0' );
		wp_enqueue_script( 'socss-codemirror-search-match-cursor', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/match-highlighter' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror', 'socss-codemirror-search' ), '5.37.0' );
		wp_enqueue_script( 'socss-codemirror-search-matchesonscrollbar', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/matchesonscrollbar' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror', 'socss-codemirror-search' ), '5.37.0' );
		wp_enqueue_script( 'socss-codemirror-scroll-annotatescrollbar', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/scroll/annotatescrollbar' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror', 'socss-codemirror-search', 'socss-codemirror-search-matchesonscrollbar' ), '5.37.0' );
		wp_enqueue_script( 'socss-codemirror-jump-to-line', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/jump-to-line' . SOCSS_JS_SUFFIX . '.js', array( 'socss-codemirror', 'socss-codemirror-search' ), '5.37.0' );

		// All the CodeMirror styles
		wp_enqueue_style( 'socss-codemirror', plugin_dir_url( __FILE__ ) . 'lib/codemirror/lib/codemirror.css', array(), '5.2.0' );
		wp_enqueue_style( 'socss-codemirror-lint-css', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/lint/lint.css', array(), '5.2.0' );
		wp_enqueue_style( 'socss-codemirror-show-hint', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/hint/show-hint.css', array(), '5.2.0' );
		wp_enqueue_style( 'socss-codemirror-dialog', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/dialog/dialog.css', '5.2.0' );
		wp_enqueue_style( 'socss-codemirror-search-matchesonscrollbar', plugin_dir_url( __FILE__ ) . 'lib/codemirror/addon/search/matchesonscrollbar.css', array(), '5.37.0' );
	}

	public function dequeue_admin_scripts( $page ) {
		if ( $page != 'appearance_page_so_custom_css' ) {
			return;
		}

		// Dequeue the core WordPress color picker on the custom CSS page.
		// This script causes conflicts and other plugins seem to be enqueueing it on the SO CSS admin page.
		wp_dequeue_script( 'wp-color-picker' );
		wp_dequeue_style( 'wp-color-picker' );
	}

	/**
	 * Get all the available property controllers
	 */
	public function get_property_controllers() {
		return include plugin_dir_path( __FILE__ ) . 'inc/controller-config.php';
	}

	public function plugin_action_links( $links ) {
		if ( isset( $links['edit'] ) ) {
			unset( $links['edit'] );
		}
		$links['css_editor'] = '<a href="' . admin_url( 'themes.php?page=so_custom_css' ) . '">' . esc_html__( 'CSS Editor', 'so-css' ) . '</a>';
		$links['support'] = '<a href="https://siteorigin.com/thread/" target="_blank">' . esc_html__( 'Support', 'so-css' ) . '</a>';

		if ( apply_filters( 'siteorigin_premium_upgrade_teaser', true ) && ! defined( 'SITEORIGIN_PREMIUM_VERSION' ) ) {
			$links['addons'] = '<a href="https://siteorigin.com/downloads/premium/?featured_addon=plugin/web-font-selector" style="color: #3db634" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Addons', 'so-css' ) . '</a>';
		}

		return $links;
	}

	public function display_admin_page() {
		$socss_post_id = filter_input( INPUT_GET, 'socss_post_id', FILTER_VALIDATE_INT );
		$theme = filter_input( INPUT_GET, 'theme' );
		$time = filter_input( INPUT_GET, 'time', FILTER_VALIDATE_INT );

		$page_title = esc_html__( 'SiteOrigin CSS', 'so-css' );
		$theme_obj = wp_get_theme();
		$theme_name = $theme_obj->get( 'Name' );
		$editor_description = sprintf( esc_html__( 'Changes apply to %s and its child themes', 'so-css' ), $theme_name );
		$save_button_label = esc_html__( 'Save CSS', 'so-css' );
		$form_save_url = admin_url( 'themes.php?page=so_custom_css' );

		if ( ! empty( $socss_post_id ) ) {
			$selected_post = get_post( $socss_post_id );

			$page_title = sprintf(
				esc_html__( 'Editing CSS for: %s', 'so-css' ),
				$selected_post->post_title
			);

			$editor_description = sprintf(
				esc_html__( 'Changes apply to the %s %s when the current theme is %s or its child themes', 'so-css' ),
				$selected_post->post_type,
				$selected_post->post_title,
				$theme_name
			);
			$post_type_obj = get_post_type_object( $selected_post->post_type );
			$post_type_labels = $post_type_obj->labels;
			$save_button_label = sprintf( esc_html__( 'Save %s CSS', 'so-css' ), $post_type_labels->singular_name );
			$form_save_url = add_query_arg( 'socss_post_id', urlencode( $socss_post_id ), $form_save_url );
		}
		$custom_css = $this->get_custom_css( $this->theme, $socss_post_id );
		$custom_css_revisions = $this->get_custom_css_revisions( $this->theme, $socss_post_id );
		$current_revision = 0;

		if ( ! empty( $theme ) && $theme == $this->theme && ! empty( $time ) && ! empty( $custom_css_revisions[ $time ] ) ) {
			$current_revision = $time;
			$custom_css = $custom_css_revisions[ $time ];
		}

		if ( ! empty( $current_revision ) ) {
			$save_button_label = esc_html__( 'Revert to this revision', 'so-css' );
		}

		if ( ! empty( $custom_css_revisions ) ) {
			krsort( $custom_css_revisions );
		}

		$theme = basename( get_template_directory() );

		$editor_theme = get_option( 'so_css_editor_theme', 'neat' );

		include plugin_dir_path( __FILE__ ) . 'tpl/page.php';
	}

	public function display_teaser() {
		return apply_filters( 'siteorigin_premium_upgrade_teaser', true ) &&
			   ! defined( 'SITEORIGIN_PREMIUM_VERSION' );
	}

	/**
	 *  Generates the url to edit the custom CSS for a post.
	 */
	public function get_edit_css_link( $post ) {
		$url = admin_url( 'themes.php?page=so_custom_css' );

		if ( ! is_int( $post ) ) {
			$post = get_post( $post );
			$post = $post->ID;
		}

		return empty( $post ) ? $url : add_query_arg( array(
			'socss_post_id' => urlencode( $post ),
			'open_visual_editor' => 1,
		), $url );
	}

	public function admin_action_hide_getting_started() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'hide' ) ) {
			return;
		}

		$user = wp_get_current_user();

		if ( ! empty( $user ) ) {
			update_user_meta( $user->ID, 'socss_hide_gs', true );
		}
	}

	/**
	 * Retrieves the post specific CSS for the supplied postId.
	 */
	public function admin_action_get_post_css() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'get_post_css' ) ) {
			wp_die(
				esc_html__( 'The supplied nonce is invalid.', 'so-css' ),
				esc_html__( 'Invalid nonce.', 'so-css' ),
				403
			);
		}

		$post_id = filter_input( INPUT_GET, 'postId', FILTER_VALIDATE_INT );

		$current = $this->get_custom_css( $this->theme, $post_id );

		$url = empty( $post_id ) ? home_url() : set_url_scheme( get_permalink( $post_id ) );

		wp_send_json( array( 'css' => empty( $current ) ? '' : $current, 'postUrl' => $url ) );
	}

	/**
	 * Retrieves the past revisions of post specific CSS for the supplied postId.
	 */
	public function admin_action_get_revisions_list() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'get_revisions_list' ) ) {
			wp_die(
				esc_html__( 'The supplied nonce is invalid.', 'so-css' ),
				esc_html__( 'Invalid nonce.', 'so-css' ),
				403
			);
		}

		$post_id = filter_input( INPUT_GET, 'postId', FILTER_VALIDATE_INT );

		$this->custom_css_revisions_list( $this->theme, $post_id );

		wp_die();
	}

	/**
	 * Retrieves the past revisions of post specific CSS for the supplied postId.
	 */
	public function admin_action_save_css() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'so-css-ajax' ) ) {
			wp_die(
				esc_html__( 'The supplied nonce is invalid.', 'so-css' ),
				esc_html__( 'Invalid nonce.', 'so-css' ),
				403
			);
		}

		if ( current_user_can( 'edit_theme_options' ) && isset( $_POST['css'] ) ) {
			// Sanitize CSS input. Should keep most tags, apart from script and style tags.
			$custom_css = self::sanitize_css( stripslashes( $_POST['css'] ) );

			if ( empty( $this->css_file ) ) {
				$current = $this->get_custom_css( $this->theme );
				$this->save_custom_css( $custom_css, $this->theme );
			} else {
				$current = $this->css_file;
			}

			// If this has changed, then add a revision.
			if ( $current != $custom_css ) {
				$this->add_custom_css_revision( $custom_css, $this->theme );
				$this->save_custom_css_file( $custom_css, $this->theme );

				// Output the full revisions list.
				$this->custom_css_revisions_list( $this->theme );
			}
		}
		wp_die();
	}

	public function custom_css_revisions_list( $theme, $post_id = null, $current_revision = null ) {
		$revisions = $this->get_custom_css_revisions( $theme, $post_id );

		if ( is_array( $revisions ) && ! empty( $revisions ) ) {
			$i = 0;

			foreach ( $revisions as $time => $css ) {
				$is_current = ( empty( $current_revision ) && $i == 0 ) || ( ! empty( $current_revision ) && $time == $current_revision );
				$query_args = array( 'theme' => $theme, 'time' => $time, 'open_visual_editor' => false );

				if ( ! empty( $post_id ) ) {
					$query_args['socss_post_id'] = $post_id;
				}
				?>
				<li>
					<?php if ( ! $is_current ) { ?>
					<a href="<?php echo esc_url( add_query_arg( $query_args, admin_url( 'themes.php?page=so_custom_css' ) ) ); ?>"
					   class="load-css-revision">
					<?php } ?>
					<?php echo date( 'j F Y @ H:i:s', $time + get_option( 'gmt_offset' ) * 60 * 60 ); ?>
					<?php if ( ! $is_current ) { ?>
					</a>
					<?php } ?>
					(<?php printf( esc_html__( '%d chars', 'so-css' ), strlen( $css ) ); ?>)<?php if ( $i == 0 ) { ?> (<?php esc_html_e( 'Latest', 'so-css' ); ?>)<?php } ?>
				</li>
				<?php
				$i++;
			}
		} else {
			printf( '<em>%s</em>', esc_html__( 'No revisions yet.', 'so-css' ) );
		}
	}

	/**
	 *  Add one or more paths to the registered snippet paths
	 *
	 * @param string|array $path
	 */
	public function register_snippet_path( $path ) {
		$this->snippet_paths = array_merge( $this->snippet_paths, (array) $path );
	}

	/**
	 * Get all the available snippets
	 *
	 * @return array|bool
	 */
	public function get_snippets() {
		// Get the snippet paths
		$snippet_paths = apply_filters( 'siteorigin_css_snippet_paths', $this->snippet_paths );

		if ( empty( $snippet_paths ) ) {
			return array();
		}

		static $snippets = array();

		if ( ! empty( $snippets ) ) {
			return $snippets;
		}

		if ( ! WP_Filesystem() ) {
			return false;
		}
		global $wp_filesystem;

		foreach ( $snippet_paths as $path ) {
			foreach ( glob( $path . '/*.css' ) as $css_file ) {
				$data = get_file_data( $css_file, array(
					'Name'        => 'Name',
					'Description' => 'Description',
				) );

				// Get the CSS and strip out the first header
				$css = $wp_filesystem->get_contents( $css_file );
				$css = preg_replace( '!/\*.*?\*/!s', '', $css, 1 );

				$snippets[] = wp_parse_args( $data, array(
					'css' => str_replace( "\t", '  ', trim( $css ) ),
				) );
			}
		}

		usort( $snippets, array( $this, 'sort_snippet_callback' ) );

		return $snippets;
	}

	/**
	 * Sort snippets by name.
	 *
	 * @return int
	 */
	public static function sort_snippet_callback( $a, $b ) {
		return $a['Name'] > $b['Name'] ? 1 : - 1;
	}

	/**
	 * A very simple CSS sanitization function.
	 *
	 * @return string
	 */
	public static function sanitize_css( $css ) {
		return trim( strip_tags( $css ) );
	}

	/**
	 * Get all the available theme CSS
	 */
	public function get_theme_css() {
		$css = '';

		if ( file_exists( get_template_directory() . '/style.css' ) ) {
			$css .= file_get_contents( get_template_directory() . '/style.css' );
		}

		if ( is_child_theme() ) {
			$css .= file_get_contents( get_stylesheet_directory() . '/style.css' );
		}

		// Remove all CSS comments
		$regex = array(
			"`^([\t\s]+)`ism"                             => '',
			"`^\/\*(.+?)\*\/`ism"                         => '',
			"`(\A|[\n;]+)/\*[^*]*\*+(?:[^/*][^*]*\*+)*/`" => '$1',
			"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"       => "\n",
		);
		$css = preg_replace( array_keys( $regex ), $regex, $css );
		$css = preg_replace( '/\s+/', ' ', $css );

		return $css;
	}

	public function enqueue_inspector_scripts() {
		if ( ! current_user_can( 'edit_theme_options' ) ) {
			return;
		}

		wp_enqueue_style( 'dashicons' );

		wp_enqueue_script( 'siteorigin-css-parser-lib', plugin_dir_url( __FILE__ ) . 'js/css' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), SOCSS_VERSION );

		wp_enqueue_script( 'siteorigin-css-sizes', plugin_dir_url( __FILE__ ) . 'js/jquery.sizes' . SOCSS_JS_SUFFIX . '.js', array( 'jquery' ), '0.33' );
		wp_enqueue_script( 'siteorigin-css-specificity', plugin_dir_url( __FILE__ ) . 'js/specificity' . SOCSS_JS_SUFFIX . '.js', array() );
		wp_enqueue_script( 'siteorigin-css-inspector', plugin_dir_url( __FILE__ ) . 'js/inspector' . SOCSS_JS_SUFFIX . '.js', array(
			'jquery',
			'underscore',
			'backbone',
		), SOCSS_VERSION, true );
		wp_enqueue_style( 'siteorigin-css-inspector', plugin_dir_url( __FILE__ ) . 'css/inspector.css', array(), SOCSS_VERSION );

		wp_localize_script( 'siteorigin-css-inspector', 'socssOptions', array() );
	}

	public function inspector_templates() {
		if ( ! current_user_can( 'edit_theme_options' ) ) {
			return;
		}

		include plugin_dir_path( __FILE__ ) . 'tpl/inspector-templates.php';
	}

	/**
	 * Change the stylesheets to all be inline
	 */
	public function inline_inspector_scripts() {
		if ( ! current_user_can( 'edit_theme_options' ) ) {
			return;
		}

		$regex = array(
			"`^([\t\s]+)`ism"                             => '',
			"`^\/\*(.+?)\*\/`ism"                         => '',
			"`(\A|[\n;]+)/\*[^*]*\*+(?:[^/*][^*]*\*+)*/`" => '$1',
			"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"       => "\n",
		);

		global $wp_styles;

		if ( empty( $wp_styles->queue ) ) {
			return;
		}

		// Make each of the scripts inline
		foreach ( $wp_styles->queue as $handle ) {
			if ( $handle === 'siteorigin-css-inspector' || $handle === 'dashicons' ) {
				continue;
			}
			$style = $wp_styles->registered[ $handle ];

			if ( empty( $style->src ) || substr( $style->src, 0, 4 ) !== 'http' ) {
				continue;
			}
			$response = wp_remote_get( $style->src );

			if ( is_wp_error( $response ) || $response['response']['code'] !== 200 || empty( $response['body'] ) ) {
				continue;
			}

			$css = $response['body'];
			$css = preg_replace( array_keys( $regex ), $regex, $css );

			?>
			<script type="text/css" class="socss-theme-styles"
					id="socss-inlined-style-<?php echo sanitize_html_class( $handle ); ?>">
				<?php echo strip_tags( $css ); ?>
			</script>
			<?php
		}
	}

	public function disable_ngg_resource_manager() {
		if ( ! current_user_can( 'edit_theme_options' ) ) {
			return;
		}

		//The NextGen Gallery plugin does some weird interfering with the output buffer.
		define( 'NGG_DISABLE_RESOURCE_MANAGER', true );
	}

	private function get_latest_revision_timestamp() {
		$revisions = $this->get_custom_css_revisions( $this->theme );

		if ( empty( $revisions ) ) {
			return false;
		}
		krsort( $revisions );
		$revision_times = array_keys( $revisions );

		return $revision_times[0];
	}
}

// Initialize the single
SiteOrigin_CSS::single();
�0OS/2c�`cmap�ڈ��gasp�glyfc���head#��6hheao�$hmtxO]L(`loca0�,d�2maxp�� name�J	���postd ��������3	@�m�n�m� � ���3�9�h�n��������� ���1�6�e�n����������������G:
��797979���  0'.#!"3!2654&'"&54632#!"&=463!2b�
'�5KK5�5K
�^5KK55KK�
�@

�
^�
K5��5KK5�(
��K55KK55K�

�

E����#"'&54?632632����N�vN�M�wN���	k2327&'767676767673"'&#"#4?276727676767654'&'&'%3"'&#"##�a;;!18�b


��Iu*)'($HI$,OPK��!BC!
->!���r��-`���-gf6??!		..78!OO		��%=�3254'&'&'&'&'&#"3276767654'&'&'&#"76767676767654='&'&'&'&'&#'67632332#"'&#"=*&�!*&/##!!&-��	((

8��K
(&&$#
	

X;;"!.-00522<ss�A&
	<=""�!!0(:9
�6	

&10#$+		98U:--��IN767676767676=&'&'&'73276767"#"'&#&#"
++##22$#!(())#"

`!!O'54V1%����;

	T��0	
��(<Q%#!"'&=4763!2'#!"'&=4763!27#!"'&=4763!2'#!"'&=4763!2�J���%����m�
�n�
`II�I

I�II

�I

I��(<Q%#!"'&=4763!2'#!"'&=4763!27#!"'&=4763!2'#!"'&=4763!2�J������$�
��

n
`II�I

I�II

�I

I��(<P%#!"'&=4763!25#!"'&=4763!25#!"'&=4763!25#!"'&=4763!2�J��%���m�n

�`II�I

I�II

�I

I��(<P%#!"'&=4763!25#!"'&=4763!25#!"'&=4763!25#!"'&=4763!2�J��J��J��J�`II�I

I�II

�I

I��n?#!"'&5476327632#"/#"/&54?'&54763!2��R�S�A�R�A�S

�S

R�A�
R�A�S
��f?#"/#"/&54?'&54763!2#!"'&5476327632�
S�A�R
��R�R�B;�R�A�S��SR�A��%,++"'&=#"'&=476;5476;232%�n��n��m��m��%�#!"'&=4763!2%�I��mm���0I&'#"'&54732764'&#"3276547632765#"'&'&54767632�W�#KKjjKK#�WLsr��rs��G43##1�P������PP������P;�C;EjKKKKjE;C�uEFFEQ33G1#"��POPO��OPPO����;!@\%4'&#"3276534'&#"327657#!"'&=476;;276732++"'&5#"'&7632�

�

I���#�"��
��
�	







���  r�



���;n2#!"'&=4763!%&'&547632/&'&#"!3#"/&'&=4'&?5732767654'&'��$�&
ML�C&?03EB&'&&y(;!�W"�
)-*.FA/P 	:		$")%+,.;`%%%84gII.F"U 4"!2*&'#
�@9 

	>!"#'0*��nh|&/6323276727#"327676767654'&'&/&'&'737#"'&'&'&=4'&'54'&#!"3!276"K1/B "%"#23;2 

90u+E
)*+=>T_CD"#
	
FS��I�2$C��G-"
 ")Y.**1!'1	�p>+%! *,D.Y�k��%%���%!!3%!!2765#!"'&54763!2[\����[I&�%%&�����m��J&&�&��n1"32767654'&'&##"'&'&54767632�UGH)**)HGUTHG****GHT�;;eewxde;;;;edxwee;;�**GGUUGG****GGUUGG**��wee;;;;eewwee;;;;eew�``+1#"/+'7547'&54?6327632	'3�66�;x<��t�%IY<x<5LL5�[In��n*5LL5<x<��I%�tY<x;�66��In��nHE��_<��so��so��``m�n�E�%I%%��
h�:|�d�D�>`�R���2���`6uK
�		g	=	|	 	R	
4�icomoonicomoonVersion 1.0Version 1.0icomoonicomoonicomoonicomoonRegularRegularicomoonicomoonFont generated by IcoMoon.Font generated by IcoMoon.{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M866.2 258.2l-167.8-167.8c-13.8-13.76-44.2-26.4-66.2-26.4h-504.2c-70.7 0-128 57.3-128 128v640c0 70.7 57.3 128 128 128h640c70.7 0 128-57.3 128-128v-504.2c0-22-12.6-52.4-29.8-69.6zM448 832c-70.68 0-128-57.32-128-128s57.32-128 128-128 128 57.32 128 128-57.4 128-128 128zM640 416c0 17.6-14.4 32-32 32h-448c-17.68 0-32-14.4-32-32v-192c0-17.6 14.32-32 32-32h448c17.6 0 32 14.4 32 32v192z"],"attrs":[{}],"width":896,"isMulticolor":false,"isMulticolor2":false,"grid":0,"tags":["floppy-disk-solid"]},"attrs":[{}],"properties":{"order":34,"id":520,"name":"floppy-disk-solid","prevSize":32,"code":59648},"setIdx":0,"setId":2,"iconIdx":0},{"icon":{"paths":["M954.857 323.429q0 22.857-16 38.857l-491.429 491.429q-16 16-38.857 16t-38.857-16l-284.571-284.571q-16-16-16-38.857t16-38.857l77.714-77.714q16-16 38.857-16t38.857 16l168 168.571 374.857-375.429q16-16 38.857-16t38.857 16l77.714 77.714q16 16 16 38.857z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61452,"grid":0},"properties":{"id":13,"order":2,"ligatures":"","prevSize":32,"code":61452,"name":"check"},"setIdx":0,"setId":2,"iconIdx":1},{"icon":{"paths":["M414.286 319.429l-97.143 257.143q18.857 0 78 1.143t91.714 1.143q10.857 0 32.571-1.143-49.714-144.571-105.143-258.286zM0 950.857l1.143-45.143q13.143-4 32-7.143t32.571-6 28.286-8.286 25.429-16.571 17.714-28.857l135.429-352 160-413.714h73.143q4.571 8 6.286 12l117.143 274.286q18.857 44.571 60.571 147.143t65.143 156.857q8.571 19.429 33.143 82.571t41.143 96.286q11.429 25.714 20 32.571 10.857 8.571 50.286 16.857t48 11.714q3.429 21.714 3.429 32.571 0 2.286-0.286 7.429t-0.286 7.429q-36 0-108.571-4.571t-109.143-4.571q-43.429 0-122.857 4t-101.714 4.571q0-24.571 2.286-44.571l74.857-16q0.571 0 7.143-1.429t8.857-2 8.286-2.571 8.571-3.714 6.286-4.571 5.143-6.286 1.429-8q0-9.143-17.714-55.143t-41.143-101.429-24-57.143l-257.143-1.143q-14.857 33.143-43.714 111.714t-28.857 92.857q0 12.571 8 21.429t24.857 14 27.714 7.714 32.571 4.857 23.429 2.286q0.571 10.857 0.571 33.143 0 5.143-1.143 15.429-33.143 0-99.714-5.714t-99.714-5.714q-4.571 0-15.143 2.286t-12.286 2.286q-45.714 8-107.429 8z"],"width":951,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61489,"grid":0},"properties":{"id":47,"order":35,"ligatures":"","prevSize":32,"code":61489,"name":"uniF031"},"setIdx":0,"setId":2,"iconIdx":2},{"icon":{"paths":["M317.143 869.143q42.286 18.286 80 18.286 214.857 0 214.857-191.429 0-65.143-23.429-102.857-15.429-25.143-35.143-42.286t-38.571-26.571-46-14.286-48-6-54-1.143q-41.714 0-57.714 5.714 0 30.286-0.286 90.857t-0.286 90.286q0 4.571-0.571 38.571t-0.286 55.143 2.571 47.714 6.857 38zM309.143 442.857q24 4 62.286 4 46.857 0 81.714-7.429t62.857-25.429 42.571-51.143 14.571-81.143q0-40-16.571-70t-45.143-46.857-61.714-24.857-70.857-8q-28.571 0-74.286 7.429 0 28.571 2.286 86.286t2.286 86.857q0 15.429-0.286 45.714t-0.286 45.143q0 26.286 0.571 39.429zM0 950.857l1.143-53.714q8.571-2.286 48.571-9.143t60.571-15.429q4-6.857 7.143-15.429t4.857-19.143 3.143-18.571 1.714-21.429 0.286-19.429v-37.429q0-561.143-12.571-585.714-2.286-4.571-12.571-8.286t-25.429-6.286-28.286-4-27.714-2.571-17.429-1.714l-2.286-47.429q56-1.143 194.286-6.571t213.143-5.429q13.143 0 39.143 0.286t38.571 0.286q40 0 78 7.429t73.429 24 61.714 40.571 42.286 59.714 16 78.571q0 29.714-9.429 54.571t-22.286 41.143-36.857 32.857-41.714 25.714-48 22.857q88 20 146.571 76.571t58.571 141.714q0 57.143-20 102.571t-53.429 74.571-78.857 48.857-93.429 27.714-100.571 8q-25.143 0-75.429-1.714t-75.429-1.714q-60.571 0-175.429 6.286t-132 6.857z"],"width":805,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61490,"grid":0},"properties":{"id":48,"order":36,"ligatures":"","prevSize":32,"code":61490,"name":"uniF032"},"setIdx":0,"setId":2,"iconIdx":3},{"icon":{"paths":["M0 949.714l9.714-48.571q3.429-1.143 46.571-12.286t63.714-21.429q16-20 23.429-57.714 0.571-4 35.429-165.143t65.143-310.571 29.714-169.429v-14.286q-13.714-7.429-31.143-10.571t-39.714-4.571-33.143-3.143l10.857-58.857q18.857 1.143 68.571 3.714t85.429 4 68.857 1.429q27.429 0 56.286-1.429t69.143-4 56.286-3.714q-2.857 22.286-10.857 50.857-17.143 5.714-58 16.286t-62 19.143q-4.571 10.857-8 24.286t-5.143 22.857-4.286 26-3.714 24q-15.429 84.571-50 239.714t-44.286 203.143q-1.143 5.143-7.429 33.143t-11.429 51.429-9.143 47.714-3.429 32.857l0.571 10.286q9.714 2.286 105.714 17.714-1.714 25.143-9.143 56.571-6.286 0-18.571 0.857t-18.571 0.857q-16.571 0-49.714-5.714t-49.143-5.714q-78.857-1.143-117.714-1.143-29.143 0-81.714 5.143t-69.143 6.286z"],"width":585,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61491,"grid":0},"properties":{"id":49,"order":37,"ligatures":"","prevSize":32,"code":61491,"name":"uniF033"},"setIdx":0,"setId":2,"iconIdx":4},{"icon":{"paths":["M1024 768v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM804.571 548.571v73.143q0 14.857-10.857 25.714t-25.714 10.857h-731.429q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h731.429q14.857 0 25.714 10.857t10.857 25.714zM950.857 329.143v73.143q0 14.857-10.857 25.714t-25.714 10.857h-877.714q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h877.714q14.857 0 25.714 10.857t10.857 25.714zM731.429 109.714v73.143q0 14.857-10.857 25.714t-25.714 10.857h-658.286q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h658.286q14.857 0 25.714 10.857t10.857 25.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61494,"grid":0},"properties":{"id":52,"order":40,"ligatures":"","prevSize":32,"code":61494,"name":"uniF036"},"setIdx":0,"setId":2,"iconIdx":5},{"icon":{"paths":["M1024 768v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM804.571 548.571v73.143q0 14.857-10.857 25.714t-25.714 10.857h-512q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h512q14.857 0 25.714 10.857t10.857 25.714zM950.857 329.143v73.143q0 14.857-10.857 25.714t-25.714 10.857h-804.571q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h804.571q14.857 0 25.714 10.857t10.857 25.714zM731.429 109.714v73.143q0 14.857-10.857 25.714t-25.714 10.857h-365.714q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h365.714q14.857 0 25.714 10.857t10.857 25.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61495,"grid":0},"properties":{"id":53,"order":38,"ligatures":"","prevSize":32,"code":61495,"name":"uniF037"},"setIdx":0,"setId":2,"iconIdx":6},{"icon":{"paths":["M1024 768v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM1024 548.571v73.143q0 14.857-10.857 25.714t-25.714 10.857h-731.429q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h731.429q14.857 0 25.714 10.857t10.857 25.714zM1024 329.143v73.143q0 14.857-10.857 25.714t-25.714 10.857h-877.714q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h877.714q14.857 0 25.714 10.857t10.857 25.714zM1024 109.714v73.143q0 14.857-10.857 25.714t-25.714 10.857h-658.286q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h658.286q14.857 0 25.714 10.857t10.857 25.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61496,"grid":0},"properties":{"id":54,"order":39,"ligatures":"","prevSize":32,"code":61496,"name":"uniF038"},"setIdx":0,"setId":2,"iconIdx":7},{"icon":{"paths":["M1024 768v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM1024 548.571v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM1024 329.143v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714zM1024 109.714v73.143q0 14.857-10.857 25.714t-25.714 10.857h-950.857q-14.857 0-25.714-10.857t-10.857-25.714v-73.143q0-14.857 10.857-25.714t25.714-10.857h950.857q14.857 0 25.714 10.857t10.857 25.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61497,"grid":0},"properties":{"id":55,"order":41,"ligatures":"","prevSize":32,"code":61497,"name":"uniF039"},"setIdx":0,"setId":2,"iconIdx":8},{"icon":{"paths":["M431.429 603.429q0 7.429-5.714 13.143l-189.714 189.714 82.286 82.286q10.857 10.857 10.857 25.714t-10.857 25.714-25.714 10.857h-256q-14.857 0-25.714-10.857t-10.857-25.714v-256q0-14.857 10.857-25.714t25.714-10.857 25.714 10.857l82.286 82.286 189.714-189.714q5.714-5.714 13.143-5.714t13.143 5.714l65.143 65.143q5.714 5.714 5.714 13.143zM877.714 109.714v256q0 14.857-10.857 25.714t-25.714 10.857-25.714-10.857l-82.286-82.286-189.714 189.714q-5.714 5.714-13.143 5.714t-13.143-5.714l-65.143-65.143q-5.714-5.714-5.714-13.143t5.714-13.143l189.714-189.714-82.286-82.286q-10.857-10.857-10.857-25.714t10.857-25.714 25.714-10.857h256q14.857 0 25.714 10.857t10.857 25.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61541,"grid":0},"properties":{"id":96,"order":42,"ligatures":"","prevSize":32,"code":61541,"name":"uniF065"},"setIdx":0,"setId":2,"iconIdx":9},{"icon":{"paths":["M438.857 548.571v256q0 14.857-10.857 25.714t-25.714 10.857-25.714-10.857l-82.286-82.286-189.714 189.714q-5.714 5.714-13.143 5.714t-13.143-5.714l-65.143-65.143q-5.714-5.714-5.714-13.143t5.714-13.143l189.714-189.714-82.286-82.286q-10.857-10.857-10.857-25.714t10.857-25.714 25.714-10.857h256q14.857 0 25.714 10.857t10.857 25.714zM870.286 164.571q0 7.429-5.714 13.143l-189.714 189.714 82.286 82.286q10.857 10.857 10.857 25.714t-10.857 25.714-25.714 10.857h-256q-14.857 0-25.714-10.857t-10.857-25.714v-256q0-14.857 10.857-25.714t25.714-10.857 25.714 10.857l82.286 82.286 189.714-189.714q5.714-5.714 13.143-5.714t13.143 5.714l65.143 65.143q5.714 5.714 5.714 13.143z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61542,"grid":0},"properties":{"id":97,"order":43,"ligatures":"","prevSize":32,"code":61542,"name":"uniF066"},"setIdx":0,"setId":2,"iconIdx":10},{"icon":{"paths":["M804.571 420.571v109.714q0 22.857-16 38.857t-38.857 16h-237.714v237.714q0 22.857-16 38.857t-38.857 16h-109.714q-22.857 0-38.857-16t-16-38.857v-237.714h-237.714q-22.857 0-38.857-16t-16-38.857v-109.714q0-22.857 16-38.857t38.857-16h237.714v-237.714q0-22.857 16-38.857t38.857-16h109.714q22.857 0 38.857 16t16 38.857v237.714h237.714q22.857 0 38.857 16t16 38.857z"],"width":805,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61543,"grid":0},"properties":{"id":98,"order":44,"ligatures":"","prevSize":32,"code":61543,"name":"plus"},"setIdx":0,"setId":2,"iconIdx":11},{"icon":{"paths":["M804.571 420.571v109.714q0 22.857-16 38.857t-38.857 16h-694.857q-22.857 0-38.857-16t-16-38.857v-109.714q0-22.857 16-38.857t38.857-16h694.857q22.857 0 38.857 16t16 38.857z"],"width":805,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61544,"grid":0},"properties":{"id":99,"order":45,"ligatures":"","prevSize":32,"code":61544,"name":"minus"},"setIdx":0,"setId":2,"iconIdx":12},{"icon":{"paths":["M950.857 548.571q-86.857-134.857-217.714-201.714 34.857 59.429 34.857 128.571 0 105.714-75.143 180.857t-180.857 75.143-180.857-75.143-75.143-180.857q0-69.143 34.857-128.571-130.857 66.857-217.714 201.714 76 117.143 190.571 186.571t248.286 69.429 248.286-69.429 190.571-186.571zM539.429 329.143q0-11.429-8-19.429t-19.429-8q-71.429 0-122.571 51.143t-51.143 122.571q0 11.429 8 19.429t19.429 8 19.429-8 8-19.429q0-49.143 34.857-84t84-34.857q11.429 0 19.429-8t8-19.429zM1024 548.571q0 19.429-11.429 39.429-80 131.429-215.143 210.571t-285.429 79.143-285.429-79.429-215.143-210.286q-11.429-20-11.429-39.429t11.429-39.429q80-130.857 215.143-210.286t285.429-79.429 285.429 79.429 215.143 210.286q11.429 20 11.429 39.429z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61550,"grid":0},"properties":{"id":105,"order":33,"ligatures":"","prevSize":32,"code":61550,"name":"uniF06E"},"setIdx":0,"setId":2,"iconIdx":13},{"icon":{"paths":["M27.429 127.429q-21.143-1.143-25.714-2.286l-1.714-50.286q7.429-0.571 22.857-0.571 34.286 0 64 2.286 75.429 4 94.857 4 49.143 0 96-1.714 66.286-2.286 83.429-2.857 32 0 49.143-1.143l-0.571 8 1.143 36.571v5.143q-34.286 5.143-70.857 5.143-34.286 0-45.143 14.286-7.429 8-7.429 75.429 0 7.429 0.286 18.571t0.286 14.571l0.571 130.857 8 160q3.429 70.857 29.143 115.429 20 33.714 54.857 52.571 50.286 26.857 101.143 26.857 59.429 0 109.143-16 32-10.286 56.571-29.143 27.429-20.571 37.143-36.571 20.571-32 30.286-65.143 12-41.714 12-130.857 0-45.143-2-73.143t-6.286-70-7.714-91.143l-2.286-33.714q-2.857-38.286-13.714-50.286-19.429-20-44-19.429l-57.143 1.143-8-1.714 1.143-49.143h48l117.143 5.714q43.429 1.714 112-5.714l10.286 1.143q3.429 21.714 3.429 29.143 0 4-2.286 17.714-25.714 6.857-48 7.429-41.714 6.286-45.143 9.714-8.571 8.571-8.571 23.429 0 4 0.857 15.429t0.857 17.714q4.571 10.857 12.571 226.286 3.429 111.429-8.571 173.714-8.571 43.429-23.429 69.714-21.714 37.143-64 70.286-42.857 32.571-104 50.857-62.286 18.857-145.714 18.857-95.429 0-162.286-26.286-68-26.857-102.286-69.714-34.857-43.429-47.429-111.429-9.143-45.714-9.143-135.429v-190.286q0-107.429-9.714-121.714-14.286-20.571-84-22.286zM877.714 932.571v-36.571q0-8-5.143-13.143t-13.143-5.143h-841.143q-8 0-13.143 5.143t-5.143 13.143v36.571q0 8 5.143 13.143t13.143 5.143h841.143q8 0 13.143-5.143t5.143-13.143z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61645,"grid":0},"properties":{"id":182,"order":12,"ligatures":"","prevSize":32,"code":61645,"name":"uniF0CD"},"setIdx":0,"setId":2,"iconIdx":14},{"icon":{"paths":["M1005.714 512q8 0 13.143 5.143t5.143 13.143v36.571q0 8-5.143 13.143t-13.143 5.143h-987.429q-8 0-13.143-5.143t-5.143-13.143v-36.571q0-8 5.143-13.143t13.143-5.143h987.429zM276 475.429q-16-20-29.143-45.714-27.429-55.429-27.429-107.429 0-103.429 76.571-176.571 76-72.571 224.571-72.571 28.571 0 95.429 10.857 37.714 6.857 101.143 27.429 5.714 21.714 12 67.429 8 70.286 8 104.571 0 10.286-2.857 25.714l-6.857 1.714-48-3.429-8-1.143q-28.571-85.143-58.857-117.143-50.286-52-120-52-65.143 0-104 33.714-38.286 33.143-38.286 83.429 0 41.714 37.714 80t159.429 73.714q39.429 11.429 98.857 37.714 33.143 16 54.286 29.714h-424.571zM565.714 621.714h234.857q4 22.286 4 52.571 0 63.429-23.429 121.143-13.143 31.429-40.571 59.429-21.143 20-62.286 46.286-45.714 27.429-87.429 37.714-45.714 12-116 12-65.143 0-111.429-13.143l-80-22.857q-32.571-9.143-41.143-16-4.571-4.571-4.571-12.571v-7.429q0-61.714-1.143-89.143-0.571-17.143 0-38.857l1.143-21.143v-25.143l58.286-1.143q8.571 19.429 17.143 40.571t12.857 32 7.143 15.429q20 32.571 45.714 53.714 24.571 20.571 60 32.571 33.714 12.571 75.429 12.571 36.571 0 79.429-15.429 44-14.857 69.714-49.143 26.857-34.857 26.857-73.714 0-48-46.286-89.714-19.429-16.571-78.286-40.571z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61644,"grid":0},"properties":{"id":181,"order":11,"ligatures":"","prevSize":32,"code":61644,"name":"uniF0CC"},"setIdx":0,"setId":2,"iconIdx":15},{"icon":{"paths":["M91.429 877.714h347.429v-658.286h-365.714v640q0 7.429 5.429 12.857t12.857 5.429zM877.714 859.429v-640h-365.714v658.286h347.429q7.429 0 12.857-5.429t5.429-12.857zM950.857 164.571v694.857q0 37.714-26.857 64.571t-64.571 26.857h-768q-37.714 0-64.571-26.857t-26.857-64.571v-694.857q0-37.714 26.857-64.571t64.571-26.857h768q37.714 0 64.571 26.857t26.857 64.571z"],"width":951,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61659,"grid":0},"properties":{"id":195,"order":13,"ligatures":"","prevSize":32,"code":61659,"name":"uniF0DB"},"setIdx":0,"setId":2,"iconIdx":16},{"icon":{"paths":["M438.857 201.143q-84.571 0-156 41.714t-113.143 113.143-41.714 156 41.714 156 113.143 113.143 156 41.714 156-41.714 113.143-113.143 41.714-156-41.714-156-113.143-113.143-156-41.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61708,"grid":0},"properties":{"id":241,"order":19,"ligatures":"","prevSize":32,"code":61708,"name":"uniF10C"},"setIdx":0,"setId":2,"iconIdx":17},{"icon":{"paths":["M970.286 53.714q53.714 53.714 53.714 129.429t-53.714 128.857l-128.571 127.429 59.429 59.429q5.714 5.714 5.714 13.143t-5.714 13.143l-120 120q-5.714 5.714-13.143 5.714t-13.143-5.714l-60-60-344.571 344.571q-21.143 21.143-51.429 21.143h-116l-146.286 73.143-36.571-36.571 73.143-146.286v-116q0-30.286 21.143-51.429l344.571-344.571-60-60q-5.714-5.714-5.714-13.143t5.714-13.143l120-120q5.714-5.714 13.143-5.714t13.143 5.714l59.429 59.429 127.429-128.571q53.143-53.714 128.857-53.714t129.429 53.714zM292.571 841.143l329.143-329.143-109.714-109.714-329.143 329.143v109.714h109.714z"],"isMulticolor":false,"isMulticolor2":false,"defaultCode":61947,"grid":0},"properties":{"id":463,"order":14,"ligatures":"","prevSize":32,"code":61947,"name":"uniF1FB"},"setIdx":0,"setId":2,"iconIdx":18},{"icon":{"paths":["M731.429 841.143q0-14.857-10.857-25.714t-25.714-10.857-25.714 10.857-10.857 25.714 10.857 25.714 25.714 10.857 25.714-10.857 10.857-25.714zM877.714 841.143q0-14.857-10.857-25.714t-25.714-10.857-25.714 10.857-10.857 25.714 10.857 25.714 25.714 10.857 25.714-10.857 10.857-25.714zM950.857 713.143v182.857q0 22.857-16 38.857t-38.857 16h-841.143q-22.857 0-38.857-16t-16-38.857v-182.857q0-22.857 16-38.857t38.857-16h244q12 32 40.286 52.571t63.143 20.571h146.286q34.857 0 63.143-20.571t40.286-52.571h244q22.857 0 38.857 16t16 38.857zM765.143 342.857q-9.714 22.857-33.714 22.857h-146.286v256q0 14.857-10.857 25.714t-25.714 10.857h-146.286q-14.857 0-25.714-10.857t-10.857-25.714v-256h-146.286q-24 0-33.714-22.857-9.714-22.286 8-39.429l256-256q10.286-10.857 25.714-10.857t25.714 10.857l256 256q17.714 17.143 8 39.429z"],"width":951,"isMulticolor":false,"isMulticolor2":false,"defaultCode":61587,"grid":0},"properties":{"id":139,"order":32,"ligatures":"","prevSize":32,"code":61587,"name":"uniF093"},"setIdx":0,"setId":2,"iconIdx":19}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon","majorVersion":1,"minorVersion":0},"metrics":{"emSize":1024,"baseline":14.285714285714285,"whitespace":25},"embed":false,"noie8":true,"ie7":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215,"classSelector":".icon"},"historySize":50,"showCodes":true,"gridSize":16}}<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="877.7142857142858" descent="-146.28571428571428" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="256" d="" />
<glyph unicode="&#xe900;" glyph-name="floppy-disk-solid" horiz-adv-x="896" d="M866.2 605.8l-167.8 167.8c-13.8 13.76-44.2 26.4-66.2 26.4h-504.2c-70.7 0-128-57.3-128-128v-640c0-70.7 57.3-128 128-128h640c70.7 0 128 57.3 128 128v504.2c0 22-12.6 52.4-29.8 69.6zM448 32c-70.68 0-128 57.32-128 128s57.32 128 128 128 128-57.32 128-128-57.4-128-128-128zM640 448c0-17.6-14.4-32-32-32h-448c-17.68 0-32 14.4-32 32v192c0 17.6 14.32 32 32 32h448c17.6 0 32-14.4 32-32v-192z" />
<glyph unicode="&#xf00c;" glyph-name="check" d="M954.857 540.571q0-22.857-16-38.857l-491.429-491.429q-16-16-38.857-16t-38.857 16l-284.571 284.571q-16 16-16 38.857t16 38.857l77.714 77.714q16 16 38.857 16t38.857-16l168-168.571 374.857 375.429q16 16 38.857 16t38.857-16l77.714-77.714q16-16 16-38.857z" />
<glyph unicode="&#xf031;" glyph-name="uniF031" horiz-adv-x="951" d="M414.286 544.571l-97.143-257.143q18.857 0 78-1.143t91.714-1.143q10.857 0 32.571 1.143-49.714 144.571-105.143 258.286zM0-86.857l1.143 45.143q13.143 4 32 7.143t32.571 6 28.286 8.286 25.429 16.571 17.714 28.857l135.429 352 160 413.714h73.143q4.571-8 6.286-12l117.143-274.286q18.857-44.571 60.571-147.143t65.143-156.857q8.571-19.429 33.143-82.571t41.143-96.286q11.429-25.714 20-32.571 10.857-8.571 50.286-16.857t48-11.714q3.429-21.714 3.429-32.571 0-2.286-0.286-7.429t-0.286-7.429q-36 0-108.571 4.571t-109.143 4.571q-43.429 0-122.857-4t-101.714-4.571q0 24.571 2.286 44.571l74.857 16q0.571 0 7.143 1.429t8.857 2 8.286 2.571 8.571 3.714 6.286 4.571 5.143 6.286 1.429 8q0 9.143-17.714 55.143t-41.143 101.429-24 57.143l-257.143 1.143q-14.857-33.143-43.714-111.714t-28.857-92.857q0-12.571 8-21.429t24.857-14 27.714-7.714 32.571-4.857 23.429-2.286q0.571-10.857 0.571-33.143 0-5.143-1.143-15.429-33.143 0-99.714 5.714t-99.714 5.714q-4.571 0-15.143-2.286t-12.286-2.286q-45.714-8-107.429-8z" />
<glyph unicode="&#xf032;" glyph-name="uniF032" horiz-adv-x="805" d="M317.143-5.143q42.286-18.286 80-18.286 214.857 0 214.857 191.429 0 65.143-23.429 102.857-15.429 25.143-35.143 42.286t-38.571 26.571-46 14.286-48 6-54 1.143q-41.714 0-57.714-5.714 0-30.286-0.286-90.857t-0.286-90.286q0-4.571-0.571-38.571t-0.286-55.143 2.571-47.714 6.857-38zM309.143 421.143q24-4 62.286-4 46.857 0 81.714 7.429t62.857 25.429 42.571 51.143 14.571 81.143q0 40-16.571 70t-45.143 46.857-61.714 24.857-70.857 8q-28.571 0-74.286-7.429 0-28.571 2.286-86.286t2.286-86.857q0-15.429-0.286-45.714t-0.286-45.143q0-26.286 0.571-39.429zM0-86.857l1.143 53.714q8.571 2.286 48.571 9.143t60.571 15.429q4 6.857 7.143 15.429t4.857 19.143 3.143 18.571 1.714 21.429 0.286 19.429v37.429q0 561.143-12.571 585.714-2.286 4.571-12.571 8.286t-25.429 6.286-28.286 4-27.714 2.571-17.429 1.714l-2.286 47.429q56 1.143 194.286 6.571t213.143 5.429q13.143 0 39.143-0.286t38.571-0.286q40 0 78-7.429t73.429-24 61.714-40.571 42.286-59.714 16-78.571q0-29.714-9.429-54.571t-22.286-41.143-36.857-32.857-41.714-25.714-48-22.857q88-20 146.571-76.571t58.571-141.714q0-57.143-20-102.571t-53.429-74.571-78.857-48.857-93.429-27.714-100.571-8q-25.143 0-75.429 1.714t-75.429 1.714q-60.571 0-175.429-6.286t-132-6.857z" />
<glyph unicode="&#xf033;" glyph-name="uniF033" horiz-adv-x="585" d="M0-85.714l9.714 48.571q3.429 1.143 46.571 12.286t63.714 21.429q16 20 23.429 57.714 0.571 4 35.429 165.143t65.143 310.571 29.714 169.429v14.286q-13.714 7.429-31.143 10.571t-39.714 4.571-33.143 3.143l10.857 58.857q18.857-1.143 68.571-3.714t85.429-4 68.857-1.429q27.429 0 56.286 1.429t69.143 4 56.286 3.714q-2.857-22.286-10.857-50.857-17.143-5.714-58-16.286t-62-19.143q-4.571-10.857-8-24.286t-5.143-22.857-4.286-26-3.714-24q-15.429-84.571-50-239.714t-44.286-203.143q-1.143-5.143-7.429-33.143t-11.429-51.429-9.143-47.714-3.429-32.857l0.571-10.286q9.714-2.286 105.714-17.714-1.714-25.143-9.143-56.571-6.286 0-18.571-0.857t-18.571-0.857q-16.571 0-49.714 5.714t-49.143 5.714q-78.857 1.143-117.714 1.143-29.143 0-81.714-5.143t-69.143-6.286z" />
<glyph unicode="&#xf036;" glyph-name="uniF036" d="M1024 96v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM804.571 315.429v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-731.429q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h731.429q14.857 0 25.714-10.857t10.857-25.714zM950.857 534.857v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-877.714q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h877.714q14.857 0 25.714-10.857t10.857-25.714zM731.429 754.286v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-658.286q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h658.286q14.857 0 25.714-10.857t10.857-25.714z" />
<glyph unicode="&#xf037;" glyph-name="uniF037" d="M1024 96v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM804.571 315.429v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-512q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h512q14.857 0 25.714-10.857t10.857-25.714zM950.857 534.857v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-804.571q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h804.571q14.857 0 25.714-10.857t10.857-25.714zM731.429 754.286v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-365.714q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h365.714q14.857 0 25.714-10.857t10.857-25.714z" />
<glyph unicode="&#xf038;" glyph-name="uniF038" d="M1024 96v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM1024 315.429v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-731.429q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h731.429q14.857 0 25.714-10.857t10.857-25.714zM1024 534.857v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-877.714q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h877.714q14.857 0 25.714-10.857t10.857-25.714zM1024 754.286v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-658.286q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h658.286q14.857 0 25.714-10.857t10.857-25.714z" />
<glyph unicode="&#xf039;" glyph-name="uniF039" d="M1024 96v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM1024 315.429v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM1024 534.857v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714zM1024 754.286v-73.143q0-14.857-10.857-25.714t-25.714-10.857h-950.857q-14.857 0-25.714 10.857t-10.857 25.714v73.143q0 14.857 10.857 25.714t25.714 10.857h950.857q14.857 0 25.714-10.857t10.857-25.714z" />
<glyph unicode="&#xf065;" glyph-name="uniF065" d="M431.429 260.571q0-7.429-5.714-13.143l-189.714-189.714 82.286-82.286q10.857-10.857 10.857-25.714t-10.857-25.714-25.714-10.857h-256q-14.857 0-25.714 10.857t-10.857 25.714v256q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857l82.286-82.286 189.714 189.714q5.714 5.714 13.143 5.714t13.143-5.714l65.143-65.143q5.714-5.714 5.714-13.143zM877.714 754.286v-256q0-14.857-10.857-25.714t-25.714-10.857-25.714 10.857l-82.286 82.286-189.714-189.714q-5.714-5.714-13.143-5.714t-13.143 5.714l-65.143 65.143q-5.714 5.714-5.714 13.143t5.714 13.143l189.714 189.714-82.286 82.286q-10.857 10.857-10.857 25.714t10.857 25.714 25.714 10.857h256q14.857 0 25.714-10.857t10.857-25.714z" />
<glyph unicode="&#xf066;" glyph-name="uniF066" d="M438.857 315.429v-256q0-14.857-10.857-25.714t-25.714-10.857-25.714 10.857l-82.286 82.286-189.714-189.714q-5.714-5.714-13.143-5.714t-13.143 5.714l-65.143 65.143q-5.714 5.714-5.714 13.143t5.714 13.143l189.714 189.714-82.286 82.286q-10.857 10.857-10.857 25.714t10.857 25.714 25.714 10.857h256q14.857 0 25.714-10.857t10.857-25.714zM870.286 699.429q0-7.429-5.714-13.143l-189.714-189.714 82.286-82.286q10.857-10.857 10.857-25.714t-10.857-25.714-25.714-10.857h-256q-14.857 0-25.714 10.857t-10.857 25.714v256q0 14.857 10.857 25.714t25.714 10.857 25.714-10.857l82.286-82.286 189.714 189.714q5.714 5.714 13.143 5.714t13.143-5.714l65.143-65.143q5.714-5.714 5.714-13.143z" />
<glyph unicode="&#xf067;" glyph-name="plus" horiz-adv-x="805" d="M804.571 443.429v-109.714q0-22.857-16-38.857t-38.857-16h-237.714v-237.714q0-22.857-16-38.857t-38.857-16h-109.714q-22.857 0-38.857 16t-16 38.857v237.714h-237.714q-22.857 0-38.857 16t-16 38.857v109.714q0 22.857 16 38.857t38.857 16h237.714v237.714q0 22.857 16 38.857t38.857 16h109.714q22.857 0 38.857-16t16-38.857v-237.714h237.714q22.857 0 38.857-16t16-38.857z" />
<glyph unicode="&#xf068;" glyph-name="minus" horiz-adv-x="805" d="M804.571 443.429v-109.714q0-22.857-16-38.857t-38.857-16h-694.857q-22.857 0-38.857 16t-16 38.857v109.714q0 22.857 16 38.857t38.857 16h694.857q22.857 0 38.857-16t16-38.857z" />
<glyph unicode="&#xf06e;" glyph-name="uniF06E" d="M950.857 315.429q-86.857 134.857-217.714 201.714 34.857-59.429 34.857-128.571 0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857q0 69.143 34.857 128.571-130.857-66.857-217.714-201.714 76-117.143 190.571-186.571t248.286-69.429 248.286 69.429 190.571 186.571zM539.429 534.857q0 11.429-8 19.429t-19.429 8q-71.429 0-122.571-51.143t-51.143-122.571q0-11.429 8-19.429t19.429-8 19.429 8 8 19.429q0 49.143 34.857 84t84 34.857q11.429 0 19.429 8t8 19.429zM1024 315.429q0-19.429-11.429-39.429-80-131.429-215.143-210.571t-285.429-79.143-285.429 79.429-215.143 210.286q-11.429 20-11.429 39.429t11.429 39.429q80 130.857 215.143 210.286t285.429 79.429 285.429-79.429 215.143-210.286q11.429-20 11.429-39.429z" />
<glyph unicode="&#xf093;" glyph-name="uniF093" horiz-adv-x="951" d="M731.429 22.857q0 14.857-10.857 25.714t-25.714 10.857-25.714-10.857-10.857-25.714 10.857-25.714 25.714-10.857 25.714 10.857 10.857 25.714zM877.714 22.857q0 14.857-10.857 25.714t-25.714 10.857-25.714-10.857-10.857-25.714 10.857-25.714 25.714-10.857 25.714 10.857 10.857 25.714zM950.857 150.857v-182.857q0-22.857-16-38.857t-38.857-16h-841.143q-22.857 0-38.857 16t-16 38.857v182.857q0 22.857 16 38.857t38.857 16h244q12-32 40.286-52.571t63.143-20.571h146.286q34.857 0 63.143 20.571t40.286 52.571h244q22.857 0 38.857-16t16-38.857zM765.143 521.143q-9.714-22.857-33.714-22.857h-146.286v-256q0-14.857-10.857-25.714t-25.714-10.857h-146.286q-14.857 0-25.714 10.857t-10.857 25.714v256h-146.286q-24 0-33.714 22.857-9.714 22.286 8 39.429l256 256q10.286 10.857 25.714 10.857t25.714-10.857l256-256q17.714-17.143 8-39.429z" />
<glyph unicode="&#xf0cc;" glyph-name="uniF0CC" d="M1005.714 352q8 0 13.143-5.143t5.143-13.143v-36.571q0-8-5.143-13.143t-13.143-5.143h-987.429q-8 0-13.143 5.143t-5.143 13.143v36.571q0 8 5.143 13.143t13.143 5.143h987.429zM276 388.571q-16 20-29.143 45.714-27.429 55.429-27.429 107.429 0 103.429 76.571 176.571 76 72.571 224.571 72.571 28.571 0 95.429-10.857 37.714-6.857 101.143-27.429 5.714-21.714 12-67.429 8-70.286 8-104.571 0-10.286-2.857-25.714l-6.857-1.714-48 3.429-8 1.143q-28.571 85.143-58.857 117.143-50.286 52-120 52-65.143 0-104-33.714-38.286-33.143-38.286-83.429 0-41.714 37.714-80t159.429-73.714q39.429-11.429 98.857-37.714 33.143-16 54.286-29.714h-424.571zM565.714 242.286h234.857q4-22.286 4-52.571 0-63.429-23.429-121.143-13.143-31.429-40.571-59.429-21.143-20-62.286-46.286-45.714-27.429-87.429-37.714-45.714-12-116-12-65.143 0-111.429 13.143l-80 22.857q-32.571 9.143-41.143 16-4.571 4.571-4.571 12.571v7.429q0 61.714-1.143 89.143-0.571 17.143 0 38.857l1.143 21.143v25.143l58.286 1.143q8.571-19.429 17.143-40.571t12.857-32 7.143-15.429q20-32.571 45.714-53.714 24.571-20.571 60-32.571 33.714-12.571 75.429-12.571 36.571 0 79.429 15.429 44 14.857 69.714 49.143 26.857 34.857 26.857 73.714 0 48-46.286 89.714-19.429 16.571-78.286 40.571z" />
<glyph unicode="&#xf0cd;" glyph-name="uniF0CD" d="M27.429 736.571q-21.143 1.143-25.714 2.286l-1.714 50.286q7.429 0.571 22.857 0.571 34.286 0 64-2.286 75.429-4 94.857-4 49.143 0 96 1.714 66.286 2.286 83.429 2.857 32 0 49.143 1.143l-0.571-8 1.143-36.571v-5.143q-34.286-5.143-70.857-5.143-34.286 0-45.143-14.286-7.429-8-7.429-75.429 0-7.429 0.286-18.571t0.286-14.571l0.571-130.857 8-160q3.429-70.857 29.143-115.429 20-33.714 54.857-52.571 50.286-26.857 101.143-26.857 59.429 0 109.143 16 32 10.286 56.571 29.143 27.429 20.571 37.143 36.571 20.571 32 30.286 65.143 12 41.714 12 130.857 0 45.143-2 73.143t-6.286 70-7.714 91.143l-2.286 33.714q-2.857 38.286-13.714 50.286-19.429 20-44 19.429l-57.143-1.143-8 1.714 1.143 49.143h48l117.143-5.714q43.429-1.714 112 5.714l10.286-1.143q3.429-21.714 3.429-29.143 0-4-2.286-17.714-25.714-6.857-48-7.429-41.714-6.286-45.143-9.714-8.571-8.571-8.571-23.429 0-4 0.857-15.429t0.857-17.714q4.571-10.857 12.571-226.286 3.429-111.429-8.571-173.714-8.571-43.429-23.429-69.714-21.714-37.143-64-70.286-42.857-32.571-104-50.857-62.286-18.857-145.714-18.857-95.429 0-162.286 26.286-68 26.857-102.286 69.714-34.857 43.429-47.429 111.429-9.143 45.714-9.143 135.429v190.286q0 107.429-9.714 121.714-14.286 20.571-84 22.286zM877.714-68.571v36.571q0 8-5.143 13.143t-13.143 5.143h-841.143q-8 0-13.143-5.143t-5.143-13.143v-36.571q0-8 5.143-13.143t13.143-5.143h841.143q8 0 13.143 5.143t5.143 13.143z" />
<glyph unicode="&#xf0db;" glyph-name="uniF0DB" horiz-adv-x="951" d="M91.429-13.714h347.429v658.286h-365.714v-640q0-7.429 5.429-12.857t12.857-5.429zM877.714 4.571v640h-365.714v-658.286h347.429q7.429 0 12.857 5.429t5.429 12.857zM950.857 699.429v-694.857q0-37.714-26.857-64.571t-64.571-26.857h-768q-37.714 0-64.571 26.857t-26.857 64.571v694.857q0 37.714 26.857 64.571t64.571 26.857h768q37.714 0 64.571-26.857t26.857-64.571z" />
<glyph unicode="&#xf10c;" glyph-name="uniF10C" d="M438.857 662.857q-84.571 0-156-41.714t-113.143-113.143-41.714-156 41.714-156 113.143-113.143 156-41.714 156 41.714 113.143 113.143 41.714 156-41.714 156-113.143 113.143-156 41.714zM877.714 352q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
<glyph unicode="&#xf1fb;" glyph-name="uniF1FB" d="M970.286 810.286q53.714-53.714 53.714-129.429t-53.714-128.857l-128.571-127.429 59.429-59.429q5.714-5.714 5.714-13.143t-5.714-13.143l-120-120q-5.714-5.714-13.143-5.714t-13.143 5.714l-60 60-344.571-344.571q-21.143-21.143-51.429-21.143h-116l-146.286-73.143-36.571 36.571 73.143 146.286v116q0 30.286 21.143 51.429l344.571 344.571-60 60q-5.714 5.714-5.714 13.143t5.714 13.143l120 120q5.714 5.714 13.143 5.714t13.143-5.714l59.429-59.429 127.429 128.571q53.143 53.714 128.857 53.714t129.429-53.714zM292.571 22.857l329.143 329.143-109.714 109.714-329.143-329.143v-109.714h109.714z" />
</font></defs></svg>wOFF��OS/2``ccmaph���ڈ�gaspglyfc��head66#�hheaP$$o�hmtxt``O]Lloca�220�,dmaxp  �name(���J	�post�  ��������3	@�m�n�m� � ���3�9�h�n��������� ���1�6�e�n����������������G:
��797979���  0'.#!"3!2654&'"&54632#!"&=463!2b�
'�5KK5�5K
�^5KK55KK�
�@

�
^�
K5��5KK5�(
��K55KK55K�

�

E����#"'&54?632632����N�vN�M�wN���	k2327&'767676767673"'&#"#4?276727676767654'&'&'%3"'&#"##�a;;!18�b


��Iu*)'($HI$,OPK��!BC!
->!���r��-`���-gf6??!		..78!OO		��%=�3254'&'&'&'&'&#"3276767654'&'&'&#"76767676767654='&'&'&'&'&#'67632332#"'&#"=*&�!*&/##!!&-��	((

8��K
(&&$#
	

X;;"!.-00522<ss�A&
	<=""�!!0(:9
�6	

&10#$+		98U:--��IN767676767676=&'&'&'73276767"#"'&#&#"
++##22$#!(())#"

`!!O'54V1%����;

	T��0	
��(<Q%#!"'&=4763!2'#!"'&=4763!27#!"'&=4763!2'#!"'&=4763!2�J���%����m�
�n�
`II�I

I�II

�I

I��(<Q%#!"'&=4763!2'#!"'&=4763!27#!"'&=4763!2'#!"'&=4763!2�J������$�
��

n
`II�I

I�II

�I

I��(<P%#!"'&=4763!25#!"'&=4763!25#!"'&=4763!25#!"'&=4763!2�J��%���m�n

�`II�I

I�II

�I

I��(<P%#!"'&=4763!25#!"'&=4763!25#!"'&=4763!25#!"'&=4763!2�J��J��J��J�`II�I

I�II

�I

I��n?#!"'&5476327632#"/#"/&54?'&54763!2��R�S�A�R�A�S

�S

R�A�
R�A�S
��f?#"/#"/&54?'&54763!2#!"'&5476327632�
S�A�R
��R�R�B;�R�A�S��SR�A��%,++"'&=#"'&=476;5476;232%�n��n��m��m��%�#!"'&=4763!2%�I��mm���0I&'#"'&54732764'&#"3276547632765#"'&'&54767632�W�#KKjjKK#�WLsr��rs��G43##1�P������PP������P;�C;EjKKKKjE;C�uEFFEQ33G1#"��POPO��OPPO����;!@\%4'&#"3276534'&#"327657#!"'&=476;;276732++"'&5#"'&7632�

�

I���#�"��
��
�	







���  r�



���;n2#!"'&=4763!%&'&547632/&'&#"!3#"/&'&=4'&?5732767654'&'��$�&
ML�C&?03EB&'&&y(;!�W"�
)-*.FA/P 	:		$")%+,.;`%%%84gII.F"U 4"!2*&'#
�@9 

	>!"#'0*��nh|&/6323276727#"327676767654'&'&/&'&'737#"'&'&'&=4'&'54'&#!"3!276"K1/B "%"#23;2 

90u+E
)*+=>T_CD"#
	
FS��I�2$C��G-"
 ")Y.**1!'1	�p>+%! *,D.Y�k��%%���%!!3%!!2765#!"'&54763!2[\����[I&�%%&�����m��J&&�&��n1"32767654'&'&##"'&'&54767632�UGH)**)HGUTHG****GHT�;;eewxde;;;;edxwee;;�**GGUUGG****GGUUGG**��wee;;;;eewwee;;;;eew�``+1#"/+'7547'&54?6327632	'3�66�;x<��t�%IY<x<5LL5�[In��n*5LL5<x<��I%�tY<x;�66��In��nHE��_<��so��so��``m�n�E�%I%%��
h�:|�d�D�>`�R���2���`6uK
�		g	=	|	 	R	
4�icomoonicomoonVersion 1.0Version 1.0icomoonicomoonicomoonicomoonRegularRegularicomoonicomoonFont generated by IcoMoon.Font generated by IcoMoon.@font-face {
  font-family: 'SoCSSIcons';
  src: url('icons/so-css-icons.ttf?joepfs') format('truetype'), url('icons/so-css-icons.woff?joepfs') format('woff'), url('icons/so-css-icons.svg?joepfs#icomoon') format(' svg');
  font-weight: normal;
  font-style: normal;
  font-display: block;
}
.so-css-icon {
  display: inline-block;
  font: normal normal normal 14px/1 SoCSSIcons;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transform: translate(0, 0);
}
.so-css-icon-compress:before {
  content: "\f066";
}
.so-css-icon-plus:before {
  content: "\f067";
}
.so-css-icon-minus:before {
  content: "\f068";
}
.so-css-icon-check:before {
  content: "\f00c";
}
.so-css-icon-font:before {
  content: "\f031";
}
.so-css-icon-bold:before {
  content: "\f032";
}
.so-css-icon-italic:before {
  content: "\f033";
}
.so-css-icon-align-left:before {
  content: "\f036";
}
.so-css-icon-align-center:before {
  content: "\f037";
}
.so-css-icon-align-right:before {
  content: "\f038";
}
.so-css-icon-align-justify:before {
  content: "\f039";
}
.so-css-icon-expand:before {
  content: "\f065";
}
.so-css-icon-compress:before {
  content: "\f066";
}
.so-css-icon-eye:before {
  content: "\f06e";
}
.so-css-icon-upload:before {
  content: "\f093";
}
.so-css-icon-save:before {
  content: "\e900";
}
.so-css-icon-strikethrough:before {
  content: "\f0cc";
}
.so-css-icon-underline:before {
  content: "\f0cd";
}
.so-css-icon-columns:before {
  content: "\f0db";
}
.so-css-icon-circle:before {
  content: "\f10c";
}
.so-css-icon-eyedropper:before {
  content: "\f1fb";
}
#siteorigin-custom-css {
  color: #333;
  margin: 0 0 0 -20px;
}
#siteorigin-custom-css h2 {
  background: #f8f8f8;
  padding: 20px;
  border-bottom: 1px solid #d0d0d0;
  margin-bottom: 20px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.035);
}
#siteorigin-custom-css h2 .icon {
  width: 40px;
  height: auto;
  margin: -8px 10px -8px 0;
}
#siteorigin-custom-css .notice {
  margin: 0 20px 20px 20px;
}
#siteorigin-custom-css #poststuff {
  padding: 0 20px;
}
#siteorigin-custom-css #poststuff .postbox {
  border: 1px solid #D0D0D0;
}
#siteorigin-custom-css #poststuff .postbox h3.hndle {
  cursor: default;
  border-bottom: 1px solid #D0D0D0;
  background: #efefef;
  position: relative;
}
#siteorigin-custom-css #poststuff .postbox h3.hndle .hide {
  position: absolute;
  top: 50%;
  line-height: 1em;
  margin-top: -0.5em;
  right: 12px;
}
#siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside {
  padding: 0 6px 6px 6px;
}
#siteorigin-custom-css #poststuff #so-custom-css-getting-started .inside img {
  display: block;
  width: 100%;
  height: auto;
}
#so-custom-css-form {
  margin-right: 340px;
}
#so-custom-css-info {
  float: right;
  width: 315px;
}
#so-custom-css-info *:first-child {
  margin-top: 0;
}
#so-custom-css-info *:last-child {
  margin-bottom: 0;
}
#so-custom-css-info p.so-custom-css-submit {
  padding-top: 1px;
}
#so-custom-css-info p.so-custom-css-submit .button-primary {
  font-size: 14px;
  min-height: 40px;
  width: 100%;
}
#so-custom-css-info #so_css_editor_theme {
  margin-top: 6px;
  width: 100%;
}
#so-custom-css-revisions ol {
  list-style: none;
  margin: 0;
}
#so-custom-css-revisions ol li {
  margin: 0;
  line-height: 2.2em;
}
#so-custom-css-form .custom-css-preview iframe,
#so-custom-css-form .custom-css-preview #preview-navigator {
  display: none;
}
#so-custom-css-form .custom-css-toolbar {
  border: 1px solid #D0D0D0;
  border-bottom: none;
  background: #efefef;
  padding: 8px 10px;
  overflow: auto;
}
#so-custom-css-form .custom-css-toolbar .toolbar-function-buttons {
  float: left;
}
#so-custom-css-form .custom-css-toolbar .toolbar-function-buttons .toolbar-functions-dropdown {
  display: none;
}
#so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons {
  margin: 0;
}
#so-custom-css-form .custom-css-toolbar .toolbar-function-buttons ul.toolbar-buttons li {
  display: inline-block;
  margin: 0;
  padding: 0;
}
#so-custom-css-form .custom-css-toolbar .toolbar-action-buttons {
  float: right;
}
#so-custom-css-form .custom-css-toolbar .toolbar-action-buttons a.active {
  border-color: #b4c4cf;
  background-color: #e9f9ff;
  color: #596872;
}
#so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand {
  float: right;
  text-decoration: none;
  color: #666;
}
#so-custom-css-form .custom-css-toolbar .toolbar-action-buttons .editor-expand .so-css-icon-compress {
  display: none;
}
#so-custom-css-form .custom-css-toolbar .so-css-icon {
  font-size: 14px;
}
#so-custom-css-form .custom-css-container {
  border: 1px solid #D0D0D0;
  background: #f7f7f7;
  cursor: text;
  overflow: hidden;
}
#so-custom-css-form .custom-css-container .CodeMirror {
  height: auto;
}
#so-custom-css-form .custom-css-container .CodeMirror-scroll {
  margin: 0;
  min-height: 300px;
  overflow-x: hidden !important;
  padding: 0;
}
#so-custom-css-form .custom-css-container .CodeMirror-lines {
  padding: 8px 0 8px 0;
}
#so-custom-css-form .custom-css-container textarea {
  border: 0;
  padding: 8px 0 8px 4px;
  width: 100%;
  min-height: 300px;
  display: block;
  font-family: monospace;
  font-size: 13px;
  line-height: 1.4em;
  border-left: 1px solid #ddd;
  margin-left: 16px;
}
#so-custom-css-form .so-css-footer {
  align-items: center;
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}
@media (max-width: 800px) {
  #so-custom-css-form .so-css-footer {
    align-items: start;
    flex-direction: column-reverse;
  }
}
#so-custom-css-form .decoration {
  display: none;
}
#so-custom-css-form:not(.expanded) .save.socss-button {
  display: none;
}
#so-custom-css-form.expanded {
  z-index: 100000;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 340px;
}
#so-custom-css-form.expanded .custom-css-toolbar .editor-expand .so-css-icon-expand {
  display: none;
}
#so-custom-css-form.expanded .custom-css-toolbar .editor-expand .so-css-icon-compress {
  display: inline-block;
}
#so-custom-css-form.expanded .decoration {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 339px;
  width: 2px;
  background: rgba(0, 0, 0, 0.1);
}
#so-custom-css-form.expanded .description {
  display: none;
}
#so-custom-css-form.expanded .submit {
  display: none;
}
#so-custom-css-form.expanded .custom-css-preview {
  position: fixed;
  display: block;
  top: 40px;
  right: 0;
  bottom: 0;
  left: 340px;
  background: #ffffff;
}
#so-custom-css-form.expanded .custom-css-preview #preview-navigator {
  display: block;
  -ms-box-sizing: border-box;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  padding: 6px 10px;
  position: absolute;
  width: 100%;
  height: 40px;
  top: -40px;
  background: #bbb;
  background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #bbb), color-stop(1, #eee));
  background: -ms-linear-gradient(bottom, #bbb, #eee);
  background: -moz-linear-gradient(center bottom, #bbb 0%, #eee 100%);
  background: -o-linear-gradient(#eee, #bbb);
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eee', endColorstr='#bbb', GradientType=0);
  border-bottom: 1px solid #888;
}
#so-custom-css-form.expanded .custom-css-preview #preview-navigator input {
  width: 100%;
  border: 1px solid #888;
  border-radius: 2px;
  color: #444;
  -webkit-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
  -moz-box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
  box-shadow: inset 2px 2px 2px rgba( 0,0,0,0.1 );
}
#so-custom-css-form.expanded .custom-css-preview #preview-iframe {
  display: block;
  width: 100%;
  height: 100%;
  overflow-x: hidden;
}
#so-custom-css-properties {
  display: none;
  position: fixed;
  top: 0;
  left: -338px;
  bottom: 0;
  width: 338px;
  background: #ffffff;
  border: 1px solid #D0D0D0;
  overflow-y: auto;
  z-index: 100000;
}
#so-custom-css-properties .toolbar {
  display: block;
  padding: 7px 10px;
  border-bottom: 1px solid #aaa;
  background: #F6F6F6;
  text-align: left;
}
#so-custom-css-properties .toolbar select {
  font-size: 13px;
  height: 30px;
  line-height: 30px;
  max-width: 225px;
  min-height: 0;
  width: 100%;
}
#so-custom-css-properties .toolbar select.highlighted {
  background: #daeaf7;
}
#so-custom-css-properties .toolbar .close,
#so-custom-css-properties .toolbar .save {
  float: right;
}
#so-custom-css-properties .section-tabs {
  list-style: none;
  height: auto;
  margin: 0;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
#so-custom-css-properties .section-tabs li {
  box-sizing: border-box;
  float: left;
  width: 33.333%;
  padding: 10px 7px;
  border: 1px solid #aaa;
  background: #F6F6F6;
  font-weight: bold;
  border-top: 0;
  border-left: 0;
  font-size: 13px;
  line-height: 1em;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  color: #666;
}
#so-custom-css-properties .section-tabs li:hover {
  background: #fff;
}
#so-custom-css-properties .section-tabs li .so-css-icon {
  float: left;
  display: block;
  margin: -1px 6px -1px 0;
  font-size: 15px;
  color: #666;
}
#so-custom-css-properties .section-tabs li:last-child {
  border-right: 0;
}
#so-custom-css-properties .section-tabs li.active {
  color: #444;
  background: #e8e8e8;
}
#so-custom-css-properties .section-tabs li.active .so-css-icon {
  color: #333;
}
#so-custom-css-properties .sections .section {
  display: none;
  padding: 10px;
}
#so-custom-css-properties .sections .fields-table {
  width: 100%;
  padding-top: 5px;
}
#so-custom-css-properties .sections .fields-table th,
#so-custom-css-properties .sections .fields-table td {
  position: relative;
  zoom: 1;
}
#so-custom-css-properties .sections .fields-table th:before,
#so-custom-css-properties .sections .fields-table td:before {
  content: '';
  display: block;
}
#so-custom-css-properties .sections .fields-table th:after,
#so-custom-css-properties .sections .fields-table td:after {
  content: '';
  display: table;
  clear: both;
}
#so-custom-css-properties .sections .fields-table th[scope="row"] {
  font-weight: bold;
  font-size: 12px;
  padding-right: 10px;
  text-align: left;
  width: 36%;
  vertical-align: top;
}
#so-custom-css-properties .sections .fields-table td {
  padding: 0 0 12px 0  ;
}
#so-custom-css-properties .sections .fields-table input,
#so-custom-css-properties .sections .fields-table select {
  display: block;
  margin: 0 25px 0 0;
  border: 1px solid #c0c0c0;
  width: 175px;
  box-sizing: border-box;
  border-radius: 0;
  font-size: 12px;
}
#so-custom-css-properties .sections .fields-table .socss-field-number input {
  margin: 0;
  width: 120px;
}
#so-custom-css-properties .sections .fields-table .minicolors input {
  box-sizing: border-box;
  height: 30px;
  padding: 5px 0 5px 30px;
}
#so-custom-css-properties .sections .fields-table .select {
  display: block;
  position: absolute;
  top: 0px;
  right: 0;
  line-height: inherit;
  margin: 0;
  padding: 4px 5px 6px;
  cursor: pointer;
  font-size: 15px;
}
#so-custom-css-properties .sections .fields-table .select-tabs {
  margin: 0;
  height: 40px;
}
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab {
  cursor: pointer;
  float: left;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  text-align: center;
  border: 1px solid #c0c0c0;
  padding: 4px 2px;
  border-right-width: 0;
  background: #f7f7f7;
}
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab .so-css-icon {
  line-height: 14px;
  font-size: 14px;
  color: #777;
}
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab:last-child {
  border-right-width: 1px;
}
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover,
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active {
  background: #e9e9e9;
}
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab:hover .so-css-icon,
#so-custom-css-properties .sections .fields-table .select-tabs .select-tab.active .so-css-icon {
  color: #333;
}
#so-custom-css-properties .sections .fields-table .side-tabs {
  height: 26px;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab {
  width: 20%;
  text-align: center;
  padding: 5px;
  line-height: 0;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab div {
  display: inline-block;
  width: 10px;
  height: 10px;
  border: 2px solid #aaa;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-all {
  border-color: #12609b;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-top {
  border-top-color: #12609b;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-left {
  border-left-color: #12609b;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-bottom {
  border-bottom-color: #12609b;
}
#so-custom-css-properties .sections .fields-table .side-tabs .side-tab .spacing-right {
  border-right-color: #12609b;
}
#so-custom-css-properties .sections .fields-table .sides .side > div {
  margin-bottom: 5px;
}
#so-custom-css-properties .sections .fields-table .sides .side > div:last-child {
  margin-bottom: 0;
}
.css-editor-snippet-browser {
  display: none;
}
.css-editor-snippet-browser .snippet-browser-overlay {
  position: fixed;
  z-index: 100000;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
}
.css-editor-snippet-browser .snippet-browser-dialog > div {
  position: fixed;
  z-index: 100001;
  background: #fff;
  box-sizing: border-box;
}
.css-editor-snippet-browser .snippet-browser-dialog .toolbar {
  top: 40px;
  left: 40px;
  right: 40px;
  height: 50px;
  background: #FCFCFC;
  border-bottom: 1px solid #dddddd;
  overflow: hidden;
}
.css-editor-snippet-browser .snippet-browser-dialog .toolbar h1 {
  padding: 0 16px;
  font-size: 22px;
  line-height: 50px;
  margin: 0;
  color: #444;
}
.css-editor-snippet-browser .snippet-browser-dialog .toolbar .close {
  cursor: pointer;
  color: #777;
  background-color: transparent;
  height: 50px;
  width: 50px;
  padding: 15px 0 0 0;
  position: absolute;
  text-align: center;
  border: 0;
  border-left: 1px solid #ddd;
  top: 0;
  right: 0;
  text-decoration: none;
  box-sizing: border-box;
}
.css-editor-snippet-browser .snippet-browser-dialog .toolbar .close:hover {
  background: #dddddd;
}
.css-editor-snippet-browser .snippet-browser-dialog .toolbar .close .icon:before {
  content: '\f158';
  font: normal 20px/1 'dashicons';
  vertical-align: middle;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #666;
}
.css-editor-snippet-browser .snippet-browser-dialog .sidebar {
  top: 90px;
  left: 40px;
  bottom: 90px;
  width: 300px;
  background: #f3f3f3;
  border-right: 1px solid #dddddd;
  padding: 16px;
  overflow: auto;
}
.css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippet-search {
  width: 100%;
  margin-bottom: 20px;
  padding: 8px;
}
.css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets {
  margin: 0;
}
.css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet {
  cursor: pointer;
  font-size: 1.1em;
  line-height: 1.35em;
  margin-bottom: 20px;
}
.css-editor-snippet-browser .snippet-browser-dialog .sidebar .snippets .snippet.active {
  font-weight: bold;
}
.css-editor-snippet-browser .snippet-browser-dialog .main {
  top: 90px;
  left: 340px;
  right: 40px;
  bottom: 90px;
  background: #fff;
  overflow: auto;
}
.css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view {
  padding: 20px;
}
.css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-title {
  margin: 0 0 0.75em 0;
  padding: 0;
}
.css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-description {
  font-size: 1.1em;
  color: #666;
  margin-bottom: 2em;
}
.css-editor-snippet-browser .snippet-browser-dialog .main .snippet-view .snippet-code {
  padding: 20px;
  border: 1px solid #d0d0d0;
  background: #f8f8f8;
}
.css-editor-snippet-browser .snippet-browser-dialog .buttons {
  bottom: 40px;
  left: 40px;
  right: 40px;
  height: 50px;
  background: #FCFCFC;
  border-top: 1px solid #dddddd;
  text-align: right;
  padding: 10px 20px;
  overflow: hidden;
}
.socss-field-measurement {
  position: relative;
}
.socss-field-measurement input.socss-field-input {
  padding-right: 50px;
  width: 120px !important;
  box-sizing: border-box;
}
.socss-field-measurement .dashicons-arrow-down {
  position: absolute;
  top: 4px;
  left: 97px;
  cursor: pointer;
}
.socss-field-measurement .dropdown {
  display: none;
  background: #F5F5F5;
  border: 1px solid #c0c0c0;
  position: absolute;
  top: 27px;
  left: 71px;
  width: 50px;
  z-index: 2;
  margin: 0;
  box-sizing: border-box;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
}
.socss-field-measurement .dropdown li {
  padding: 5px 0;
  text-align: center;
  line-height: 1.1em;
  font-size: 11px;
  margin: 0;
}
.socss-field-measurement .dropdown li:hover,
.socss-field-measurement .dropdown li.active {
  background: #e8e8e8;
  cursor: pointer;
}
.socss-field-measurement .units {
  position: absolute;
  top: 5px;
  left: 12px;
  color: #bbb;
  pointer-events: none;
}
.socss-diw {
  position: absolute;
  top: 0px;
  left: 124px;
}
.socss-diw .inc-button,
.socss-diw .dec-button {
  cursor: pointer;
  box-sizing: border-box;
  float: left;
  padding: 9px;
  user-select: none;
  text-align: center;
  margin: 0;
  width: 30px;
  height: 30px;
}
.socss-diw .inc-button .so-css-icon,
.socss-diw .dec-button .so-css-icon {
  font-size: 10px;
}
.socss-diw .inc-button {
  border-left: 0;
}
.custom-css-toolbar .socss-button,
#so-custom-css-properties .toolbar .socss-button {
  align-items: center;
  border: 1px solid #c0c0c0;
  color: #555;
  cursor: pointer;
  display: flex;
  float: right;
  font-size: 0.95em;
  font-weight: bold;
  justify-content: center;
  line-height: 1em;
  margin-left: 7px;
  min-height: 0;
  text-decoration: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  -webkit-user-select: none;
  user-select: none;
}
.custom-css-toolbar .socss-button:not(.save),
#so-custom-css-properties .toolbar .socss-button:not(.save) {
  height: 28px;
  width: 28px;
}
.custom-css-toolbar .socss-button:not(.save):hover,
#so-custom-css-properties .toolbar .socss-button:not(.save):hover {
  background: #fff;
  border-color: #b0b0b0;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.custom-css-toolbar .socss-button:not(.save):hover .so-css-icon,
#so-custom-css-properties .toolbar .socss-button:not(.save):hover .so-css-icon {
  color: #333;
}
.custom-css-toolbar .socss-button .so-css-icon,
#so-custom-css-properties .toolbar .socss-button .so-css-icon {
  color: #555;
}
.custom-css-toolbar .socss-button .so-css-icon.so-css-icon-save,
#so-custom-css-properties .toolbar .socss-button .so-css-icon.so-css-icon-save {
  color: #fff;
}
.custom-css-toolbar .socss-button.save,
#so-custom-css-properties .toolbar .socss-button.save {
  border-color: #dcdcde;
  border-radius: 0;
  height: 30px;
  width: 30px;
}
.custom-css-toolbar .socss-button.save.button-primary-disabled,
#so-custom-css-properties .toolbar .socss-button.save.button-primary-disabled {
  cursor: default;
}
.custom-css-toolbar .socss-button.save.button-primary-disabled .so-css-icon-save,
#so-custom-css-properties .toolbar .socss-button.save.button-primary-disabled .so-css-icon-save {
  color: #a7aaad;
}
body .CodeMirror-lint-tooltip,
body .CodeMirror-hints {
  /* This is above the editor in full-screen mode */
  z-index: 100002;
}
#socss-inspector-interface {
  color: #333;
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 220px;
  background: #ffffff;
  box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.05);
  z-index: 100000;
  font-family: "Arial", sans-serif;
  font-size: 14px;
  border-top: 1px solid #a3a3a3;
}
#socss-inspector-interface .socss-link {
  box-sizing: border-box;
  background: #f3f3f3;
  box-shadow: 0 -2px 2px rgba(0, 0, 0, 0.05);
  border-top: 1px solid #a3a3a3;
  position: absolute;
  top: -29px;
  height: 28px;
  padding: 6px 15px;
  width: 100%;
  font-size: 13px;
  text-align: right;
  line-height: 1em;
  display: none;
}
#socss-inspector-interface .socss-toolbar {
  box-sizing: border-box;
  background: #e6e6e6;
  padding: 0 4px;
  user-select: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 30px;
  overflow: hidden;
}
#socss-inspector-interface .socss-toolbar .socss-enable-inspector {
  font-size: 20px;
  display: inline-block;
  padding: 5px;
  color: #777;
  border-left: 1px solid transparent;
  border-right: 1px solid transparent;
  position: absolute;
  top: 0;
  left: 5px;
  bottom: 0;
  height: 30px;
  width: 30px;
  box-sizing: border-box;
}
#socss-inspector-interface .socss-toolbar .socss-enable-inspector:hover {
  cursor: pointer;
  background-color: #f3f3f3;
  color: #596872;
}
#socss-inspector-interface .socss-toolbar .socss-hierarchy {
  position: absolute;
  top: 0;
  right: 20px;
  left: 40px;
  bottom: 0;
  display: block;
  padding-left: 10px;
  overflow: hidden;
  white-space: nowrap;
  background: #e6e6e6;
}
#socss-inspector-interface .socss-toolbar .socss-hierarchy .socss-selector {
  font-size: 12px;
  line-height: 1em;
  padding: 9px 20px 9px 9px;
  display: inline-block;
  background: url(./images/separator.png) top right no-repeat;
  background-size: contain;
  cursor: pointer;
}
#socss-inspector-interface .socss-toolbar .socss-hierarchy .socss-selector:last-child {
  background: none;
  padding-right: 9px;
}
#socss-inspector-interface .socss-selectors-window,
#socss-inspector-interface .socss-properties-window {
  overflow-y: scroll;
  font-family: "Courier New", "Lucida Console", Courier, monospace;
  font-size: 13px;
  border-top: 1px solid #a3a3a3;
}
#socss-inspector-interface .socss-selectors-window > div,
#socss-inspector-interface .socss-properties-window > div {
  line-height: 1.2em;
  padding: 4px 10px;
  white-space: nowrap;
}
#socss-inspector-interface .socss-selectors-window > div:hover,
#socss-inspector-interface .socss-properties-window > div:hover {
  background: #f6f6f6;
  cursor: pointer;
}
#socss-inspector-interface .socss-selectors-window strong,
#socss-inspector-interface .socss-properties-window strong {
  font-weight: bold;
}
#socss-inspector-interface .socss-selectors-window {
  position: absolute;
  top: 29px;
  left: 0;
  right: 50%;
  bottom: 0;
  background: #fff;
  border-right: 1px solid #aaa;
}
#socss-inspector-interface .socss-properties-window {
  position: absolute;
  top: 29px;
  right: 0;
  left: 50%;
  bottom: 0;
  background: #fff;
}
body.socss-active {
  padding-bottom: 200px !important;
}
body.socss-active #socss-inspector-interface {
  display: block;
  height: 200px;
}
body.socss-active #socss-inspector-interface .socss-toolbar .socss-enable-inspector {
  border-left: 1px solid #aaa;
  border-right: 1px solid #aaa;
  background-color: #f3f3f3;
  color: #005a67;
}
body.socss-inactive {
  padding-bottom: 29px !important;
}
body.socss-inactive #socss-inspector-interface {
  display: block;
  height: 29px;
}
body.socss-inactive #socss-inspector-interface .socss-selectors-window,
body.socss-inactive #socss-inspector-interface .socss-attributes-window {
  display: none;
}
.socss-inspector-hover {
  pointer-events: none;
  position: absolute;
  /* Same index as the admin bar */
  z-index: 99999;
  border: 1px dashed #0075cb;
  background: rgba(0, 117, 203, 0.15);
  box-sizing: border-box;
}
.socss-inspector-hover .socss-guide {
  display: none;
}
.socss-inspector-hover .socss-guide-margin,
.socss-inspector-hover .socss-guide-padding {
  position: absolute;
}
.socss-inspector-hover .socss-guide-margin.socss-guide-top,
.socss-inspector-hover .socss-guide-padding.socss-guide-top,
.socss-inspector-hover .socss-guide-margin.socss-guide-bottom,
.socss-inspector-hover .socss-guide-padding.socss-guide-bottom {
  right: 0;
  left: 0;
}
.socss-inspector-hover .socss-guide-margin.socss-guide-left,
.socss-inspector-hover .socss-guide-padding.socss-guide-left,
.socss-inspector-hover .socss-guide-margin.socss-guide-right,
.socss-inspector-hover .socss-guide-padding.socss-guide-right {
  top: 0;
  bottom: 0;
}
.socss-inspector-hover .socss-guide-margin {
  background: rgba(20, 126, 74, 0.25);
}
.socss-inspector-hover .socss-guide-margin.socss-guide-top {
  bottom: 100%;
}
.socss-inspector-hover .socss-guide-margin.socss-guide-bottom {
  top: 100%;
}
.socss-inspector-hover .socss-guide-margin.socss-guide-left {
  right: 100%;
}
.socss-inspector-hover .socss-guide-margin.socss-guide-right {
  left: 100%;
}
.socss-inspector-hover .socss-guide-padding {
  background: rgba(0, 117, 203, 0.25);
}
.socss-inspector-hover .socss-guide-padding.socss-guide-top {
  top: 0;
}
.socss-inspector-hover .socss-guide-padding.socss-guide-bottom {
  bottom: 0;
}
.socss-inspector-hover .socss-guide-padding.socss-guide-left {
  left: 0;
}
.socss-inspector-hover .socss-guide-padding.socss-guide-right {
  right: 0;
}
body,
html {
  max-width: 100% !important;
  overflow-x: hidden !important;
}
���

ExifII*!����(1$�2�i��$��
'��
'Adobe Photoshop CC 2014 (Macintosh)2015:07:18 16:07:30�0221����!��rz(��HH���Adobe_CM��Adobed����			



��Z�"��
��?	
	
3!1AQa"q�2���B#$R�b34r��C%�S���cs5���&D�TdE£t6�U�e���u��F'������������Vfv�������7GWgw�������5!1AQaq"2����B#�R��3$b�r��CScs4�%���&5��D�T�dEU6te����u��F������������Vfv�������'7GWgw������?��I$���I%)$�IJI%*���H�cK��BGMJ���~��G�;���R��Կ�����)��?z?hG{������7��;���R��Կ�����){���\Q�>ֺJv�u?�T����7��('z��$�IJI$�R�I$������I$���I%)$�IN�A�,α��Ƥ������O�67���2��c�Xѵ�y5�՝�y���?<���/s�Ea�e�4�>�H�1����G4��A�&��y)"cb��n5f�a�1�׷�7��h�uniȵ�-�q&?7{�6������?{�V�H���շ�c6_`���+Pn��
n-��:��܌�|�p>ԘH4	%���4�Zu�ҹ�����3�({��P�?A��Y���޺�i��8+?��?�fڢ��ik�J+�X�DR�{�'�f<M�$��o)$�IJI$�S����I$���I%)$�IOaд�ؽ���ϖ.���/����o��K���Z?�~��??ع��oe}3��.c79�;�e���y�f�܌wnc�D�kڲ�aǓ��fA���޿����I�IOՍ�z`�h4
����}dF����m[�ȯ��l�wk\�UK~�J�K6��7ʳov��w�Qͦ�y�׽���� ��X�^?egF��|(W�N���C��9�����eya����b�<��$�K}���I%)$�IO����I�	Ѥ�IIRB�@����}�~��Ĕ�$/��ؗ��?�IOm��lO�>X�:P������L��Sc1��퍳�b�����=h���9�������Bd��#B$7��̣6��c�s� ��Ƿ�^�u��O�֧��@��`<���
�˵�S�z�5�9��5����oS�Qc��Z��82��ȋ0����<�Q:z��{��s���"g�1�t;cO���+n��:?Ko������4�e��M�������0�9�.w�q$�|?��s��
%!s�X1f�ӡ#Q��*�[�I���V�^�c��ĸ}�*x������I�?4|��$�K�t�I$�$�I)����*��9UR�V��}�s>������'��aXC_��7b[�����b,�mr��o�������z;>�f6;*�Ͱ;x�mħ�^�{���"Jy[j��U���Xa�X�Ǵ���xkڢ�m�_k����s̾�^����9E%=_��;�=�,k�m#���mk�[���[�ϱ˚ƹ���;�� ����h���khm��"?9����u~�
f�\��3�-e����l�	��z��Y����h �ien�/���o�r��#��W�n;�"�����n;�"��%�D�F4F�J����x���ɿ.�dd;}����]m��ڄ����ï��w�E/�ّ�p����@�<�$��:�g��{OO�=�͚ʰ���`���SN���{v1g���=�U]T���|=Og��c��[k��<���$��?-�N3�C���Q�2c�D���Zb�I-6ʒI$���I%?���Ў8����$�_g�W�Ծ�����$�_g�W�Ծ�����$���ֆ���I%)$�IJI$�R�I$���I%)$�IJI$�S����Photoshop 3.08BIMZ%G8BIM%��}�Ǿ	pv���N8BIM:�printOutputPstSboolInteenumInteClrmprintSixteenBitboolprinterNameTEXTprintProofSetupObjcProof Setup
proofSetupBltnenumbuiltinProof	proofCMYK8BIM;-printOutputOptionsCptnboolClbrboolRgsMboolCrnCboolCntCboolLblsboolNgtvboolEmlDboolIntrboolBckgObjcRGBCRd  doub@o�Grn doub@o�Bl  doub@o�BrdTUntF#RltBld UntF#RltRsltUntF#Pxl@R
vectorDataboolPgPsenumPgPsPgPCLeftUntF#RltTop UntF#RltScl UntF#Prc@YcropWhenPrintingboolcropRectBottomlongcropRectLeftlong
cropRectRightlongcropRectToplong8BIM�HH8BIM&?�8BIM
8BIM8BIM�	8BIM'
8BIM�H/fflff/ff���2Z5-8BIM�p��������������������������������������������������������������������������������������������8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIM?�!video!�nullboundsObjcRct1Top longLeftlongBtomlong�Rghtlong!slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenumESliceOrigin
autoGeneratedTypeenum
ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong�Rghtlong!urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT	horzAlignenumESliceHorzAligndefault	vertAlignenumESliceVertAligndefaultbgColorTypeenumESliceBGColorTypeNone	topOutsetlong
leftOutsetlongbottomOutsetlongrightOutsetlong8BIM(?�8BIM8BIM8BIM��Z�������Adobe_CM��Adobed����			



��Z�"��
��?	
	
3!1AQa"q�2���B#$R�b34r��C%�S���cs5���&D�TdE£t6�U�e���u��F'������������Vfv�������7GWgw�������5!1AQaq"2����B#�R��3$b�r��CScs4�%���&5��D�T�dEU6te����u��F������������Vfv�������'7GWgw������?��I$���I%)$�IJI%*���H�cK��BGMJ���~��G�;���R��Կ�����)��?z?hG{������7��;���R��Կ�����){���\Q�>ֺJv�u?�T����7��('z��$�IJI$�R�I$������I$���I%)$�IN�A�,α��Ƥ������O�67���2��c�Xѵ�y5�՝�y���?<���/s�Ea�e�4�>�H�1����G4��A�&��y)"cb��n5f�a�1�׷�7��h�uniȵ�-�q&?7{�6������?{�V�H���շ�c6_`���+Pn��
n-��:��܌�|�p>ԘH4	%���4�Zu�ҹ�����3�({��P�?A��Y���޺�i��8+?��?�fڢ��ik�J+�X�DR�{�'�f<M�$��o)$�IJI$�S����I$���I%)$�IOaд�ؽ���ϖ.���/����o��K���Z?�~��??ع��oe}3��.c79�;�e���y�f�܌wnc�D�kڲ�aǓ��fA���޿����I�IOՍ�z`�h4
����}dF����m[�ȯ��l�wk\�UK~�J�K6��7ʳov��w�Qͦ�y�׽���� ��X�^?egF��|(W�N���C��9�����eya����b�<��$�K}���I%)$�IO����I�	Ѥ�IIRB�@����}�~��Ĕ�$/��ؗ��?�IOm��lO�>X�:P������L��Sc1��퍳�b�����=h���9�������Bd��#B$7��̣6��c�s� ��Ƿ�^�u��O�֧��@��`<���
�˵�S�z�5�9��5����oS�Qc��Z��82��ȋ0����<�Q:z��{��s���"g�1�t;cO���+n��:?Ko������4�e��M�������0�9�.w�q$�|?��s��
%!s�X1f�ӡ#Q��*�[�I���V�^�c��ĸ}�*x������I�?4|��$�K�t�I$�$�I)����*��9UR�V��}�s>������'��aXC_��7b[�����b,�mr��o�������z;>�f6;*�Ͱ;x�mħ�^�{���"Jy[j��U���Xa�X�Ǵ���xkڢ�m�_k����s̾�^����9E%=_��;�=�,k�m#���mk�[���[�ϱ˚ƹ���;�� ����h���khm��"?9����u~�
f�\��3�-e����l�	��z��Y����h �ien�/���o�r��#��W�n;�"�����n;�"��%�D�F4F�J����x���ɿ.�dd;}����]m��ڄ����ï��w�E/�ّ�p����@�<�$��:�g��{OO�=�͚ʰ���`���SN���{v1g���=�U]T���|=Og��c��[k��<���$��?-�N3�C���Q�2c�D���Zb�I-6ʒI$���I%?���Ў8����$�_g�W�Ծ�����$�_g�W�Ծ�����$���ֆ���I%)$�IJI$�R�I$���I%)$�IJI$�S��8BIM!]Adobe PhotoshopAdobe Photoshop CC 20148BIM���http://ns.adobe.com/xap/1.0/<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/" xmpMM:DocumentID="adobe:docid:photoshop:b98d0534-6de4-1178-8250-f30151358dbf" xmpMM:InstanceID="xmp.iid:885411b3-3e47-4659-a88d-bf7ca293488e" xmpMM:OriginalDocumentID="xmp.did:6110AC04022B11E5837E9A6D6177C712" xmp:CreatorTool="Adobe Photoshop CC 2014 (Macintosh)" xmp:CreateDate="2015-06-03T17:41:44+02:00" xmp:ModifyDate="2015-07-18T16:07:30+02:00" xmp:MetadataDate="2015-07-18T16:07:30+02:00" dc:format="image/jpeg" photoshop:ColorMode="3"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:A40AE503FD3C11E487CCC847C6CB0B0B" stRef:documentID="xmp.did:A40AE504FD3C11E487CCC847C6CB0B0B"/> <xmpMM:History> <rdf:Seq> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:fda85ebb-3c71-427e-b159-6261df895548" stEvt:when="2015-07-18T16:07:30+02:00" stEvt:softwareAgent="Adobe Photoshop CC 2014 (Macintosh)" stEvt:changed="/"/> <rdf:li stEvt:action="saved" stEvt:instanceID="xmp.iid:885411b3-3e47-4659-a88d-bf7ca293488e" stEvt:when="2015-07-18T16:07:30+02:00" stEvt:softwareAgent="Adobe Photoshop CC 2014 (Macintosh)" stEvt:changed="/"/> </rdf:Seq> </xmpMM:History> <photoshop:DocumentAncestors> <rdf:Bag> <rdf:li>adobe:docid:photoshop:5e594251-498e-1178-8b77-cda4a221b58d</rdf:li> <rdf:li>adobe:docid:photoshop:e27e73bf-4996-1178-abec-9e920570c518</rdf:li> <rdf:li>xmp.did:E582B984FE3C11E4A5CAC27EA05F3240</rdf:li> </rdf:Bag> </photoshop:DocumentAncestors> </rdf:Description> </rdf:RDF> </x:xmpmeta>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 <?xpacket end="w"?>��Adobed���		





���!��%���	
	
s!1AQa"q�2���B#�R��3b�$r��%C4S���cs�5D'���6Tdt���&�	
��EF��V�U(�������eu�������fv�������7GWgw�������8HXhx�������)9IYiy�������*:JZjz�������m!1AQa"q��2������#BRbr�3$4C��S%�c��s�5�D�T�	
&6E'dtU7��()��󄔤�����eu�������FVfv�������GWgw�������8HXhx�������9IYiy�������*:JZjz��������?��Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb��Q:~�}��{(ZiOe�����U�<1NJg�0��E�_c�]z���!'�F�C���4�{v#艗��.�àL��I��w�࿭[1Ood���G].�U~��-_�Q������e���O�;�U~��-_�Q��<�swC���R�z}����/�h����������������_��E��O����e����pw����Z.���x�.��/�����W�_��u��я��n����_�O�-o���
��>�3�#�r�6���w��_�M����eM��ƹ~>�tҖq��)��gX�ڷ���,��F~���q��b����Nf<�$�2�]��v*�Uث�Wb��]��v*�U����Wb��]��v*�Uث�Wb��#K��5l���)ݏEQ�1��Q�8�g.�2d���h�-��f���@7�C�����q:�L�K�_�ɐ��G�;[�Wb��]��v*�Uث�U9�x^�d�A�хA�%��A��o9y\跪�T�\a'r�:�?��s���w�?\~���o���7��͛��Uث�Wb��]��v*�Uث�W����Wb��]��v*�Uث�Wb�D����[�j,>7ag�To�����k�sz���n�{�����b��]��v*� lM��V���;7�\����*�H��q*�Uث�T��:z�yv�2*�!�#�4�5九ٹ�<�=�3~�|3���;v*�Uث�Wb��]��v*�U����Wb��]��v*�Uث�Wb�Y���'� a��F?�E�\�bW�>@:�a��d٫q]��_o���h�y��8Գ~>��"dj#��E h2�_˛�@�W�@�Tƪ\��M@ʹ;dz�#��ʎ��(�)Y���4�K@WU
�����㕒dC(��Jd��x�W�O�3(��8X4����Ʋ-@uZً��m|�N���XO�jt�_����Fጢ
S.�JE��I���9i�l�q��MŬ���U�~�v9�8�ڈ!K �+�Ė��w��|�2P5 R
�硽�Wb��]��v*�Uث�Wb��_����Wb��]��v*�Uث�Wb�^����_9������7��]6����sZ㮊)f�!�Y�`�D���z0�$���g�_���kd�m n(����O�W+�ġŔ�d❄4T.L�����
�)o�D�A������8�T@������*䒀�"�� ���2�{k�B�L��'q�_�1�ͬ�C\�EO2�����0A�V&��|U���&���C���ZP��<u�F�)�d���Dzb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb�^����_9�������7��]6������YeHaF�iX$Q �3���@�q������ȴX���YuYV��u�O�'�n����uݛ٣�O����M����Nm��ݧ
��i|=�c��[��E��S��Յ��U����b�E��1ZPW����Q��	s@ݟ��9���Hb@����LR��#9�����bl�Q(��Iz���>�$P��O�*^���.�]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb�^����_9�������7��]6�����+L62�I��xZ��PtU�����fӰ�C�����I9Zq�/�gy�s݊�@]�p��������f>Lu�k�P�K��/NsO�����-RR���!�#1���,�?���'6� od�A���c�;S\�Wu?��_�����\����M%�����'�+�s��ث�Wb��]��v*�Uث�Wb�����Wb��]��v*�Uث�Wb�^����_9�������7��]6������]j�F�[�6��Y�'�?���V����jg�|Q�:?�jǐ��{��XkVwh���}�ߺ��>Y�i5p�(��.�Q1a1̖�b��Pv�+$c����n���>prc��E��
�[��>
��ae��$���c��9�i<�{�����(��Nad�V��ݤr���3�6��i��b�9�B�Uث�Wb��]��v*�Uث�W����Wb��]��v*�Uث�Wb�^����_9�������7��]6�����sZ㣴]j�F�[�&��Y�o�*+ƭ�9~�S<3��{<y
���:���`�v��L�7ۍ���坮�W��"�e�lv*�UwiƮ��~�x|�&:�5�,cP��H��A۶j�Ƭ8�n�^!�wr@>��k2ʭřc�3���v�g��5���'�R�!ثM�O���Ezb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb�^����_9������7��]6�����sZ�Gh���~��M�l�B��?���V���M���G��=�<����z�Z�[�F�&X���Շ����I��xqG��wX���	�d�(^�Y�۵���	��������8�H�Ō�",�麾�����1�Ƈ��ڴ>u:�yE��"#.F��0i���+U
}E�ޣ1�xv�
Y����j���1!�l��rz��h:�����+[�Wb�7�?,!^���.�]��v*�Uث�Wb��]������T;^�
7>�k��7�?�*�C��p������}���>
�늻��7�?�*�C��p������}��z����^�{"���ʚ�e�U�q��?�%�o����G��ث�Tv��_���{d��4-�%O�o�տg/�jg�|Q�:?�g�!���=]�֬�ѿɖ&�q�ua�|���ꡞQ��]�,�b��д��=6��{�:�Ro!���F4�*�ӗ�r�Onc��qc������D�y�s@yq曽GL���F�}3ԂǏz�C>�c��YGdNjQ)�LJ���� ��Q0e>o�M��bWio��kz���5���9��|pB��_L�K�.^�8���xڂ�>'8���]��[!�1���Y�B�Uث�Wb��]��v*�Uث�W���ɿ��O��R�Uث�Wb��]��v*�U������֭�>��k��nF�������f��p݊�v*��u���ol���f���*+ƭ�9�������t��Ca�z�a�X-ݣ�4-��~���gi��C<8��H��YDń���i�Z��`~�kZW���ٍ����|t�����Z����Cyyw{w-�ܦk��d���U���7&INFR<R������j9;v*�U	�܋m.��zP����.�Ë$c� �n@</;�|�Uث�Wb��]��v*�Uث�W���ɿ��O��R�Uث�Vq�)�iZ��f�����w��-��n��g3
�e�>%lU����Z����>M��!Vm2R>�����e����qW��[�[O%��O�1Ib�J��؆SB�T�Wb��Y�冸�}����m�HNG�ȿ`��J棶4�&>!�c�s�N&�ls��s�u.�]��v*��5]GK�7:|��8�a���V�l�y�	e	�&�R��������V��_�+�4�=��!�$�#))JD�<Բv*�Uث�V���%��4���Ti�����������b�L���O���+�s��v��]��v*�Uث�Wb��]�����ɿ��O��R�Uث�W��<���������=o^Ѵ-:MGX����/�<�W����Q~&�_&~w�i�[Η���Ɔݩ�ve)u*���R?u��z��LX��qWb��Q�?ܟ��*�O+~abK-`�*�c����u?��9�c�<_�?�~}%������1%��·z���g=��j@��Ly�|���Wb��]��v*�Ud���� ��@�8cMد�?0t��=���e�%>%��/�m�}��!��!���ä����<������K����y;���U�a��v������d�Uث�Wb��]��v*�Uث�W���ɿ��O��R�Uث�T���m��-<�i\��,�(e$!i�xAn;�}NT��U�6����m�M��|�R
�Q�(���q���3~�*�b��]��G�r�8�#\��ܑ���A��05!�ֲ��p��J��'M���Ň���W+��'�Ճ���G���w�w��W_�:O���a�d?��|w��O�r�����X�S�!��+�ø|��]�������j����_�����\���t��V?������0�'~����u�#�������C�,W��p�4u�l��.O�i?�?������P�Y�n'5�W���?�]F<�3��I.�]��v*�Uث�Wb��]��v*�U�����2����[+)�#�*�*�Uث�Wb��]������
P�Zb�ث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث����Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]������Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]��v*�Uث�Wb��]���ىPNG


IHDRPB�Q=tEXtSoftwareAdobe ImageReadyq�e<hiTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmpMM:OriginalDocumentID="xmp.did:995BC9B6082068119457FBCBD0AC2E91" xmpMM:DocumentID="xmp.did:3916D97AFD4F11E4BDA5A18EA550D44B" xmpMM:InstanceID="xmp.iid:3916D979FD4F11E4BDA5A18EA550D44B" xmp:CreatorTool="Adobe Photoshop CS6 (Macintosh)"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:615FF2F9FCD111E4A500EA302DB51657" stRef:documentID="xmp.did:615FF2FAFCD111E4A500EA302DB51657"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>}-P��IDATx��ɏU�_���f�aM��2APPD!��
�1&��r0����ɋF�&��FqID#"aغg��Yz+�����J-����j�%�d��~��S��~Սu��1��L�*ec�&�U>�H�|ߔ݈k���ۭ� �X����J�z[�8^ו=��neyek�����]�?|G�r���W�X���Jx]U֫l
�K�me�rHو�?�Y�6(낇�.t�=�Ae[��+�U�B��,[3����8^�39rp�O%�+��x6�]���܄;/�j
�����[��8�I���qN@~�0� B8�s��.E��B�:���=�ބw
���;
oҹ�	��[lp���Ǘqfp�k�㸙�W֩���7��J�<.�B�OٟX�4��A�o1�{��6¸�����GH'���+�){�Fq�"�,�ѝ�6��o��oi�w
s�"�W���cw*;�숲��/p�%��/��b���:+*UC�̭��,^w#'Vqco�	���s�m���"�ih2`�3,���Y�04m�-�!EL�
?ϼ�>W�7�!e�pR�[W����ԋ�~6�m��1]��7�`Ӹ���D;���(�M�;;��8����G����@������Mu k
��, � �F�n��]ٻʆ�WH�����9(^4(qQ���Z$`�r��
��P��
�e߹�B��j�^�PLr�Ո����k~]��б�(�����Q��-�E!���L�AX:.
h�R�!U���c
�t�ɐc���v��'�U�!"x`�w+Ļ�
si�y_�\C,E����
�/$aմf�&=���C6!i�dD��ǚ�X��y�wB$���"���Ɂ�%��e��q�-B��5*�8Nb�z�Z�t�`"�c�z�,c��ǖ VPL��*`6��E$���ߎ�Ͱ!�j~w��b1"D�4�laZ0L:�xL�x�{�I~r>v(�����]��|��"���hJ�/�����[
/�;��1th���u,zm�D�m-; ��C�Յ�Ԙ�t��y
�TL�8���X?����(p, �	�%/q/�9>%:ӝ�
�/\��b�xX�h��s_��t���<c���g#@(���:4a�O(��U99@+�%6.�������|��6��AB��>C��(&zl�� 
(}r��p�;���*#l��9$ .��;�GLk
X�.�>�Y?�+�]���S�6V粁�H��ύ�g.ĵd�4�"�<w��1A\/�*9�Z���_�{_��]�j�m���m	B�j��b���Z�خ0v�d5\�t���d�D(Pi��h@�-�b��݅��8�.Z�\�"*@
q8�4�j��uЯ�5ƶx:��[��i\ę!.Aa�<¸ϣ�8Lz���-�u�*ϼOW�Q�ί ��Q��W�H���r�	�.x�t��8� D��!@�r /\���i��ҥ��z�v�YA+ :	B�vy�n��!�-WxZ�m�[�莳����WM*�]"—c�D�k�����׀DS����^=N�4~sm�$ f< ��R�Z��B��}��Y��`��8�8� D�'�2PR�y_����
�R�^Wt
 �XN�
��g��րB=����cQ�����[� nE��'���v���g���@?���Tʉ��1��8
�K��c��6
�H ��S1X}l�q��B�r���
g�8$��e�SfQ,J��H�8j�j�D����fbZsK���Z�*٦y�a��	B����ۺ�6m
)���V�Si|�Մ@�2X�6��0�Z\'�m�� >�F���<���c	ڋ����)t�� ���A�G?��E��
*(ə��
Gqb�&ɘ�%��Z�<�$�S�{�!����6����I���G�r����sl�``�?d��
�3kK�o0�I�g
��D�Utn�U�8ک�/;t�x���C��W�V�{8��Tt��ii|a��y�Gb��e$��
�w��ⳓM!R��oʾ�zra_Z��m�H���о�=e���>�������w4@S�4���B��ޤ�%���İ��M�א(�V!�M"�
`��&�yi�!>kx��K@�){!䘧D2��^i|��O�zSPC����/1�Q>��=�µ����N��IEND�B`��PNG


IHDR:oaTtEXtSoftwareAdobe ImageReadyq�e<&iTXtXML:com.adobe.xmp<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c014 79.156797, 2014/08/20-09:53:02        "> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/" xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" xmp:CreatorTool="Adobe Photoshop CC 2014 Macintosh" xmpMM:InstanceID="xmp.iid:708082F9F28511E4A52DD8D9D0735E04" xmpMM:DocumentID="xmp.did:708082FAF28511E4A52DD8D9D0735E04"> <xmpMM:DerivedFrom stRef:instanceID="xmp.iid:708082F7F28511E4A52DD8D9D0735E04" stRef:documentID="xmp.did:708082F8F28511E4A52DD8D9D0735E04"/> </rdf:Description> </rdf:RDF> </x:xmpmeta> <?xpacket end="r"?>�dVKDIDATxڜ�MKUQ���
D��I��h D�"H*"H'Rq`
B�o�K$s`�Ě��}ٙEDЗAD
j DRݞ���{6<,��>���k��CV!�*��Zg��A\�/��-��,�QO��C5ۺ`�Ia��A�[5ۺ_a����(þ=��m���p��0�/�QߞPͶ�'t�:)��e·U����+�0�g�;��Ts��^9���)�@�j����2a����8,���(�|۩�m��g��&=��z}ȷ�Ts��6�s�E
c�F�m�j>i�}�5Ja�)��S�E�ڴ=��0v��S��W�!���2�"�L�8�y�V�%��<�Dy��f��vA$��n���:O���׃�(��M��!��޶�X�
�89�uEt�
���]��ƺ<��F���pU
W��>��ȭ�-�.�C���ͥ~a�ĺ��^����\X��
.j�j�񕿱=V|R�ؓ��������k�&?���$=��_�0��"R���*�3�a�u�6���C����0�J4����l�pY
�8Y�����l��v�\��
����p�IEND�B`�<?php

/**
 * Remove the menu item for the CSS editor that comes bundled with SiteOrigin themes
 */
function siteorigin_css_legacy_remove_legacy_actions() {
	remove_action( 'admin_menu', 'siteorigin_custom_css_admin_menu' );
	remove_action( 'wp_head', 'siteorigin_custom_css_display', 15 );
}
add_action( 'after_setup_theme', 'siteorigin_css_legacy_remove_legacy_actions', 100 );
jQuery( function( $ ) {
	$( '#siteorigin-installer-notice .siteorigin-notice-dismiss' ).on( 'click', function( e ) {
		e.preventDefault();
		var $$ = $( this ).trigger( 'blur' );
		$.get( $$.attr('href') );

		$( '#siteorigin-installer-notice' ).slideUp( function(){
			$( this ).remove();
		} )
	} );
} );
jQuery( function( $ ) {
	var currentSection = '';
	$( '.page-sections a' ).on( 'click', function( e ) {
		e.preventDefault();

		$( '.page-sections li' ).removeClass( 'active-section' );
		var $$ = $( this );

		currentSection = $$.data( 'section' );
		$$.parent( 'li' ).addClass( 'active-section' );

		$( '.siteorigin-installer-item').show();
		if ( currentSection != 'all' ) {
			$( '.siteorigin-installer-item:not(.siteorigin-' + currentSection + ')' ).hide();
		}

		$( window ).trigger( 'resize' );
	} );

	$( 'span.siteorigin-installer' ).on( 'click', function( e ) {
		e.preventDefault();

		var $$ = $( this );
		if ( ! $$.hasClass( 'disabled' ) ) {
			$$.addClass( 'disabled' );
			$.post(
				soInstallerAdmin.manageUrl,
				{
					'type' : $$.data( 'type' ),
					'slug' : $$.data( 'slug' ),
					'task' : $$.data( 'status' ),
					'version' : $$.data( 'version' )
				},
				function( data ) {
					if ( $$.data( 'status' ) == 'activate' ) {
						if ( $$.data( 'type' ) == 'themes' ) {
							var $activeItem = $( '.siteorigin-installer-item-active.siteorigin-themes' )
							$activeItem.addClass( 'siteorigin-installer-item-inactive' ).removeClass( 'siteorigin-installer-item-active' );
							$activeItem.find( '.siteorigin-installer' ).removeClass( 'disabled' );
							$activeItem.removeClass( 'siteorigin-installer-item-active' );
							$( '.siteorigin-themes span.siteorigin-installer' ).show();
							$$.hide();
						}
						$$.parents( '.siteorigin-installer-item-inactive' ).removeClass( 'siteorigin-installer-item-inactive' ).addClass( 'siteorigin-installer-item-active' );
						if ( $$.data( 'type' ) == 'plugins' ) {
							$$.remove();
						}
					} else if ( $$.data( 'status' ) == 'update' ) {
						$$.remove();
					} else {
						$$.removeClass( 'disabled' );
						$$.text( soInstallerAdmin.activateText )
						$$.data( 'status', 'activate' );
					}
					$( window ).trigger( 'resize' );
				}
			);
		}
	} );

	$( '.page-sections li:first-of-type a' ).trigger( 'click' );

	// Make sure product heights are all the same on a row by row basis.
	$( window ).on( 'resize', function() {
		var $products = $( '.siteorigin-installer-item:visible' ).css( 'height', 'auto' );
		var largestHeight = [];
		var column = 0;

		$( '.siteorigin-installer-item-body' ).css( 'height', 'auto' );

		$products.each( function( index ) {
			column = index / 3;
			// Turnicate column number - IE 11 friendly.
			column = column < 0 ? Math.ceil( column ) : Math.floor( column );
			$( this ).data( 'column', column )

			largestHeight[ column ] = Math.max( typeof largestHeight[ column ] == 'undefined' ? 0 : largestHeight[ column ], $( this ).height() );
		} );

		$products.each( function () {
			$( this ).find( '.siteorigin-installer-item-body' ).css( 'height', largestHeight[ $( this ).data( 'column' ) ] + 'px' );
		} );

	} ).trigger( 'resize' );
} );
<span
	class="siteorigin-installer-button siteorigin-installer"
	data-type="<?php echo esc_attr( $item['type'] ); ?>"
	data-slug="<?php echo esc_attr( $slug ); ?>"
	data-status="<?php echo esc_attr( $item['status'] ); ?>"
	data-version="<?php echo esc_attr( $item['version'] ); ?>"
	<?php if ( empty( $item['status'] ) ) { ?>
		style="display: none;"
	<?php } ?>
>
	<?php echo esc_html( $text ); ?>
</span>
<div class="wrap siteorigin-installer-wrap">
	<div class="siteorigin-installer-header">
		<h1 class="siteorigin-logo">
			<img src="<?php echo esc_url( plugin_dir_url( __FILE__ ) ) . '../img/siteorigin.svg'; ?>" />
			<?php esc_html_e( 'SiteOrigin Installer', 'siteorigin-installer' ); ?>
		</h1>

		<ul class="page-sections">
			<li><a href="#" data-section="plugins"><?php esc_html_e( 'Plugins', 'siteorigin-installer' ); ?></a></li>
			<li><a href="#" data-section="themes"><?php esc_html_e( 'Themes', 'siteorigin-installer' ); ?></a></li>
			<li class="active-section"><a href="#" data-section="all"><?php esc_html_e( 'All', 'siteorigin-installer' ); ?></a></li>
		</ul>
	</div>

	<ul class="siteorigin-products">
		<?php
		foreach ( $products as $slug => $item ) {
			$classes = array();
			$classes[] = $slug == 'siteorigin-premium' || empty( $item['status'] ) ? 'active' : 'inactive';

			if ( ! empty( $highlight ) && $slug == $highlight ) {
				$classes[] = 'highlight-item';
			}
			?>
			<li class="siteorigin-installer-item siteorigin-<?php echo esc_attr( $item['type'] ); ?> siteorigin-installer-item-<?php echo sanitize_html_class( implode( ' ', $classes ) ); ?>">
				<div
					class="siteorigin-installer-item-body"
					data-slug="<?php echo esc_attr( $slug ); ?>"
					data-version="<?php echo esc_attr( $item['version'] ); ?>"
				>
					<?php if ( ! empty( $item['screenshot'] ) ) { ?>
						<img class="siteorigin-installer-item-banner" src="<?php echo esc_url( $item['screenshot'] ); ?>" />
					<?php } ?>

					<div class="siteorigin-product-content">

						<h3>
							<?php echo esc_html( $item['name'] ); ?>
						</h3>
						<p class="so-description">
							<?php
							if ( ! empty( $highlight ) && $slug == $highlight ) {
								echo '<span class="siteorigin-required">';
								printf(
									esc_html( 'Required %s', 'siteorigin-installer' ),
									$item['type'] == 'plugins' ? esc_html( 'Plugin', 'siteorigin-installer' ) : esc_html( 'Theme', 'siteorigin-installer' )
								);
								echo '</span>';
							}
							echo esc_html( $item['description'] );
							?>
						</p>

						<div class="so-type-indicator">
							<?php
							if ( $item['type'] == 'plugins' ) {
								esc_html_e( 'Plugin', 'siteorigin-installer' );
							} else {
								esc_html_e( 'Theme', 'siteorigin-installer' );
							}
							?>
						</div>

						<div class="so-buttons <?php
						echo $slug != 'siteorigin-premium' && ! empty( $item['status'] ) && ! empty( $item['update'] ) ? 'so-buttons-force-wrap' : ''; ?>">
							<?php
							if (
								$slug == 'siteorigin-premium' ||
								! empty( $item['status'] ) ||
								! empty( $item['update'] ) ||
								$item['type'] == 'themes'
							) {
								if ( $slug == 'siteorigin-premium' ) {
									$premium_url = 'https://siteorigin.com/downloads/premium/';
									$affiliate_id = apply_filters( 'siteorigin_premium_affiliate_id', '' );
									if ( $affiliate_id && is_numeric( $affiliate_id ) ) {
										$premium_url = add_query_arg( 'ref', urlencode( $affiliate_id ), $premium_url );
									}
									?>
									<a href="<?php echo esc_url( $premium_url ); ?>" target="_blank" rel="noopener noreferrer" class="button-primary">
										<?php esc_html_e( 'Get SiteOrigin Premium', 'siteorigin-installer' ); ?>
									</a>
									<?php
								} elseif ( ! empty( $item['status'] ) || $item['type'] == 'themes' ) {
									if ( $item['status'] == 'install' ) {
										$text = __( 'Install', 'siteorigin-installer' );
									} else {
										$text = __( 'Activate', 'siteorigin-installer' );
									}
									require 'action-btn.php';
								}

								if ( ! empty( $item['update'] ) ) {
									$text = __( 'Update', 'siteorigin-installer' );
									$item['status'] = 'update';
									require 'action-btn.php';
								}
							}


							if (
								$item['type'] == 'themes' &&
								! empty( $item['demo'] )
							) {
								?>
								<a href="<?php echo esc_url( $item['demo'] ); ?>" target="_blank" rel="noopener noreferrer" class="siteorigin-demo">
									<?php esc_html_e( 'Demo', 'siteorigin-installer' ); ?>
								</a>
							<?php } ?>

							<?php if ( ! empty( $item['documentation'] ) ) { ?>
								<a href="<?php echo esc_url( $item['documentation'] ); ?>" target="_blank" rel="noopener noreferrer" class="siteorigin-docs">
									<?php esc_html_e( 'Documentation', 'siteorigin-installer' ); ?>
								</a>
							<?php } ?>
						</div>
					</div>
				</div>
			</li>
			<?php
		}
		?>
	</ul>

</div>
{
  "siteorigin-premium" : {
    "name" : "SiteOrigin Premium",
    "description" : "SiteOrigin Premium is a collection of powerful addons that enhance every aspect of our products. They improve existing features and add entirely new functionality. You'll love all the power they offer you.",
    "documentation" : "https://siteorigin.com/premium-documentation/",
    "weight" : 100,
    "version" : 1,
    "type" : "plugins"
  },
  "siteorigin-panels" : {
    "name" : "Page Builder by SiteOrigin",
    "documentation" : "https://siteorigin.com/page-builder/documentation/",
    "weight" : 95,
    "type" : "plugins"
  },
  "so-widgets-bundle" : {
    "name" : "SiteOrigin Widgets Bundle",
    "weight" : 90,
    "documentation" : "https://siteorigin.com/widgets-bundle/getting-started/",
    "type" : "plugins"
  },
  "so-css" : {
    "name" : "SiteOrigin CSS",
    "documentation" : "https://siteorigin.com/css/getting-started/",
    "weight" : 85,
    "type" : "plugins"
  },
   "siteorigin-corp" : {
    "name" : "Corp",
    "demo" : "https://demo.siteorigin.com/corp/",
    "documentation" : "https://siteorigin.com/corp-documentation/",
    "screenshot" : "https://ts.w.org/wp-content/themes/siteorigin-corp/screenshot.jpg",
    "weight" : 80,
    "type" : "themes"
  },
  "siteorigin-unwind" : {
    "name" : "Unwind",
    "demo" : "https://demo.siteorigin.com/unwind/",
    "documentation" : "https://siteorigin.com/unwind-documentation/",
    "screenshot" : "https://ts.w.org/wp-content/themes/siteorigin-unwind/screenshot.jpg",
    "weight" : 75,
    "type" : "themes"
  },
  "siteorigin-north" : {
    "name" : "North",
    "demo" : "https://demo.siteorigin.com/north/",
    "documentation" : "https://siteorigin.com/north-documentation/",
    "screenshot" : "https://ts.w.org/wp-content/themes/siteorigin-north/screenshot.jpg",
    "weight" : 70,
    "type" : "themes"
  },
  "vantage" : {
    "name" : "Vantage",
    "demo" : "https://demo.siteorigin.com/vantage/",
    "documentation" : "https://siteorigin.com/vantage-documentation/",
    "screenshot" : "https://ts.w.org/wp-content/themes/vantage/screenshot.jpg",
    "weight" : 65,
    "type" : "themes"
  },
  "origami" : {
    "name" : "Origami",
    "demo" : "https://demo.siteorigin.com/origami/",
    "documentation" : "https://siteorigin.com/origami-documentation/",
    "screenshot" : "https://ts.w.org/wp-content/themes/origami/screenshot.png",
    "weight" : 60,
    "type" : "themes"
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<svg width="256px" height="256px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>Icon</title>
    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Icon">
            <path d="M64,0 L192,0 C227.346224,0 256,28.653776 256,64 L256,192 C256,227.346224 227.346224,256 192,256 L64,256 C28.653776,256 0,227.346224 0,192 L0,64 C0,28.653776 28.653776,0 64,0 Z" id="Background" fill="#F84646"></path>
            <g id="Package" transform="translate(57.000000, 58.000000)">
                <path d="M21.333624,0 L120.666376,0 C121.854365,0 122.952276,0.642021928 123.547166,1.6845907 L142,34.0239044 L0,34.0239044 L18.4528339,1.6845907 C19.0477244,0.642021928 20.1456352,0 21.333624,0 Z" id="Cover" fill="#F6C3C3"></path>
                <path d="M0,34.0239044 L142,34.0239044 L142,136.653386 C142,138.50167 140.509948,140 138.671875,140 L3.328125,140 C1.49005232,140 0,138.50167 0,136.653386 L0,34.0239044 Z" id="Cover" fill="#FFFFFF"></path>
                <rect id="Line" fill="#FDD8D8" x="13.3125" y="96.4940239" width="33.28125" height="8.36653386"></rect>
                <rect id="Line" fill="#FDD8D8" x="13.3125" y="110.438247" width="33.28125" height="8.36653386"></rect>
                <polygon id="Ribbon" fill="#EA7777" fill-rule="nonzero" points="84.8671875 34.0239044 57.1328125 34.0239044 61.6739433 0 80.4610098 0"></polygon>
                <polygon id="Ribbon" fill="#F6C3C3" fill-rule="nonzero" points="57.1328125 73.0677291 71.0901367 61.9123506 84.8671875 73.0677291 84.8671875 34.0239044 57.1328125 34.0239044"></polygon>
                <path d="M96.9211911,121.185806 C98.5991863,122.873123 98.5991863,125.608804 96.9211911,127.296121 C95.8025277,128.420999 92.5241098,129.680858 87.0859375,131.075697 C88.4730712,125.607315 89.7259697,122.310684 90.8446332,121.185806 C92.5226283,119.49849 95.243196,119.49849 96.9211911,121.185806 Z M132.689368,85.2184559 C134.338622,95.0337565 131.304955,103.816952 123.588367,111.568041 C122.656797,112.503777 121.719972,113.362885 120.783623,114.150483 L120.101688,123.726203 C120.058916,124.326845 119.744887,124.874023 119.250624,125.212321 L119.218832,125.233629 L111.229744,130.476032 C111.004821,130.623625 110.752086,130.723183 110.48724,130.768521 C109.431616,130.949228 108.429455,130.24555 108.232338,129.192577 L108.226321,129.158854 L106.906794,121.38222 C105.389025,121.731282 103.988882,121.908442 102.749654,121.952364 L96.1189697,115.292034 C96.1623167,114.058077 96.3360136,112.665282 96.6775593,111.156006 L88.9939491,109.840492 C87.9270949,109.657862 87.2096304,108.641088 87.3914472,107.569464 C87.4365831,107.303434 87.5356981,107.049569 87.6826344,106.823641 L92.9017019,98.7988332 C93.2365509,98.2839715 93.7917277,97.9559064 94.4024188,97.9120296 L103.839087,97.2339573 C104.635979,96.2746018 105.506838,95.3146296 106.45707,94.3601487 C114.173658,86.6090591 122.917758,83.5618282 132.689368,85.2184559 Z M114.895772,96.0121333 C112.946201,97.9725341 112.946201,101.150972 114.895772,103.111373 C116.845342,105.071774 120.00622,105.071774 121.955791,103.111373 C123.905361,101.150972 123.905361,97.9725341 121.955791,96.0121333 C120.00622,94.0517325 116.845342,94.0517325 114.895772,96.0121333 Z" id="Rocket" fill="#FF6B6B"></path>
            </g>
        </g>
    </g>
</svg>GIF89a((������ӊ��������������!�NETSCAPE2.0!�XMP DataXMPE?xpacket586180" xmpMM:InstanceID="xmp.iid:9ACA89C2E0Cpacket end="r"?>!�	,((@�x��0`�����y'�$Y0[��4P�
���d���Ƌ�[䎣����k�y>�@P
��1Q���8�#U�Uq1`2���(`��2
�f!�"'O�voc�����hS�����ce"3B��5�#�q%�K*s>2��"��S
m�$s���,z�#}���u�"x�ϲ�����N5�{��RG;�
XZz^`���	!�	,((@�x��0`��f��+ ׍diL`��@՚�9�<ﭨ-c 0���1Q�@>!��A��A�(�B��u�h������q1p~�,�oo	:}U
��$"�B>�NWe�����S�k�����eg%)kz!+�8$�L��|��I���
q�$s����,�����u����s���Mȹ7��l�TI<�
Z\^`b���	!�	,((@�x��0`��U���Sxdi^ӝl@ղ�9�<ﭬ3A�10��$�1Q�@�!��Q� P2�B��u�fa��������(:���|�;�jU
��%r�)Q�NXe�����S�V�����eg4d~l7�&���M3�q$P�I�u���3p���H�-�����(D�%|n�t?��R�w�����TIV�
[]zx��	!�	,((@�x��0`��W0 O��dY�����C��l�}t�J�1 ��$�1Q�>��⁢�A�@!0�:`���	ʋ"樐+W����u93
��${�(Qzxf�����S��W��i�Xh:c[p!A�)��*�R#P�w�j
mJa�F����,~�$����v����t
���R�i�6�k�TA<�D[]`�d��X	!�	,((@�x��0`�������Yi@A��p|а�00DOp�O���F���,5&Mch� �dA�:�>A*��>lQ�nXd
���Ǣ��+�E��?��8?�9
��$�-T�ipf�����V�������fh�k<�F�
P��L��S����.�yau�� �2������%}{�uz�����g�R�TWLA�
]*sbd�[	!�	,((@�x��0`��8c@^�`&�a�l{�@�-@FN0�����$�1Q�8�����D��@ �B�vuȜD2D��g�{1@���k�	;},E���'�)Q&vVe�����S5���h�eq�6@�Ja��MNs|=�
�C�*D
yJj��s�mb��
�.���ϋu���ԯA��vP@�h���<>�
Y[|`b��	!�	,((@�x��0`��8c@^�`&t�gL��@ղ�=�<�{+�]�r5�HLc��q~B��#A�@ �B�v}0���/���6w!+�rހ0(�-:y!
��&�D?�IVe�����R�U��m�e1�j7���K�B�~i�
�3#��E�to�;�l�
�����ώp�v@׿����OX�N�WSB=�
Y[x`b���	!�	,((@�x��0`��8c@^ѠxV�a�^�3P�
�������BW�)�)A!��4&��� �V��:``Iۺ�Q]9�K�F�m��;�.hsuht!
��M�&T�Qf�����V����t�f/�j=���P���Rk{:
mn��F�1�8�������%��w>�,6�q��S=�t�W@;�
]C{bd��[	!�	,((@�x��0`��8c@^� 8_U0A����C��l�}��`���N�ɥ�4�8��t��A�T�B��}�;r���E �b��\��g{�;
�r%�H>�FWe�����S�V��m�e0�i>���L��P�� 
lmx�D�2�z���
�z���~���q�x?�o��C�B�6�m4�TA<�
Z\z`b���	!�	,((@�x��0`��8c@^�`PV�a�^4�o�s�֘/,��cA�ᢤm������� P*@!��>f���L�����WV|�8�"`T�q4
xj�*R�OXf�����T/W��n�fh�k9��������+� z�B�
��
��Kwsz
m}�n$�)q�u��0:�y�G�?�i�f;�Ƙ[]wacԘ�?	!�	,((@�x��0`��8c@^�`(L �0�W
z��IJ��b�
o��JcR�qz�
��@��@ �����5/�Z�.��ЍW
V�E���V,)
~luv$P�Mxd�����R�U��E�Wzvi���L����:H�m}�_���
�J�p^�Mn
���vaZsk��>�B�gO=���PS@;�
Y[u_a���	!�	,((@�x��0`��8c@^�`(L ��PU
,*C����b�o:
�1)9���!��A�T�B��}(�Z�
�v����eF�)P5bwj>v��~6�hGe�����S{V��N�Xg����)M�W���%� o���D�}[�m�qy�No���rtI�lw\��>��R�hPY�:�QTA;�
Z�_ac��X	!�	,((@�x��0`��8c@^�`(L ��cZ4Pg�
���ʊ��p�iL��€0(,ނ��t�t(O��i/�e��A;��3+��aE�J
}@Y9�yIZ�D�g�����T�X��o�gi�l5�����
��)��!q���
�'xtdLN{�C���s�*v=�
n�nt��G��h�2�ZUC:�
\^abd���	!�	,((@�x��0`��8c@^�`(L �C3a4Pg���q��b�o,bT��PAX8��&t��A�p
�B��u��2�-�vP���d[\�oz@$6ma}�=�hWe�����S�;���r�egv:j��H�P�� �%�!K���
�!~�x�h3R��q���lE��o>md���ƞ.�9ǕTA;�
Z\u`b���	!�	,((@�x��0`��8c@^�`(L �°�@ub�FN ���
ox�-�HLc�$9>pA��|��t(-��i��
(T�����h>��3c�|CN�PDYL�8�M�g�����U�X��s�gi}u����R��%� p���� w�z�jc��rj)
��mDp��AI���T�!c]|�8�s��VD>���5bd��	!�	,((@�x��0`��8c@^�`(L � �4P�U�wC�p\-���+^��Ә(;�G� �b@(U8��V�,�}8�7r��f9m�������]h�}$
6�1H��B�FZe�����VY��q�e/{?s��M��S~� }%�!����
�!u�x���ph�� �lE����1���g>���:�v8�WF@�
])uac��[	!�	,((@�x��0`��8c@^�`(L ��@u�[9���z+����[���$% 9t�oAȡz��t(h��i-d�	�A��b�ޱ����̓
}'Yi(N��7�H�g�����U�X��G�Z�y0?�~�K�����%�!r���
�"x�{���tGM]�ln(����"r��*���Q��"c�R�VB=�
\^`bd��	!�	,((@�x��0`��8c@^�`(L ��@r������b�
o,Z����`=��1��A�T�B��}���Y�
�v���ʕ��П
4Sv|'6 $QNFWe�����S~2���m�eg{j5�{�I����:
l�o���D� �����qE�"t>9��˵��6�B��
�P5�Oc[2�QT@;�
Z\v`b���	!�	,((@�x��0`��8c@^�`(L ��@�qLC�nj����`��-�ɉ��`>��u��A�T�B��}Ȏ�ω1������QF�l�S3!W#X�G�e������U���m�egwj6�|$J��
��;
l�L���!v�y���p�t?Uʡ!o�"��"��гP6���/�XTA<�
Z\v`b���	!�	,((@�x��0`��8c@^�`(L ��@���$C�nj�}��`��-
���8���D��@�4�@�h/4�"*l�Xэ���=h�5<:} n
L>�lVd�����S'���g�df{i6�{�I��P~� �k�/y���!u�x���p)�r
�s
�"�?m��
J�o����b���W�)<�
Y[]_a���	!�	,((@�x��0`��8c@^�`(L ��@�
K�p�nj����`��-����q|n�@��@ ��@��-4�"�غ�G	�z��ߏ	A|���#W�lVd�����Ry <���g�dfui6�z$J��
���k�n��;� t�w���
'a[Gr�!��(n��%:���Ҙ��h�3�PS�ۓY[t_a�	!�	,((@�x��0`��8c@^�`(L  �a
�U��V�=A|�Na�+��qiiL2�3\z�`�:�T+`��>`�KnXL����X�Y��4�$
6F~�%F�;�K[f�����W�Z��n�fh|k;�|(��T� �m�I��@�!v�����q ��LtD�
�F����7�O��'�;�n��X�ڗ^)abd��	!�	,((@�x��0`��8c@^�`(L�	�2��>��=�<W�{����S����Br|��߂��:R� P�@!`��tH^9L��p}`�w�4�~Ni��Q
OCM?�rXf�����T{=���n�f1|j?���J���z� �
m�E����!v�y�]|�q�
+nt@��BE����hc�;��w5�UC=��\^ac���	!�	,((@�x��0`��8c@^�`(L�u� �4Pk��q��b�o,b��@�Z���ނp���� P,
@!@�>^�M9�L����>�@w�?x
8p�P�]s$R�EXf�����T| ;�f���.�n3=���I�Q���
m�p��:�!w�z��q�@�r��1um�
�"�>�>_F�S�E�Z�+�UA;�
[]�ac��	!�	,((@�x��0`��8c@^�`(Lp%��3��
�����a�S#H�4&Aa@|�NoA��v��t(�Pд$4z���!�b��zL���Op
0$GyP�z�=�EYh�����U~X��p�h/�:w���G��R���
o�r���
�!�fM�A|��
��t��k����E�
���T�E�5�u3�VA;�
\^yce���	!�	,((@�x��0`��8c@^�`(L`��4P�
�����b�
o��)���1Q�8���u��A�T�B��u���Y�	��A;G>x�+�r$�}8dgs�
x$QHmWe�����S8!V��h�e�xj5���M�����l�p��'bw��u�Nz�%x�r��JŴ:�hpج���P=�h�T@;�
Z\w`b��	!�	,((@�x��0`��8c@^�`(Lp�@���>j�C��l�}��`��89BPc��q|n�@��@ ��@�
�5w��"*l]�е��O��ȹul
f^{vz�$PylVd�����R�<���g�d1�w6���G��O���
k�D�\����l�s�g����)aZ�l���x�g����PSA<�
Y[u_a���	!�	,((@�x��0`��8c@^�@@��g�h�^4�o�S�V�/,��c\:
��-m�߁�<���� P*@!��>fOP9L������>|���[��q�UO
�s�*R�OXf�����T/W��n�fh�7?�������+�'p~u�s�
G��w�
zi|�"���r�uų���x���Z�B��;�ז[]wacӗ�9	!�	,((@�x��0`��8c@^��h$.c��V
�C��l��������p��1Qʎ>��u��A�T�B��}��Fr�&�x�m[ԇ��У9]vF
��I� X�JWe�����S�V��m�eg�4>��'M����;
lo~ho9oR�J�E-q�~�������p�|lԾ?����P6�mʗTA<�
Z\u`b|��	!�	,((@�x��0`��8c@^��h�.c��V
�C$Ʋ���Z��'W�-L����jL�9NoA�J��t:H�A0P�>`�M9�K����݆��w��Wx*
����'=CiZf�����U�����x�fh�4=���N���
8k�x�(@��t8��i�jT�n���� q�zm�t����±g�2��VL;�
]_bd��[	!�	,((@�x��0`��8c@^��CZ��K`��@ղ�=�<�{+*�o��e�
�Ә,g�߂�k�:R� PH@!`�>b�K�L�����{����0��u�&
���(?�JXf�����T�W��n�fh�k7���ud�FQ��
#n�mp
�;H�p�;�Iy����D�%�r�w@�s�пS�i�7���YU��[]`ac�7	!�	,((@�x��0`��8c@^�E��f�Lp��@ղ�=�<�{+������*��q�iL�3�oAȵz��o(J��i1�V�4�`��Ҭ��gz'
���DS�P!g�����U�Y���Zi�p�b^�OB�~GR�.j�)�vt�C]��3����̎��|@�w8�H�P�7��gV�x�\^r�e��	!�	,((@�x��0`�%j����leZL��p@��=�}����a9�7Kp�l�g2$\z1��Zh���q5�''D^�V�s�|�]m��|7>�8
��$�FB�j[g�����W�������gi�l;�T
�N�P>��?�
���S
nxu�s��0�
�1�����)�{�~��yC��V�|�;����XM@�
^rd��	!�	,((@�x��0`��˻�Sxdir�v���=՞�=�<�}l[c0���d�1Q�@�!�Ⅲ�A�.�B@�u4�2h���n*\	#����	:}+
��$�"�)Qx}ve�����S��W��h�X1b[E5>y�*3�L��RIP�$�
�;
l$a�G���H�+|ǽ��(q�o��s
���R�h�7����T�ܔZ\|�bo��7	!�	,((@�x��0`�
m�; OэdYL`�,�=ղ�=�<�{*��� lv>�nIjL���oAȵz��t(�@!@�:b#�nU�;(�{%H*,��pd�}P;k�W
��%"�$q?��Yf�����U�i�����fhC�l!i�-�N���4�
�m
�K�sy�I���;��B��#�x�%���v
���T�PR?���V��\^`bd���	!�,((@�x��0`�5ō�+ OэdyeK`��@՚�=�<ﭨ%��!j���1Q�@>!��A��A�T�B`���Ncj�����3	�ش�N���'q~I
r�#�!�#(>EyWe�����S�V����e1oMk{���'��}4�
� �U
n�%p���,����̭v����t?����Q��l�j;ޖZ\}`b���7	;�PNG


IHDR����Z�PLTE�z=�tRNS@��f�IDATx�������`��@��TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU�=8 �u;`.��R��IEND�B`�<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 viewBox="0 0 212.3 101.7" style="enable-background:new 0 0 212.3 101.7;" xml:space="preserve">
<style type="text/css">
	.st0{fill:none;stroke:#4D4D4D;stroke-width:8.7434;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:22.9256;}
	.st1{clip-path:url(#SVGID_2_);fill:url(#SVGID_3_);}
	.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#4D4D4D;}
</style>
<path class="st0" d="M145,56.9c4.6,5.5,7.7,6.7,13.6-1.9c1.3-2,7.7-7.8,9.8-8.8c0.6-0.3,9.9,5.2,9.9,5.3c1.1,1.4-14.1,2-15.8,3.6
	c-6,5.7-4.5,11-14.5,11.9c-12.6,1.2-16.2-7.7-19.4-10.8c-2-1.2-4-2.3-6-3.5c1.7,10.8,0.2,22.1,0.2,33c0,7.6-27.5,3.5-27,1.8
	c9.7-29.1-32.4-37.3-22.6-0.8c-8.8,3.9-17.7,3.9-26.5,0c-1.5-17.5-3.4-34.9,4.1-46.5c-5.2-2.2-7.7-2.9-8.1,3.9
	c-0.1,1.3-0.9,4.4-1.6,5.5c-0.2,0.3-2.2-1.2-2.1-1.2c0.1-0.5,1.5-2,1.9-3.3c1.3-4.4-0.9-6.6,3.7-9.8c4.9-3.4,8.6-1.6,11.1-0.6
	c6.3-5.4,13.8-8.6,29-8.6c-0.5,9.1,11.4,30.9,28.6,34.1C99,53.1,91.9,39.9,90.6,32.6c0-0.2-0.1-0.4-0.1-0.6
	c-4.6-26.9,25.8-25.1,31.4-8.9c16.7-2.8,14.7,7.6,18.9,14.5C143.9,44.1,146.1,52.1,145,56.9z"/>
<g>
	<defs>
		<path id="SVGID_1_" d="M145,56.9c4.6,5.5,7.7,6.7,13.6-1.9c1.3-2,7.7-7.8,9.8-8.8c0.6-0.3,9.9,5.2,9.9,5.3
			c1.1,1.4-14.1,2-15.8,3.6c-6,5.7-4.5,11-14.5,11.9c-12.6,1.2-16.2-7.7-19.4-10.8c-2-1.2-4-2.3-6-3.5c1.7,10.8,0.2,22.1,0.2,33
			c0,7.6-27.5,3.5-27,1.8c9.7-29.1-32.4-37.3-22.6-0.8c-8.8,3.9-17.7,3.9-26.5,0c-1.5-17.5-3.4-34.9,4.1-46.5
			c-5.2-2.2-7.7-2.9-8.1,3.9c-0.1,1.3-0.9,4.4-1.6,5.5c-0.2,0.3-2.2-1.2-2.1-1.2c0.1-0.5,1.5-2,1.9-3.3c1.3-4.4-0.9-6.6,3.7-9.8
			c4.9-3.4,8.6-1.6,11.1-0.6c6.3-5.4,13.8-8.6,29-8.6c-0.5,9.1,11.4,30.9,28.6,34.1C99,53.1,91.9,39.9,90.6,32.6
			c0-0.2-0.1-0.4-0.1-0.6C85.9,5.1,116.3,6.8,121.8,23c16.7-2.8,14.7,7.6,18.9,14.5C143.9,44.1,146.1,52.1,145,56.9"/>
	</defs>
	<clipPath id="SVGID_2_">
		<use xlink:href="#SVGID_1_"  style="overflow:visible;"/>
	</clipPath>
	
		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-30.7393" y1="807.7318" x2="-30.2793" y2="807.7318" gradientTransform="matrix(-179.082 -103.3928 85.8686 -148.7292 -74733.3203 117016.5)">
		<stop  offset="0" style="stop-color:#E5E5E5"/>
		<stop  offset="1" style="stop-color:#FFFFFF"/>
	</linearGradient>
	<polygon class="st1" points="217.6,27.1 74,-55.8 0.6,71.2 144.3,154.2 	"/>
</g>
<path class="st2" d="M131.3,32c1.2,0.3,2,1.3,1.8,2.2c-0.2,0.9-1.4,1.3-2.6,1c-1.2-0.3-2-1.3-1.8-2.2
	C128.9,32.1,130.1,31.6,131.3,32"/>
</svg>
GIF89a���ݞ�������������뀀����!�NETSCAPE2.0!�XMP DataXMPE?xpacket586180" xmpMM:InstanceID="xmp.iid:9ACA89BEE0Cpacket end="r"?>!�	,@\x��.&�I�`V)@+ZD(�$˰���k�b�L��w�,��H�� �@G\��e�7S�(C�*8q��|��%L{�(t'����!�	,@^x��.&�I�`V)@+�D(W,æ����mA��w��󑀃4��p(B��!3�N����"�	Uf`��\����n�.�+!�	,@Zx��.&�I�`�	Zђ@(C$K������(�Jݱ�rC �An�(-J�!C	8-K_EH�vP��nb����->ꓣ�ʤ�E!�	,@Zx��.&�I�`V)@+�$	�2l�1|���đw���O�0�:�(8!��LE8%8�K�2�-d7��m!�e��$Af����̠�F!�	,@Zx��.&�)���A+�!����l�fl�)�]�CTL��pQ<
�˃(P�j7D�P���u�pfN��(A铣��Ȣ�F!�	,@Yx��.&��F�;{M�y$�@��k�n��x����60	��P4!�N-���@�P�Z	��k�(F�L8�[��'G�ڑA�!�	,@Yx��.&�9��8�M�u^�d*UL����{�A�˻K�0�9�(� ��������EK�X?C+Q�†L-I��Y�ډA�!�	,@Zx��.&�0�8�M�u^�d*
a���J��1S���4��9�e`� �����
�M% h������FW�0-I����`��F!�	,@]x��.&�i�F0)M�y�P,�C����$x��@����H�q@�����J�C,��P�[���
g92��
�L���(hr���t�H!�	,@\x��.&�i!� ����`��0ff�r�)�J(D���H�� ��F\��e����P�
N\���3(r1B!��z'L�W0c�W����!�	,@^x��.&�)�XZA+W� NA��b���u$J-�\$�P�`p+.�JC��<hr��"($*L‰�
����Y���	
H����g$!�	,@Yx��.&�I�`�	Zћ$�F������[w�I���⑀C ��m�(-J�!C,}�`)+i݀��-gZ�iX~�#G�W�I�!�	,@Wx��.&�I�`V)@+��� F�÷n��[JG�.��C���)�(������݂
�m�:l+�ЦKpidH���$��!�	,@Zx��.&�I�`V)@+��� Z�D�����w�ۥ��G��j �6�@4"������A��*iݸEhH-��.I��F�`�Ġ�F!�	,@Xx��.&�I�`V)@+��� q��b@b������B@�0���pA<Z��Uh�i�r�v��m'�)urY��%�
 Zf�•"��	!�	,@Xx��.&�I�`R�M�U�P,
@*
a�'���qߋ\�
W��hi,b��I*3�O÷��U
0[Q���`֓����p xj��BSډ	!�	,@^x��.&�I�`�F@Sh�$�W
b�(���qߋL��8t � W��e�誀�]�xPi%0�פ�j/���50GA�:9
m��6�7!�	,@]x��.&�I�`�Q@�@Sh�$�P�� ~e�bl����@(�I�@�����J�!S,��P��M\8�IA_����5,G�:rr��t�H!�	,@\x��.&�I�`�PH��Z5	�2��1���5@k�GiOK,
%�P�`�+.�J�y��B
ߎ�X�&�÷��}/�J��4I�AJ�X3���!�	,@Zx��.&�I�`�ʘ�Z�g������x���J6QF�0��pA<n��Cj�p���:���{�R���$����p=ˢ�E!�	,@Zx��.&�I�`�BMU�P,C���Upb,5{)�}���C4�a�x�$������M���u��m)���B��B�����Δ�F!�	,@[x��.&�I�`��M�U�P,�4)ia�'��qߋ����C��V�FQ�Lfv��o*ZT	L��(F�� ����Ad!��Q@Oh�0!�	,@Yx��.&�I�`�V�
ԓP,��h]�#�j�1k��
����@j�`X<&�H���$�u²m'
�E\�rPҳ��1F�U�=�!�	,@Zx��.&�I�`V)@+���yV����"J��@`��bh� ��U��x�$@��:i�����.��B:I�,쑣`�Ġ�F!�	,@Xx��.&�I�`V)@+���` F�����wH������;�Ch�0e� �����P
oҺm)
'!;%Z��H	�
d��u[ڇ	!�	,@]x��.&�I�`V)@+���`
n(Sb@b��Q@E--0�$�P�`p+.�J�y�:���@T���G[� Mr��ԕ&h+���9;u�H!�	,@Zx��.&�H�d`�
Z�%�`@���a@b,��L���C@��m�("
ɥ#�H?�Pa���Э	�ۮJ�r�ȡbɘ�a!�	,@Zx��.&���`����`��0Vf�r�)������C@��m�("5J�S5��@*�q,����H
X�fʽ,IA���^ɤ�F!�	,@]x��.(b��F0�St�W,C�CSjpnkVA�����J�� � D\����y��@
`p�H��u��(=E��T��((���u�H!�	,@]x��.�`���x{l�a�2��1����!@�J�%�i��)C�����0"e4�a,��PqZ��� 
Y�"��җe�
c���t�H!�	,@[x��.F5��X0�@St�W,U�Z����Eӑ������Ct��pQ@�J�j��7��b���΂�$s���(Gf��Q��b�0!�	,@\x��.&��F01M	���`��Vf�n�Rz��C�2��pQ<
��g'P���%T�9�
��=�1�8_���`�(�0����!�	,@Xx��.&����z�M��M�2��1���-x���C@(��f<&�S�ӈ	D�J"�N����'�sD)h��2��	!�	,@Zx��.&�I�`V)@+�@�6	�2l�1|��,��m�����h��pQ��Kb(`�(��bU��$��nU�h�(Aj���ʣxE!�	,@Zx��.&�I�`V)@+�0(��˰������G�z�.1�$�P!��8
B��#�9��uy�(�.�%�\��Ũ�,Ae�%ΙxF!�,@\x��.&�I�`�	Z�Fw�U,æ����QA����˻K�0��pA<Z��C&p�RወH4ԏ�:�)�Ci��%�[�(ti�^�;<svg viewBox="0 0 55 32.25" xmlns="http://www.w3.org/2000/svg"><g fill="#3f3f3f"><path d="m54.91 17a2.74 2.74 0 0 0 -.22-.55 5.88 5.88 0 0 0 -3.09-2.72 3.82 3.82 0 0 0 -2.23-.14 3.94 3.94 0 0 0 -1.89 1.14l-.35.4-.83 1.08c-.35.45-.73.92-1.12 1.37-.2.22-.39.42-.58.6a2.86 2.86 0 0 1 -.57.46.69.69 0 0 1 -.36.14h-.08s0 0-.05 0v-.05-.05a4.48 4.48 0 0 1 -.63-1.37c-.18-.57-.31-1.17-.42-1.68s-.22-1.16-.3-1.75c0-.22-.08-.46-.12-.7v-.22c0-.2-.07-.41-.12-.61s0-.21-.07-.32a13.86 13.86 0 0 0 -.6-1.83 8.92 8.92 0 0 0 -.92-1.74 7.4 7.4 0 0 0 -3-2.61 7.56 7.56 0 0 0 -2.94-.67h-.39a7.76 7.76 0 0 0 -2.57-3.31 8.9 8.9 0 0 0 -4.57-1.82 6.91 6.91 0 0 0 -2.46.14 6.1 6.1 0 0 0 -2.27 1.07 6.45 6.45 0 0 0 -1.65 1.89 8.12 8.12 0 0 0 -.86 2.25 7.72 7.72 0 0 0 -.17 1 15.81 15.81 0 0 0 -2.48.08c-.43 0-.85.08-1.27.14h-.32l-.52.1-.27.05-.39.08-.39.1a19.47 19.47 0 0 0 -3 1c-.47.19-.95.4-1.46.66l-.18.09-.53.3-.23.13a4.61 4.61 0 0 0 -.7-.42 4.2 4.2 0 0 0 -1.4-.39 3.52 3.52 0 0 0 -1.51.17l-.35.16h-.05l-.13.06-.15.11-.32.22-.27.26a4.91 4.91 0 0 0 -1.21 2.49 3.1 3.1 0 0 0 -.09.5.77.77 0 0 1 0 .15l-.07.56a1.86 1.86 0 0 1 -.32.79 3.94 3.94 0 0 1 -.68.74l-.46.47-.07.07a2.59 2.59 0 0 0 -.46.53l-.07.12a.83.83 0 0 0 -.07.18l-.06.1a.36.36 0 0 0 0 .11 1 1 0 0 0 0 .24.6.6 0 0 0 0 .24 1 1 0 0 0 .09.21 1.17 1.17 0 0 0 .2.26l.12.11.26.19a3.69 3.69 0 0 0 .35.19 2.19 2.19 0 0 0 .82.23 2.3 2.3 0 0 0 .86-.07 3.43 3.43 0 0 0 1.39-.71c-.09 1-.25 2-.33 3.18-.1 1.54-.14 3.12-.1 4.83s.14 3.3.3 4.81a.73.73 0 0 0 .32.54 9.75 9.75 0 0 0 2.82 1.36 9.61 9.61 0 0 0 3.09.38 12.05 12.05 0 0 0 3-.5 13.07 13.07 0 0 0 1.44-.52l.7-.31.7-.38a.76.76 0 0 0 .35-.79 11.7 11.7 0 0 1 0-4.7 3.42 3.42 0 0 1 1-1.78 2.68 2.68 0 0 1 1.86-.55 2.54 2.54 0 0 1 1.8.68 3.83 3.83 0 0 1 1 1.85 9.23 9.23 0 0 1 .28 2.33v1.21a11.63 11.63 0 0 1 -.14 1.18.72.72 0 0 0 .43.79l1.4.61.16.05 1.3.44 1.12.28h.26.13l.77.11h.52.27.48a9.19 9.19 0 0 0 2.68-.37l.23-.07c.17-.06.36-.12.53-.2l.37-.16.25-.12.11-.06a3.35 3.35 0 0 0 .36-.21l.09-.06.26-.17h.07l.27-.21v-.05l.11-.09h.05l.14-.14a.7.7 0 0 0 .18-.39 38.29 38.29 0 0 0 .39-5.61c0-.85 0-1.77 0-2.79 0-.16 0-.32 0-.47v-.1c.37.38.74.72 1.11 1a14.36 14.36 0 0 0 3.18 2.13 7.81 7.81 0 0 0 1.89.64 5.35 5.35 0 0 0 2.11 0 4.6 4.6 0 0 0 1.93-.95 2.1 2.1 0 0 0 .27-.24l.12-.11.24-.26.04-.04c.16-.2.32-.42.45-.61a1.36 1.36 0 0 0 .12-.17 10.11 10.11 0 0 1 2.27-2.45 4.58 4.58 0 0 1 1.39-.68 5.24 5.24 0 0 1 1.58-.18h.75 1.08a1.57 1.57 0 0 0 .86-.27 1.22 1.22 0 0 0 .39-.45 1.43 1.43 0 0 0 .13-.49 2 2 0 0 0 -.11-.7zm-21.57 1.79c.06.82.11 1.71.14 2.72s0 1.9 0 2.73a37.47 37.47 0 0 1 -.33 5.11s0 0 0 0a1.24 1.24 0 0 1 -.18.14h-.07l-.18.12-.08.05a1.64 1.64 0 0 1 -.28.16l-.28.15-.31.13a3.25 3.25 0 0 1 -.4.15l-.22.07a8.2 8.2 0 0 1 -2.64.29h-.27-.41l-.69-.11h-.12-.21l-1-.25c-.36-.11-.72-.24-1.07-.36l-.26-.09-.79-.34c0-.23.05-.47.07-.73 0-.45.05-.9.05-1.33a11.22 11.22 0 0 0 -.33-2.71 6.48 6.48 0 0 0 -.5-1.34 4.55 4.55 0 0 0 -.9-1.23 3.88 3.88 0 0 0 -1.33-.84 4.65 4.65 0 0 0 -1.5-.28 4.75 4.75 0 0 0 -1.49.18 3.76 3.76 0 0 0 -1.4.74 4.14 4.14 0 0 0 -1 1.21 5.83 5.83 0 0 0 -.52 1.37 10.23 10.23 0 0 0 -.27 2.72c0 .44 0 .89.09 1.34 0 .27.06.52.1.76l-.12.07-.62.28a12.85 12.85 0 0 1 -1.27.45 10.47 10.47 0 0 1 -2.65.44 8.31 8.31 0 0 1 -2.61-.32 7.84 7.84 0 0 1 -2.07-.95 57 57 0 0 1 -.17-9 33.2 33.2 0 0 1 .61-4.6l.28-1.11c.07-.23.14-.46.22-.68l.13-.4s0 0 0-.06c.12-.26.21-.49.3-.71l.06-.19a.29.29 0 0 0 0-.09c.14-.23-.13-.6-.37-.79s-.34-.19-.43-.12a.83.83 0 0 0 -.63.4l-.21.48c0 .14-.11.28-.15.42l-.06.33a11.91 11.91 0 0 1 -1.16 1.89 5.22 5.22 0 0 1 -.71.75 2 2 0 0 1 -.73.41.89.89 0 0 1 -.64-.06l.45-.4a5.78 5.78 0 0 0 .9-1 3.35 3.35 0 0 0 .57-1.4l.08-.61s0-.09 0-.14a1.78 1.78 0 0 1 .07-.39 3.41 3.41 0 0 1 .81-1.74l.15-.15.21-.17.07-.06h.06l.22-.1a2.19 2.19 0 0 1 .84-.09 3 3 0 0 1 1.68.79.78.78 0 0 0 1 .06c.21-.13.42-.26.61-.36l.47-.26.17-.09c.48-.23.92-.43 1.35-.61a18.53 18.53 0 0 1 2.82-.92l.36-.09.35-.1.27-.05a3.4 3.4 0 0 1 .46-.09h.33c.37-.05.76-.11 1.14-.13a15.87 15.87 0 0 1 2.35 0 9.14 9.14 0 0 0 .54 2.18 13 13 0 0 0 1 2.08 17 17 0 0 0 1.24 1.88 31.73 31.73 0 0 0 6.29 6.22.49.49 0 0 0 .65-.06.55.55 0 0 0 .12-.35.5.5 0 0 0 -.16-.33 37.41 37.41 0 0 1 -3-3 29.09 29.09 0 0 1 -2.65-3.31 15.79 15.79 0 0 1 -2.01-3.77 8.54 8.54 0 0 1 -.42-1.92v-.47-.47a6.76 6.76 0 0 1 .17-.94 5.38 5.38 0 0 1 1.9-3.14 4.91 4.91 0 0 1 3.49-.88 7.39 7.39 0 0 1 3.58 1.39 6.27 6.27 0 0 1 2.3 3 .73.73 0 0 0 .85.47 3.05 3.05 0 0 1 .36 0h.4a6.44 6.44 0 0 1 .8.07 6 6 0 0 1 1.52.46 5.81 5.81 0 0 1 2.39 2.08 7.15 7.15 0 0 1 .77 1.46 11.11 11.11 0 0 1 .52 1.61c0 .1.05.2.07.3s.08.36.11.54v.24c0 .2.07.41.1.63.1.62.2 1.23.32 1.82s.26 1.2.46 1.84a5.94 5.94 0 0 0 .91 1.88 2 2 0 0 0 .49.46 2.69 2.69 0 0 0 .29.16h.07a2 2 0 0 0 .4.1 1.9 1.9 0 0 0 .76-.08 2.26 2.26 0 0 0 .33-.13 1.48 1.48 0 0 0 .25-.14 4.64 4.64 0 0 0 .84-.66c.26-.24.49-.5.68-.7.39-.45.75-.91 1.17-1.44l.83-1.08c.08-.09.16-.19.25-.28a2.41 2.41 0 0 1 1.15-.72 2.25 2.25 0 0 1 1.34.1 4.16 4.16 0 0 1 1.29.78 4.4 4.4 0 0 1 1 1.18 1.72 1.72 0 0 1 .1.26h-.8-.83a6.73 6.73 0 0 0 -2 .24 6.24 6.24 0 0 0 -1.86.9 11.39 11.39 0 0 0 -2.64 2.83l-.1.13a6.32 6.32 0 0 1 -.4.54.52.52 0 0 1 -.1.11c0 .07-.1.12-.15.18a.52.52 0 0 0 -.11.1c-.06.05-.11.11-.17.15a3 3 0 0 1 -1.29.63 4.83 4.83 0 0 1 -3-.52 12.7 12.7 0 0 1 -2.82-1.9 17.79 17.79 0 0 1 -2.4-2.51.78.78 0 0 0 -1.19 0 .83.83 0 0 0 -.21.53z"/><circle cx="36.12" cy="10.78" r="1.02"/></g></svg>.siteorigin-installer-wrap {
	margin-top: 0;
}

.siteorigin-installer-header {
	background: #f6f6f6;
	margin: 0 -20px;
	padding: 15px 30px 0 30px;
}

.siteorigin-installer-wrap .siteorigin-logo {
	align-items: center;
	color: #666;
	display: flex;
	font: 300 2.3em/1.4em "proxima-nova","Open Sans",Helvetica,Arial,sans-serif;
	gap: 8.5px;
	margin-bottom: 8px;
	margin-top: 9px;
}

.siteorigin-installer-wrap .siteorigin-logo img {
	height: 26px;
	opacity: 0.7;
	width: auto;
}

.siteorigin-installer-wrap .page-sections {
	border-bottom: 1px solid #d6d6d6;
	display: flex;
	margin: 0 -29px;
	padding: 5px 0 0 30px;
}

.siteorigin-installer-wrap .page-sections li {
	background: #f6f6f6;
	border: 1px solid #d6d6d6;
	border-right-width: 0;
	display: inline-block;
	font-size: 12px;
	line-height: 1em;
	margin: 0 0 -0.7px 0;
	transition: all .2s;
}

.siteorigin-installer-wrap .page-sections li:last-child {
	border-right-width: 1px
}

.siteorigin-installer-wrap .page-sections li a {
	box-shadow: none !important;
	color: #555;
	display: block;
	font-weight: bold;
	padding: 12px 25px;
	text-decoration: none;
}

.siteorigin-installer-wrap .page-sections li:hover {
 	background: #f3f3f3;
}

.siteorigin-installer-wrap .page-sections li.active-section {
	background: #f0f0f0;
	border-bottom-color: #f0f0f0;
}

.siteorigin-installer-wrap .siteorigin-products {
	display: flex;
	flex-flow: row wrap;
	min-width: 100%;
	position: relative;
}
.siteorigin-installer-wrap .siteorigin-installer-item {
	box-sizing: border-box;
	padding: 0 10px 24px 10px;
	position: relative;
	width: 33.33%;
}

.siteorigin-installer-wrap .siteorigin-installer-item .siteorigin-installer-item-body {
	background: #fefefe;
	border: 1px solid #d9d9d9;
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
	box-sizing: border-box;
	overflow: hidden;
	padding: 24px;
	display: flex;
}

.siteorigin-installer-wrap .siteorigin-installer-item.highlight-item .siteorigin-installer-item-body {
	box-shadow: 0 1px 12px rgba(0, 0, 0, 0.2);
}

.siteorigin-installer-wrap .siteorigin-installer-item.highlight-item .siteorigin-installer-item-body .siteorigin-required {
	display: block;
	color: #0073aa;
	margin-bottom: 1em;
}

@media screen and (max-width: 1280px) {
	.siteorigin-installer-wrap .siteorigin-installer-item {
		width: 50%;
	}
}

@media screen and (max-width: 960px) {
	.siteorigin-installer-wrap .siteorigin-installer-item {
		width: 100%;
	}
}

.siteorigin-installer-wrap .siteorigin-installer-item .siteorigin-installer-item-banner {
	flex: 5;
	height: 128px;
	margin: 0 15px 15px 0;
	object-fit: contain;
	overflow: hidden;
}

.siteorigin-installer-wrap .siteorigin-installer-item .siteorigin-product-content {
	flex: 9;
}

.siteorigin-installer-wrap .siteorigin-installer-item h3 {
	color: #0073aa;
	font-size: 1.4em;
	font-weight: 500;
	margin-top: 0;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-type-indicator {
	background-color: #00a0d2;
	color: #fff;
	display: inline-block;
	font-size: 0.85em;
	line-height: 1.5em;
	margin: 14px 0;
	padding: 2px 6px;
	text-decoration: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-description {
	color: #777777;
	line-height: 1.35em;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 15px;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons a:focus {
	outline: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .so-buttons-main {
	display: flex;
	gap: 10px;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons.so-buttons-force-wrap a {
	flex: 100%;

}

@-webkit-keyframes SiteOriginInstallerloading {
	from {
		background-position-x: 0;
	}
	to {
		background-position-x: 20.5em
	}
}

@keyframes SiteOriginInstallerloading {
	from {
		background-position: 0;
	}
	to {
		background-position-x: 20.5em;
	}
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .siteorigin-installer-button {
	-webkit-appearance: none;
	background: #f6f7f7;
	border-color: #2271b1;
	border-radius: 3px;
	border-style: solid;
	border-width: 1px;
	box-sizing: border-box;
	color: #2271b1;
	cursor: pointer;
	display: inline-block;
	font-size: 13px;
	line-height: 2.15384615;
	margin: 0;
	min-height: 30px;
	padding: 0 10px;
	text-decoration: none;
	vertical-align: top;
	white-space: nowrap;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .siteorigin-installer-button:focus {
	background: #f6f7f7;
	border-color: #3582c4;
	color: #0a4b78;
	box-shadow: 0 0 0 1px #3582c4;
	outline: 2px solid transparent;
	outline-offset: 0;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .siteorigin-installer-button:hover {
	background: #f0f0f1;
	border-color: #0a4b78;
	color: #0a4b78;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .siteorigin-installer-button:active {
	background: #f6f7f7;
	border-color: #8c8f94;
	box-shadow: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item .so-buttons .siteorigin-installer-button.disabled {
	border-color: #dcdcde;
	box-shadow: none;
	color: #a7aaad;
	cursor: default;
	-webkit-animation: SiteOriginInstallerloading 3s linear infinite;
	background: linear-gradient( 90deg, #f0f0f1 0%, rgba( 240,240,241, 0.5 ) 40%, rgba( 240,240,241, 0.5 ) 60%, #f0f0f1 100% );
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-active .siteorigin-installer-item-toggle-active .siteorigin-installer-item-activate {
	display: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive .siteorigin-installer-item-toggle-active .siteorigin-installer-item-deactivate {
	display: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive .product-status {
	opacity: 0;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive h3 {
	color: #666;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive .siteorigin-installer-item-text .siteorigin-installer-item-links {
	display: none;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive .siteorigin-installer-item-banner {
	-webkit-filter: grayscale(1);
	filter: gray;
	opacity: 0.7;
}

.siteorigin-installer-wrap .siteorigin-installer-item.siteorigin-installer-item-inactive .so-buttons .so-section-link {
	display: none;
}
#siteorigin-installer-notice {
	position: relative;
	margin: 15px 0;
}
#siteorigin-installer-notice .siteorigin-notice-dismiss {
	background: none;
	border: none;
	color: #787c82;
	cursor: pointer;
	margin: 0;
	padding: 9px;
	position: absolute;
	right: 1px;
	text-decoration: none;
	top: 0;
}
#siteorigin-installer-notice .siteorigin-notice-dismiss:before {
	-webkit-font-smoothing: antialiased;
	background: none;
	color: #787c82;
	content: '\f153';
	display: block;
	font: normal 16px/20px 'dashicons';
	height: 20px;
	speak: none;
	text-align: center;
	width: 20px;
}

#siteorigin-installer-notice .siteorigin-notice-dismiss:focus:before,
#siteorigin-installer-notice .siteorigin-notice-dismiss:hover:before {
	color: #d63638;
}
<?php
/*
Plugin Name: SiteOrigin Installer
Plugin URI: https://siteorigin.com/installer/
Description: This plugin installs all the SiteOrigin themes and plugins you need to get started with your new site.
Author: SiteOrigin
Author URI: https://siteorigin.com
Version: 1.0.3
License: GNU General Public License v3.0
License URI: http://www.opensource.org/licenses/gpl-license.php
*/

if ( ! defined( 'SITEORIGIN_INSTALLER_VERSION' ) ) {
	define( 'SITEORIGIN_INSTALLER_VERSION', '1.0.3' );
	define( 'SITEORIGIN_INSTALLER_DIR', plugin_dir_path( __FILE__ ) );
	define( 'SITEORIGIN_INSTALLER_URL', plugin_dir_url( __FILE__ ) );
}

if ( ! class_exists( 'SiteOrigin_Installer' ) ) {
	class SiteOrigin_Installer {
		public function __construct() {
			add_filter( 'siteorigin_premium_affiliate_id', array( $this, 'affiliate_id' ) );
			add_filter( 'init', array( $this, 'setup' ) );
			add_filter( 'siteorigin_add_installer', array( $this, 'load_status' ) );
			add_action( 'wp_ajax_so_installer_status', array( $this, 'installer_status_ajax' ) );
		}

		public static function single() {
			static $single;

			return empty( $single ) ? $single = new self() : $single;
		}

		public static function user_has_permission() {
			return (
				! defined( 'DISALLOW_FILE_MODS' ) ||
				! DISALLOW_FILE_MODS
			) &&
			current_user_can( 'install_plugins' ) &&
			current_user_can( 'install_themes' ) &&
			current_user_can( 'update_themes' ) &&
			current_user_can( 'update_plugins' );
		}

		public function setup() {
			if (
				apply_filters( 'siteorigin_add_installer', true ) &&
				is_admin() &&
				self::user_has_permission()
			) {
				// If the installer has been installed as a plugin (rather than bundled), setup the Github updater.
				if ( basename( SITEORIGIN_INSTALLER_DIR ) == 'siteorigin-installer-develop' ) {
					require_once SITEORIGIN_INSTALLER_DIR . '/inc/github-plugin-updater.php';
					new SiteOrigin_Installer_GitHub_Updater( __FILE__ );
				}

				require_once __DIR__ . '/inc/admin.php';
			}
		}

		/**
		 * Get the Affiliate ID from the database.
		 *
		 * @return mixed|void
		 */
		public function affiliate_id( $id ) {
			if ( get_option( 'siteorigin_premium_affiliate_id' ) ) {
				$id = get_option( 'siteorigin_premium_affiliate_id' );
			}

			return $id;
		}

		public function load_status() {
			return (bool) get_option( 'siteorigin_installer', true );
		}

		public function installer_status_ajax () {
			check_ajax_referer( 'siteorigin_installer_status', 'nonce' );
			update_option( 'siteorigin_installer', rest_sanitize_boolean( $_POST['status'] ) );
			die();
		}
	}
}
SiteOrigin_Installer::single();
> You might also like [Caret](http://caret.io?ref=parsedown) - our Markdown editor for Mac / Windows / Linux.

## Parsedown

[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown)
<!--[![Total Downloads](http://img.shields.io/packagist/dt/erusev/parsedown.svg?style=flat-square)](https://packagist.org/packages/erusev/parsedown)-->

Better Markdown Parser in PHP

[Demo](http://parsedown.org/demo) |
[Benchmarks](http://parsedown.org/speed) |
[Tests](http://parsedown.org/tests/) |
[Documentation](https://github.com/erusev/parsedown/wiki/)

### Features

* Super Fast
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Extensible
* Tested in 5.3 to 7.0 and in HHVM
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)

### Installation

Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).

### Example

``` php
$Parsedown = new Parsedown();

echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```

More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).

### Questions

**How does Parsedown work?**

It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line start with a `-` then it perhaps belong to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).

We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.

**Is it compliant with CommonMark?**

It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.

**Who uses it?**

[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [Herbie CMS](http://www.getherbie.org/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).

**How can I help?**

Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
<?php

#
#
# Parsedown
# http://parsedown.org
#
# (c) Emanuil Rusev
# http://erusev.com
#
# For the full license information, view the LICENSE file that was distributed
# with this source code.
#
#

class Parsedown
{
    # ~

    const version = '1.6.0';

    # ~

    function text($text)
    {
        # make sure no definitions are set
        $this->DefinitionData = array();

        # standardize line breaks
        $text = str_replace(array("\r\n", "\r"), "\n", $text);

        # remove surrounding line breaks
        $text = trim($text, "\n");

        # split text into lines
        $lines = explode("\n", $text);

        # iterate through lines to identify blocks
        $markup = $this->lines($lines);

        # trim line breaks
        $markup = trim($markup, "\n");

        return $markup;
    }

    #
    # Setters
    #

    function setBreaksEnabled($breaksEnabled)
    {
        $this->breaksEnabled = $breaksEnabled;

        return $this;
    }

    protected $breaksEnabled;

    function setMarkupEscaped($markupEscaped)
    {
        $this->markupEscaped = $markupEscaped;

        return $this;
    }

    protected $markupEscaped;

    function setUrlsLinked($urlsLinked)
    {
        $this->urlsLinked = $urlsLinked;

        return $this;
    }

    protected $urlsLinked = true;

    #
    # Lines
    #

    protected $BlockTypes = array(
        '#' => array('Header'),
        '*' => array('Rule', 'List'),
        '+' => array('List'),
        '-' => array('SetextHeader', 'Table', 'Rule', 'List'),
        '0' => array('List'),
        '1' => array('List'),
        '2' => array('List'),
        '3' => array('List'),
        '4' => array('List'),
        '5' => array('List'),
        '6' => array('List'),
        '7' => array('List'),
        '8' => array('List'),
        '9' => array('List'),
        ':' => array('Table'),
        '<' => array('Comment', 'Markup'),
        '=' => array('SetextHeader'),
        '>' => array('Quote'),
        '[' => array('Reference'),
        '_' => array('Rule'),
        '`' => array('FencedCode'),
        '|' => array('Table'),
        '~' => array('FencedCode'),
    );

    # ~

    protected $unmarkedBlockTypes = array(
        'Code',
    );

    #
    # Blocks
    #

    protected function lines(array $lines)
    {
        $CurrentBlock = null;

        foreach ($lines as $line)
        {
            if (chop($line) === '')
            {
                if (isset($CurrentBlock))
                {
                    $CurrentBlock['interrupted'] = true;
                }

                continue;
            }

            if (strpos($line, "\t") !== false)
            {
                $parts = explode("\t", $line);

                $line = $parts[0];

                unset($parts[0]);

                foreach ($parts as $part)
                {
                    $shortage = 4 - mb_strlen($line, 'utf-8') % 4;

                    $line .= str_repeat(' ', $shortage);
                    $line .= $part;
                }
            }

            $indent = 0;

            while (isset($line[$indent]) and $line[$indent] === ' ')
            {
                $indent ++;
            }

            $text = $indent > 0 ? substr($line, $indent) : $line;

            # ~

            $Line = array('body' => $line, 'indent' => $indent, 'text' => $text);

            # ~

            if (isset($CurrentBlock['continuable']))
            {
                $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);

                if (isset($Block))
                {
                    $CurrentBlock = $Block;

                    continue;
                }
                else
                {
                    if ($this->isBlockCompletable($CurrentBlock['type']))
                    {
                        $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
                    }
                }
            }

            # ~

            $marker = $text[0];

            # ~

            $blockTypes = $this->unmarkedBlockTypes;

            if (isset($this->BlockTypes[$marker]))
            {
                foreach ($this->BlockTypes[$marker] as $blockType)
                {
                    $blockTypes []= $blockType;
                }
            }

            #
            # ~

            foreach ($blockTypes as $blockType)
            {
                $Block = $this->{'block'.$blockType}($Line, $CurrentBlock);

                if (isset($Block))
                {
                    $Block['type'] = $blockType;

                    if ( ! isset($Block['identified']))
                    {
                        $Blocks []= $CurrentBlock;

                        $Block['identified'] = true;
                    }

                    if ($this->isBlockContinuable($blockType))
                    {
                        $Block['continuable'] = true;
                    }

                    $CurrentBlock = $Block;

                    continue 2;
                }
            }

            # ~

            if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted']))
            {
                $CurrentBlock['element']['text'] .= "\n".$text;
            }
            else
            {
                $Blocks []= $CurrentBlock;

                $CurrentBlock = $this->paragraph($Line);

                $CurrentBlock['identified'] = true;
            }
        }

        # ~

        if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
        {
            $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
        }

        # ~

        $Blocks []= $CurrentBlock;

        unset($Blocks[0]);

        # ~

        $markup = '';

        foreach ($Blocks as $Block)
        {
            if (isset($Block['hidden']))
            {
                continue;
            }

            $markup .= "\n";
            $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']);
        }

        $markup .= "\n";

        # ~

        return $markup;
    }

    #
    # Allow for plugin extensibility
    #
    protected function isBlockContinuable($Type)
    {
        return method_exists($this, 'block'.$Type.'Continue');
    }

    protected function isBlockCompletable($Type)
    {
        return method_exists($this, 'block'.$Type.'Complete');
    }

    #
    # Code

    protected function blockCode($Line, $Block = null)
    {
        if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted']))
        {
            return;
        }

        if ($Line['indent'] >= 4)
        {
            $text = substr($Line['body'], 4);

            $Block = array(
                'element' => array(
                    'name' => 'pre',
                    'handler' => 'element',
                    'text' => array(
                        'name' => 'code',
                        'text' => $text,
                    ),
                ),
            );

            return $Block;
        }
    }

    protected function blockCodeContinue($Line, $Block)
    {
        if ($Line['indent'] >= 4)
        {
            if (isset($Block['interrupted']))
            {
                $Block['element']['text']['text'] .= "\n";

                unset($Block['interrupted']);
            }

            $Block['element']['text']['text'] .= "\n";

            $text = substr($Line['body'], 4);

            $Block['element']['text']['text'] .= $text;

            return $Block;
        }
    }

    protected function blockCodeComplete($Block)
    {
        $text = $Block['element']['text']['text'];

        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');

        $Block['element']['text']['text'] = $text;

        return $Block;
    }

    #
    # Comment

    protected function blockComment($Line)
    {
        if ($this->markupEscaped)
        {
            return;
        }

        if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!')
        {
            $Block = array(
                'markup' => $Line['body'],
            );

            if (preg_match('/-->$/', $Line['text']))
            {
                $Block['closed'] = true;
            }

            return $Block;
        }
    }

    protected function blockCommentContinue($Line, array $Block)
    {
        if (isset($Block['closed']))
        {
            return;
        }

        $Block['markup'] .= "\n" . $Line['body'];

        if (preg_match('/-->$/', $Line['text']))
        {
            $Block['closed'] = true;
        }

        return $Block;
    }

    #
    # Fenced Code

    protected function blockFencedCode($Line)
    {
        if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches))
        {
            $Element = array(
                'name' => 'code',
                'text' => '',
            );

            if (isset($matches[1]))
            {
                $class = 'language-'.$matches[1];

                $Element['attributes'] = array(
                    'class' => $class,
                );
            }

            $Block = array(
                'char' => $Line['text'][0],
                'element' => array(
                    'name' => 'pre',
                    'handler' => 'element',
                    'text' => $Element,
                ),
            );

            return $Block;
        }
    }

    protected function blockFencedCodeContinue($Line, $Block)
    {
        if (isset($Block['complete']))
        {
            return;
        }

        if (isset($Block['interrupted']))
        {
            $Block['element']['text']['text'] .= "\n";

            unset($Block['interrupted']);
        }

        if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text']))
        {
            $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1);

            $Block['complete'] = true;

            return $Block;
        }

        $Block['element']['text']['text'] .= "\n".$Line['body'];;

        return $Block;
    }

    protected function blockFencedCodeComplete($Block)
    {
        $text = $Block['element']['text']['text'];

        $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');

        $Block['element']['text']['text'] = $text;

        return $Block;
    }

    #
    # Header

    protected function blockHeader($Line)
    {
        if (isset($Line['text'][1]))
        {
            $level = 1;

            while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
            {
                $level ++;
            }

            if ($level > 6)
            {
                return;
            }

            $text = trim($Line['text'], '# ');

            $Block = array(
                'element' => array(
                    'name' => 'h' . min(6, $level),
                    'text' => $text,
                    'handler' => 'line',
                ),
            );

            return $Block;
        }
    }

    #
    # List

    protected function blockList($Line)
    {
        list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]');

        if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches))
        {
            $Block = array(
                'indent' => $Line['indent'],
                'pattern' => $pattern,
                'element' => array(
                    'name' => $name,
                    'handler' => 'elements',
                ),
            );

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $matches[2],
                ),
            );

            $Block['element']['text'] []= & $Block['li'];

            return $Block;
        }
    }

    protected function blockListContinue($Line, array $Block)
    {
        if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
        {
            if (isset($Block['interrupted']))
            {
                $Block['li']['text'] []= '';

                unset($Block['interrupted']);
            }

            unset($Block['li']);

            $text = isset($matches[1]) ? $matches[1] : '';

            $Block['li'] = array(
                'name' => 'li',
                'handler' => 'li',
                'text' => array(
                    $text,
                ),
            );

            $Block['element']['text'] []= & $Block['li'];

            return $Block;
        }

        if ($Line['text'][0] === '[' and $this->blockReference($Line))
        {
            return $Block;
        }

        if ( ! isset($Block['interrupted']))
        {
            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'] []= $text;

            return $Block;
        }

        if ($Line['indent'] > 0)
        {
            $Block['li']['text'] []= '';

            $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);

            $Block['li']['text'] []= $text;

            unset($Block['interrupted']);

            return $Block;
        }
    }

    #
    # Quote

    protected function blockQuote($Line)
    {
        if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
        {
            $Block = array(
                'element' => array(
                    'name' => 'blockquote',
                    'handler' => 'lines',
                    'text' => (array) $matches[1],
                ),
            );

            return $Block;
        }
    }

    protected function blockQuoteContinue($Line, array $Block)
    {
        if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
        {
            if (isset($Block['interrupted']))
            {
                $Block['element']['text'] []= '';

                unset($Block['interrupted']);
            }

            $Block['element']['text'] []= $matches[1];

            return $Block;
        }

        if ( ! isset($Block['interrupted']))
        {
            $Block['element']['text'] []= $Line['text'];

            return $Block;
        }
    }

    #
    # Rule

    protected function blockRule($Line)
    {
        if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
        {
            $Block = array(
                'element' => array(
                    'name' => 'hr'
                ),
            );

            return $Block;
        }
    }

    #
    # Setext

    protected function blockSetextHeader($Line, array $Block = null)
    {
        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
        {
            return;
        }

        if (chop($Line['text'], $Line['text'][0]) === '')
        {
            $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';

            return $Block;
        }
    }

    #
    # Markup

    protected function blockMarkup($Line)
    {
        if ($this->markupEscaped)
        {
            return;
        }

        if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
        {
            $element = strtolower($matches[1]);

            if (in_array($element, $this->textLevelElements))
            {
                return;
            }

            $Block = array(
                'name' => $matches[1],
                'depth' => 0,
                'markup' => $Line['text'],
            );

            $length = strlen($matches[0]);

            $remainder = substr($Line['text'], $length);

            if (trim($remainder) === '')
            {
                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
                {
                    $Block['closed'] = true;

                    $Block['void'] = true;
                }
            }
            else
            {
                if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
                {
                    return;
                }

                if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
                {
                    $Block['closed'] = true;
                }
            }

            return $Block;
        }
    }

    protected function blockMarkupContinue($Line, array $Block)
    {
        if (isset($Block['closed']))
        {
            return;
        }

        if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
        {
            $Block['depth'] ++;
        }

        if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
        {
            if ($Block['depth'] > 0)
            {
                $Block['depth'] --;
            }
            else
            {
                $Block['closed'] = true;
            }
        }

        if (isset($Block['interrupted']))
        {
            $Block['markup'] .= "\n";

            unset($Block['interrupted']);
        }

        $Block['markup'] .= "\n".$Line['body'];

        return $Block;
    }

    #
    # Reference

    protected function blockReference($Line)
    {
        if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
        {
            $id = strtolower($matches[1]);

            $Data = array(
                'url' => $matches[2],
                'title' => null,
            );

            if (isset($matches[3]))
            {
                $Data['title'] = $matches[3];
            }

            $this->DefinitionData['Reference'][$id] = $Data;

            $Block = array(
                'hidden' => true,
            );

            return $Block;
        }
    }

    #
    # Table

    protected function blockTable($Line, array $Block = null)
    {
        if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted']))
        {
            return;
        }

        if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '')
        {
            $alignments = array();

            $divider = $Line['text'];

            $divider = trim($divider);
            $divider = trim($divider, '|');

            $dividerCells = explode('|', $divider);

            foreach ($dividerCells as $dividerCell)
            {
                $dividerCell = trim($dividerCell);

                if ($dividerCell === '')
                {
                    continue;
                }

                $alignment = null;

                if ($dividerCell[0] === ':')
                {
                    $alignment = 'left';
                }

                if (substr($dividerCell, - 1) === ':')
                {
                    $alignment = $alignment === 'left' ? 'center' : 'right';
                }

                $alignments []= $alignment;
            }

            # ~

            $HeaderElements = array();

            $header = $Block['element']['text'];

            $header = trim($header);
            $header = trim($header, '|');

            $headerCells = explode('|', $header);

            foreach ($headerCells as $index => $headerCell)
            {
                $headerCell = trim($headerCell);

                $HeaderElement = array(
                    'name' => 'th',
                    'text' => $headerCell,
                    'handler' => 'line',
                );

                if (isset($alignments[$index]))
                {
                    $alignment = $alignments[$index];

                    $HeaderElement['attributes'] = array(
                        'style' => 'text-align: '.$alignment.';',
                    );
                }

                $HeaderElements []= $HeaderElement;
            }

            # ~

            $Block = array(
                'alignments' => $alignments,
                'identified' => true,
                'element' => array(
                    'name' => 'table',
                    'handler' => 'elements',
                ),
            );

            $Block['element']['text'] []= array(
                'name' => 'thead',
                'handler' => 'elements',
            );

            $Block['element']['text'] []= array(
                'name' => 'tbody',
                'handler' => 'elements',
                'text' => array(),
            );

            $Block['element']['text'][0]['text'] []= array(
                'name' => 'tr',
                'handler' => 'elements',
                'text' => $HeaderElements,
            );

            return $Block;
        }
    }

    protected function blockTableContinue($Line, array $Block)
    {
        if (isset($Block['interrupted']))
        {
            return;
        }

        if ($Line['text'][0] === '|' or strpos($Line['text'], '|'))
        {
            $Elements = array();

            $row = $Line['text'];

            $row = trim($row);
            $row = trim($row, '|');

            preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);

            foreach ($matches[0] as $index => $cell)
            {
                $cell = trim($cell);

                $Element = array(
                    'name' => 'td',
                    'handler' => 'line',
                    'text' => $cell,
                );

                if (isset($Block['alignments'][$index]))
                {
                    $Element['attributes'] = array(
                        'style' => 'text-align: '.$Block['alignments'][$index].';',
                    );
                }

                $Elements []= $Element;
            }

            $Element = array(
                'name' => 'tr',
                'handler' => 'elements',
                'text' => $Elements,
            );

            $Block['element']['text'][1]['text'] []= $Element;

            return $Block;
        }
    }

    #
    # ~
    #

    protected function paragraph($Line)
    {
        $Block = array(
            'element' => array(
                'name' => 'p',
                'text' => $Line['text'],
                'handler' => 'line',
            ),
        );

        return $Block;
    }

    #
    # Inline Elements
    #

    protected $InlineTypes = array(
        '"' => array('SpecialCharacter'),
        '!' => array('Image'),
        '&' => array('SpecialCharacter'),
        '*' => array('Emphasis'),
        ':' => array('Url'),
        '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
        '>' => array('SpecialCharacter'),
        '[' => array('Link'),
        '_' => array('Emphasis'),
        '`' => array('Code'),
        '~' => array('Strikethrough'),
        '\\' => array('EscapeSequence'),
    );

    # ~

    protected $inlineMarkerList = '!"*_&[:<>`~\\';

    #
    # ~
    #

    public function line($text)
    {
        $markup = '';

        # $excerpt is based on the first occurrence of a marker

        while ($excerpt = strpbrk($text, $this->inlineMarkerList))
        {
            $marker = $excerpt[0];

            $markerPosition = strpos($text, $marker);

            $Excerpt = array('text' => $excerpt, 'context' => $text);

            foreach ($this->InlineTypes[$marker] as $inlineType)
            {
                $Inline = $this->{'inline'.$inlineType}($Excerpt);

                if ( ! isset($Inline))
                {
                    continue;
                }

                # makes sure that the inline belongs to "our" marker

                if (isset($Inline['position']) and $Inline['position'] > $markerPosition)
                {
                    continue;
                }

                # sets a default inline position

                if ( ! isset($Inline['position']))
                {
                    $Inline['position'] = $markerPosition;
                }

                # the text that comes before the inline
                $unmarkedText = substr($text, 0, $Inline['position']);

                # compile the unmarked text
                $markup .= $this->unmarkedText($unmarkedText);

                # compile the inline
                $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);

                # remove the examined text
                $text = substr($text, $Inline['position'] + $Inline['extent']);

                continue 2;
            }

            # the marker does not belong to an inline

            $unmarkedText = substr($text, 0, $markerPosition + 1);

            $markup .= $this->unmarkedText($unmarkedText);

            $text = substr($text, $markerPosition + 1);
        }

        $markup .= $this->unmarkedText($text);

        return $markup;
    }

    #
    # ~
    #

    protected function inlineCode($Excerpt)
    {
        $marker = $Excerpt['text'][0];

        if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
        {
            $text = $matches[2];
            $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
            $text = preg_replace("/[ ]*\n/", ' ', $text);

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'code',
                    'text' => $text,
                ),
            );
        }
    }

    protected function inlineEmailTag($Excerpt)
    {
        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
        {
            $url = $matches[1];

            if ( ! isset($matches[2]))
            {
                $url = 'mailto:' . $url;
            }

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'a',
                    'text' => $matches[1],
                    'attributes' => array(
                        'href' => $url,
                    ),
                ),
            );
        }
    }

    protected function inlineEmphasis($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]))
        {
            return;
        }

        $marker = $Excerpt['text'][0];

        if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'strong';
        }
        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'em';
        }
        else
        {
            return;
        }

        return array(
            'extent' => strlen($matches[0]),
            'element' => array(
                'name' => $emphasis,
                'handler' => 'line',
                'text' => $matches[1],
            ),
        );
    }

    protected function inlineEscapeSequence($Excerpt)
    {
        if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
        {
            return array(
                'markup' => $Excerpt['text'][1],
                'extent' => 2,
            );
        }
    }

    protected function inlineImage($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
        {
            return;
        }

        $Excerpt['text']= substr($Excerpt['text'], 1);

        $Link = $this->inlineLink($Excerpt);

        if ($Link === null)
        {
            return;
        }

        $Inline = array(
            'extent' => $Link['extent'] + 1,
            'element' => array(
                'name' => 'img',
                'attributes' => array(
                    'src' => $Link['element']['attributes']['href'],
                    'alt' => $Link['element']['text'],
                ),
            ),
        );

        $Inline['element']['attributes'] += $Link['element']['attributes'];

        unset($Inline['element']['attributes']['href']);

        return $Inline;
    }

    protected function inlineLink($Excerpt)
    {
        $Element = array(
            'name' => 'a',
            'handler' => 'line',
            'text' => null,
            'attributes' => array(
                'href' => null,
                'title' => null,
            ),
        );

        $extent = 0;

        $remainder = $Excerpt['text'];

        if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
        {
            $Element['text'] = $matches[1];

            $extent += strlen($matches[0]);

            $remainder = substr($remainder, $extent);
        }
        else
        {
            return;
        }

        if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches))
        {
            $Element['attributes']['href'] = $matches[1];

            if (isset($matches[2]))
            {
                $Element['attributes']['title'] = substr($matches[2], 1, - 1);
            }

            $extent += strlen($matches[0]);
        }
        else
        {
            if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
            {
                $definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
                $definition = strtolower($definition);

                $extent += strlen($matches[0]);
            }
            else
            {
                $definition = strtolower($Element['text']);
            }

            if ( ! isset($this->DefinitionData['Reference'][$definition]))
            {
                return;
            }

            $Definition = $this->DefinitionData['Reference'][$definition];

            $Element['attributes']['href'] = $Definition['url'];
            $Element['attributes']['title'] = $Definition['title'];
        }

        $Element['attributes']['href'] = str_replace(array('&', '<'), array('&amp;', '&lt;'), $Element['attributes']['href']);

        return array(
            'extent' => $extent,
            'element' => $Element,
        );
    }

    protected function inlineMarkup($Excerpt)
    {
        if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
        {
            return;
        }

        if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }

        if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }

        if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
        {
            return array(
                'markup' => $matches[0],
                'extent' => strlen($matches[0]),
            );
        }
    }

    protected function inlineSpecialCharacter($Excerpt)
    {
        if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
        {
            return array(
                'markup' => '&amp;',
                'extent' => 1,
            );
        }

        $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');

        if (isset($SpecialCharacter[$Excerpt['text'][0]]))
        {
            return array(
                'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
                'extent' => 1,
            );
        }
    }

    protected function inlineStrikethrough($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]))
        {
            return;
        }

        if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
        {
            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'del',
                    'text' => $matches[1],
                    'handler' => 'line',
                ),
            );
        }
    }

    protected function inlineUrl($Excerpt)
    {
        if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
        {
            return;
        }

        if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
        {
            $Inline = array(
                'extent' => strlen($matches[0][0]),
                'position' => $matches[0][1],
                'element' => array(
                    'name' => 'a',
                    'text' => $matches[0][0],
                    'attributes' => array(
                        'href' => $matches[0][0],
                    ),
                ),
            );

            return $Inline;
        }
    }

    protected function inlineUrlTag($Excerpt)
    {
        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
        {
            $url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'a',
                    'text' => $url,
                    'attributes' => array(
                        'href' => $url,
                    ),
                ),
            );
        }
    }

    # ~

    protected function unmarkedText($text)
    {
        if ($this->breaksEnabled)
        {
            $text = preg_replace('/[ ]*\n/', "<br />\n", $text);
        }
        else
        {
            $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "<br />\n", $text);
            $text = str_replace(" \n", "\n", $text);
        }

        return $text;
    }

    #
    # Handlers
    #

    protected function element(array $Element)
    {
        $markup = '<'.$Element['name'];

        if (isset($Element['attributes']))
        {
            foreach ($Element['attributes'] as $name => $value)
            {
                if ($value === null)
                {
                    continue;
                }

                $markup .= ' '.$name.'="'.$value.'"';
            }
        }

        if (isset($Element['text']))
        {
            $markup .= '>';

            if (isset($Element['handler']))
            {
                $markup .= $this->{$Element['handler']}($Element['text']);
            }
            else
            {
                $markup .= $Element['text'];
            }

            $markup .= '</'.$Element['name'].'>';
        }
        else
        {
            $markup .= ' />';
        }

        return $markup;
    }

    protected function elements(array $Elements)
    {
        $markup = '';

        foreach ($Elements as $Element)
        {
            $markup .= "\n" . $this->element($Element);
        }

        $markup .= "\n";

        return $markup;
    }

    # ~

    protected function li($lines)
    {
        $markup = $this->lines($lines);

        $trimmedMarkup = trim($markup);

        if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '<p>')
        {
            $markup = $trimmedMarkup;
            $markup = substr($markup, 3);

            $position = strpos($markup, "</p>");

            $markup = substr_replace($markup, '', $position, 4);
        }

        return $markup;
    }

    #
    # Deprecated Methods
    #

    function parse($text)
    {
        $markup = $this->text($text);

        return $markup;
    }

    #
    # Static Methods
    #

    static function instance($name = 'default')
    {
        if (isset(self::$instances[$name]))
        {
            return self::$instances[$name];
        }

        $instance = new static();

        self::$instances[$name] = $instance;

        return $instance;
    }

    private static $instances = array();

    #
    # Fields
    #

    protected $DefinitionData;

    #
    # Read-Only

    protected $specialCharacters = array(
        '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
    );

    protected $StrongRegex = array(
        '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
        '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
    );

    protected $EmRegex = array(
        '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
        '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
    );

    protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';

    protected $voidElements = array(
        'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
    );

    protected $textLevelElements = array(
        'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont',
        'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing',
        'i', 'rp', 'del', 'code',          'strike', 'marquee',
        'q', 'rt', 'ins', 'font',          'strong',
        's', 'tt', 'sub', 'mark',
        'u', 'xm', 'sup', 'nobr',
                   'var', 'ruby',
                   'wbr', 'span',
                          'time',
    );
}
<?php

if ( ! class_exists( 'SiteOrigin_Installer_Admin' ) ) {
	class SiteOrigin_Installer_Admin {
		public function __construct() {
			add_action( 'admin_notices', array( $this, 'display_admin_notices' ) );
			add_action( 'wp_ajax_so_installer_dismiss', array( $this, 'dismiss_notice' ) );
			add_action( 'wp_ajax_siteorigin_installer_manage', array( $this, 'manage_product' ) );
			add_action( 'admin_menu', array( $this, 'admin_menu' ), 11 );
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 15 );
			add_action( 'activated_plugin', array( $this, 'maybe_clear_cache' ) );
			add_action( 'deactivated_plugin', array( $this, 'maybe_clear_cache' ) );
		}

		public static function single() {
			static $single;

			return empty( $single ) ? $single = new self() : $single;
		}

		public function maybe_clear_cache( $plugin ) {
			$products = apply_filters( 'siteorigin_installer_products_transient', get_transient( 'siteorigin_installer_product_data' ) );

			if ( ! empty( $products ) && ! empty( $products[ basename( $plugin, '.php' ) ] ) ) {
				delete_transient( 'siteorigin_installer_product_data' );
			}
		}

		public function display_admin_notices() {
			global $pagenow;

			if (
				! get_option( 'siteorigin_installer_admin_dismissed' ) &&
				current_user_can( 'install_plugins' ) &&
				(
					$pagenow != 'admin.php' ||
					(
						! empty( $_GET['page'] ) &&
						$_GET['page'] != 'siteorigin-installer'
					)
				)
			) {
				$dismiss_url = wp_nonce_url( add_query_arg( array( 'action' => 'so_installer_dismiss' ), admin_url( 'admin-ajax.php' ) ), 'so_installer_dismiss' );
				?>
				<div id="siteorigin-installer-notice" class="notice notice-warning">
					<p>
						<?php
						printf(
							__( '%s to install recommended SiteOrigin plugins and a SiteOrigin theme to get your site going.', 'siteorigin-installer' ),
							'<a href="' . esc_url( admin_url( 'admin.php?page=siteorigin-installer' ) ) . '" target="_blank" rel="noopener noreferrer" >' . __( 'Click here', 'siteorigin-installer' ) . '</a>'
						);
						?>
					</p>
					<a href="<?php echo esc_url( $dismiss_url ); ?>" class="siteorigin-notice-dismiss"></a>
				</div>
				<?php
				wp_enqueue_script(
					'siteorigin-installer-notice',
					SITEORIGIN_INSTALLER_URL . 'js/notices.js',
					array( 'jquery' ),
					SITEORIGIN_INSTALLER_VERSION
				);

				wp_enqueue_style(
					'siteorigin-installer-notice',
					SITEORIGIN_INSTALLER_URL . 'css/notices.css'
				);
			}
		}

		public function dismiss_notice() {
			check_ajax_referer( 'so_installer_dismiss' );
			update_option( 'siteorigin_installer_admin_dismissed', true );

			die();
		}

		public function admin_menu() {
			global $menu;

			if (
				! defined( 'SITEORIGIN_INSTALLER_THEME_MODE' ) &&
				empty( $GLOBALS['admin_page_hooks']['siteorigin'] )
			) {
				add_menu_page(
					__( 'SiteOrigin', 'siteorigin-installer' ),
					__( 'SiteOrigin', 'siteorigin-installer' ),
					false,
					'admin.php?page=siteorigin-installer',
					false,
					SITEORIGIN_INSTALLER_URL . '/img/icon.svg',
					66
				);
			}

			add_submenu_page(
				'siteorigin',
				__( 'Installer', 'siteorigin-installer' ),
				__( 'Installer', 'siteorigin-installer' ),
				'manage_options',
				'siteorigin-installer',
				array( $this, 'display_admin_page' )
			);
		}

		public function enqueue_scripts( $prefix ) {
			if (
				$prefix !== 'admin_page_siteorigin-installer' &&
				$prefix !== 'siteorigin_page_siteorigin-installer'
			) {
				return;
			}

			wp_enqueue_style(
				'siteorigin-installer',
				SITEORIGIN_INSTALLER_URL . '/css/admin.css',
				array(),
				SITEORIGIN_INSTALLER_VERSION
			);

			wp_enqueue_script(
				'siteorigin-installer',
				SITEORIGIN_INSTALLER_URL . '/js/script.js',
				array( 'jquery' ),
				SITEORIGIN_INSTALLER_VERSION
			);

			wp_localize_script(
				'siteorigin-installer',
				'soInstallerAdmin',
				array(
					'manageUrl' => wp_nonce_url( admin_url( 'admin-ajax.php?action=siteorigin_installer_manage' ), 'siteorigin-installer-manage' ),
					'activateText' => __( 'Activate', 'siteorigin-installer' ),
				)
			);
		}

		public function manage_product() {
			check_ajax_referer( 'siteorigin-installer-manage' );

			if ( empty( $_POST['slug'] ) || empty( $_POST['task'] ) || empty( $_POST['type'] ) || empty( $_POST['version'] ) ) {
				die();
			}

			$slug = sanitize_file_name( $_POST['slug'] );

			$product_url = 'https://wordpress.org/' . urlencode( $_POST['type'] ) . '/download/' . urlencode( $slug ) . '.' . urlencode( $_POST['version'] ) . '.zip';
			// check_ajax_referer( 'so_installer_manage' );
			if ( ! class_exists( 'WP_Upgrader' ) ) {
				require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
			}
			$upgrader = new WP_Upgrader();
			if ( $_POST['type'] == 'plugins' ) {
				if ( $_POST['task'] == 'install' || $_POST['task'] == 'update' ) {
					$upgrader->run( array(
						'package' => esc_url( $product_url ),
						'destination' => WP_PLUGIN_DIR,
						'clear_destination' => true,
						'abort_if_destination_exists' => false,
						'hook_extra' => array(
							'type' => 'plugin',
							'action' => 'install',
						),
					) );

					$clear = true;
				} elseif (
					$_POST['task'] == 'activate' &&
					! is_wp_error( validate_plugin( $slug . '/' . $slug . '.php' ) )
				) {
					activate_plugin( $slug . '/' . $slug . '.php' );
					$clear = true;
				}
			} elseif ( $_POST['type'] == 'themes' ) {
				if ( $_POST['task'] == 'install' || $_POST['task'] == 'update' ) {
					$upgrader->run( array(
						'package' => esc_url( $product_url ),
						'destination' => get_theme_root(),
						'clear_destination' => true,
						'clear_working' => true,
						'abort_if_destination_exists' => false,
					) );
					$clear = true;
				} elseif ( $_POST['task'] == 'activate' ) {
					switch_theme( $slug );
					$clear = true;
				}
			}

			if ( ! empty( $clear ) ) {
				delete_transient( 'siteorigin_installer_product_data' );
			}
			die();
		}

		private function update_product_data( $product = array(), $return = true ) {
			$current_theme = wp_get_theme();

			if ( empty( $products ) ) {
				$products = apply_filters( 'siteorigin_installer_products', json_decode( file_get_contents( SITEORIGIN_INSTALLER_DIR . '/data/products.json' ), true ) );
			}

			require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
			$fields = array(
				'short_description' => true,
				'version' => true,
			);

			// $product_data = get_transient( 'siteorigin_installer_product_data' );
			foreach ( $products as $slug => $item ) {
				$status = false;

				if ( $slug != 'siteorigin-premium' ) {
					if ( $item['type'] == 'themes' ) {
						$api = themes_api(
							'theme_information',
							array(
								'slug' => $slug,
								'fields' => $fields,
							)
						);

						$theme = wp_get_theme( $slug );

						// Work out the status of the theme.
						if ( is_object( $theme->errors() ) ) {
							$status = 'install';
						} else {
							$products[ $slug ]['update'] = version_compare( $theme->get( 'Version' ), $api->version, '<' );

							if ( $theme->get_stylesheet() != $current_theme->get_stylesheet() ) {
								$status = 'activate';
							}
						}

						// Theme descriptions are too long so we need to shorten them.
						$description = explode( '.', $api->sections['description'] );
						$description = $description[0] . '. ' . $description[1];
					} else {
						$api = plugins_api(
							'plugin_information',
							array(
								'slug' => $slug,
								'fields' => $fields,
							)
						);

						// Work out the status of the plugin.
						$plugin_file = "$slug/$slug.php";

						if ( ! file_exists( WP_PLUGIN_DIR . "/$plugin_file" ) ) {
							$status = 'install';
						} elseif ( ! is_plugin_active( $plugin_file ) ) {
							$status = 'activate';
						}

						if ( $status != 'install' ) {
							$plugin = get_plugin_data( WP_PLUGIN_DIR . "/$plugin_file" );
							$products[ $slug ]['update'] = version_compare( $plugin['Version'], $api->version, '<' );
						}

						if ( empty( $item['screenshot'] ) ) {
							$products[ $slug ]['screenshot'] = 'https://plugins.svn.wordpress.org/' . $slug . '/assets/icon.svg';
						}
					}

					$products[ $slug ]['status'] = $status;
					$products[ $slug ]['version'] = $api->version;

					if ( empty( $item['description'] ) ) {
						$products[ $slug ]['description'] = $item['type'] == 'themes' ? "$description." : $api->short_description;
					}
				} elseif (
					! apply_filters( 'siteorigin_premium_upgrade_teaser', true ) ||
					defined( 'SITEORIGIN_PREMIUM_VERSION' )
				) {
					unset( $products['siteorigin-premium'] );
				} else {
					$products['siteorigin-premium']['screenshot'] = SITEORIGIN_INSTALLER_URL . 'img/premium-icon.svg';
				}
			}
			uasort( $products, array( $this, 'sort_compare' ) );
			set_transient( 'siteorigin_installer_product_data', $products, 43200 );

			return $products;
		}

		/**
		 * Display the theme admin page
		 */
		public function display_admin_page() {
			$products = apply_filters( 'siteorigin_installer_products_transient', get_transient( 'siteorigin_installer_product_data' ) );

			if ( empty( $products ) ) {
				$products = $this->update_product_data();
			}

			if ( ! empty( $_GET['highlight'] ) && isset( $products[ (string) $_GET['highlight'] ] ) ) {
				$products[ (string) $_GET['highlight'] ]['weight'] = 9999;
				uasort( $products, array( $this, 'sort_compare' ) );
				$highlight = $_GET['highlight'];
			}

			include SITEORIGIN_INSTALLER_DIR . '/tpl/admin.php';
		}

		/**
		 * Comparison function for sorting
		 *
		 * @return int
		 */
		public function sort_compare( $a, $b ) {
			if ( empty( $a['weight'] ) || empty( $b['weight'] ) ) {
				return 0;
			}

			return $a['weight'] < $b['weight'] ? 1 : -1;
		}
	}
}
SiteOrigin_Installer_Admin::single();
#### 0.1.3 - 22 January 2016
* Added affiliate ID filter.

#### 0.1.2 - 22 January 2016
* Cleaned up recommended plugins.
* Fixed duplicated SiteOrigin menu items.

#### 0.1.1 - 22 January 2016
* Added WooCommerce to recommended plugins.

#### 0.1 - 20 January 2016
* Initial plugin release
SiteOrigin installer helps you install SiteOrigin themes and plugins.<?php

return array(
	'text'       => array(
		'title'       => esc_html__( 'Text', 'so-css' ),
		'icon'        => 'align-left',
		'controllers' => array(
			array(
				'title' => esc_html__( 'Text Color', 'so-css' ),
				'type'  => 'color',
				'args'  => array(
					'property' => 'color',
				),
			),
			array(
				'title' => esc_html__( 'Font Size', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property'    => 'font-size',
					'defaultUnit' => 'px',
				),
			),
			array(
				'title' => esc_html__( 'Line Height', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property'    => 'line-height',
					'defaultUnit' => 'em',
				),
			),
			array(
				'title' => esc_html__( 'Font Weight', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'font-weight',
					'options'  => array(
						'normal'  => esc_html__( 'Normal', 'so-css' ),
						'bold'    => esc_html__( 'Bold', 'so-css' ),
						'bolder'  => esc_html__( 'Bolder', 'so-css' ),
						'lighter' => esc_html__( 'Lighter', 'so-css' ),
						'100'     => '100',
						'200'     => '200',
						'300'     => '300',
						'400'     => '400',
						'500'     => '500',
						'600'     => '600',
						'700'     => '700',
						'800'     => '800',
						'900'     => '900',
					),
				),
			),
			array(
				'title' => esc_html__( 'Font Style', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property'     => 'font-style',
					'options'      => array(
						'none'   => esc_html__( 'None', 'so-css' ),
						'normal' => esc_html__( 'Normal', 'so-css' ),
						'italic' => esc_html__( 'Italic', 'so-css' ),
					),
					'option_icons' => array(
						'normal' => 'font',
						'italic' => 'italic',
					),
				),
			),
			array(
				'title' => esc_html__( 'Text Decoration', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property'     => 'text-decoration',
					'options'      => array(
						'none'         => esc_html__( 'None', 'so-css' ),
						'underline'    => esc_html__( 'Underline', 'so-css' ),
						'overline'     => esc_html__( 'Overline', 'so-css' ),
						'line-through' => esc_html__( 'Line Through', 'so-css' ),
					),
					'option_icons' => array(
						'none'         => 'font',
						'underline'    => 'underline',
						'line-through' => 'strikethrough',
					),
				),
			),
			array(
				'title' => esc_html__( 'Font Variant', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'font-variant',
					'options'  => array(
						'normal'     => esc_html__( 'Normal', 'so-css' ),
						'small-caps' => esc_html__( 'Small Caps', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Text Transform', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'text-transform',
					'options'  => array(
						'none'       => esc_html__( 'None', 'so-css' ),
						'capitalize' => esc_html__( 'Capitalize', 'so-css' ),
						'uppercase'  => esc_html__( 'Uppercase', 'so-css' ),
						'lowercase'  => esc_html__( 'Lowercase', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Font Family', 'so-css' ),
				'type'  => 'font_select',
				'args'  => array(
					'property' => 'font-family',
				),
			),
			array(
				'title' => esc_html__( 'Text Align', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property'     => 'text-align',
					'options'      => array(
						'left'    => esc_html__( 'Left', 'so-css' ),
						'right'   => esc_html__( 'Right', 'so-css' ),
						'center'  => esc_html__( 'Center', 'so-css' ),
						'justify' => esc_html__( 'Justify', 'so-css' ),
					),
					'option_icons' => array(
						'left'    => 'align-left',
						'right'   => 'align-right',
						'center'  => 'align-center',
						'justify' => 'align-justify',
					),
				),
			),
			array(
				'title' => esc_html__( 'Text Indent', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property' => 'text-indent',
				),
			),
			array(
				'title' => esc_html__( 'Letter Spacing', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property' => 'letter-spacing',
				),
			),
			array(
				'title' => esc_html__( 'Word Spacing', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property' => 'word-spacing',
				),
			),
			array(
				'title' => esc_html__( 'White Space', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'white-space',
					'options'  => array(
						'normal'      => esc_html__( 'Normal', 'so-css' ),
						'encountered' => esc_html__( 'Encountered', 'so-css' ),
						'pre'         => esc_html__( 'Pre', 'so-css' ),
						'pre-line'    => esc_html__( 'Pre Line', 'so-css' ),
						'pre-wrap'    => esc_html__( 'Pre Wrap', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Text Shadow', 'so-css' ),
				'type'  => 'shadow',
				'args'  => array(
					'property' => 'text-shadow',
				),
			),
		),
	),

	//////////////////////////////////////////////////////////////////////

	'decoration' => array(
		'title'       => esc_html__( 'Decoration', 'so-css' ),
		'icon'        => 'eyedropper',
		'controllers' => array(
			array(
				'title' => esc_html__( 'Background Color', 'so-css' ),
				'type'  => 'color',
				'args'  => array(
					'property' => 'background-color',
				),
			),
			array(
				'title' => esc_html__( 'Background Image', 'so-css' ),
				'type'  => 'image',
				'args'  => array(
					'property' => 'background-image',
					'value'    => 'url("{{url}}")',
				),
			),
			array(
				'title' => esc_html__( 'Background Position', 'so-css' ),
				'type'  => 'position',
				'args'  => array(
					'property' => 'background-position',
				),
			),
			array(
				'title' => esc_html__( 'Background Repeat', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'background-repeat',
					'options'  => array(
						'repeat'    => esc_html__( 'repeat', 'so-css' ),
						'repeat-x'  => esc_html__( 'repeat-x', 'so-css' ),
						'repeat-y'  => esc_html__( 'repeat-y', 'so-css' ),
						'no-repeat' => esc_html__( 'no-repeat', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Background Size', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'background-size',
					'options'  => array(
						'auto'       => esc_html__( 'auto', 'so-css' ),
						'length'     => esc_html__( 'length', 'so-css' ),
						'percentage' => esc_html__( 'percentage', 'so-css' ),
						'cover'      => esc_html__( 'cover', 'so-css' ),
						'contain'    => esc_html__( 'contain', 'so-css' ),
					),
				),
			),

			array(
				'title' => esc_html__( 'Box Shadow', 'so-css' ),
				'type'  => 'shadow',
				'args'  => array(
					'property' => 'box-shadow',
				),
			),

			array(
				'title' => esc_html__( 'Opacity', 'so-css' ),
				'type'  => 'number',
				'args'  => array(
					'property'  => 'opacity',
					'default'   => 1,
					'min'       => 0,
					'max'       => 1,
					'increment' => 0.05,
					'decrement' => -0.05,
				),
			),

			array(
				'title' => esc_html__( 'Borders', 'so-css' ),
				'type'  => 'sides',
				'args'  => array(
					'controllers' => array(
						array(
							'type' => 'measurement',
							'args' => array(
								'property'    => 'border-{dir}-width',
								'propertyAll' => 'border-width',
								'defaultUnit' => 'px',
							),
						),
						array(
							'type' => 'select',
							'args' => array(
								'property'    => 'border-{dir}-style',
								'propertyAll' => 'border-style',
								'options'     => array(
									'hidden' => 'Hidden',
									'dotted' => 'Dotted',
									'dashed' => 'Dashed',
									'solid'  => 'Solid',
									'double' => 'Double',
									'groove' => 'Groove',
									'ridge'  => 'Ridge',
									'inset'  => 'Inset',
									'outset' => 'Outset',
								),
							),
						),
						array(
							'type' => 'color',
							'args' => array(
								'property'    => 'border-{dir}-color',
								'propertyAll' => 'border-color',
							),
						),
					),
					'hasAll'      => true,
				),
			),

			array(
				'title' => esc_html__( 'Border Radius', 'so-css' ),
				'type'  => 'sides',
				'args'  => array(
					'controllers' => array(
						array(
							'type' => 'measurement',
							'args' => array(
								'property'    => 'border-{dir}-radius',
								'propertyAll' => 'border-radius',
								'defaultUnit' => 'px',
							),
						),
					),
					'isRadius'    => true,
					'hasAll'      => true,
				),
			),
		),
	),

	//////////////////////////////////////////////////////////////////////

	'layout'     => array(
		'title'       => esc_html__( 'Layout', 'so-css' ),
		'icon'        => 'columns',
		'controllers' => array(
			array(
				'title' => esc_html__( 'Margin', 'so-css' ),
				'type'  => 'sides',
				'args'  => array(
					'controllers' => array(
						array(
							'type' => 'measurement',
							'args' => array(
								'property'    => 'margin-{dir}',
								'propertyAll' => 'margin',
								'defaultUnit' => 'px',
							),
						),
					),
					'hasAll'      => true,
				),
			),
			array(
				'title' => esc_html__( 'Padding', 'so-css' ),
				'type'  => 'sides',
				'args'  => array(
					'controllers' => array(
						array(
							'type' => 'measurement',
							'args' => array(
								'property'    => 'padding-{dir}',
								'propertyAll' => 'padding',
								'defaultUnit' => 'px',
							),
						),
					),
					'hasAll'      => true,
				),
			),
			array(
				'title' => esc_html__( 'Position', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'position',
					'options'  => array(
						'absolute' => esc_html__( 'Absolute', 'so-css' ),
						'fixed'    => esc_html__( 'Fixed', 'so-css' ),
						'relative' => esc_html__( 'Relative', 'so-css' ),
						'static'   => esc_html__( 'Static', 'so-css' ),
						'inherit'  => esc_html__( 'Inherit', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Absolute Position', 'so-css' ),
				'type'  => 'sides',
				'args'  => array(
					'controllers' => array(
						array(
							'type' => 'measurement',
							'args' => array(
								'property'    => '{dir}',
								'defaultUnit' => 'px',
							),
						),
					),
					'hasAll'      => false,
				),
			),
			array(
				'title' => esc_html__( 'Width', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property'    => 'width',
					'defaultUnit' => 'px',
				),
			),
			array(
				'title' => esc_html__( 'Height', 'so-css' ),
				'type'  => 'measurement',
				'args'  => array(
					'property'    => 'height',
					'defaultUnit' => '%',
				),
			),
			array(
				'title' => esc_html__( 'Display', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'display',
					'options'  => array(
						'none'               => esc_html__( 'None', 'so-css' ),
						'inline'             => esc_html__( 'Inline', 'so-css' ),
						'block'              => esc_html__( 'Block', 'so-css' ),
						'flex'               => esc_html__( 'Flex', 'so-css' ),
						'inline-block'       => esc_html__( 'Inline Block', 'so-css' ),
						'inline-flex'        => esc_html__( 'Inline Flex', 'so-css' ),
						'inline-table'       => esc_html__( 'Inline Table', 'so-css' ),
						'list-item'          => esc_html__( 'List Item', 'so-css' ),
						'run-in'             => esc_html__( 'Run In', 'so-css' ),
						'table'              => esc_html__( 'Table', 'so-css' ),
						'table-caption'      => esc_html__( 'Table Caption', 'so-css' ),
						'table-column-group' => esc_html__( 'Table Column Group', 'so-css' ),
						'table-header-group' => esc_html__( 'Table Header Group', 'so-css' ),
						'table-footer-group' => esc_html__( 'Table Footer Group', 'so-css' ),
						'table-row-group'    => esc_html__( 'Table Row Group', 'so-css' ),
						'table-cell'         => esc_html__( 'Table Cell', 'so-css' ),
						'table-column'       => esc_html__( 'Table Column', 'so-css' ),
						'table-row'          => esc_html__( 'Table Row', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Float', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'float',
					'options'  => array(
						'none'  => esc_html__( 'None', 'so-css' ),
						'left'  => esc_html__( 'Left', 'so-css' ),
						'right' => esc_html__( 'Right', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Clear', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'clear',
					'options'  => array(
						'none'  => esc_html__( 'None', 'so-css' ),
						'left'  => esc_html__( 'Left', 'so-css' ),
						'right' => esc_html__( 'Right', 'so-css' ),
						'both'  => esc_html__( 'Both', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Visibility', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'visibility',
					'options'  => array(
						'visible'  => esc_html__( 'Visible', 'so-css' ),
						'hidden'   => esc_html__( 'Hidden', 'so-css' ),
						'collapse' => esc_html__( 'Collapse', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Overflow', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'overflow',
					'options'  => array(
						'visible' => esc_html__( 'Visible', 'so-css' ),
						'hidden'  => esc_html__( 'Hidden', 'so-css' ),
						'scroll'  => esc_html__( 'Scroll', 'so-css' ),
						'auto'    => esc_html__( 'Auto', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Overflow X', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'overflow-x',
					'options'  => array(
						'visible' => esc_html__( 'Visible', 'so-css' ),
						'hidden'  => esc_html__( 'Hidden', 'so-css' ),
						'scroll'  => esc_html__( 'Scroll', 'so-css' ),
						'auto'    => esc_html__( 'Auto', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Overflow Y', 'so-css' ),
				'type'  => 'select',
				'args'  => array(
					'property' => 'overflow-y',
					'options'  => array(
						'visible' => esc_html__( 'Visible', 'so-css' ),
						'hidden'  => esc_html__( 'Hidden', 'so-css' ),
						'scroll'  => esc_html__( 'Scroll', 'so-css' ),
						'auto'    => esc_html__( 'Auto', 'so-css' ),
					),
				),
			),
			array(
				'title' => esc_html__( 'Z-Index', 'so-css' ),
				'type'  => 'number',
				'args'  => array(
					'property' => 'z-index',
				),
			),
		),
	),
);
=== SiteOrigin CSS ===
Tags: css, visual css, css editor, design, customize
Requires at least: 3.9
Requires PHP: 7.0.0
Tested up to: 6.5
Stable tag: 1.5.10
Build time: 2024-05-31T21:56:24+01:00
License: GPLv2 or later
Contributors: gpriday, alexgso
Donate link: https://siteorigin.com/downloads/premium/

SiteOrigin CSS is the simple yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.

== Description ==

SiteOrigin CSS is the simple yet powerful CSS editor for WordPress. It gives you visual controls that let you edit the look and feel of your site in real-time.

We've created a site editing experience that will suit both beginners and advanced users alike. Beginners will love the simple visual controls and real-time preview. Advanced users will love the code autocompletion that makes writing CSS faster than ever.

[vimeo https://vimeo.com/129660380]

= Inspector =

The hardest part of editing your site's design using CSS is usually finding the correct selector to use. The powerful inspector that comes with SiteOrigin CSS makes this easy. While viewing a full preview of your site, just click on an element, and it'll help you identify the best selector to use to target that element.

The inspector will help you even if you have no idea what a CSS selector is.

= Visual Editor =

Don't like playing around with code? No problem. SiteOrigin CSS has a set of simple controls that make it easy to choose colors, styles, and measurements. Combined with the inspector, you'll be able to make changes in just a few clicks.

= CSS Editor =

SiteOrigin CSS has a powerful CSS editor, the likes of which you'd usually only expect from high-end IDEs. It has autocompletion for both CSS selectors and attributes. It also features very useful CSS linting to help you identify issues in your code before you publish your changes.

= It's Free =

We're committed to keeping SiteOrigin CSS free. You can install it on as many sites as you like without ever worrying about licensing. All future updates and upgrades will be free, and we even offer free support over on our friendly support forums.

= Works With Any Theme =

There's an ever-growing collection of awesome WordPress themes, and now with SiteOrigin CSS, you can edit every single one of them to your heart's content. No matter what theme you're using, SiteOrigin CSS will work perfectly.

= Actively Developed =

We're actively developing SiteOrigin CSS. Keep track of what's happening over on [GitHub](https://github.com/siteorigin/so-css/).

== Installation ==

1. Upload and install SiteOrigin CSS in the same way you'd install any other plugin.
2. Read the [usage documentation](http://siteorigin.com/css/getting-started/) on SiteOrigin.

== Screenshots ==
1. Inspector for finding elements on your site.
2. Simple visual controls, including a background image uploader.
3. A full CSS editor that works in real-time with a preview of your site.
4. Code completion for all your theme's selectors.

== Documentation ==

[Documentation](https://siteorigin.com/css/getting-started/) is available on SiteOrigin.

== Support ==

Free support is available on the [SiteOrigin support forums](https://siteorigin.com/thread/).

== SiteOrigin Premium ==

[SiteOrigin Premium](https://siteorigin.com/downloads/premium/) enhances SiteOrigin CSS with a Google Web Font Selector. Choose from hundreds of beautiful web fonts right in the visual editor.

SiteOrigin Premium includes access to our professional email support service, perfect for those times when you need fast and effective technical support. We're standing by to assist you in any way we can.

== Changelog ==

= 1.5.10 - 31 May 2024 =
* Updated SiteOrigin Installer.
* Updated Tested up to tag.
* Updated Required PHP version.

= 1.5.9 - 11 November 2023 =
* Updated Tested up to tag.
* Updated SiteOrigin Installer.

= 1.5.8 - 11 August 2023 =
* Updated the SiteOrigin Installer submodule.

= 1.5.7 - 09 August 2023 =
* Updated the expand/compress title depending on the state in the visual editor.
* Updated the "Tested up to" version in the readme.txt file from 6.2 to 6.3, indicating compatibility with WordPress version 6.3.
* Added SiteOrigin Installer submodule and functionality to handle the installer link and status in the editor and page templates.

= 1.5.6 - 07 April 2023 =
* WordPress PHP Coding Standards improvements.
* Updated `Tested up to` tag.

= 1.5.5 - 30 September 2022 =
* Added a check to ensure WP Filesystem is setup. 

= 1.5.4 - 28 September 2022 =
* Developer: Introduced definable Custom CSS file name and location using `siteorigin_custom_css_file` and `siteorigin_css_enqueue_css`.

= 1.5.3 - 25 May 2022 =
* Updated WordPress `Tested up to` tag.

= 1.5.2 - 27 January 2022 =
* Updated `Tested up to` tag to `5.9`.

= 1.5.1 - 30 December 2021 =
* Basic Editor Theme Setting: Updated field to show selected option.

= 1.5.0 - 16 December 2021 =
* Basic Editor: Added a dark theme option.
* Ajax Saving: Resolved unintended slashes added during escaping.

= 1.4.3 - 29 November 2021 =
* Restored editor scrollbar.
* Added a fixed editor height.

= 1.4.2 - 08 November 2021 =
* Fixed string translation functions.

= 1.4.1 - 02 November 2021 =
* Removed Save button rounding.
* Fixed Visual Editor `Navigate To` link functionality.

= 1.4.0 - 11 October 2021 =
* Added Ajax saving. Users can now save in the expanded and visual editors without exiting to basic editor.
* Expanded/Visual toolbar buttons re-ordered for consistency between modes.
* Removed Font Awesome. Icons are now added via a custom font.

= 1.3.2 - 20 July 2021 =
* Updated `Tested up to` tag.

= 1.3.1 - 10 July 2021 =
* Updated the Plugins page action link list.

= 1.3.0 - 14 June 2021 =
* Inspector: Added a new Border Radius setting to the Decoration tab.
* Allowed for right-clicking anywhere in the Basic Editor.

= 1.2.14 - 26 April 2021 =
* Resolved Photo Gallery by 10Web plugin conflict.

= 1.2.13 - 01 February 2021 =
* Inspector: Added support for WooCommerce single product tabs.
* Inspector: Highlight important classes when element with class is selected.
* Restored the scrollbar in the Custom CSS content field.
* Developer: Further changes for jQuery 3.5.
* Developer: For WP 4.9+ use the WordPress version of CodeMirror if available.
* Developer: Removed `socss-codemirror-show-hint` as a dependency. The script can now be removed to disable hints.

= 1.2.12 - 12 December 2020 =
* Developer: jQuery updates for WordPress 5.6.

= 1.2.11 - 21 October 2020 =
* Fixed Background image setting writing to CSS.

= 1.2.10 - 09 September 2020 =
* Increased the specificity of the Save CSS button styling to prevent plugin conflicts.

= 1.2.9 - 29 July 2020 =
* Resolved Font Family field output.

= 1.2.8 - 22 May 2020 =
* Renamed `custom_css` textarea to prevent conflicts.

= 1.2.7 - 19 May 2020 =
* Restored `Save` button functionality.

= 1.2.6 - 15 May 2020 =
* Minor visual editor form styling fixes.
* Resolved PHP 7.4 `preg_replace()` warning.
* Moved the basic editor Save button to the sidebar.

= 1.2.5 - 05 February 2020 =
* Removed `themeCSS` localized script to prevent `preg_replace()` warning.
* Minor form styling fixes.
* Updated CSS NPM library.
* Rebuilt minified files using new build script.

= 1.2.4 - 17 January 2019 =
* Prefix so-css for all codemirror assets.
* Prevent JS error when attempting to set active element to null.

= 1.2.3 - 25 June 2018 =
* Add preview iframe 'load' event listener in `render` function.
* Reverted change to stylesheet hook.

= 1.2.2 - 16 June 2018 =
* Removed reference to non-existent view.

= 1.2.1 - 15 June 2018 =
* Removed `.min` suffix from new stylesheets for CodeMirror plugins.

= 1.2.0 - 6 June 2018 =
* Updated CSS library.
* UI changes to make it more obvious when viewing revision.
* Ensure revisions are sorted in descending time order.
* Don't link to revision currently being displayed.
* Add search functionality to editor.
* Enable persistent search and JumpToLine.

= 1.1.5 - 19 September 2017 =
* Use `home_url` instead of `site_url` to determine where to open CSS preview.
* Increment and decrement buttons work when value empty or zero. Also added repeating action while button held down.
* Scroll editor instead of the whole page so 'Save' button is always visible.
* Set color CSS on visual editor and inspector.
* Saving generated CSS to stylesheet file in uploads directory.

= 1.1.4 - 31 January 2017 =
* Updated CodeMirror to 2.25.2.
* Removed extra line padding.
* Better integration with WordPress.org translation.

= 1.1.3 - 31 January 2017 =
* Removed leading slash in paths after plugin_dir_url().
* Updated to latest CodeMirror.
* Fixed padding issue that was causing problems with Firefox and the color picker.

= 1.1.2 - 11 November 2016 =
* Ignore anything other than actual rules in media query subrules.
* Removed depreciated jQuery function.
* Updated CSSLint library.
* Updated minicolors.

= 1.1.1 - 28 September 2016 =
* Properly handle errors in frontend CSS.
* Added notice about SiteOrigin Premium.

= 1.1 - 26 September 2016 =
* Changed CSS parsing library. Fixed several issues with the visual editor mode.
* Added address bar to preview window.
* Small CSS fixes.
* Small changes to allow adding more visual editor fields.

= 1.0.8 - 15 August 2016 =
* Fixed action link.
* Support for GlotPress.
* Removed unused code.
* Handling of @imports for future addons.

= 1.0.7 - 4 July 2016 =
* Ensure user can copy/paste in editor via context menu.
* Added plugin action links
* Add classes on `body` element to selectors window.

= 1.0.6 - 24 February 2016 =
* Disabled autocompletion on single item (automatic autocompletion).
* Fixed conflict with NextGen Gallery.
* Only display relevant linting messages.

= 1.0.5 - 21 January 2016 =
* Updated to latest version of Code Mirror.

= 1.0.4 - 10 November 2015 =
* Fixed CSS parsing when going into visual mode.

= 1.0.3 - 29 October 2015 =
* Changed video image
* Adjust revision times by GMT offset.
* Don't overwrite media queries sub styles, rather just append them.

= 1.0.2 =
* Dequeue functionality that conflicted with WordPress color picker, if it's enqueued.
* Removed wp_styles for compatibility with older versions of WordPress

= 1.0.1 =
* Fixed conflicts with CSS editor in SiteOrigin themes.
* Force dequeue scripts that cause problems with main editing interface.
* Made it easier to follow links with inspector enabled.

= 1.0 =
* Initial release.
# Copyright (C) 2024 so-css
# This file is distributed under the same license as the so-css package.
msgid ""
msgstr ""
"Project-Id-Version: so-css\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language-Team: SiteOrigin <support@siteorigin.com>\n"
"Last-Translator: SiteOrigin <support@siteorigin.com>\n"
"Report-Msgid-Bugs-To: http://www.siteorigin.com/thread\n"
"X-Poedit-Basepath: ..\n"
"X-Poedit-KeywordsList: __;_e;_ex:1,2c;_n:1,2;_n_noop:1,2;_nx:1,2,4c;_nx_noop:1,2,3c;_x:1,2c;esc_attr__;esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPathExcluded-0: *.js\n"
"X-Poedit-SourceCharset: UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: so-css.php:3, so-css.php:561
msgid "SiteOrigin CSS"
msgstr ""

#: so-css.php:4
msgid "An advanced CSS editor from SiteOrigin."
msgstr ""

#: so-css.php:6, inc/installer/siteorigin-installer.php:6
msgid "SiteOrigin"
msgstr ""

#: so-css.php:7, inc/installer/siteorigin-installer.php:7
msgid "https://siteorigin.com"
msgstr ""

#: so-css.php:8
msgid "https://siteorigin.com/css/"
msgstr ""

#: so-css.php:365, so-css.php:365, so-css.php:408
msgid "Custom CSS"
msgstr ""

#: so-css.php:410
msgid "SiteOrigin CSS adds any custom CSS you enter here into your site's header. "
msgstr ""

#: so-css.php:411
msgid "These changes will persist across updates so it's best to make all your changes here. "
msgstr ""

#: so-css.php:477
msgid "Unchanged"
msgstr ""

#: so-css.php:478
msgid "Select"
msgstr ""

#: so-css.php:479
msgid "Select Image"
msgstr ""

#: so-css.php:480
msgid "Are you sure you want to leave without saving?"
msgstr ""

#: so-css.php:546
msgid "CSS Editor"
msgstr ""

#: so-css.php:547
msgid "Support"
msgstr ""

#: so-css.php:550
msgid "Addons"
msgstr ""

#: so-css.php:564
msgid "Changes apply to %s and its child themes"
msgstr ""

#: so-css.php:565, tpl/page.php:112, tpl/page.php:168
msgid "Save CSS"
msgstr ""

#: so-css.php:572
msgid "Editing CSS for: %s"
msgstr ""

#: so-css.php:577
msgid "Changes apply to the %s %s when the current theme is %s or its child themes"
msgstr ""

#: so-css.php:584
msgid "Save %s CSS"
msgstr ""

#: so-css.php:597
msgid "Revert to this revision"
msgstr ""

#: so-css.php:651, so-css.php:672, so-css.php:691
msgid "The supplied nonce is invalid."
msgstr ""

#: so-css.php:652, so-css.php:673, so-css.php:692
msgid "Invalid nonce."
msgstr ""

#: so-css.php:743
msgid "%d chars"
msgstr ""

#: so-css.php:743
msgid "Latest"
msgstr ""

#: so-css.php:749
msgid "No revisions yet."
msgstr ""

#: inc/controller-config.php:5
msgid "Text"
msgstr ""

#: inc/controller-config.php:9
msgid "Text Color"
msgstr ""

#: inc/controller-config.php:16
msgid "Font Size"
msgstr ""

#: inc/controller-config.php:24
msgid "Line Height"
msgstr ""

#: inc/controller-config.php:32
msgid "Font Weight"
msgstr ""

#: inc/controller-config.php:37, inc/controller-config.php:60, inc/controller-config.php:93, inc/controller-config.php:164
msgid "Normal"
msgstr ""

#: inc/controller-config.php:38
msgid "Bold"
msgstr ""

#: inc/controller-config.php:39
msgid "Bolder"
msgstr ""

#: inc/controller-config.php:40
msgid "Lighter"
msgstr ""

#: inc/controller-config.php:54
msgid "Font Style"
msgstr ""

#: inc/controller-config.php:59, inc/controller-config.php:75, inc/controller-config.php:104, inc/controller-config.php:415, inc/controller-config.php:442, inc/controller-config.php:454
msgid "None"
msgstr ""

#: inc/controller-config.php:61
msgid "Italic"
msgstr ""

#: inc/controller-config.php:70
msgid "Text Decoration"
msgstr ""

#: inc/controller-config.php:76
msgid "Underline"
msgstr ""

#: inc/controller-config.php:77
msgid "Overline"
msgstr ""

#: inc/controller-config.php:78
msgid "Line Through"
msgstr ""

#: inc/controller-config.php:88
msgid "Font Variant"
msgstr ""

#: inc/controller-config.php:94
msgid "Small Caps"
msgstr ""

#: inc/controller-config.php:99
msgid "Text Transform"
msgstr ""

#: inc/controller-config.php:105
msgid "Capitalize"
msgstr ""

#: inc/controller-config.php:106
msgid "Uppercase"
msgstr ""

#: inc/controller-config.php:107
msgid "Lowercase"
msgstr ""

#: inc/controller-config.php:112
msgid "Font Family"
msgstr ""

#: inc/controller-config.php:119
msgid "Text Align"
msgstr ""

#: inc/controller-config.php:124, inc/controller-config.php:443, inc/controller-config.php:455
msgid "Left"
msgstr ""

#: inc/controller-config.php:125, inc/controller-config.php:444, inc/controller-config.php:456
msgid "Right"
msgstr ""

#: inc/controller-config.php:126
msgid "Center"
msgstr ""

#: inc/controller-config.php:127
msgid "Justify"
msgstr ""

#: inc/controller-config.php:138
msgid "Text Indent"
msgstr ""

#: inc/controller-config.php:145
msgid "Letter Spacing"
msgstr ""

#: inc/controller-config.php:152
msgid "Word Spacing"
msgstr ""

#: inc/controller-config.php:159
msgid "White Space"
msgstr ""

#: inc/controller-config.php:165
msgid "Encountered"
msgstr ""

#: inc/controller-config.php:166
msgid "Pre"
msgstr ""

#: inc/controller-config.php:167
msgid "Pre Line"
msgstr ""

#: inc/controller-config.php:168
msgid "Pre Wrap"
msgstr ""

#: inc/controller-config.php:173
msgid "Text Shadow"
msgstr ""

#: inc/controller-config.php:185
msgid "Decoration"
msgstr ""

#: inc/controller-config.php:189
msgid "Background Color"
msgstr ""

#: inc/controller-config.php:196
msgid "Background Image"
msgstr ""

#: inc/controller-config.php:204
msgid "Background Position"
msgstr ""

#: inc/controller-config.php:211
msgid "Background Repeat"
msgstr ""

#: inc/controller-config.php:216
msgid "repeat"
msgstr ""

#: inc/controller-config.php:217
msgid "repeat-x"
msgstr ""

#: inc/controller-config.php:218
msgid "repeat-y"
msgstr ""

#: inc/controller-config.php:219
msgid "no-repeat"
msgstr ""

#: inc/controller-config.php:224
msgid "Background Size"
msgstr ""

#: inc/controller-config.php:229
msgid "auto"
msgstr ""

#: inc/controller-config.php:230
msgid "length"
msgstr ""

#: inc/controller-config.php:231
msgid "percentage"
msgstr ""

#: inc/controller-config.php:232
msgid "cover"
msgstr ""

#: inc/controller-config.php:233
msgid "contain"
msgstr ""

#: inc/controller-config.php:239
msgid "Box Shadow"
msgstr ""

#: inc/controller-config.php:247
msgid "Opacity"
msgstr ""

#: inc/controller-config.php:260
msgid "Borders"
msgstr ""

#: inc/controller-config.php:303
msgid "Border Radius"
msgstr ""

#: inc/controller-config.php:326
msgid "Layout"
msgstr ""

#: inc/controller-config.php:330
msgid "Margin"
msgstr ""

#: inc/controller-config.php:347
msgid "Padding"
msgstr ""

#: inc/controller-config.php:364
msgid "Position"
msgstr ""

#: inc/controller-config.php:369
msgid "Absolute"
msgstr ""

#: inc/controller-config.php:370
msgid "Fixed"
msgstr ""

#: inc/controller-config.php:371
msgid "Relative"
msgstr ""

#: inc/controller-config.php:372
msgid "Static"
msgstr ""

#: inc/controller-config.php:373
msgid "Inherit"
msgstr ""

#: inc/controller-config.php:378
msgid "Absolute Position"
msgstr ""

#: inc/controller-config.php:394
msgid "Width"
msgstr ""

#: inc/controller-config.php:402
msgid "Height"
msgstr ""

#: inc/controller-config.php:410
msgid "Display"
msgstr ""

#: inc/controller-config.php:416
msgid "Inline"
msgstr ""

#: inc/controller-config.php:417
msgid "Block"
msgstr ""

#: inc/controller-config.php:418
msgid "Flex"
msgstr ""

#: inc/controller-config.php:419
msgid "Inline Block"
msgstr ""

#: inc/controller-config.php:420
msgid "Inline Flex"
msgstr ""

#: inc/controller-config.php:421
msgid "Inline Table"
msgstr ""

#: inc/controller-config.php:422
msgid "List Item"
msgstr ""

#: inc/controller-config.php:423
msgid "Run In"
msgstr ""

#: inc/controller-config.php:424
msgid "Table"
msgstr ""

#: inc/controller-config.php:425
msgid "Table Caption"
msgstr ""

#: inc/controller-config.php:426
msgid "Table Column Group"
msgstr ""

#: inc/controller-config.php:427
msgid "Table Header Group"
msgstr ""

#: inc/controller-config.php:428
msgid "Table Footer Group"
msgstr ""

#: inc/controller-config.php:429
msgid "Table Row Group"
msgstr ""

#: inc/controller-config.php:430
msgid "Table Cell"
msgstr ""

#: inc/controller-config.php:431
msgid "Table Column"
msgstr ""

#: inc/controller-config.php:432
msgid "Table Row"
msgstr ""

#: inc/controller-config.php:437
msgid "Float"
msgstr ""

#: inc/controller-config.php:449
msgid "Clear"
msgstr ""

#: inc/controller-config.php:457
msgid "Both"
msgstr ""

#: inc/controller-config.php:462
msgid "Visibility"
msgstr ""

#: inc/controller-config.php:467, inc/controller-config.php:479, inc/controller-config.php:492, inc/controller-config.php:505
msgid "Visible"
msgstr ""

#: inc/controller-config.php:468, inc/controller-config.php:480, inc/controller-config.php:493, inc/controller-config.php:506
msgid "Hidden"
msgstr ""

#: inc/controller-config.php:469
msgid "Collapse"
msgstr ""

#: inc/controller-config.php:474
msgid "Overflow"
msgstr ""

#: inc/controller-config.php:481, inc/controller-config.php:494, inc/controller-config.php:507
msgid "Scroll"
msgstr ""

#: inc/controller-config.php:482, inc/controller-config.php:495, inc/controller-config.php:508
msgid "Auto"
msgstr ""

#: inc/controller-config.php:487
msgid "Overflow X"
msgstr ""

#: inc/controller-config.php:500
msgid "Overflow Y"
msgstr ""

#: inc/controller-config.php:513
msgid "Z-Index"
msgstr ""

#: tpl/inspector-templates.php:4
msgid "Navigate To: "
msgstr ""

#: tpl/js-templates.php:8
msgid "CSS Snippets"
msgstr ""

#: tpl/js-templates.php:14
msgid "Search Snippets"
msgstr ""

#: tpl/js-templates.php:26
msgid "Insert Snippet"
msgstr ""

#: tpl/js-templates.php:59
msgid "Invalid URI. Please make sure you're using a URL from the same site."
msgstr ""

#: tpl/js-templates.php:69
msgid "Get a %sGoogle Font%s selector."
msgstr ""

#: tpl/page.php:28
msgid "Site design updated."
msgstr ""

#: tpl/page.php:33
msgid "Editing revision dated %s. Click %sRevert to this revision%s to keep using it."
msgstr ""

#: tpl/page.php:47
msgid "Get The Full Experience"
msgstr ""

#: tpl/page.php:49
msgid "%sSiteOrigin Premium%s adds a <strong>Google Web Font</strong> selector to SiteOrigin CSS so you can easily change any font."
msgstr ""

#: tpl/page.php:57
msgid "Getting Started Video"
msgstr ""

#: tpl/page.php:58
msgid "Dismiss"
msgstr ""

#: tpl/page.php:67
msgid "CSS Revisions"
msgstr ""

#: tpl/page.php:69
msgid "Are you sure you want to load this revision?"
msgstr ""

#: tpl/page.php:76
msgid "Editor Theme"
msgstr ""

#: tpl/page.php:79
msgid "Light"
msgstr ""

#: tpl/page.php:80
msgid "Dark"
msgstr ""

#: tpl/page.php:103, tpl/page.php:104
msgid "Open Expanded Mode"
msgstr ""

#: tpl/page.php:105
msgid "Close Expanded Mode"
msgstr ""

#: tpl/page.php:108
msgid "Open Visual Mode"
msgstr ""

#: tpl/page.php:137
msgid "Other Settings"
msgstr ""

#: tpl/page.php:142
msgid "Enable SiteOrigin Installer: "
msgstr ""

#: tpl/page.php:165
msgid "Close"
msgstr ""

#: inc/installer/siteorigin-installer.php:3
msgid "SiteOrigin Installer"
msgstr ""

#: inc/installer/siteorigin-installer.php:4
msgid "https://siteorigin.com/installer/"
msgstr ""

#: inc/installer/siteorigin-installer.php:5
msgid "This plugin installs all the SiteOrigin themes and plugins you need to get started with your new site."
msgstr ""
/*
 * jQuery MiniColors: A tiny color picker built on jQuery
 *
 * Copyright: Cory LaViska for A Beautiful Site, LLC: http://www.abeautifulsite.net/
 *
 * Contribute: https://github.com/claviska/jquery-minicolors
 *
 * @license: http://opensource.org/licenses/MIT
 *
 */
(function (factory) {
    /* jshint ignore:start */
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }
    /* jshint ignore:end */
}(function ($) {

    'use strict';

    // Defaults
    $.minicolors = {
        defaults: {
            animationSpeed: 50,
            animationEasing: 'swing',
            change: null,
            changeDelay: 0,
            control: 'hue',
            dataUris: true,
            defaultValue: '',
            format: 'hex',
            hide: null,
            hideSpeed: 100,
            inline: false,
            keywords: '',
            letterCase: 'lowercase',
            opacity: false,
            position: 'bottom left',
            show: null,
            showSpeed: 100,
            theme: 'default',
            swatches: []
        }
    };

    // Public methods
    $.extend($.fn, {
        minicolors: function(method, data) {

            switch(method) {

                // Destroy the control
                case 'destroy':
                    $(this).each( function() {
                        destroy($(this));
                    });
                    return $(this);

                // Hide the color picker
                case 'hide':
                    hide();
                    return $(this);

                // Get/set opacity
                case 'opacity':
                    // Getter
                    if( data === undefined ) {
                        // Getter
                        return $(this).attr('data-opacity');
                    } else {
                        // Setter
                        $(this).each( function() {
                            updateFromInput($(this).attr('data-opacity', data));
                        });
                    }
                    return $(this);

                // Get an RGB(A) object based on the current color/opacity
                case 'rgbObject':
                    return rgbObject($(this), method === 'rgbaObject');

                // Get an RGB(A) string based on the current color/opacity
                case 'rgbString':
                case 'rgbaString':
                    return rgbString($(this), method === 'rgbaString');

                // Get/set settings on the fly
                case 'settings':
                    if( data === undefined ) {
                        return $(this).data('minicolors-settings');
                    } else {
                        // Setter
                        $(this).each( function() {
                            var settings = $(this).data('minicolors-settings') || {};
                            destroy($(this));
                            $(this).minicolors($.extend(true, settings, data));
                        });
                    }
                    return $(this);

                // Show the color picker
                case 'show':
                    show( $(this).eq(0) );
                    return $(this);

                // Get/set the hex color value
                case 'value':
                    if( data === undefined ) {
                        // Getter
                        return $(this).val();
                    } else {
                        // Setter
                        $(this).each( function() {
                            if( typeof(data) === 'object' && typeof(data) !== null ) {
                                if( data.opacity ) {
                                    $(this).attr('data-opacity', keepWithin(data.opacity, 0, 1));
                                }
                                if( data.color ) {
                                    $(this).val(data.color);
                                }
                            } else {
                                $(this).val(data);
                            }
                            updateFromInput($(this));
                        });
                    }
                    return $(this);

                // Initializes the control
                default:
                    if( method !== 'create' ) data = method;
                    $(this).each( function() {
                        init($(this), data);
                    });
                    return $(this);

            }

        }
    });

    // Initialize input elements
    function init(input, settings) {

        var minicolors = $('<div class="minicolors" />'),
            defaults = $.minicolors.defaults,
            size,
            swatches,
            swatch,
            panel,
            i;

        // Do nothing if already initialized
        if( input.data('minicolors-initialized') ) return;

        // Handle settings
        settings = $.extend(true, {}, defaults, settings);

        // The wrapper
        minicolors
            .addClass('minicolors-theme-' + settings.theme)
            .toggleClass('minicolors-with-opacity', settings.opacity)
            .toggleClass('minicolors-no-data-uris', settings.dataUris !== true);

        // Custom positioning
        if( settings.position !== undefined ) {
            $.each(settings.position.split(' '), function() {
                minicolors.addClass('minicolors-position-' + this);
            });
        }

        // Input size
        if( settings.format === 'rgb' ) {
            size = settings.opacity ? '25' : '20';
        } else {
            size = settings.keywords ? '11' : '7';
        }

        // The input
        input
            .addClass('minicolors-input')
            .data('minicolors-initialized', false)
            .data('minicolors-settings', settings)
            .prop('size', size)
            .wrap(minicolors)
            .after(
                '<div class="minicolors-panel minicolors-slider-' + settings.control + '">' +
                    '<div class="minicolors-slider minicolors-sprite">' +
                        '<div class="minicolors-picker"></div>' +
                    '</div>' +
                    '<div class="minicolors-opacity-slider minicolors-sprite">' +
                        '<div class="minicolors-picker"></div>' +
                    '</div>' +
                    '<div class="minicolors-grid minicolors-sprite">' +
                        '<div class="minicolors-grid-inner"></div>' +
                        '<div class="minicolors-picker"><div></div></div>' +
                    '</div>' +
                '</div>'
            );

        // The swatch
        if( !settings.inline ) {
            input.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>');
            input.next('.minicolors-input-swatch').on('click', function(event) {
                event.preventDefault();
                input.focus();
            });
        }

        // Prevent text selection in IE
        panel = input.parent().find('.minicolors-panel');
        panel.on('selectstart', function() { return false; }).end();

        // Swatches
        if (settings.swatches && settings.swatches.length !== 0) {
            if (settings.swatches.length > 7) {
                settings.swatches.length = 7;
            }
            panel.addClass('minicolors-with-swatches');
            swatches = $('<ul class="minicolors-swatches"></ul>')
                .appendTo(panel);
            for(i = 0; i < settings.swatches.length; ++i) {
                swatch = settings.swatches[i];
                swatch = isRgb(swatch) ? parseRgb(swatch, true) : hex2rgb(parseHex(swatch, true));
                $('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>')
                    .appendTo(swatches)
                    .data('swatch-color', settings.swatches[i])
                    .find('.minicolors-swatch-color')
                    .css({
                        backgroundColor: rgb2hex(swatch),
                        opacity: swatch.a
                    });
                settings.swatches[i] = swatch;
            }

        }

        // Inline controls
        if( settings.inline ) input.parent().addClass('minicolors-inline');

        updateFromInput(input, false);

        input.data('minicolors-initialized', true);

    }

    // Returns the input back to its original state
    function destroy(input) {

        var minicolors = input.parent();

        // Revert the input element
        input
            .removeData('minicolors-initialized')
            .removeData('minicolors-settings')
            .removeProp('size')
            .removeClass('minicolors-input');

        // Remove the wrap and destroy whatever remains
        minicolors.before(input).remove();

    }

    // Shows the specified dropdown panel
    function show(input) {

        var minicolors = input.parent(),
            panel = minicolors.find('.minicolors-panel'),
            settings = input.data('minicolors-settings');

        // Do nothing if uninitialized, disabled, inline, or already open
        if( !input.data('minicolors-initialized') ||
            input.prop('disabled') ||
            minicolors.hasClass('minicolors-inline') ||
            minicolors.hasClass('minicolors-focus')
        ) return;

        hide();

        minicolors.addClass('minicolors-focus');
        panel
            .stop(true, true)
            .fadeIn(settings.showSpeed, function() {
                if( settings.show ) settings.show.call(input.get(0));
            });

    }

    // Hides all dropdown panels
    function hide() {

        $('.minicolors-focus').each( function() {

            var minicolors = $(this),
                input = minicolors.find('.minicolors-input'),
                panel = minicolors.find('.minicolors-panel'),
                settings = input.data('minicolors-settings');

            panel.fadeOut(settings.hideSpeed, function() {
                if( settings.hide ) settings.hide.call(input.get(0));
                minicolors.removeClass('minicolors-focus');
            });

        });
    }

    // Moves the selected picker
    function move(target, event, animate) {

        var input = target.parents('.minicolors').find('.minicolors-input'),
            settings = input.data('minicolors-settings'),
            picker = target.find('[class$=-picker]'),
            offsetX = target.offset().left,
            offsetY = target.offset().top,
            x = Math.round(event.pageX - offsetX),
            y = Math.round(event.pageY - offsetY),
            duration = animate ? settings.animationSpeed : 0,
            wx, wy, r, phi;

        // Touch support
        if( event.originalEvent.changedTouches ) {
            x = event.originalEvent.changedTouches[0].pageX - offsetX;
            y = event.originalEvent.changedTouches[0].pageY - offsetY;
        }

        // Constrain picker to its container
        if( x < 0 ) x = 0;
        if( y < 0 ) y = 0;
        if( x > target.width() ) x = target.width();
        if( y > target.height() ) y = target.height();

        // Constrain color wheel values to the wheel
        if( target.parent().is('.minicolors-slider-wheel') && picker.parent().is('.minicolors-grid') ) {
            wx = 75 - x;
            wy = 75 - y;
            r = Math.sqrt(wx * wx + wy * wy);
            phi = Math.atan2(wy, wx);
            if( phi < 0 ) phi += Math.PI * 2;
            if( r > 75 ) {
                r = 75;
                x = 75 - (75 * Math.cos(phi));
                y = 75 - (75 * Math.sin(phi));
            }
            x = Math.round(x);
            y = Math.round(y);
        }

        // Move the picker
        if( target.is('.minicolors-grid') ) {
            picker
                .stop(true)
                .animate({
                    top: y + 'px',
                    left: x + 'px'
                }, duration, settings.animationEasing, function() {
                    updateFromControl(input, target);
                });
        } else {
            picker
                .stop(true)
                .animate({
                    top: y + 'px'
                }, duration, settings.animationEasing, function() {
                    updateFromControl(input, target);
                });
        }

    }

    // Sets the input based on the color picker values
    function updateFromControl(input, target) {

        function getCoords(picker, container) {

            var left, top;
            if( !picker.length || !container ) return null;
            left = picker.offset().left;
            top = picker.offset().top;

            return {
                x: left - container.offset().left + (picker.outerWidth() / 2),
                y: top - container.offset().top + (picker.outerHeight() / 2)
            };

        }

        var hue, saturation, brightness, x, y, r, phi,

            hex = input.val(),
            opacity = input.attr('data-opacity'),

            // Helpful references
            minicolors = input.parent(),
            settings = input.data('minicolors-settings'),
            swatch = minicolors.find('.minicolors-input-swatch'),

            // Panel objects
            grid = minicolors.find('.minicolors-grid'),
            slider = minicolors.find('.minicolors-slider'),
            opacitySlider = minicolors.find('.minicolors-opacity-slider'),

            // Picker objects
            gridPicker = grid.find('[class$=-picker]'),
            sliderPicker = slider.find('[class$=-picker]'),
            opacityPicker = opacitySlider.find('[class$=-picker]'),

            // Picker positions
            gridPos = getCoords(gridPicker, grid),
            sliderPos = getCoords(sliderPicker, slider),
            opacityPos = getCoords(opacityPicker, opacitySlider);

        // Handle colors
        if( target.is('.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider') ) {

            // Determine HSB values
            switch(settings.control) {

                case 'wheel':
                    // Calculate hue, saturation, and brightness
                    x = (grid.width() / 2) - gridPos.x;
                    y = (grid.height() / 2) - gridPos.y;
                    r = Math.sqrt(x * x + y * y);
                    phi = Math.atan2(y, x);
                    if( phi < 0 ) phi += Math.PI * 2;
                    if( r > 75 ) {
                        r = 75;
                        gridPos.x = 69 - (75 * Math.cos(phi));
                        gridPos.y = 69 - (75 * Math.sin(phi));
                    }
                    saturation = keepWithin(r / 0.75, 0, 100);
                    hue = keepWithin(phi * 180 / Math.PI, 0, 360);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });

                    // Update UI
                    slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
                    break;

                case 'saturation':
                    // Calculate hue, saturation, and brightness
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });

                    // Update UI
                    slider.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: brightness }));
                    minicolors.find('.minicolors-grid-inner').css('opacity', saturation / 100);
                    break;

                case 'brightness':
                    // Calculate hue, saturation, and brightness
                    hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360);
                    saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });

                    // Update UI
                    slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
                    minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (brightness / 100));
                    break;

                default:
                    // Calculate hue, saturation, and brightness
                    hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360);
                    saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
                    brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
                    hex = hsb2hex({
                        h: hue,
                        s: saturation,
                        b: brightness
                    });

                    // Update UI
                    grid.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: 100 }));
                    break;

            }

            // Handle opacity
            if( settings.opacity ) {
                opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2);
            } else {
                opacity = 1;
            }

            updateInput(input, hex, opacity);
        }
        else {
            // Set swatch color
            swatch.find('span').css({
                backgroundColor: hex,
                opacity: opacity
            });

            // Handle change event
            doChange(input, hex, opacity);
        }
    }

    // Sets the value of the input and does the appropriate conversions
    // to respect settings, also updates the swatch
    function updateInput(input, value, opacity) {
        var rgb,

        // Helpful references
        minicolors = input.parent(),
        settings = input.data('minicolors-settings'),
        swatch = minicolors.find('.minicolors-input-swatch');

        if( settings.opacity ) input.attr('data-opacity', opacity);

        // Set color string
        if( settings.format === 'rgb' ) {
            // Returns RGB(A) string

            // Checks for input format and does the conversion
            if ( isRgb(value) ) {
                rgb = parseRgb(value, true);
            }
            else {
                rgb = hex2rgb(parseHex(value, true));
            }

            opacity = input.attr('data-opacity') === '' ? 1 : keepWithin( parseFloat( input.attr('data-opacity') ).toFixed(2), 0, 1 );
            if( isNaN( opacity ) || !settings.opacity ) opacity = 1;

            if( input.minicolors('rgbObject').a <= 1 && rgb && settings.opacity) {
                // Set RGBA string if alpha
                value = 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat( opacity ) + ')';
            } else {
                // Set RGB string (alpha = 1)
                value = 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
            }
        } else {
            // Returns hex color

            // Checks for input format and does the conversion
            if ( isRgb(value) ) {
                value = rgbString2hex(value);
            }

            value = convertCase( value, settings.letterCase );
        }

        // Update value from picker
        input.val( value );

        // Set swatch color
        swatch.find('span').css({
            backgroundColor: value,
            opacity: opacity
        });

        // Handle change event
        doChange(input, value, opacity);
    }

    // Sets the color picker values from the input
    function updateFromInput(input, preserveInputValue) {

        var hex,
            hsb,
            opacity,
            keywords,
            alpha,
            value,
            x, y, r, phi,

            // Helpful references
            minicolors = input.parent(),
            settings = input.data('minicolors-settings'),
            swatch = minicolors.find('.minicolors-input-swatch'),

            // Panel objects
            grid = minicolors.find('.minicolors-grid'),
            slider = minicolors.find('.minicolors-slider'),
            opacitySlider = minicolors.find('.minicolors-opacity-slider'),

            // Picker objects
            gridPicker = grid.find('[class$=-picker]'),
            sliderPicker = slider.find('[class$=-picker]'),
            opacityPicker = opacitySlider.find('[class$=-picker]');

        // Determine hex/HSB values
        if( isRgb(input.val()) ) {
            // If input value is a rgb(a) string, convert it to hex color and update opacity
            hex = rgbString2hex(input.val());
            alpha = keepWithin(parseFloat(getAlpha(input.val())).toFixed(2), 0, 1);
            if( alpha ) {
                input.attr('data-opacity', alpha);
            }
        } else {
            hex = convertCase(parseHex(input.val(), true), settings.letterCase);
        }

        if( !hex ){
            hex = convertCase(parseInput(settings.defaultValue, true), settings.letterCase);
        }
        hsb = hex2hsb(hex);

        // Get array of lowercase keywords
        keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) {
            return $.trim(a.toLowerCase());
        });

        // Set color string
        if( input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1 ) {
            value = convertCase(input.val());
        } else {
            value = isRgb(input.val()) ? parseRgb(input.val()) : hex;
        }

        // Update input value
        if( !preserveInputValue ) input.val(value);

        // Determine opacity value
        if( settings.opacity ) {
            // Get from data-opacity attribute and keep within 0-1 range
            opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
            if( isNaN(opacity) ) opacity = 1;
            input.attr('data-opacity', opacity);
            swatch.find('span').css('opacity', opacity);

            // Set opacity picker position
            y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height());
            opacityPicker.css('top', y + 'px');
        }

        // Set opacity to zero if input value is transparent
        if( input.val().toLowerCase() === 'transparent' ) {
            swatch.find('span').css('opacity', 0);
        }

        // Update swatch
        swatch.find('span').css('backgroundColor', hex);

        // Determine picker locations
        switch(settings.control) {

            case 'wheel':
                // Set grid position
                r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
                phi = hsb.h * Math.PI / 180;
                x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
                y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
                gridPicker.css({
                    top: y + 'px',
                    left: x + 'px'
                });

                // Set slider position
                y = 150 - (hsb.b / (100 / grid.height()));
                if( hex === '' ) y = 0;
                sliderPicker.css('top', y + 'px');

                // Update panel color
                slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
                break;

            case 'saturation':
                // Set grid position
                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                gridPicker.css({
                    top: y + 'px',
                    left: x + 'px'
                });

                // Set slider position
                y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                // Update UI
                slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: hsb.b }));
                minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
                break;

            case 'brightness':
                // Set grid position
                x = keepWithin((5 * hsb.h) / 12, 0, 150);
                y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
                gridPicker.css({
                    top: y + 'px',
                    left: x + 'px'
                });

                // Set slider position
                y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                // Update UI
                slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
                minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100));
                break;

            default:
                // Set grid position
                x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
                y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
                gridPicker.css({
                    top: y + 'px',
                    left: x + 'px'
                });

                // Set slider position
                y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height());
                sliderPicker.css('top', y + 'px');

                // Update panel color
                grid.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: 100 }));
                break;

        }

        // Fire change event, but only if minicolors is fully initialized
        if( input.data('minicolors-initialized') ) {
            doChange(input, value, opacity);
        }

    }

    // Runs the change and changeDelay callbacks
    function doChange(input, value, opacity) {

        var settings = input.data('minicolors-settings'),
            lastChange = input.data('minicolors-lastChange'),
            obj,
            sel,
            i;

        // Only run if it actually changed
        if( !lastChange || lastChange.value !== value || lastChange.opacity !== opacity ) {

            // Remember last-changed value
            input.data('minicolors-lastChange', {
                value: value,
                opacity: opacity
            });

            // Check and select applicable swatch
            if (settings.swatches && settings.swatches.length !== 0) {
                if(!isRgb(value)) {
                    obj = hex2rgb(value);
                }
                else {
                    obj = parseRgb(value, true);
                }
                sel = -1;
                for(i = 0; i < settings.swatches.length; ++i) {
                    if (obj.r === settings.swatches[i].r && obj.g === settings.swatches[i].g && obj.b === settings.swatches[i].b && obj.a === settings.swatches[i].a) {
                        sel = i;
                        break;
                    }
                }

                input.parent().find('.minicolors-swatches .minicolors-swatch').removeClass('selected');
                if (i !== -1) {
                    input.parent().find('.minicolors-swatches .minicolors-swatch').eq(i).addClass('selected');
                }
            }

            // Fire change event
            if( settings.change ) {
                if( settings.changeDelay ) {
                    // Call after a delay
                    clearTimeout(input.data('minicolors-changeTimeout'));
                    input.data('minicolors-changeTimeout', setTimeout( function() {
                        settings.change.call(input.get(0), value, opacity);
                    }, settings.changeDelay));
                } else {
                    // Call immediately
                    settings.change.call(input.get(0), value, opacity);
                }
            }
            input.trigger('change').trigger('input');
        }

    }

    // Generates an RGB(A) object based on the input's value
    function rgbObject(input) {
        var hex = parseHex($(input).val(), true),
            rgb = hex2rgb(hex),
            opacity = $(input).attr('data-opacity');
        if( !rgb ) return null;
        if( opacity !== undefined ) $.extend(rgb, { a: parseFloat(opacity) });
        return rgb;
    }

    // Generates an RGB(A) string based on the input's value
    function rgbString(input, alpha) {
        var hex = parseHex($(input).val(), true),
            rgb = hex2rgb(hex),
            opacity = $(input).attr('data-opacity');
        if( !rgb ) return null;
        if( opacity === undefined ) opacity = 1;
        if( alpha ) {
            return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
        } else {
            return 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
        }
    }

    // Converts to the letter case specified in settings
    function convertCase(string, letterCase) {
        return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
    }

    // Parses a string and returns a valid hex string when possible
    function parseHex(string, expand) {
        string = string.replace(/^#/g, '');
        if( !string.match(/^[A-F0-9]{3,6}/ig) ) return '';
        if( string.length !== 3 && string.length !== 6 ) return '';
        if( string.length === 3 && expand ) {
            string = string[0] + string[0] + string[1] + string[1] + string[2] + string[2];
        }
        return '#' + string;
    }

    // Parses a string and returns a valid RGB(A) string when possible
    function parseRgb(string, obj) {

        var values = string.replace(/[^\d,.]/g, ''),
            rgba = values.split(',');

        rgba[0] = keepWithin(parseInt(rgba[0], 10), 0, 255);
        rgba[1] = keepWithin(parseInt(rgba[1], 10), 0, 255);
        rgba[2] = keepWithin(parseInt(rgba[2], 10), 0, 255);
        if( rgba[3] ) {
            rgba[3] = keepWithin(parseFloat(rgba[3], 10), 0, 1);
        }

        // Return RGBA object
        if( obj ) {
            return {
                r: rgba[0],
                g: rgba[1],
                b: rgba[2],
                a: rgba[3] ? rgba[3] : null
            };
        }

        // Return RGBA string
        if( typeof(rgba[3]) !== 'undefined' && rgba[3] <= 1 ) {
            return 'rgba(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ', ' + rgba[3] + ')';
        } else {
            return 'rgb(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ')';
        }

    }

    // Parses a string and returns a valid color string when possible
    function parseInput(string, expand) {
        if( isRgb(string) ) {
            // Returns a valid rgb(a) string
            return parseRgb(string);
        } else {
            return parseHex(string, expand);
        }
    }

    // Keeps value within min and max
    function keepWithin(value, min, max) {
        if( value < min ) value = min;
        if( value > max ) value = max;
        return value;
    }

    // Checks if a string is a valid RGB(A) string
    function isRgb(string) {
        var rgb = string.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
        return (rgb && rgb.length === 4) ? true : false;
    }

    // Function to get alpha from a RGB(A) string
    function getAlpha(rgba) {
        rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i);
        return (rgba && rgba.length === 6) ? rgba[4] : '1';
    }

   // Converts an HSB object to an RGB object
    function hsb2rgb(hsb) {
        var rgb = {};
        var h = Math.round(hsb.h);
        var s = Math.round(hsb.s * 255 / 100);
        var v = Math.round(hsb.b * 255 / 100);
        if(s === 0) {
            rgb.r = rgb.g = rgb.b = v;
        } else {
            var t1 = v;
            var t2 = (255 - s) * v / 255;
            var t3 = (t1 - t2) * (h % 60) / 60;
            if( h === 360 ) h = 0;
            if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
            else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
            else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
            else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
            else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
            else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
            else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
        }
        return {
            r: Math.round(rgb.r),
            g: Math.round(rgb.g),
            b: Math.round(rgb.b)
        };
    }

    // Converts an RGB string to a hex string
    function rgbString2hex(rgb){
        rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
        return (rgb && rgb.length === 4) ? '#' +
        ('0' + parseInt(rgb[1],10).toString(16)).slice(-2) +
        ('0' + parseInt(rgb[2],10).toString(16)).slice(-2) +
        ('0' + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
    }

    // Converts an RGB object to a hex string
    function rgb2hex(rgb) {
        var hex = [
            rgb.r.toString(16),
            rgb.g.toString(16),
            rgb.b.toString(16)
        ];
        $.each(hex, function(nr, val) {
            if (val.length === 1) hex[nr] = '0' + val;
        });
        return '#' + hex.join('');
    }

    // Converts an HSB object to a hex string
    function hsb2hex(hsb) {
        return rgb2hex(hsb2rgb(hsb));
    }

    // Converts a hex string to an HSB object
    function hex2hsb(hex) {
        var hsb = rgb2hsb(hex2rgb(hex));
        if( hsb.s === 0 ) hsb.h = 360;
        return hsb;
    }

    // Converts an RGB object to an HSB object
    function rgb2hsb(rgb) {
        var hsb = { h: 0, s: 0, b: 0 };
        var min = Math.min(rgb.r, rgb.g, rgb.b);
        var max = Math.max(rgb.r, rgb.g, rgb.b);
        var delta = max - min;
        hsb.b = max;
        hsb.s = max !== 0 ? 255 * delta / max : 0;
        if( hsb.s !== 0 ) {
            if( rgb.r === max ) {
                hsb.h = (rgb.g - rgb.b) / delta;
            } else if( rgb.g === max ) {
                hsb.h = 2 + (rgb.b - rgb.r) / delta;
            } else {
                hsb.h = 4 + (rgb.r - rgb.g) / delta;
            }
        } else {
            hsb.h = -1;
        }
        hsb.h *= 60;
        if( hsb.h < 0 ) {
            hsb.h += 360;
        }
        hsb.s *= 100/255;
        hsb.b *= 100/255;
        return hsb;
    }

    // Converts a hex string to an RGB object
    function hex2rgb(hex) {
        hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
        return {
            /* jshint ignore:start */
            r: hex >> 16,
            g: (hex & 0x00FF00) >> 8,
            b: (hex & 0x0000FF)
            /* jshint ignore:end */
        };
    }

    // Handle events
    $([document, top.document])
        // Hide on clicks outside of the control
        .on('mousedown.minicolors touchstart.minicolors', function(event) {
            if( !$(event.target).parents().add(event.target).hasClass('minicolors') ) {
                hide();
            }
        })
        // Start moving
        .on('mousedown.minicolors touchstart.minicolors', '.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider', function(event) {
            var target = $(this);
            event.preventDefault();
            $(event.delegateTarget).data('minicolors-target', target);
            move(target, event, true);
        })
        // Move pickers
        .on('mousemove.minicolors touchmove.minicolors', function(event) {
            var target = $(event.delegateTarget).data('minicolors-target');
            if( target ) move(target, event);
        })
        // Stop moving
        .on('mouseup.minicolors touchend.minicolors', function() {
            $(this).removeData('minicolors-target');
        })
        // Selected a swatch
        .on('click.minicolors', '.minicolors-swatches li', function(event) {
            event.preventDefault();
            var target = $(this), input = target.parents('.minicolors').find('.minicolors-input'), color = target.data('swatch-color');
            updateInput(input, color, getAlpha(color));
            updateFromInput(input);
        })
        // Show panel when swatch is clicked
        .on('mousedown.minicolors touchstart.minicolors', '.minicolors-input-swatch', function(event) {
            var input = $(this).parent().find('.minicolors-input');
            event.preventDefault();
            show(input);
        })
        // Show on focus
        .on('focus.minicolors', '.minicolors-input', function() {
            var input = $(this);
            if( !input.data('minicolors-initialized') ) return;
            show(input);
        })
        // Update value on blur
        .on('blur.minicolors', '.minicolors-input', function() {
            var input = $(this),
                settings = input.data('minicolors-settings'),
                keywords,
                hex,
                rgba,
                swatchOpacity,
                value;

            if( !input.data('minicolors-initialized') ) return;

            // Get array of lowercase keywords
            keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) {
                return $.trim(a.toLowerCase());
            });

            // Set color string
            if( input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1 ) {
                value = input.val();
            } else {
                // Get RGBA values for easy conversion
                if( isRgb(input.val()) ) {
                    rgba = parseRgb(input.val(), true);
                } else {
                    hex = parseHex(input.val(), true);
                    rgba = hex ? hex2rgb(hex) : null;
                }

                // Convert to format
                if( rgba === null ) {
                    value = settings.defaultValue;
                } else if( settings.format === 'rgb' ) {
                    value = settings.opacity ?
                        parseRgb('rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + input.attr('data-opacity') + ')') :
                        parseRgb('rgb(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ')');
                } else {
                    value = rgb2hex(rgba);
                }
            }

            // Update swatch opacity
            swatchOpacity = settings.opacity ? input.attr('data-opacity') : 1;
            if( value.toLowerCase() === 'transparent' ) swatchOpacity = 0;
            input
                .closest('.minicolors')
                .find('.minicolors-input-swatch > span')
                .css('opacity', swatchOpacity);

            // Set input value
            input.val(value);

            // Is it blank?
            if( input.val() === '' ) input.val(parseInput(settings.defaultValue, true));

            // Adjust case
            input.val( convertCase(input.val(), settings.letterCase) );

        })
        // Handle keypresses
        .on('keydown.minicolors', '.minicolors-input', function(event) {
            var input = $(this);
            if( !input.data('minicolors-initialized') ) return;
            switch(event.keyCode) {
                case 9: // tab
                    hide();
                    break;
                case 13: // enter
                case 27: // esc
                    hide();
                    input.blur();
                    break;
            }
        })
        // Update on keyup
        .on('keyup.minicolors', '.minicolors-input', function() {
            var input = $(this);
            if( !input.data('minicolors-initialized') ) return;
            updateFromInput(input, true);
        })
        // Update on paste
        .on('paste.minicolors', '.minicolors-input', function() {
            var input = $(this);
            if( !input.data('minicolors-initialized') ) return;
            setTimeout( function() {
                updateFromInput(input, true);
            }, 1);
        });

}));
/*
 * jQuery MiniColors: A tiny color picker built on jQuery
 *
 * Copyright: Cory LaViska for A Beautiful Site, LLC: http://www.abeautifulsite.net/
 *
 * Contribute: https://github.com/claviska/jquery-minicolors
 *
 * @license: http://opensource.org/licenses/MIT
 *
 */
!function(i){"function"==typeof define&&define.amd?define(["jquery"],i):"object"==typeof exports?module.exports=i(require("jquery")):i(jQuery)}((function(i){"use strict";function t(i){var t=i.parent();i.removeData("minicolors-initialized").removeData("minicolors-settings").removeProp("size").removeClass("minicolors-input"),t.before(i).remove()}function o(i){var t=i.parent(),o=t.find(".minicolors-panel"),a=i.data("minicolors-settings");!i.data("minicolors-initialized")||i.prop("disabled")||t.hasClass("minicolors-inline")||t.hasClass("minicolors-focus")||(s(),t.addClass("minicolors-focus"),o.stop(!0,!0).fadeIn(a.showSpeed,(function(){a.show&&a.show.call(i.get(0))})))}function s(){i(".minicolors-focus").each((function(){var t=i(this),o=t.find(".minicolors-input"),s=t.find(".minicolors-panel"),a=o.data("minicolors-settings");s.fadeOut(a.hideSpeed,(function(){a.hide&&a.hide.call(o.get(0)),t.removeClass("minicolors-focus")}))}))}function a(i,t,o){var s,a,r,e,c=i.parents(".minicolors").find(".minicolors-input"),l=c.data("minicolors-settings"),h=i.find("[class$=-picker]"),d=i.offset().left,p=i.offset().top,u=Math.round(t.pageX-d),g=Math.round(t.pageY-p),m=o?l.animationSpeed:0;t.originalEvent.changedTouches&&(u=t.originalEvent.changedTouches[0].pageX-d,g=t.originalEvent.changedTouches[0].pageY-p),u<0&&(u=0),g<0&&(g=0),u>i.width()&&(u=i.width()),g>i.height()&&(g=i.height()),i.parent().is(".minicolors-slider-wheel")&&h.parent().is(".minicolors-grid")&&(s=75-u,a=75-g,r=Math.sqrt(s*s+a*a),(e=Math.atan2(a,s))<0&&(e+=2*Math.PI),r>75&&(r=75,u=75-75*Math.cos(e),g=75-75*Math.sin(e)),u=Math.round(u),g=Math.round(g)),i.is(".minicolors-grid")?h.stop(!0).animate({top:g+"px",left:u+"px"},m,l.animationEasing,(function(){n(c,i)})):h.stop(!0).animate({top:g+"px"},m,l.animationEasing,(function(){n(c,i)}))}function n(i,t){function o(i,t){var o,s;return i.length&&t?(o=i.offset().left,s=i.offset().top,{x:o-t.offset().left+i.outerWidth()/2,y:s-t.offset().top+i.outerHeight()/2}):null}var s,a,n,e,l,h,d,p=i.val(),g=i.attr("data-opacity"),m=i.parent(),f=i.data("minicolors-settings"),v=m.find(".minicolors-input-swatch"),w=m.find(".minicolors-grid"),y=m.find(".minicolors-slider"),C=m.find(".minicolors-opacity-slider"),k=w.find("[class$=-picker]"),M=y.find("[class$=-picker]"),x=C.find("[class$=-picker]"),I=o(k,w),S=o(M,y),z=o(x,C);if(t.is(".minicolors-grid, .minicolors-slider, .minicolors-opacity-slider")){switch(f.control){case"wheel":e=w.width()/2-I.x,l=w.height()/2-I.y,h=Math.sqrt(e*e+l*l),(d=Math.atan2(l,e))<0&&(d+=2*Math.PI),h>75&&(h=75,I.x=69-75*Math.cos(d),I.y=69-75*Math.sin(d)),a=u(h/.75,0,100),p=b({h:s=u(180*d/Math.PI,0,360),s:a,b:n=u(100-Math.floor(S.y*(100/y.height())),0,100)}),y.css("backgroundColor",b({h:s,s:a,b:100}));break;case"saturation":p=b({h:s=u(parseInt(I.x*(360/w.width()),10),0,360),s:a=u(100-Math.floor(S.y*(100/y.height())),0,100),b:n=u(100-Math.floor(I.y*(100/w.height())),0,100)}),y.css("backgroundColor",b({h:s,s:100,b:n})),m.find(".minicolors-grid-inner").css("opacity",a/100);break;case"brightness":p=b({h:s=u(parseInt(I.x*(360/w.width()),10),0,360),s:a=u(100-Math.floor(I.y*(100/w.height())),0,100),b:n=u(100-Math.floor(S.y*(100/y.height())),0,100)}),y.css("backgroundColor",b({h:s,s:a,b:100})),m.find(".minicolors-grid-inner").css("opacity",1-n/100);break;default:p=b({h:s=u(360-parseInt(S.y*(360/y.height()),10),0,360),s:a=u(Math.floor(I.x*(100/w.width())),0,100),b:n=u(100-Math.floor(I.y*(100/w.height())),0,100)}),w.css("backgroundColor",b({h:s,s:100,b:100}))}r(i,p,g=f.opacity?parseFloat(1-z.y/C.height()).toFixed(2):1)}else v.find("span").css({backgroundColor:p,opacity:g}),c(i,p,g)}function r(i,t,o){var s,a=i.parent(),n=i.data("minicolors-settings"),r=a.find(".minicolors-input-swatch");n.opacity&&i.attr("data-opacity",o),"rgb"===n.format?(s=g(t)?d(t,!0):w(h(t,!0)),o=""===i.attr("data-opacity")?1:u(parseFloat(i.attr("data-opacity")).toFixed(2),0,1),!isNaN(o)&&n.opacity||(o=1),t=i.minicolors("rgbObject").a<=1&&s&&n.opacity?"rgba("+s.r+", "+s.g+", "+s.b+", "+parseFloat(o)+")":"rgb("+s.r+", "+s.g+", "+s.b+")"):(g(t)&&(t=f(t)),t=l(t,n.letterCase)),i.val(t),r.find("span").css({backgroundColor:t,opacity:o}),c(i,t,o)}function e(t,o){var s,a,n,r,e,v,y,C,k,M,x=t.parent(),I=t.data("minicolors-settings"),S=x.find(".minicolors-input-swatch"),z=x.find(".minicolors-grid"),F=x.find(".minicolors-slider"),T=x.find(".minicolors-opacity-slider"),D=z.find("[class$=-picker]"),j=F.find("[class$=-picker]"),q=T.find("[class$=-picker]");switch(g(t.val())?(s=f(t.val()),(e=u(parseFloat(m(t.val())).toFixed(2),0,1))&&t.attr("data-opacity",e)):s=l(h(t.val(),!0),I.letterCase),s||(s=l(p(I.defaultValue,!0),I.letterCase)),a=function(i){var t=function(i){var t={h:0,s:0,b:0},o=Math.min(i.r,i.g,i.b),s=Math.max(i.r,i.g,i.b),a=s-o;t.b=s,t.s=0!==s?255*a/s:0,0!==t.s?i.r===s?t.h=(i.g-i.b)/a:i.g===s?t.h=2+(i.b-i.r)/a:t.h=4+(i.r-i.g)/a:t.h=-1;t.h*=60,t.h<0&&(t.h+=360);return t.s*=100/255,t.b*=100/255,t}(w(i));0===t.s&&(t.h=360);return t}(s),r=I.keywords?i.map(I.keywords.split(","),(function(t){return i.trim(t.toLowerCase())})):[],v=""!==t.val()&&i.inArray(t.val().toLowerCase(),r)>-1?l(t.val()):g(t.val())?d(t.val()):s,o||t.val(v),I.opacity&&(n=""===t.attr("data-opacity")?1:u(parseFloat(t.attr("data-opacity")).toFixed(2),0,1),isNaN(n)&&(n=1),t.attr("data-opacity",n),S.find("span").css("opacity",n),C=u(T.height()-T.height()*n,0,T.height()),q.css("top",C+"px")),"transparent"===t.val().toLowerCase()&&S.find("span").css("opacity",0),S.find("span").css("backgroundColor",s),I.control){case"wheel":k=u(Math.ceil(.75*a.s),0,z.height()/2),M=a.h*Math.PI/180,y=u(75-Math.cos(M)*k,0,z.width()),C=u(75-Math.sin(M)*k,0,z.height()),D.css({top:C+"px",left:y+"px"}),C=150-a.b/(100/z.height()),""===s&&(C=0),j.css("top",C+"px"),F.css("backgroundColor",b({h:a.h,s:a.s,b:100}));break;case"saturation":y=u(5*a.h/12,0,150),C=u(z.height()-Math.ceil(a.b/(100/z.height())),0,z.height()),D.css({top:C+"px",left:y+"px"}),C=u(F.height()-a.s*(F.height()/100),0,F.height()),j.css("top",C+"px"),F.css("backgroundColor",b({h:a.h,s:100,b:a.b})),x.find(".minicolors-grid-inner").css("opacity",a.s/100);break;case"brightness":y=u(5*a.h/12,0,150),C=u(z.height()-Math.ceil(a.s/(100/z.height())),0,z.height()),D.css({top:C+"px",left:y+"px"}),C=u(F.height()-a.b*(F.height()/100),0,F.height()),j.css("top",C+"px"),F.css("backgroundColor",b({h:a.h,s:a.s,b:100})),x.find(".minicolors-grid-inner").css("opacity",1-a.b/100);break;default:y=u(Math.ceil(a.s/(100/z.width())),0,z.width()),C=u(z.height()-Math.ceil(a.b/(100/z.height())),0,z.height()),D.css({top:C+"px",left:y+"px"}),C=u(F.height()-a.h/(360/F.height()),0,F.height()),j.css("top",C+"px"),z.css("backgroundColor",b({h:a.h,s:100,b:100}))}t.data("minicolors-initialized")&&c(t,v,n)}function c(i,t,o){var s,a,n=i.data("minicolors-settings"),r=i.data("minicolors-lastChange");if(!r||r.value!==t||r.opacity!==o){if(i.data("minicolors-lastChange",{value:t,opacity:o}),n.swatches&&0!==n.swatches.length){for(s=g(t)?d(t,!0):w(t),-1,a=0;a<n.swatches.length;++a)if(s.r===n.swatches[a].r&&s.g===n.swatches[a].g&&s.b===n.swatches[a].b&&s.a===n.swatches[a].a){a;break}i.parent().find(".minicolors-swatches .minicolors-swatch").removeClass("selected"),-1!==a&&i.parent().find(".minicolors-swatches .minicolors-swatch").eq(a).addClass("selected")}n.change&&(n.changeDelay?(clearTimeout(i.data("minicolors-changeTimeout")),i.data("minicolors-changeTimeout",setTimeout((function(){n.change.call(i.get(0),t,o)}),n.changeDelay))):n.change.call(i.get(0),t,o)),i.trigger("change").trigger("input")}}function l(i,t){return"uppercase"===t?i.toUpperCase():i.toLowerCase()}function h(i,t){return(i=i.replace(/^#/g,"")).match(/^[A-F0-9]{3,6}/gi)?3!==i.length&&6!==i.length?"":(3===i.length&&t&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),"#"+i):""}function d(i,t){var o=i.replace(/[^\d,.]/g,"").split(",");return o[0]=u(parseInt(o[0],10),0,255),o[1]=u(parseInt(o[1],10),0,255),o[2]=u(parseInt(o[2],10),0,255),o[3]&&(o[3]=u(parseFloat(o[3],10),0,1)),t?{r:o[0],g:o[1],b:o[2],a:o[3]?o[3]:null}:void 0!==o[3]&&o[3]<=1?"rgba("+o[0]+", "+o[1]+", "+o[2]+", "+o[3]+")":"rgb("+o[0]+", "+o[1]+", "+o[2]+")"}function p(i,t){return g(i)?d(i):h(i,t)}function u(i,t,o){return i<t&&(i=t),i>o&&(i=o),i}function g(i){var t=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);return!(!t||4!==t.length)}function m(i){return(i=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i))&&6===i.length?i[4]:"1"}function f(i){return(i=i.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i))&&4===i.length?"#"+("0"+parseInt(i[1],10).toString(16)).slice(-2)+("0"+parseInt(i[2],10).toString(16)).slice(-2)+("0"+parseInt(i[3],10).toString(16)).slice(-2):""}function v(t){var o=[t.r.toString(16),t.g.toString(16),t.b.toString(16)];return i.each(o,(function(i,t){1===t.length&&(o[i]="0"+t)})),"#"+o.join("")}function b(i){return v(function(i){var t={},o=Math.round(i.h),s=Math.round(255*i.s/100),a=Math.round(255*i.b/100);if(0===s)t.r=t.g=t.b=a;else{var n=a,r=(255-s)*a/255,e=o%60*(n-r)/60;360===o&&(o=0),o<60?(t.r=n,t.b=r,t.g=r+e):o<120?(t.g=n,t.b=r,t.r=n-e):o<180?(t.g=n,t.r=r,t.b=r+e):o<240?(t.b=n,t.r=r,t.g=n-e):o<300?(t.b=n,t.g=r,t.r=r+e):o<360?(t.r=n,t.g=r,t.b=n-e):(t.r=0,t.g=0,t.b=0)}return{r:Math.round(t.r),g:Math.round(t.g),b:Math.round(t.b)}}(i))}function w(i){return{r:(i=parseInt(i.indexOf("#")>-1?i.substring(1):i,16))>>16,g:(65280&i)>>8,b:255&i}}i.minicolors={defaults:{animationSpeed:50,animationEasing:"swing",change:null,changeDelay:0,control:"hue",dataUris:!0,defaultValue:"",format:"hex",hide:null,hideSpeed:100,inline:!1,keywords:"",letterCase:"lowercase",opacity:!1,position:"bottom left",show:null,showSpeed:100,theme:"default",swatches:[]}},i.extend(i.fn,{minicolors:function(a,n){switch(a){case"destroy":return i(this).each((function(){t(i(this))})),i(this);case"hide":return s(),i(this);case"opacity":return void 0===n?i(this).attr("data-opacity"):(i(this).each((function(){e(i(this).attr("data-opacity",n))})),i(this));case"rgbObject":return function(t){var o=w(h(i(t).val(),!0)),s=i(t).attr("data-opacity");if(!o)return null;void 0!==s&&i.extend(o,{a:parseFloat(s)});return o}(i(this));case"rgbString":case"rgbaString":return function(t,o){var s=w(h(i(t).val(),!0)),a=i(t).attr("data-opacity");if(!s)return null;void 0===a&&(a=1);return o?"rgba("+s.r+", "+s.g+", "+s.b+", "+parseFloat(a)+")":"rgb("+s.r+", "+s.g+", "+s.b+")"}(i(this),"rgbaString"===a);case"settings":return void 0===n?i(this).data("minicolors-settings"):(i(this).each((function(){var o=i(this).data("minicolors-settings")||{};t(i(this)),i(this).minicolors(i.extend(!0,o,n))})),i(this));case"show":return o(i(this).eq(0)),i(this);case"value":return void 0===n?i(this).val():(i(this).each((function(){"object"==typeof n&&null!==typeof n?(n.opacity&&i(this).attr("data-opacity",u(n.opacity,0,1)),n.color&&i(this).val(n.color)):i(this).val(n),e(i(this))})),i(this));default:return"create"!==a&&(n=a),i(this).each((function(){!function(t,o){var s,a,n,r,c,l=i('<div class="minicolors" />'),p=i.minicolors.defaults;if(t.data("minicolors-initialized"))return;o=i.extend(!0,{},p,o),l.addClass("minicolors-theme-"+o.theme).toggleClass("minicolors-with-opacity",o.opacity).toggleClass("minicolors-no-data-uris",!0!==o.dataUris),void 0!==o.position&&i.each(o.position.split(" "),(function(){l.addClass("minicolors-position-"+this)}));s="rgb"===o.format?o.opacity?"25":"20":o.keywords?"11":"7";t.addClass("minicolors-input").data("minicolors-initialized",!1).data("minicolors-settings",o).prop("size",s).wrap(l).after('<div class="minicolors-panel minicolors-slider-'+o.control+'"><div class="minicolors-slider minicolors-sprite"><div class="minicolors-picker"></div></div><div class="minicolors-opacity-slider minicolors-sprite"><div class="minicolors-picker"></div></div><div class="minicolors-grid minicolors-sprite"><div class="minicolors-grid-inner"></div><div class="minicolors-picker"><div></div></div></div></div>'),o.inline||(t.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>'),t.next(".minicolors-input-swatch").on("click",(function(i){i.preventDefault(),t.focus()})));if((r=t.parent().find(".minicolors-panel")).on("selectstart",(function(){return!1})).end(),o.swatches&&0!==o.swatches.length)for(o.swatches.length>7&&(o.swatches.length=7),r.addClass("minicolors-with-swatches"),a=i('<ul class="minicolors-swatches"></ul>').appendTo(r),c=0;c<o.swatches.length;++c)n=g(n=o.swatches[c])?d(n,!0):w(h(n,!0)),i('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>').appendTo(a).data("swatch-color",o.swatches[c]).find(".minicolors-swatch-color").css({backgroundColor:v(n),opacity:n.a}),o.swatches[c]=n;o.inline&&t.parent().addClass("minicolors-inline");e(t,!1),t.data("minicolors-initialized",!0)}(i(this),n)})),i(this)}}}),i([document,top.document]).on("mousedown.minicolors touchstart.minicolors",(function(t){i(t.target).parents().add(t.target).hasClass("minicolors")||s()})).on("mousedown.minicolors touchstart.minicolors",".minicolors-grid, .minicolors-slider, .minicolors-opacity-slider",(function(t){var o=i(this);t.preventDefault(),i(t.delegateTarget).data("minicolors-target",o),a(o,t,!0)})).on("mousemove.minicolors touchmove.minicolors",(function(t){var o=i(t.delegateTarget).data("minicolors-target");o&&a(o,t)})).on("mouseup.minicolors touchend.minicolors",(function(){i(this).removeData("minicolors-target")})).on("click.minicolors",".minicolors-swatches li",(function(t){t.preventDefault();var o=i(this),s=o.parents(".minicolors").find(".minicolors-input"),a=o.data("swatch-color");r(s,a,m(a)),e(s)})).on("mousedown.minicolors touchstart.minicolors",".minicolors-input-swatch",(function(t){var s=i(this).parent().find(".minicolors-input");t.preventDefault(),o(s)})).on("focus.minicolors",".minicolors-input",(function(){var t=i(this);t.data("minicolors-initialized")&&o(t)})).on("blur.minicolors",".minicolors-input",(function(){var t,o,s,a,n,r=i(this),e=r.data("minicolors-settings");r.data("minicolors-initialized")&&(t=e.keywords?i.map(e.keywords.split(","),(function(t){return i.trim(t.toLowerCase())})):[],n=""!==r.val()&&i.inArray(r.val().toLowerCase(),t)>-1?r.val():null===(s=g(r.val())?d(r.val(),!0):(o=h(r.val(),!0))?w(o):null)?e.defaultValue:"rgb"===e.format?e.opacity?d("rgba("+s.r+","+s.g+","+s.b+","+r.attr("data-opacity")+")"):d("rgb("+s.r+","+s.g+","+s.b+")"):v(s),a=e.opacity?r.attr("data-opacity"):1,"transparent"===n.toLowerCase()&&(a=0),r.closest(".minicolors").find(".minicolors-input-swatch > span").css("opacity",a),r.val(n),""===r.val()&&r.val(p(e.defaultValue,!0)),r.val(l(r.val(),e.letterCase)))})).on("keydown.minicolors",".minicolors-input",(function(t){var o=i(this);if(o.data("minicolors-initialized"))switch(t.keyCode){case 9:s();break;case 13:case 27:s(),o.blur()}})).on("keyup.minicolors",".minicolors-input",(function(){var t=i(this);t.data("minicolors-initialized")&&e(t,!0)})).on("paste.minicolors",".minicolors-input",(function(){var t=i(this);t.data("minicolors-initialized")&&setTimeout((function(){e(t,!0)}),1)}))}));�PNG


IHDRf����z�IDATx���ū�[{�ό�03'�0}�D�|�033sDaf2�hg*ջorO�3}^y�-��zz�v|�m���ɷDz��6a��-��P�a�n����7�d�z�m��G?���/zы4os�[[�
��'?1/x��Z�{���u�$!vS�!��N�9�
��+��U�1"���m��j�ܻa�A�3�kM���u��h�oˀ�#&�I�4M{tt���^���Ӟ9s&~�ߴ�x�;���TN��hl�ܚ�ޒ�n�,uL6�;:e��=m��)�)��<s����(c���#c�����X�7)>�bXv�:+���E�h4���fO)qn����r��XJ�2�J��>��H��ݤ=��}$�l(��N�qG1�#�5�{:�֢i��,�M�Wi�z��4x���ٜ�*X�<|}���V���%_����0��%��?��㶔�Sn���2�ۣ56Y�zҘ6�f�o�]u�k�xB�}�`�*K�� �(�Ǻf���ÿ�'���+4��c��[)�f�)~@{�El� ���x��,%����EڔW�s��_����c�}}��eM]��a��;��ន�ܛ��5��t��E؊yJ�f�f�SCV-2�����Eљ[��x�Z��s�a�Υ�M��o�l��?��f�f�y�s��Ԁ��4$�|��o�AE��9�ms�]�P0�Z�=�W[��x�`��F�Vh�A��H k�De������)���c�=����&'�VQ��6:��+l�	�`�����m����u�U�6�y@6:Y\�3��\
f�S�f(hE�x�3}����~0[N�;�Δ1�)٦�
x��(��m?�!do��8ot�ڦ��~��{���׏T�hԩ�}a�_.�|��.=w�x��t��;��Ʋ�����4��{����;�![�
;i�0c(+��=��ؖ�*���<�l"���*VV+���f�=�k���v�}���7f�e��T�;�M�2�v@�K��F@�g
PZ_�!�|,����z+��[����;�-�/8c��?UnK�	bU�Z�h�g0{���}�`��@�P�q��;1�_c�����k0��w��1������5!n
`Zt�9�3�/�����hr W�i
6CY$�5�l?vww����vcc������������6��D�>n����)��>��wq�Ļo��[bv��R�I�@�bԑ�	ܐ#0 s&Li���i��>7/�A��ЉO�nv��,���K,*�6=1+���b2��n��Eq��������y�3/qڞO�ie�n˼��ݔ�zS�p���i���ڊ����:�@���}ݱ�܁z��+a�v|a�����R��b�=>��Xh���!�kts��_�1����D{�gk��ӿ���W�NW�1��1��3H�_v8�߹�>��G��
Cg80���ml�����
�J��v�p���=�k#�s4�E6�����7-���~��̟��S���	��VXb_�,�
h�����l���K��/3~x����¼-f��0��fn��_��b`6�����|f��)c�'~s@V䨞Ru^ ���Z����`�Z�V�aqw�.��YZ/b���XK`6�0V|��"��O���mmm��)����n����^�1�69N�>0s��M����1�AkL���lrb���/8���l��N�`&�>�~�ˍ84�S�B�B���`��5A� ���]�����	�:qT�nkE�N��'�]#�i�M F'i�9��+��~�492cy@2�Y�?J� ��j���H�<�0������
�@�G�2���A��d��J��f������S�cX]�oux'���>k�FN���`!0��W��nX�S�#��q�F
���U�9�G�B�{?�;!��ժ��P�rbv�is(���-�|�>xS��(��R�%��2����M)s��T��m��To����!�ә�N���fOyI��g�K�@�0���-fG�3�=��c�,��J���Ye�Բ�������<���ϴ�����8���3��ݶd˖��f��=}�ꪴ��ˡUlF�{�R���ν'�`�@��{С׏m>����{E�U"���
�V����9xOX��`Ek�\of�f��3�*��Z�B�F �ዀ����fM1�ٝw�Yn���W|~	�A�
�[0W�q�7�UJ��M�[Tlj�����D�Awغ ��>�<�}�P��V���g&�e����C�;@V����6��w���}r-�8�2zе
se@P&r��c����N�Ϥ>���`��8�Ùd�R�f�PF-q6��g6g���7��
�fmf6̇U�~3�DV��@D��!�1g#>A�r�fݕ��B�	q�1�e"ͼX����rʃٞ:�����~E-�]��^b�B�잝�X��š�c��f�p�k�Ry˰�r-���k�6�=�BYBh<�1�|����ٳC�0tlR �[W���|�Bu��[V��������j���,h�''L���m|=�YQ0cT��Q�BV��2S��`0�%�f�q뭷v�������2�<�@��/:6-��=J�˨���Z��9�/��-Z�B�1�q�K(�1+���Z�7�n(�N�z5�@��{��@�H���̞���xVB�K�ա(�,1x���:e�{��	qN��*�ѣ�D�¢��0Z_2
V���Z��@<���K�km��=l��N^�#n<�,��^�C\@BWe*�8T��Az��E��9z(150sD"�8pQE��O�p(�/������|�=�7wjk�v4��c��@0��gr;G���ڿ�}�3
�V�F3���13H��)f���Z6+���<}f�_E�(=@�Qf>�^��)f����ݵ�Ҧ�U3��tiIf�k���P6�9?tQs��0o�N�;�ry-5�1�n���W��Ŧ�`6K?�v�O�7��!���f�Z�,]D?�+]�Ur���>g}(X�z�DP�0W�@�5z��
��ݻ�����9	yD�!�I��mU̬F���~4�������͕�n�����WQ����i��-zaB<�������E�9�)�����2aV�ʨ`�g����'
i��{6z��8���y	iTŌ�?	e< .g��!�L�k�{hN䑥쿥����W�#�̔���t ў���0E����p�Y_�sG!�BK',
F��2����`�^��ҩPɏU2nK�9f�H�����n�p~�a�m\��3�>e*�qԲjq�֢z�0ZB1����Ə>��q�A�(C!Ŭ�d�9��?�S
�Z�����R�߀
`+3�5�c�e>�I���kV;���Z^ڛ��ֱ��Z`��oDP�cWU�(��r���e�<��l0�`Vs�f1��:���U��b`�MH���Jj(�)N�����0)ft�s(�F��_ê$ƊY�������gUqms�AZ3����p��K�_;��Hhb��~��I(c�ۢ�$��pzV`�CL���
r2��y�~�%4�+g�	0 c�7�MdpS��A��?�e'����]3S�
!�,��µ�L�:�����8n{ִ*o��P�2�^|��’B��'��´���p�3.CѾ�Ϝ0c������ߴB�Y����Q���2�:6qҲȰ(��?F�e���8V��U�iPE¯��I����ٗ��/�0SHC_�ʸ"m*J���[��N��f�}w��ًk�Ô_T@L2-���;!�m�̨���0�Zk����7�)��������P5
c�f0��O�00[�d0�/�3Q~�/�iǀ'`��pE�Z����B��$�P%�g@X�=�^�L�[_�H؄C�Eamw�`Ж�0ƒf�Ȫ����V0�ef�4(��pF��W�t��>,���l�1��L�b�5T����f=0�|�K� 0/l�^n}z�Y���|FNՙ��%�(�Yݙ��jx̰	�æɑ�����}���k�\S���j1�h%�B��3�a��7
h��?LUC(c���ʊ�!j��(�����E,�ќ�7і8!�:��%�v5��h��<z(�,�Ld���3�3>�B����]%���Y <
eK�\ڢў;�9����=tɴ�[JI��
��#��~�l3����j��N�}3)���&�`��*�\���;�U1S~�~p�(�gv�4?xJzO�#���̂��lJ�*
�[M�f�3���f
�~t��sGꘂ�*eP���F��l����(�f
fk�__��W��l0{�T���QcYO�����I���y���0��^��^�2b<
_�O&�	�*W�4�sCS�`��i[s����)b��PU31�'�ѽ<��pEB�B1�YS�Z��9`W�6��T0kyf�es���Q.ው��qM��E��Xp�F
"w�������\R�f��~���"eC�CU1�m['��l��R�[��ʬ�~���dm�tL���7<0���(��v$e���r,��i-��ԉ@(k���:M���@]s�{+�:x���aS�w��<��j��b9
�
O{�i�ߘ�K����33�fr�%>=K�����V����nR\(9fy��bℙ�4?�.q�<�f�J�PF_53����_n5�m$����I��T`��a�.�D�d	|��k�,T����&�ŷ�׾�Hkp�����[�P�	��Pƭ�6��/��i�l���f�a�ޟ�Ive��}�0+D	��'�኱2V$NHbx�����.>�P%�\n�%�z��*���d^�!Љ�l�>�|)���`ƊYjC
�����0��0C�Y�3+5Ϭ������3c"�e��a���xF��^Un)S�y[�>�9fs�ӗ8��q`+嘑�}� 圁,s����L!�
"�Xj���2�P�i3����*��+�早~�sXKV�B������bʦzA�b���E{.�B���,��ȉ���R��
(r��[�%���U�%E�d�	���,��:�}�B��s��8mS���k�dZ%��*ZF�~�K:�Z��Z�
�3�T4�m(�����Ytl%�	
~���6�o�>�a·���qjj��������<S��`�06R�Z���ֲ)6�gv49d��*_��a�^��b(k�o〴�j�3:ϬT0���I���~��.�	�j��.2���2�N�����-��BW�5̇��u�L��V���XA���G����1�ג2obJ��O��00[�d0���K��x.��w�(T�J��	H�����@V������PFV��EU��j�5FV%1V�
�l�X�̠�50�3�p�4��Ԝ�RU�;n�0�cn�"�S4��R7�,��RF���c(ό�?V<�8>�q� ���
�4��)
h0���lU�Kr�0�s^��2ߞ�8�l��Y10��I��a]���"��S9f�W�.���t���.�ZX�8|����T�}q��dޖH'�qw��
�`]��ȃ�
Y�����6��/��C(#A'@̻���t^_t��G�w��"�,j�zQ�"��e �
̎����)ֈ�a���ʁ�c�?6�R�*fV�К������i,QZ�"�n3{0���2B����L@f�4)`���}{꧟M�޾�#�,4�������(�(�9@&��r$��OV0��Z�0{�o��{~��'ե��ؿ��1[�d0���G`fa{~h���Eu	��X�t��U�t���l���&0�Ϭ���f��=���KW1Cm�%����?�3���Yf�1c�%�e��n�Yw�❷��T%����8�W�]��B�����
ʲ:4f3�ߝ
���B���9
Tj��d���!�D&�1j�Yb0�|���9J�ZC��#8�b�Pg��
�����PW���x~1ϸ�PBF��>3	Ѡ�t=_��	��;W����PHݢ����X��9x�/�$�u���ix�vV�|��qK�$���{����(�.�Ls��Ҵ|�|3-r�� |Xڄ`c���S�-���8[��_iρ�/O얀�8s���o0�W(�E5+��O�ώL������#��P��N] C�1Q�ޒ͝H(���e�6�5�3��m���襤�����=�>�=���:�e
l�����;̎L2�]t�EP��/��F�dk�ET�Q�c�z��Oj_���W��b���9��(�,mv������1��:�/����7�)��Bn�w3�0 �A1C~Y��a#3w�6�ڣ<�˖�⿽�X�Z���)�g���[8M���F���Zi(����ƒ�o���D�L��Nl&�l�8-�u|>�9fpe��r�\8C��>J�g-�	R��X�,_�ka:���><�	S�_'�?Ps�t�D?/�A��m�Lr�)�X�lkO�
��B������Rԏ�k���1lM���E1�#�B#�+���U���7)������i���s��ML!C��C(��>|��PFl$��J��6ڭ�lF�����C�6��~mk�
�PFp��)���&�qH㄄2�`ሾ�G[�j[��֞��Q��Vu�*�}�f��릘��m��`vQ]��y`��?��l��ݡ��'�.���I^Ԩ�#�:/:c�@�#�SV�څ�?x.<��=uM�u\�p�h�pN���2�u���������0o�!����++M-�eT7����
b8Ӭ���F����͜^�ݗ@q�ng3��0=`�B}?(��"9��`����^�}]N��E�]
�a^��YE��V=%-QqD�����9f��,�	����B�d����0�݀-m#���<$=Եԍ�6F`�g~.A��|&�X���	<�:�
*L�%v/�A�#�dt+p!;?�Κ��Og��~2-.����s�"��9e�C�U��}QN+��=�� *��&gDQ*��B�P�݇?Ml���3�t��P�*�(2﯃b��r
�0���z/�ћf��Ίk�Ye:7���lC�ן�,Ĵ�d��)}��@Y��f�1�Rf`6(�[#��:���uo��C�?���Z�ձV�ĀV2`��̵�Xd��06v(�֭�c7F�?��Ei'V�Px�=)��%�]W�;`��-+�э��n��7��C�04?ɮ�7�|�f���hueWC	�[aKy���]F�ŀS�z�
7F�犈9��qB0������'WM���6lӬ���eIU2L���0�.�L�d�cW�V�5e�չvh��+�s7&e�)cҦЗ<4�/C)�1K�r�k��l��������G�]0C'��0���3��9g�Mv���B&����H��g«
pf�E�bi%|��?aO�,�:~E�#��pa�,iϡCx�g� ���b���8�Qfnua8k?�-7USm&ۍ)K���8�%1/)��"�ɴ�h<���6�,@�G�PQ�)�w'�E��52����������J�H�����L�|��O��4]Ȃ��3�fBLճHGf-y�J��Mk:+������?��T�Գ%�Msf�o�R�W�Sm:3S�(�q�
Y���"a�����m3x۽f�Z!��.Τ�d��h���b��ɚ�CZʘ��_���
cX������ZFug5��R��
ayσ��`��='�V�\x��ϼ�f�h��즛n���xh��Ƹ/���o���}Q���U봖9�+
O�>�:˜�-�:��U+|4/<�>�Y���������`��lt
���0i`�}e0=CV�Q���9U�P��!�j�3&�X��;#)f�k4@��Y��qQ�SgѦXN��a ��h0Ï��r)f�HU�ԍ1L���~:
���c��z_�9f{�m��P����c�m����t��~�G�����G�.^9��j��B����O����f]�;�������2�Q~��84r��83��3�h^�<��1,P��@Ms���[�#��dž���c�B)�l@j
\�&P+�3�7k���[�I0������
d>��vN%��Lǹ����
�,�/S8B;�9eR���%���ɒ��Qalpρٓ�e_�e翱�˓������/:{�)f'�n��F��|�6�%���>�:�9�f�L���1Qʜ�QϢu!|���E����N����z6�|���V�S�bgu���`�``VK���>�3��o���kÜ�iJ�+xA1����1�E��E��
L(l�o�&0�5��R���e�|(����z@[ໍ�3�J�^l�M(f�1k��t ���g�5p���~3�`�l�78^�Ll�\��u�CQ;c�p�}ːX��l��l��*�uJ��ձ\pV�װF�U1�u��GbB<�#c),<?��ƍ4Fr9��}�Y����qR�2l�5d�?��B��l�B"K����6�ϟ��2~�ZcHM_z�R:��U���q��V�����
i�]@S8[�w�C�y��U�gݰ����Qϖ�T0۵���r}�BjY��(��7����{6��u��30���	�Q�6�Q�_)/��7�S`6U��P���^d�Z�����h]GFg�)���z-���˃4���2��Zc���s3�%�]�+��vπٓ?�9f�E�����k��?��sv�]>�I�뮻{fXp��1�(��ִZ��7��8���_�y�8ʗ:Gz΋�	��{��9f�WV�Ã6�%j_��:���s>Y{>L�
c��#A%�RV��NC1k�h�@j;}�ؑ��?6�Vl|�ʸ�2���e�r�b����{FR���z(S
f�c�lʙ�E&b�!6�v�%���#��1�I9gS���B�X���I���f
���;�+���'q\Ĭ��w�W3a=�!B�}Q[�C��hp"Т�g��0��+ �s�R�.�7>�`��91ϲ>'=T�\�,���_��F5��X�۲�k�/-����4���Z8�3)e��u�/���pfTG�}���&�)�A�[�v�O�۠Ȁ͜|�"�+;R��p+.��
�v#(#�,b��QI�C�ڒ�;7�`��:�+�^�\}.�[��G�f=���~H��8�X��ebn-��Q+xjG}ԉ�	k�QR��R�ٓfO�tA�	��>��v��1�`v�׶j�1z}W�b8��}Uô���`�<�Qv��emh�ϒ�/U��>^N��+2�/�Q���Ta��:��u�F,�S[���3��L��6�ZM9fm.}�ؑ+ټ��fH�lf��η�P̎��YҊ���
���>�TY��
5^2)fE��A4"T3	e��b|๟��	���:��Wr���/eS���Cb�1@����m	e,ߔf��Κ�� vˆAS�5Zg9X���q�,R�^�K.��0=��g
��О� F]�Xd��#h)x��[��D|��x�Y����h�iu�.Y���y/|�A��3ΔV���k��e��F:���{|0�
��1�~�	?
��C�@��]A�W��a�Wh>��!�r$�)e�=$��3��w 
�f|�z�Ƹ�iI�e��L`�[םl0{v{s��}PĠ�)��R�j�jf��暹
Jh�Z���<�L�ʴ1�y�備3���!��cGJ꿬���N.�=��f����Z��-��c�<�0}�$�28p`,0���1��g�a�3Seͽ�\�VH>��߅(Z�Ш����j~f��yye0��`���֯��
�k���9g�=1�5�`V�
�ʸfkWh�X"�ʢ~	���g��h6WF0	�	�Hx#C�1��yk�H�B�>��fj]B{I����̢�F-B��X����ʘ�f�y2�Y�;`Ɗ��{�-v�8�l�c��:A9C&MI{o�5v.�_��W� ����=<�-v5�?U����:�}�$����nV�����m傤���8��^�_x��������6P��}U�3��0M(,��9;��?�鱃e�3�0-�1��e����Yl#�rv��'S���g���9f�5
_<J�2����%j�;�o\}2��u�M�f�Z�%%
gt���V��5K�&	�	�AM��H)C[kߕ�S�
Wtr�d�Uܐ��0��H���v���3�10�p��W�\1��.�a`v�$����]0�>T�(�,����$����=t:�}<�-RϜE�]Ȋ�4�4�5!�qP�g`�԰6�f�J��1���hj3�+�g�0���F�Aa���y�2�;�<�a�!�� 4	��欎��Y�?f� @=��	�1�P8#�
<_m����0�S!WF{j0�1��؟#3���5 �(h�Ʀ}5�_�H�/�M�o�e|��G�">�8�y�&γƴ>��l���"<5�݉<�Ϥ��c��?��/<��-M-k�
	��L�%��V�F�͟7ſK=S��cF����38��3r5��Q,C��R=���]k��>9�+9*����+(fk�8�Z�+h�1
�a���_y���9���T�ʔ2���cc@+g2��s�ZvCm�V�[I�e%1�E`��#pvr���z��%G��I\B�����]���1�e��lvv6����i!�	D	p�!�
G�aMR��~7f���m	��Q��q�}�5���1U�x�-��0>$8+]0	iJ���,Ղå����M!�1�}vm�+�W�#5����5ZSh|�r�8�᬴:*��f�۲��Y�o��(�tV���Q��M�z}}�k���6'yh,�X1;�B��Ҋ�c
W�:W1�:�(�8�����z�!�2�t3F��#S�FI��� ��}A�x�Ud�a���b��l��k�d�Q�:��E����P�|e3
�}�R��0�����aA;ӳ`L"–�Pl��!O�D95n��JBKG#�4JU����ѫ����H(#��#0�rV��P��fj���R��լM�3����\5��"0Њ-}�PF��2j���u=���f��d�Nq�J�q?�t��,�0�A-8���d^}4����=
�Z�bS�[P��P$�L`L�Hc@��@���"�|���
��Z��)C[s���eɅ�����Fp��`��C��)W�iE1��Y��00�i��lff�D���8`6�9'9k�W��3U�\�,2	T/�>�*�m���0�+a|���P����.<�����.
��:�L�����]~+6^fm�k�l��%�L�ќo�j+f��w�0�h�N�w�3#A�����\d����8]'�kC��
�0mB=k5��6�}k� ̱�Z8���W6*���fX��B��ַ�l�+x[U����A��0M�p�&>i�p$��/N���p�w��[����}�{c��<?!1�
V3�mkk�X�O��#p��*��8�h�k.}�3c��LB;�㤞u�b����2��
���0��-c.�tz`N���	�f�\��Sc��I}��N�����}fYLRT27��+���a�0y  ��
*���aӿ�������
P��D1�]�ǜTY+=
e�pFqd�C�0g���e���a(#��-�;�2�-sM?��*g�H�l[����#0kEm����ŋ`���Kw��8�`6==��ܳ��0��.��n�<�s
cl�����+���_�Mk��	��&��\��Q��Z��P�Ԛֆ}>���"�ph��,��,}f��E�.��
g:nuf0�d��K(6�p��0�Cg��yR8|�IL�~ɚ�bPV8�1r 0˪S��1;�
^|�W@���f�n`�ЕӀ,���$���<��e��$Һtx2�d�(�酽�<��:M�ʶ��D׺�TJo4\zw_��6��_�{gG�e��=j��~z�̴�����������;?������L�ZVw>g;���������xzQ���U���?�{�
(C�g_��r�l)`*`��
(�!t�^��(rM�~�����x�T��x�+hV�_�
��
O�店�����o��M��$k�bT���	���X���jG�i��N�G�R���+��=������ ���EW�dg �`��#=���C�`�ϋ�1q6�`V�R)S�?��X�ά��W�J0�e�5(+��_��Cm�������y��6�v\l:S�jf����<�7̤���F��Z�a�
.�fI[���v��-�u�l�f�u�bv�Xu��c�Ž�{���Yve|�+^1��F����kZ3R��r�l-+0m��*�<��ዙKc;�u.n$�q����sZ>6��+e�1����ڌ3�T��֠��Ŧ�m~��x���K��B�O���Vi�ϰF�3�lЕ�2�3�>�2f�;���?40��/s�,
�1�,�`P̪�g&�jR������,����E�2��dRʴv��f�\��ޯ]a���jM�v�=����1/ǁKL��ƓԺ�vɛx��5m��2��l*��?�yiS�)����{}��BwA�����Wޘ��io̼�{0�����_��u��)�
ʂ`֡l�k/b.1<��]1��C��]1�"=e�ࡨ�]2|����X�`os�/�ݹ��Gc�ך����z٭�7�Eyz,�@@p����fg����Ba���A(c��C��έ���i^j���㍏=�-�kLoݐ㖀ك�lQ��&s�*���n�o��Ι]�o�e0{��^F0�W�6�x5�@8��]��f ^�!*ud�=s_c띡��n��1���	x�U&H۴~����������ҡQ��]Ï�v��& �g��o �k�h���^y1.�A�[�T�V�YH���}rX`�|���ѷ���X\ڀ��<X����s��_'NP�i�l�v����=75�싎��3��)�)��78�X�Y�B�=���Z���*�c<��[��)�����cޝ�ֿ�ɗ|�������z[�1Z(#,��ܪ
�\9�`v��T1;�`̹��d�e'�� �vv(*f����k3x�yS�h�Q�Bv[o��@O8#�X����{<�����C�C��=0���ֺJ�=�d=H�C��������(��bzS�R�C��^�l[`�a0��v�|ܲPF����OA���T�,l�D�����-�Uc�5�0��go��)f��Uu(�Y�f���8g`�kg�^�җ
�u+�Y�“��]s�j.쑯�5�%��@(c8�y��R)��>��m���c��1��(x�f�c��_�8)`}��	�����n��Y�L����׵�6n����?_�0�QUӘ{hc��>�%b����(��rt��zW��M�)f��&�y�&c5	fx�uk֪�;fJ70?b��(�3|a��Y �L
U�<��4N'`�+��G.^ Z��m�)�
#���fj�J�#�����Ґ��mr���B}�a(d��_��E��S��+�~�% Ўp��y��6�l-��`Pŭ��n�B05�ۇ�Gkf��l�Zn�gч�{��k ������2��QA3��Z;W��?�Pv����3����=FYm�z2��_�60���=*ʵ�[��L)�mv�G��	�塌릐5�jJT��
0+}.�~鮲b��B�4��?w�0���q����P�Hxk�/b\x�t_�a޽3?�a��#cY~6��v��-�l�8W��8�
��B�ʘ�g����YNY�[�9+&=�M
H�!�aO�|J��}�5q�����P�*W8(\�In�Q��/X��[f�[f���~�,�ً_���Ni����9��d>���C;N	��\�m0g`�[⇍�v�\��
��C9v���#���ئ�3�&WƦ���3��A�/ϩ=�g�iscb��4�P���Ap�_���/�=�l�6 J��Nse\���c[|�*�v�l}�汔g[�hh�`���,�����f��mO�kg����/�r1������JЩ�����Z]����+g��ϓ�O^�?�������`,���ѩ��3���ƃݜ�2�~d{Sb�S�m��n��=���#�v0;�+��ŭ�7�_��
�i�]0�\�a��(.�=�*Y;�����P�ͨW��٥j6��-��#�@�$�\��T�	�T%�<�¹���g��<�_TS��XL��
�|(#�ll�y���΢��>?f�áj6��m�_��r��t`6�_�M5�ύ�q�_�f%&zA�LKf���J�]W���|��_>�`�}�`v��z_��)��Z��b��Y_�|�ʚ�sP�,V\�5`���2�J�ͧ�˒Zf��ݸ���v}*h����̺�~yN�?�΄(�ʙ��w��̦&"A\�gF%�(��@��ƗKe�
��3�2�Dz���J/0��u�T��ƢQ�\fr��8���<��z5�,R���9kӕ�Ě:�)h���of�vK��Y�W�_��(A�*-U�E�
,���$#r%�RB�:(�XHӢ��Pb�_��'�c����X��_�4〞��� �5tu�Għ.]��A[��<{=G��Q���B������Q�0t��3��C��]�X��Q1���ka�?I���턖����x5.u0;rd�jv��.�}�ڪ���uPÿ��E�u�M*�V�k���}�R�yf�5�eޑ��m:Wq�X�y1���0oA���Ӄ���w�4-,�q�f 栆��i�#i�\f��.���o@V\!��e6�x����Գ��Y���Lx�����ۘ>>��ȩ��o|����t��aS]1���\��s���gՕ�C�̴u`�)Fi�W)%Xs��P�|=���@���6 ��n�1�;ƽ֯5*`������-!M���N^���P�t
��d�U3���3ml�)�=+���J��OW�\!+��1�,,�O0��@��̢�2����q=���k���
��a��?��)�D�
���T�(e����bKC�����}�|��d�Z��Z�‚Nf�^���.
	��[x-�oTX���L�jr�&|�g�d�����j����|mAw�{�ִ��6��E���Z�@�5�O��S���1��&��(��{#Ē��{*�A���k��N}�ת�_?�}�~`�����y��h+�];�6q��������}}Z��
%:��>�����ɏ��PF���m����v����m~e�8R�n�J& ���N)dWzK�1@k�T�i-(c]�Q�+�3�W�Y�~��!m�o�l�f��y��}5?���j٫�4��!�;5lhC�u�ټT5�9@;��s �������"?/&�)d����@4���Uq��<��k�2�6+Ff����r�^��v��ly���0n��g̺A�� �0�|�m��w��
�t�v_�b�AX)a���PWh��a��T�f�'L�1�L�߃J���ʆ�Y�F�|��L���5Ӝ�E�6�HyF�?�!�JY2�����e.8���q^>y(#��eX��@����'����ED��[O"����P���f�E��>�`f���|�C(c0ך9g�g›?I�Z����W������w�Scxr��z�������G��Oo#2x\�f*��rEsl}��\m��T��?������8'M`�p�ն���r�w5�ԱE�c��֢eT?Їj�Bӛ������� �A%��.�u��v��0V150kjY��� ��bP�&��Z�:���n�Op����u�2W�S��4 �,��=ȇ?��2��%��^-�K�Y�8�1�!�-�
F ���嚝��t�91μ����’pE���M>�/WҤ>�Fy��X̖��pg���4���5kW���Y�q��g̚�9�lWuP�,��k�r͡M������N�Y�)l�;��._�pg�jg���a�et�̝�|f�u�Z���+f��0�3#�L�&H�S��L�#0�?��MB}�i��~oK����1.4UJ�W���8��Z(c���6}�_�����KJ�5�1����9��;�u�?���^Fģz��<�g���^Ԙ�*���UB�F����T��ŗ���QA9 dYZ�pSc�6E��e����o5�Ly������w��Ԍ
��9�{3)�m�3���~�����5�x��Q9(�����?����)�����d����,i��B���w�Y���BF��3F/�D�3(Y�V�{;��z
�BWQ�����4�Fʙ��[��t�C�Y5Ŭ$i�s�g˞cf7f��O�k_�9��"�=��"��{b����r��c\�,�7+��F0�M>�h'��C��|L�PƁE~3@��[�.�0r�v˜<#rӾ#�|�M����p���<�lfo���:g��/?�`���̎�wK{��63�[���#�3�<51��c\=�0�a����ȡl>�ыH�`�:c}�$9f�(�s��h����Do�CC+�A���`M�m�r���/V������l��
���r�|�Kk
�C�4��W�Z;�L�~�+{�2���񊡌fGI�2��R��it��0Ȅՠ����u0���������z/�c�`���ʛVx#�]�*P��/}YԨi�n��Q��^	r X�Y�.���E!�h��:�<�8*D�e���YmQ
����z֘�Ήf=����QOT�6D�\�֛��R�pOtX�j��GLh�.�o��G��ǣ_�S��U�zGoQ�l�s͔ov�Q(c�W1A�[��KHs8k����/��Q�h�۽V!��
�V}
0��i}\{Xcl�c��0�8'*gh��OE�+��?{U�)�.�(|"�ѣ��+fe�`;����3E���r�j�;Ǣ�vE��y��6�kfk���%j!��L�Y�䘕���Y��)�Z��fYb��9��kb���}DyZ��Q��;���^{���dg�~�g/_�\����,����M�Y���y�c_�*tT�v�#�n��Xx9�)D���4�u�d�1�sEL��"��%�i_W��F���Z��!��!Jˮ���@��U�����v/6�<�֧bv_Y�K��O���)�5ڻmu�&}�z�@O������甁����yMVR� 	^�I����c��F@����+���d�]s̯u<K����$�q����h�?�2��%q�q��?�V����}�G'�ɘ��b����a��"�>0ü�U{�L���J�ɏ~*ظZ�h�G��< 
`�9���d�	�9�)f�;�������^T�OO*f;0�\s.o�w�+h��|��o�.�T~5�qr0��0���@+�vSrwe�ϸ���C���$ye�̐sV}Ϝ���5J3E\�	����s�
*����pGF�_\�����ϙ]�Kβ+�<pR0���Z���J_c-�v��+��3;|�k�u���P�=>����_c�&�ր���~;���\(#�ita��اz&0#�5 ۽^`vwYߝØ�M
��_Z���/�|���bӳu��	0c�Y��P�Y��5�0D�Û��׸ik\s\��A
���?���K��w�"�u�z�WF�T
������t ��W�ً^4��8�;2�Gg��_��ێ�&]xSM�`}��=��c�ฌ�87�?C<���w|H�k|��9�9�	�z�f4���m�*�	dk橒IV�!o�����_�0�V��wwF�i}�e3�أAT�1Sɐ��q.:9�\مF
��f�W��>w+��t�j����T�ejz-��=9���ű����ek��uZ0�pœ��8��i.��-��Yg�]>�̭�~Y�L��|N������΁�)c[�c<��}^��q£���Y���՚}��U`���G=w����^t������0��	c�^��\.����m���9f��6�)>g�Yf8�e\�>�q���&
?J�j����6ra�%�p�ʈy昵���`Us2�Xo+ ��i�m�宲����
̰��瑕�T���%`�	�<��:4F�1����9)f
�k�m<��m�A*�.�C)RdBҜB-���\�+e�{��)+t�@f���.�ꙕ8�/x��[8_Ϣ�E��D��˞��8�uɎ7{���ON��q��z(��e+�f�����P)#�Q7V�9����a
a�T��8'�
A����l[����8>g����t��)�)�j�]�b��{F�aY��`�pV�.���ize,�1`�[���9��N�!�`���R�y��ߠ�:��:3��mX�̠L}������)�o�s�8oc�pl<��oƈ�'8��ަFL���D�O|������,�ٽ��;��0E�T�Van�!��ks�n"�ˠ�#0�z!ȉ��63{�c����n�(
�t�EЦ����B�������j��u�jF1��o[k`�|��kq�N�v��$V�Ʈ���VL1KU3?�,&��W're�]�����
�b'I3�ShP
e4��€��$O�<��l�J�bƘ)f�<3�ZEh#4�O
@d~��i��H
���K#�r�͖��m�c���nu�_�i��6��)����6(!��j���e�_�K���ւ9~RU=�r��Nj>��q���~*��#!i��g4����P��r̐KVT8��u�c��p�B��{���Ù��\q�̨���lA̙�P�S9f�d��)Ǭ�Ÿ����r��p�҂�i��!�o~g9��G)?��{�
F#����7����Z�ed�[��59�a|�BӃ�2�
������Բ@����*���jv8dn�o{,���k���c��ͯK0c��'���X��m|��{�?H�;�`v��w�����^]c����<tq�h�G��Y��<�̔���2���qf"�D=Z��Z�3wd��b�����cS�h�!��r���f�70������2�#tq�>���׽,�L�1��5j^ ��Y71�<e�1{tD�9f5S�H������ �U2�6�E��-�`�j6я�5�˜������(f�u�f_3slv�v8kj��������7jpE!�w�Rz�8�8�݀wA,�	�a��`�
�ʰOK�� ʟ��M����L�`\�f��aE��hrYq���2VE�q��
��*�Y�>_�+>�z�ܪ�\5��p&(ۃ[#�5�u�dq	�5�ef�$�J�oc�F������B�P�0�������X�~�E>0���W4�P�9���3�vY��k�gs��!�o����b����;��A-W�F������2��q�&����ܲ$�l��M�ͻ0�[�Ó��+h����W��a-�cv��_����30{�Y�;����|x⬲fkھ�cfk�B�mX�r�C�P�i�ɯn�[d���2� ����-m�c���1�,(�y�F��@�]y"�L�xd����<!��ɅQ`&u���i�է&@��DcLh���s0�&�y����8F�ٜ�``6o���>v���Mf2(bk:5���3}|�MWÏ�=���%C��j����題c�\!CK��f��~v���0��w�� ���/�������(��ոS<�ir6
D��>�����'5z�kw��7��σ�Ua5��2�9��m0�9늙��@^��2�ok���zf���9���õ�
0��of�x �`���3��Mfq�;�y��GXԇj�}eM���ڀ�&aگ����E)Ϗ���r0s����@��j�-���bP�v�#e<LC�!����2�����<�,
a�7�Xq�
>x������nc8{A��#��c`V�:
�/�Sw`���_��9�c�������)���]�u������1s�F*f>&�=��u�]>�8��>9������@B�K��E�	��(�/����Cס;c@9��a�tu�s�(-��f����NW��|���zp��dk����fW����!m0w�{e<��v��b�}�-�n�`#��[�s�>6�,3<A��P�]������]>B��i����+�O-�j��[�ٳ����4���:�Ĵ{����u��L�j}�f����$����L[D�g.RЩG�d���s_�~�s�|�3��sNǾ���E���_UJ�zfi��|��w��ˁ�@�r~83��m\�)�,��Q_���{@�e��,�M�63H#�	�z(�+b%c�U����مJ;|#O�/V� �[F@�+�����7����h���2V�?	��1��
�Z+J��A;��Yh��Z_hi�ޞ:�Qc@��~��[A��V����A�-��f@�כq�X5+�z
�"���*��^/����|����=�,�ٟ��f�����L-�K�q����1S�8�(ss���:e�1_�l�VRP:����ט`F�h(���Kc�E�{;p�C5�z+�L��s�̞<]}�1�*�J����`3F��;6:�Q1�
�\1s�|B�N�c�{�@7�1B��2V�E��_�.σ�#+yR�##s��_�/0���2�S��ԩ��"�Y)^���2_�l�&�lj0��/����&���4����`�Uq��~��c�s��+��8��@�����h�֭���Y<RS�E>�=!w*$!�/r��7��/��>�j��>SԶ�2���E�S{(f����T��l�m�E���?�`N��e��N1s[S�9�c4���U(���hD���|�^�W-�,��n:8o{�jo���K�����X�z�88s`\Y;V�� 	��N^h�T��4��/�؁�M?��W�@����F��3V�|��R����z���H���zΙl��#/\��y0���Y�?��?60�"���yj��
�>W�h�4�4��!͟c^
W��gi�1�$�wc�cV5���	{��yX��2�q�`�A��
�LǐE�i��?�1{���	���ݳ�EZ����L@�	�q޿�w�Me�.�_M1+���T�k\%3B�C��/c�����e8	fc���p�OQ{;3��1����]�����UqF���8
Ow����X��ƶ��o�O�@Z��k�Bd��br��G~��^/($��~
f�Qk�� f�+BI�e}�"�z.�y�7&�_���vw�+ƛ~�W�Le�c��̕��&�J��k�PFcP��+gW����[�A�ծ�U_0��\��l��R.皵+h��y�]��z�Jfa���墭L1�͢/�km|@��C{���0f%�'���y(�|��͏��PF�;W�x���c�XN�_��pet���y���G���O��9f�V�q������Q>��՘�/c�;�y$���x������w�����r�r0���b���"��� ����|Mm�dik�UNk�����2V	Ky�|���M����ڹ��iy��F%�md������Q=s�����40{����x�D#�	���$�PFcW�|��̻b6:.���gA�!�d�>��?ּ����4H8#���PEL�;�����iO;��?���*n��V-ıh�QŦ+G`�����=��>�!Ȯ�2\�ꐏr�����#�|�]<g��g�1u@�=�îl��C'�>Vw����q�a�Z{����?q�ߛ}�� lъa��8�*����G��P�{�D��}�q���5։b�2��n�A�,0&�̠�	��w��󀯞���f*�|�ե�B��җ�����dy�)b`3�z�?\k�D��Ǘȏe��[�!	!��1�4?��AH�
�,��$
���̨�|(#�9�Ũ~Y[��Ze��n��}��l���Nn�g��
r���˻��u���qTg�x5�+�^�|�sf��e0��?���P�?�J��uNǙ��zv4o�^���P��=���W`9d�3��]�\�.���yT�L�`ޘ_�WX�i�!M�0Y��v{Q`����L�k`����c��ce/Q�؀��E}�9vai���9瘛�G3����aђD�4������<Vs�a��1/�l�f�Ilk+�[��k_fk��C6���}��u
��˴��B��Z��t(�0?	�������o$������I6��L˼G��އV�x�*S�����J~�x����K��!u�t�����[|�כ2/Uc�c���¨����Y.��,�q�1׍ad���m�./t!0s���!�{#���Y��,̴���C��!B�e���0��5�i����Ø��I|������c��b���Xz�kd�06tj�y[�r0sWF��:�R�q`>�3��l�&�s̮ZK�s�y1�!�V����
L=g�=#�����բ3E��a)��Q�6�y���Y��β+�����3�PMK�5�}X_��G_�#u�s���q~b=�}�`�U�������A��q��C����RC�vh�5������x����b�?[�p�����?(dPcߔ�f��7=�ql����k
� Iӥöo����x�(
��\�q(�;2Χ��[�v0�*v���O�S��lb��?.�Ps�e�`����U)P $�@#H�{¦��d\��?]�5�IS8���X7��O�V�^�fL�*7��X��+�����R
?o~U����ykύ��R���YII=�:��%�U[�r�[�k�/�%S���Z5 ���DU�����*�%VW�ڜ�~�*�5���������,���шH�C�b���	a�B��+f/���Zo����������X�	����y�
��GᏨU�q
mY�i��g�ȕq�r���O�_���c��wÏ�zd��!�q��y�Jմ>}�p��wF��Dr��i`FW�SW��f���m΁����2�=���%�p�f�g�9�]�֕�����T��25��0�k�}��}�e�}��x?���kU*����A"@MP���3��̹�`�ږ[�qܱ8���N�k��Ɠ<H+�e�b�(���Z�I����9fC0��΀B整{KZ�6K�n���eA���H0sEb���GR�ԃ8Yu����=����-�̕���hmu̮����Ӟv�L!r��^�=�ٚ#ba�c0�� n7r0`�/8Nm
`�{�mo�Y�:"���t��ng�W�^P_�COͫh/%@��V#`�1E�x�ڟO����]�b��7�)s՝�g���~33}��i������P��5˸�p�g�Y�g���d�j�M
��(�Ŧ��噣m�8l���u7�U��/`�ف��+f���VM��ׁbfp�h���b?J��C�"n�!�7�u��X=���c~.���cڅ1^�X�c�ˡMʖ^72�x��`�q�kF��iXh�t�B�ڊ6;]1���s�2S�4�l<�3��uv�Wj�׈�_;�}��M1�k��s�f�y�_x�����=�,��w�qS`6�Cs ��Ήi{խ�3%�C yda�Xs5���Yr��&pR?A����j�m-�-U�'��#�I�xQ1��5���*{pjܭ��g�?-��xtd���iUs�2iT0#���o�ƹ�L����2>���%�	�fx�V7�&���hn���a��+gf�x	���هB����z����[@�r$�U�{�233333333{�=�;�0��^<��̌�m�*ߓ�������4Z~z��֪]����J������pU�>�Hڢ�cia;Mݮߦ2^w�~��K�1�rS���*�Ͻ_rK��f�w�x!2����]f�c�J���JY�LbZ���9Iq��T�ĬB�)�	ĝ�1�c���Ι�O-�Λ�9Ma���Sc�M����83��g�4
f7���0KvYi��)�i_3;��H�Ӊ�,�w�G�������uZoCZ3����ξ��4q+�یʙ�i67�Qח�b��i�b�'!�i��כpƶ�N]����b�`�����TFMcܵpe����~�[�:c`��c�O|�
fc�
a�ִݗx�U�2�Fs�2%����ԙQ���ĺ��A-weTx���a����&բ��>���KL>,�I��%X�o��~��$W�
�u�3��+�E��Y�Y4&<s�H�\=�O�He���1�A9��
Y�gU��r:��pk����5fŖ���	�`�p�1�Y
c�ތm��̓�k̮�V�cS�H�#�pi
b�PxUD%C�b{���ݜ-SVu�,��t�_q�9f&&E�=��ĩ,��o���]h�JF��m���E�JK��@��™
�4�ПI��2B�����
P(S�`�&�q�Eqc�>f��i|9�vd�KyafJ�ZV�,T1׉�����?h��-�߻�#�E�gU�5�]W�z�指�>?7i���6�
gQ��ra,_9�M^S���룊��Q0���/�%�/��p]֥���eJ^l�WW����m��}�1���>��q0k��H�cno�z��tS�S�J ,{�/U�o���c��5f1'��ůp�2�(��m�e�L�
��E�G��G�Շ����
I S�#�I��\�L@*ch���yk����@���k�f=aL&��z.@��	�P��D
9ge���Z��B��(��0sg�&�x�����Ȳ� ��l�vb箹��n���S����Z��j(I�to�r�5��w�8��I��H)���5'I�Y��5��x��m�>qE\/�4�?��K y���o�wB�8đ�k{��8G�(ha��B��&��.BYA�n��l�[���豪g*fT�hRn�u>aLŨ�4�?��a�?��}b���Rk�E�fN��f N��WH�m�R׼{Y����e}�nHc]��mms���hs��T����C�5��e����l3i�Pn�YbZ�����vAj��j�4�|Y3�]0���%
Z����[�;c���=fW����f8��L�|e����6��q��1(�6�*�Eyh]{d�h^C_cL[��~�yӑQ��������1�`�9ڴM-�a
��V�f�KI��l�5f�>�G���lJ*��Y=g����D*樘鲬�ؿl�ѧ��
ڪȤ�̖/��ܷ�ԏ������*�E�Yt���d.���緉Z������%��P�kΕ�� ��J���G�MiS�1�oР����]�W_�9�Y����o��P1;�f_n΀�(��F#��-�V��&���(��
��[� =<qYĤP8���S`��#�	�(l�g��Dp�N`|	8�E�lp����_8�Lg�,���̠NҦ�_}@��?i}�4}����h�1����1���f�^��M�k���h�A��ܿ줱���jy��<ߓ�m�?���h����{~!��5��t�V6	
��}���;�10��1�����Je�>��5��
��	���J��h�d#��[/M{dYױ)Xe`�#���A�4�?j��ڇPf\hc���2F�?ح޷K�r�Z���B�+��WƋ�p�j�=�켤�DU9#��.7�B��m%���3�����l��4�����}j�9���&!�����e}&T��S�J�\e�k���5�_”����K��������z���Y��X��C��S>���b2����?u31�3��q��grp��a�AU��fМ�����׽�~!߰�*��\�_�V�J1�@u��i�l�ǖ%��ɚ���fc����d�H����5�����V�`mU�&07�Yu��gpf�Ӎ�Kso3Me$�4Rc��i�����8OQ����U�V�q�ߤ3�_5�_���_m�?4o }�]�
����ߋ;�10��c���P0��K�h���8j�=jʣe���r�t�d|�V����¼/c]��`�kp�i�%c[T�1��"ߗ
Y���`��n�^۵���PcT�<2���hQ�q So��:F*cU����0Ҡ�pF{�LO\Os�#�	˨�>\f�3�?�e1��z��?o!+&S%�d�Tơ� T#�4Wv�t�|o�C8Fd����/�벊1�����D�L��
\�}մ����p6
�$��ㄗ���K��C	��sT����؆�����x��DH�����w���xA5C|G9 L�a
2x���"�C��%J�t'�x�j�
��2��s�Y�����N��F+}�!ʙ:�b��^��ܤ1~Ж�Q(c=) �JZ�Oߡ<�f"`���7s+��
���]H����@l�k�T!km
0�g}�BԬ�e�>��'N��?�K)�}ѯʴ�\�匁�'�̾�/�l\ȉ8�
u\��-h�b!��]Q]��{��'�����
O-p�5f񾱹5a�fq��x@W���a�_ע
/�~���c�2����Lg�M*���c��0�r��9>DB���mj,Og�0���R�·�0��!�tMv�L6���w1�`��f��o���ˊ]B��3}��:�0��Y�I�
#����E����x;���v��T�ÿ�g%��#}�Z�~��ϗ���]>�1������(J�h����"��\��K��(i�L��H%_U2MS4�b��Q�13Ma�g�6�ق���-M�nd��mz��f&tiC�5��1�������Eg�5}q�R��k���
]�.�ǘ|�34U�Z���Z�2����H[[1��~l�m��0�O5Igt���2��b^拮����΄��5�̾�{��`fc�X�t�*_7��K��m�v�l*m�0iC]���~��b�*�����}D=>UǢ_��!l�qnB��5���tF5�3�z�~����n8G�����1	�����6`�df�2Ȳ��(��d%̀��B�̥��eNN�EN��j�����J��2��}��ã(�cY:c٘|�m�_{HQ�Ǽ�`W�6���˞w��/�P�	lY��` ��� 2
3&�ƙ�d�b�ou��k�i�A�eg�s�^fˀ3��(bQ&t)ר����\�w�wގ-�୘�\c7IŬ��J���+C�C�%����?����A[�_!l�.��ܔ�c��6��XK�0����=���B�,R�f���L��{��`���/���~����n�b&��ퟹ����c�=Θ+�G�ٕ�ꫯ0�IAqw��2f�A��B�1���
uG�mT��TYb�pC$<5T4ݫ,MG��T��DEc]˺�Y�=?�c��x\+bQWU�J]�U����TsSj�\q�����*d��3X��mZ��@�Y~�u3�^gL�����oQ1k�2���g٥�n؜ �:ѡ��V˭�}�؉���J_�u��F5̮���>fn��PSMS���m�P�b���`�T�G��rC�d�[~��m[A
��i����k�7M���>H{y�L;-�Emnޱ�M�hP��tP��ƭ��{|�gOsߖ\K�̴F\I�L�,�?�?IP1;�
>��-�ӂ��ږ�;Rm񗙹<��crQu
	˃�d�6���RF�C<�%Y�կv����~1*fHG�2�2�T��9���U�2�u�!p�r�v��ۖ��86��Y{�3Ie�2�L`$S�tϲ"k�,�\ٹXE=���W�q{�v{;6�}0���ݴ/���3Io��e�J���Ž��}����~��-��+6`
�L�3e-Y��|Si��|혨bx�p=��}s�A��m�q�\�L�OM>���H]p����
W�14��O���0��n>�a����]��E~#:@�&�H�8��b6I ,��AM��Me,�m�p\�$ʘ�0�� 7��=�ͦ��e�$�43�2(f�3�]=�L��jͿHG{�N?�.y�U3��3�
f�~p��>��=w� �HM�;�-iL�{�KG�LՁ]g%J���m�����^��Ț�h
f�(c9Q�D���	l�b�^;;�RwL�n�k�sI�[�7�@�Fh„�^�2�#�5f.PU"�����`f���(��`YN��y�<�ȏ�3~����)�����&��܈i]�sH�����
Z�u��X*���9��ߴ�-��[`�{^)�����i�������w�XC*ccyLA�:��mq�3f8f0{׻޵�����׈c��3���z�/U�X�j�c�p���W��yŵ�ڨ鋪��]��Ƈ���:&?�D�Hy�[�z{U��dZc��lq(KU��@6E��m�MZ/�1Kl��3�E�[�Dbb;aLb���j�L3����<xg�4�yֲ�2���N_�2��~`�������yA*a[޻y^����Pi�˜�F��2S!���2\�b��,��(�fT�t���i]����bvQ31�۰�F�,֘�s��x"V�#�r&�z	0[��A�K���NhS֜}����:s����*���0�m�?̠���3MR&�{�1>xG��i��N5����V��E�y#���=�i��{�i}~�W��lf�������č�*��~q�3`�A@z�1��UW]��1Վ�x�����c35a� |a��(b��Y�w��4�Q���q�6}B����q����%�!
ge�j�� a��i��ѭ�f3�]P�\b��A-�s�U0k�1ҎC7��lZ*�e5����[W�XX�Yf5�t�h�X����a/�]`�vފ@�ڼ~�CX���8���]R��
nE3�e�B+u�\0���CQ�����K5JT��&RH��J���rxK����]�N�z�}pmo�U�&��Zǎ\���0���U^	C��`BE
D �`&��l�r�r_��7Rϥ`�(�lE���Х@f
c�3d2V��wK��8��_Y�e5��Ld����hg��G�w����ϙw?h}��
f���-��ui�3b
n��Q�rPF0�z#�13�����>e��%��,�z���`�Yg�3n�\�T��U�R���8c`��c�w��
f%3��Z(U�f�k0Rխ�S�X&�MYw��h�����e�" ���/�}P%C|`YR -֕E9�3k���5���a�-�Y]SvSF ����MU/��:&�YYj*cb�_�ƣ���T1S0C�Օ񲺾,|�c���lه2H*#�Kכ���#R+�I*�K�NZn�=9z@v�R�i�سTm���y���9���(��i<mQ����Y;lR�|�ԧy�C�r�r��
cz�`ւ/�l
r��DA���4�1����$V����V,{�7�G��w��bu�;�(̅㠘�E�DF�q(qfmr�o{���߲οKA������y�n����s{�YuG����ȵf�ʨ�0�uff�\2���I�t[�ïKߧ]���0�p{�}_Xc��ŃΘ]���ٕ��w�ˢ�i��):N�h�l�m���UƜ"��U��e�~������6�)؉b�8��>���=�>
 �1%�Ƣ��������(bz�X�q/����U��(e�|���h�<�1�`�����u29�%��5?SL>�?'�uNlg*�Ҭ*f�-dݖ��5l��.(�"qv�4���Yw�J��w�k�}���H}R#�T�?<���V��V��^���_��SE��q�C^���Q0��:-�ن2�?[0���NH��~�1�����eg������_vCw�'PȔeN�Շ}�0�2�m�K3�fh�X]c�Iy/�����`�7\�f����F�Ro�c����(*Zh.v�n�t��
�L��i�a
0����^���|5���M�?��^��u�/���O[<䌁�U�f�<F�L�&7��,Cf���B�	�����&e}�&�)X�ז��I��–����S�
���OS��ԙ1��gJe�����F�{K�~S�[3��P1C���P��,�O��3�|�v*cX�l�l}���iXh
c��kJ���J�cl8}a�.if�.�|
^pa\Z�/��#�P��7�P���l"��ĺw��|�ؐ��i�p��$>'e�H���c`��GȋX��q�Z/cd�낍��
��0��h�B����'ga1�������y�E�:�u�~�t��U���-?�">�{�Q�*@M��P���h2�:n�L��v�*�����
�� ���˜�X��k��UOi6�K�y
���$Au�<�Y�A�M��!qY�!�ֈ�j}3�	̮�E��v�b=�ǵ�.����G>��s���ߦ5�|�Yf�/�e�7ʀ/��ŶRF8T��o�q�>~��ە
WF���̋�0�=n�3���;f0��o���i�͵gZ��s�c�<��Sa��v}��d0S���5���#�rzΔ2�7ך�N�|�̮��o0��f�β�@s�bi���j�ot��
e��]0����F���d��0�1c�!�T�d�т2�
ԍ�u�6�6��������>~�]~�͒Έ5euIg�T�oOrA�qr�6��3SؐQ�	��O�FI����i�$u�S}eUeM���I��\ITx�{�ʅ�y�I�_����G�߷d
��cھ�A�Q��y�T2���|}��ҏR�[⤘�)�P��Q��v�m0;�aMʌɏ��R�LRڵ�eQ�T��<��)��A����ai��o��/�2��U�����x7y3k�k�u��;���Z���(g���&_֕�限����<��C*bc��/f��y*��x�����8c`��c������������k@�m��Q�q�ڿM��m��:_T�j�������=�l$��	c�Ãq1=�7���@*\��1�2&`��I���YvZO�R�3#�,}�˜]~�������h�`�T�U=c2��pqp�7[��wU�.UCm@d"�1�*d.��2��s��>����{��DM	�O��{P؀ܔ�^P*�n;7��P{��w*
<�=s�|ߥ��e.��mi&
Tt,�2啂[}�i�3r�eۗ�{�F'nA�[��h�$O��v:�G��w��e�1�k_ė��$�	��
������M��G�~,ǖ� M�)Q�|ao�My[i���p�������3��>�	(�T�CY�ъ���_���~Ժş��\f˶���V��Ihe��};��Z��pn�fP�J�6X�f9��Z���� X�#OUd����^�X��ڿ���_u{�����49b�����:c`��c�����Q0�h��TF���b���ט�v^�3�j�_�6y`0�בIw��07!3*����0/�5f��x����{C��‚S�V,�2O���lT�wF�Y=F�1��r	��*J��b�dR
��	��q����M�2���núD�-�cY�7m�ܢ��+c=y��ۃ�Z� Z�E*�ߌ�5?�R����B�_Zn%ܵO*'96�r���7dK1BE�[��"N��k��}���{�Ž�\�b�:x˸?��Ƽ�o���|d@Tk�ĕ*�W�E�?�3��xy�OB�Ǘ����~�{��yĖq.P�x(�����^���#3=Zk�f�݊�j��gё�~K����bC�P�T��D�-�g�z�*fR��G�lM���%����*IRe+�7͵��'�u���|
Y,�Z���⪼�5ɔ�0ilJJ֜
�͚���6q3'���lÎ�Al/�,�}~0��n��+��/(fwY<�`�<0��ؕ������7�A�l���9� ��5��f��W��a�Ob�"7�f�Y�Ģ3�,��d�E\i���P�ufzt��ׯ�o�e��Y�M3r1��1��L1K��T��~h�b�O�p����t��X��lO��C*#���j*�`���>�9!��!�J֞5"t�2���P�v���]69�o�W�W�wc#P� ��sB���N;c.1�X�Se���	j��b��Qf�G@�>C��EP�j�V঑�ڊ����u���B�By�ͳ���(f�'��a��&���������֣-�+�����IlW�,�m|�ݪ�JS�cؒ�`��Ȏ��ѝٹ!��2�W�#uAo^ӲcTϬ�ڧ���uݧ#%Ж��PU�b�g��9�g9-�ٷ�?��(�'k�p
�G���9����_]�ߋ�]�_k���0��b�n��TF���%�֘�z��,l�qh0{�1���^����٨J6�]�i{Q�l�';/f�@Z��4��	u� =��[k�m�p�7a-�C\-��.�k�uWt�Wqi�3E�����Y��	meav��AFم����0���]p��b&����	'E���0ÍMJ��>(��YI�1��&�h[DmX�`���NҤ,U����c���o4��K@�9�ä�P.���&��r�-���t�>W��u�VD<�o�R�@�B�k �}*sس�͂�:愩P��T�~�G?�e�]Q��)�
Nq��*�0@�i����~,��'y�Z�J����a*b�$�#�ZA�c��`��\��e�JM���Y	�D���g�2��Z����1�Pf�r�#��P�"UQ��^K�9�8r3�Lߜ�e+1���|��ɺ�+GגI{��<v-�[�֘)���R뙛N	��#7� �n족��=�S��噱��?�}�*fy�b��X��`��'��}�^�`v�W��L ���*���NM�5f-�K�
��gb}K��F�
���
��VJ#떁��5K�PS�}��r��~���/���'��4�CZ����FӶܼ��mWF�N���eĩG�q�an'�L�,Y8��4��5�13�§�]�_��HG'��@@��0���+�!!+@[��6��׃,M������a�,d��4B���
�a`���J��O�G�q���U}�յ��Q��8z�'��O��Y��.�&g%�r����J�-�X�J͢�E�UƖ�W�q�0E�"אU�Y[�k�	�*Q�!`�G�g1��\c�P�2%H��V�C�|�����4F-ωM�fʤ�`}3��Q�rz�ͦi��ݎT�X[�)=T��\áA�c�En_Sט5m�kϊ�2��œ�������5�yM�惘���� ��$]�Sm�OkdE��c�ǵǤ���)�R��L�P�����1��U��sLۋ.`ZĹn0����ScA�#���L�7s��erWF���� ���JZ����2�X&n<S��kЊ5��	N�LSMo�/]���'.��fL&��_q��_�Q�A���fP�ƉD��g�)	�O��Ki�>(4Lu&�Yn��K}o�g��_��V<��b�A�Y�S�B��>D;�?���,P��}	rn�f^�PҰrT��k�E��
fN�ZEY�1�jwX��+��Lŏ�h�/��3ۣ�!�7(��R`J���;�7���Y���B�,��5���oZ�ָ���� ��5S�:��2~���{LWĴ~���l���[k*c�i�[CM�`�O=c`��c�W��U����*d1lB?^s`*��aLE3�=�;�+k���L]s���0���u��]��Lq��*h���+��K�EB���lA��1.Hf�*�/Mx �I�#�qŬ��]Z�Kr�0��ƨtX�PƔ�(s���u�ˬk����#�G/�5f1�B] �:AM	b?>~�d^�j]>���R��.�Z��()�;��9����%��!�eI�k�p�,�=h
V��
�M�m��7�Vٽd�1+���~dy�o�|�[�����s,�I^0���c��xB�����"uQbΛ1\��p[�Y�-�0�ގ���:wR\ꝫj���q`i�c&Ĩj�L6�HlW����w ̴��1�#����ӯվo��V�j28��)�T�x&�� ��vӍ����nߋTFߵy?�W󏿱x�se|�1�2~�W|�N0�X��C�2ƫd��������5����6M�*`����ȨJ��2&*ZL���XO����W���`��~�bcc�5L�,�^c����u��-�o��n�2n�0��}̚6�����9�6�h~���\�'�
Q�r�Y~��P:1�c�[���x��D4V�F�:�g液�W�	��~�R��5uZ�s5�2�b�(��Ԭ�%��\V����n�<��Fd0ѹ4�5#^f!���P�D���RMb1����ʘ|'Hj����4�w%��p�4gb�6�6�3�Q+�T0��r=ZJ���~��	�-O7��E-�1B��"�S��P���'�D����֒z�����-�M���ב�Ӿ�����ˍAJ)�Le,XG�B���_��9մ��l��K}�����W3�}ٗ}�N0����m�ߦ�*ALհ}��
��5fח:D��%׶�g���Q��ź^K��G`���~��tE�c�^ڭ_���*dl'xAe���o0K0L&6�N8�rl2��`:��He��gX]��YI鳦2�dҵf���at�
�9�%�1[��qN�q�U@ļ>�l�7�$H��LB��7�lx���ȡNI1�:�(0&����<�E�q}$Ȉ韃.�T#C�����
���M"Ѷ"�
B$C-�7N`xǾk���GX�G����	����
�c�=��_'TYE�5�`��	v��,W�N$�Q�g��B��s�]����5��Q0\	|����o�A���n�����J�)?�l�WEoV��k�Jư��ۛ^L0;t*cz�_ϖ���u-��9n�̻31� �:⡁�
f?S3���~5�q=���ų�������	f��9c�F;Y#��!Msl9D�]�dhˍA�9�T1����讈M��r;L�ڵ���AP�k4�w���y��Ϟ�OU6Mi��W�r	V����`Y���O�l(�V8�^et&�P*e���q��c%9���N�� '���Mh��|dk���6�YL`%�Mo��urǹ����87�bYA;�?r����
c�f�E`��S�SЪp�P��
�"��y)4�d�V�	�j��K�={�[鷨@V8,JYv	�ռ�u���U]o��E�I�%�ĵ$���B�;[�ݪ��PFp�3r��HV�j@��}�[��:�֯�p�[fi–�	q%��|݋>m���׋)p
�Xֱ������oک!S��c:����z0��U�����z��:�
fp��3f/9f0���k	f���n��ɩ�j���b�+�\�,����2�6w�"]���֘��:4
`	@���R�f26�u��UƖ�ߜz �o!�k�J3�d�Y�ZL��ʸ3���Ll��0��|���r0��L��Le�:�ꆢ�U-�E�����;����)|5nZb4�I�:���/2'$m�a/��R�Pc�*D])\�$��NU��?C����Ħ�xCQ��h�n�/���r�̔�*����`6s(�-3^�����f���_j?��|.*�ag34�k-��ދ�~�k2�E���o(mK�cV�5�Ql��P������q�j��dd]!*P��x��S��b�'b���`��D\�u���:>��ׄ�5�q�P���`���L�*�7/u�a{|(�z�̦�#�?]�m�_o������X�rV�v�U��|M��C1�Ŵ�u�����?���c�k���iv_�������h�o)l5`i|���A�o�(��3~&^�5g)d1�k�_�j��������R�25̗�Y�V�K�u_#�1p���?^t3�P`�u}��"T3�*���c�>6����,�7�6N2�5�]��^a쒶�Gr�E�C)�M�(e��X�%��
ZB<���/�<�#M�
�֢����uL\���
`,�}��9+|o�C�ڥ��=�ߨ��u`b!�3���Y�3�ps�����#`ɞq�)��޽�}Jk�"�; 7�_�z�ڎ�[ ��|،_�<џS��pVD<�%������א�`�)����|��Zk����TC��f)�@xZ��J]�zf���Ɖr��XS�+(����ժ4�g�b>v?e�J[�οOU��W�t��N0���P�l���埻�Ϙ+�����x���fCZ�>7�Q��5f��un�q�&�Snr[���>f��t�.m;S�TYk�d�c�̆��
�P�+bXS&�4�,f8351��0�ufm����g�N�IH} ��zƳLJ'�r`n�����>���^T3B��J/	\+x���h(f�?߬ �����Pw>B]�
���a��r*m����
�;p�vl\���S�.�BH6U�yb�>�1:�M[P&>'$3�N]<��.�)>ZI-��6e�BV����X�����_�lCuܵ��sy�-���0�<��r��	q\c�Dߋ
_,Cc�G0�5fc�R�ʘ��'�n"�_Ij�zl�Ԑ����h�)�h�v�>p"�)]k&7e�Q����;�y�·��c�C��@�q�XGf���1c�ǔtơl�?���10{�1���}�l�{�iU����5��3���Z��m{|*fjHb��Q1#��#�g��5��q����YS�,;�ۂe}P���e�39��c�]~��F��,Ԋ2&���iߚ֙q"<�n��0k��Y�5f+�ٚ V�
}�D/�Ʃ�[k[?﹑G����Կ�m��Т,��ZۣAAD)2"a�S�DF=�ɕ@H��
��@����a2T���G��@�#PQeh�͜��0���;@��W�?h���}k%Z�^tY���,U�G�/̬�Y��;#U�P/eh�	sf�����1�CSy3�0�[
�j3�,0[A����aL���̂��ƌ�L%[�2�_�i[�w���
9�_-X��0d�]��:3��K�a�2G��
�!��!��ƟG*#��W��Ǭ�f��c/=c`��c��<�9�3��2� ރ�]ט�z����ǥm�o�?nck���d̀ؾk�skY�
�?��^v���1i-���ѬP���<�H�Ha��ㅺ'��10���<�����"�N!R��+#nV� ١��b�"�^�1�+a�{�Ey
��~~����HW�������ղ���Z���V�~���nS�#n��5�
!y][�b�H��w��{T�皾�M.��Z��e ����
�?9���~ҍ
�^��n�'yB��;R	_��B�,��2�B;�k$���&�2�:y����t	Sv�ɰ�e��.S�pWX{�8���zp�Le�JS���Z�P��V0�kS�F��o�/V��m��kc��f����~�H0�q*f�_�tr�n�g_~�?H�:f0{���=fҦj�X<��}n*cK1C1Ƥ��q�n�61�����8fmH3Cs*h��an�v��̞�OSF�zvֵb���Y!E�zfA���˲��,��}��˪�G�zL_tܤոK�&�.S‚<1���.�c,Ie��uK�4ST�b
�j�T�—�~�P�5��ʸz�3B�b^n��uEQ�u�#��L�!�w��8�[�{��c���b���d��F �MS(�f��HͤU�+�g�Βkɢ�J �@&�5�*��qz낧T���?�^��c��<�������w�!/R�?]�̹���1K����h.	Ơ=OeP�����z&19��JĪ\]��G���Ġ��
��:ޘ�+9�#��}��s_D���)���K�
R���!.`U�,yƦ�K�ɏ3Բ������BG��`���sf��o��-��+�d�YQmV�쯽��3�̞��gNV��4խ�T�!�P��q;���8UM�*�5�Hm4훩e#)����0�@��g��S�%qM_���A��0F�Fy��X��s�d��;�f�F���UV�mT˄4K��,&��f*2�~�3��wG��e����5f7꼱�+�`&mq�=�i�׸���K�)��f���)�����E�H�B��F��0���4�t\!�ټ)p�-������K.�,�$WNh}s0�
̈G좢Bn����m�q�%�R8S�ma�)m�C�J�&B��"N7F�\\'�l�K�Ĩ�-k���k�����k3�	Ąbrր4�|V!��ڳ_2}��M<����F�jl@ݡo�����+|̆P�<Io�K�_��̾
���	�Շqc`��_}���v̮���Gv�Y{��<�(�Z�Sӽ�r`l�'c����Z��R����y*��PQ��ZJ�	,f p����P���Ó�ZJ�W0SH��2�d��zЁ~U� D�����z����Yi$�Np�
}�1��\�ܚh��L�T0�j�	�y�%<���Y��V�������]=�)�j|,��ؔX��M�5���7�9��V��_��+���Ii�6�K�-���-��ON#�:c�J�^{���f�T)|�=�������f����2R�����w l�{�a�`�ʉ����	h�2\�v�35Y�$�4L0[i�e�C�.�1���MsR���T��3_J����jW?
e��Z�I���z�z:��������*�
f��YØ}ժCB�a�,�솯%�韡Xh��.�.��W�10{�1�ه>�]`fS�>�2u��e�U^W�l�������T���ب���7�
�}�ˀ�e�ܢ�����X��i��,[���|����-����0q��?.ߒ����Y1[�9q�_(%�/!`��8I՟+3�����	Ň�I���ؖ4��)|1�Q\����i���ޘ����<�I�Go:"zgVJ�<�T/�c���uZɞщ2�� �ɍ/�c(�99�2���o�0��yi�80�X�P.H��l���!��Α�-��揜�`*a
E,(���
�`��Q���0N���C��%�@&�nI�������*g+�k&7���������2�mu,�_�,3,~SE�m��,'ѧ��Km��&����:���@)��qIJc�3�l�I�b�f�)�W�,����M���K��R����Y���1KZ�6���3��ٓ��>�����t
c�Oe4Bc���T9i�M���~Ҧ���ղ�ۄ��SȊx
bx�l�%�Y
fO���9��%�%�&Lӳ��Y9���Y�6���
e.N��PVo��C�逹uT�ɠ�i�:i9Tl��>�i��K{�6s[S3cjc�%�+b%K�z��<�	I�u��^$��S9�)�!
� ��{5��j��y�;Hͥ9�C�J'���vl�=�5�|sMN�i�u�O&��RE,b(�-l�6�v�/�z�D��X�ՠ��a��୺P�M����g43���V�AW�Y[�̀lMH����
3��Z�6�q�4�f>��~����;$��-���u��4�Ha�v���Iu6P�	h�����	fU1�
6���O{<V8c�]n7\[��0�{�7�p�n��3fO8f0{���?��ք��Ct]b����`l�|��sSu�lHӘ�f�#�T�])�%�Y_o�j��f
fO����s��E��@'���\h_ݤ.�m0����"�P�-�+}��I�ڮe�T�昋Xa�ʪ�E����->J�$�_���=.��0��:�-���
|�uFu���KC�2/���6���P���8hO6pA6l�\;@URcP���X1A�=���K_�㹑��?/A[��wlX����^=�G	��G�܍6��z�v;�{�w�_L�{��æ��ʟM�JA��a�P�2�rl�2F�.�H��M�
bi����]��!���K���O�3�d��!�bm��*��e����8������W���|RmO}����>7_���X�Zo���3�5�'��]5��Haܞ	%�M�����g�g���ï];,�
f�r���b����K�=d1tn���.��g�.���3�]}��m0k�z4յF��������j�\@c%�ϸe~޿oce�P�ud�ʨ��X�b�p�il�*����b7<�V�j���؄9�,L��G|G�����@V(C�c.�wf��T+��)�S����׉(x��"k�0arL9���F�]�'�\���|
�ڷm_��q�$�X�S������ԇk�B�4I��p�d@Zqի�c�Ms�d`*0�a��xc�_�`G���C�[A�^�!��M���<n�YD'َ���W+�G�*�:ɲ��p��a�
fuzt
���@m�?��7���`�O��� Sf�PJ�5�c��������-V�}܊���-
aR.����
Dk���A�����W�ջ`;��qӲ3���2�z�Z'�J�.��oO~�m�뮙mG?
ez��8�� ׄ3�3���bR������5di*c�3�*V��l�9·��i�7[jd�L���
�ۂ���,y>70��[��>f�>fW��?��)�E�q�LPc]�LALA-�����!L�G��;�@���Jm�M�O���W]&k���
�2�&T���E�S�,�g���=#��V`���b�vJ�Jd⌕�D1�	!�c�`�Iu1�4c0�Nא�2@0�X���m�U�5N[�N:֛q�ݓG?�>�������hD�2��
� �ES����2�QS�	d��U1*ȩ ���e%�“h�{���W�|T�q`[�+�
�a�QB�*�����F����U?bB.�K	
e��Y�o����nYZ"ʉChc<��f�Г��,��c�����VA����1�,z�Aܨ��EV$F����kHeLg#P��If%}<֘ey��NT1�J��L&��+��u�u��]��thk�\ҧ�4��%�ңK31�(�"�]����ԾE3����A�]?|���뭫b�U�̊��F+(�>f�<�mg�.���f�}�cG��m�·�಺�[�^
_��� 
.��8���i9mk��h�04�/�t�^�UV��u���=�a�\��8b��-f��&-�~ff���O�3f��H�9�ɍ։�Y�
���
W�F��}C
���T0�NԳ8)3������BU]��&��'���T�u@_vǝ�ظW���H�s��@e#�|3e��:�	�4���Fe��g:� ��g��A�8�j,i�E��|.�Z��c��ֿ�7	`�q��vU٘K�`�g��#�1Vj�%�v�\���ߵ��]ZЖ�
�?��&s8#� ���:��.�u��@ɾi*f�n4��Ln�I>ᵗ�w?`}�g�)�Z[/�?��mr��G���[@+���2Q��Y9UNJ�)�9�il���A�D���H1�[nް3ߵ����}�����3�=�я��ս@ڌ�E�%���ؿ�B��2w���N��U��6�����O]-��c[���C�`)�IZ�*k����a7��(C=s:5BP�~�1�ѕcPVh+�g3]�bb�vW(e��u�������_���%�;h��A"����[��q�ȗ%�X��حI'��(��V���
��{�5pC,h�1z�Gjl���%�G(�C{8K,�"�����/��쑪H�꩖�ƅ̩S�*f9��JF�a�^�	����{�];�tV�Ņ���R�0��fYz"oV�s�I&�l�L�>l�#�����
�0�#YO�2'!��b�bA��}��m��?���X�g|��[��rV׾ϑ���f���)�C�[`��k�1���dS��f���YU1���Qo��ܺ߬Jۏ[���v�;��e��1�2��;��=�쑏|��Y[��5��= ���Zw���JU?���q)�5��<�Q
A�>m2��W�~љm
h�+}�f[V������T7<�"- (�������G���Ye�TӰ�K�1N_�7u�e�삽T�ĥ��s��f�7*���E�`�U�ħ-�\
��5f�/3@�J��#����	�=��
��T��ڬ�4*&5��J��RN^��6E�paS�r��r��x�H6&�%UU�µ��Y-&�E!8Z���Z�覠�����Z`���+P�����g� T�C([dT��"�q���ua0�L�,�x.�n˾� -��zU�T1#� 
�⑀�$&���/����!�7�T�XK�B�@[�|�)'��7v�^��S�ڷ<��C�Yl\)ӱbR��H��Ǻ k�2�pF(#�E\\k\cSS��Pk����vU1{�ۅ����c����bv���:c`��c�G<�c`�tj�Ƹ���	� dĕq�]~[�����\f(��O]�I�/k�pS�M��c��
�FɎ��q�ʸ&�e�f]��zf��2j"�.�ӔŨ�H�A�7�Iᛘ,e@�2��*��e���Ccjn���h7�2�h'�����h��ALD�#P���|�l�ߦ�k��ᦲ�>�r޲�Z�~��_�3��X��#NP0��~�@�8;F���gG�zw�t��5f�,pM�ָ��e\+f���1_O�#��V_�.� L��UI�S�QW�{����b�\�Z����}Śk�4�4� t�!Fq�֔UuMS�T1۔c�YQ�|�2�Dם�����1}�Ù�L��\7{�ۅ����J�P�3^z�{Θ+��ٕ��o{
f�@^��������kZ!��uM�.[��Q6I[�uf;!K�+
��|��l�V�ޙb��s������c���j��J�r���0��a�� .��E_Ȓ+m��yQ>�a<�6�j�L��:I����sy 	����˶Heč�����A<�
��+)�i"S����KT�������^g2������񽴪�~ޣ}�}����~�#��P��k�.�2�	O/�{�ݿ�2uU$�4���3��|�$ZsRߞ	v��U0+9Qƍ�r��e3�����5&̃C-�,E�v|r~�aMn�Jo��b��~������J�{_G6s�g-k�8���."��e��E��z+�LZS	7���ʘ��K#@�f�!�[�k�@�_�������]���dP�T�_T��z���3���-oQ0�j�1)��gT�����qݟ�mi���a��V����#F!�Ho�ѝ26a-�ĸ#���5���TEm�L0{h7�_.��1��i�Ҧ�aU1[��g��G5-��7�!B݈x��q#i�(d��e@�R���YF�k��7���38���_։���(�R0�q��!�PKr��= ��~��[Xal��#5��!��_���W#�r��%���3���?x��|��t��סn��ơ�Y��+�n�q�+��/[���]=I_
xS0s��
M��db�t��a�ZrW��A��ڱVM�*W~�'�Ih������ϛۏn�*`�ue���-���km���E�k��|c������|z�/ʑI�# 
& e3�b�����<Ցc�ר�x�O�,f��~���̬����Z�\�|���?c`v�c�7���
f�uc���<��#��k�6m5m��C���2��C��f�/�[L��Ҧ��s�q�U��RwB�����f�!{/=hփc�-��q�J`k��s�1�����?2���._e>@�>�T�5�����x�2��m�ŬᲨ`�״��
vnk@W��cbV4M@�.���;�&:�w��������x���6�al	
0��]�5�14�kZ�Q2M;Ό��i�E�L���P1�}u�'�ufr�._��LЮ�%7����Q�j�q�^�E��5z��7�����{����Ơm\m��<�{�
�
ej����k��>?���يF ��Ф��5n�c���Ym�T���]p��.[0s2����������{3�]y�fTk
xMs̮A@#��Y�:
4�z��+#!M�Q`ƴO� MG���D��^c��D���
f�$�<m���}�o�GX/mo�;&J�
�Q*8Q9��tbh���k�^�֍�K��^���T�(�a�q�I���?>��q)�y�����7�c��+Q�����=IMAb����g+}m~"c�s��h�2)�_���͐I�
3!5��7gڣ��:��R;mS�%]�����6|���)[8�4��+6��n+�+���A-��KE��зY�z�?��+9iJڣd
bR�1���o����!m��� �IQ�
��1h1��{�X��{����A+|q�Xװ§��;�y���LZR��Le�p�P6�>g���3�FA,���ފ�^�3{����[뒽���j�e��a���_��3`���=����7��V�H��d��[=B
Sŧ�z21!���������7�W�}r������7+b^ٶ��c)��)o��?��{�x/B։�
-a�2J�_0�P\R-�ڶ|#~A�D��Xf�ͤN��fmÂ9�ԛ�i��ZR���4�_3C*���	f<�ĕQ�Rτ2�?^�����5�~ڦ1���`���'��Ƶ��l^�@��~o1���5ޞ��k��ķ?���0�����r\�ĊƤoF%��-9�H^��Y�V4��7�deя*�1�GQ|�#��Q@b\�>��ٶt~��4�=��#.��V�ּe���޼P��SMc=@���;�[��w�5f9�5ڒXfҞ�Z�q_<+���G(g�{�X��*e��sg�@gE\���L�,�1�ۇ@V����6��f�%۟Z�����FB<
f�����3��x�cve���7�P�p��55���CxST5I�55�`{����vQ�<��IQ�w������.�[�o�8.��
���bF C�m!2Q5+RW0\�+?�N0@�5悊�L_����q�Աo��������v�1�H
fa�a��շ���Q��z�,3�Q�4mQV��W��ݑk��vW+����ɛ�~����G�|[(c
`�G]ˤ�i��(`�6�pz�&ɾ&�/�0Se,��E�Ai���?�<�8��11>�?��G��zO\�ד5����H�T��I��2���p����_�����I���zC5k�A��bzt	���T��=�W{|ub�X�4Ss��WF(e��>����}ord�܄/�x��gA�of��~����+�
���E�`4�@����3fw=f0��}*�B\$��SP`�EAט�ϔ�J�)x�)��y��AS��x���9�fm��a��hSճ�}���'��x���)�E���u�,��by���F
�P�t����!bOf+�TF5i���zvg��II�&�5�?�S8+�4�9����NL�)BI�b��D-[���Mǣ#'���Ⳙ�l㟿˝�X�>�ֵi<��I��5����:�=_�jd�$5sT'�����O��w�C|#l�Y&���c
T���ށ�yG�L`Lb�1i��O�g*�7���U9�Hܓ�eV��u�Y��o�3k�`JS!��n����_��<�qPS[�6��hB���Q0S�m�L�#[_�?�\i*���QAK֚�յQ!�T�V��:��n�����S���7`�g�@���:��?��3fw>f0����9M�<�Ŵ��ښN�; 'ue̠����	n�g�
����+�j�N�zr��՛��kŘ�~�	�(*��<��퀽Ž��nփI�[�O�7��o�[����dճ)��۵�,S��؂���_��IF�:!�4t&qea��~B�'��ĕQב�1
g�fi)���/I��D�-[7c.��V����^q#�����+�[�
��'p��w���e܈���M�I�ڮ�]F�O��'�y�s�]h*�t%dJ:	����~��>g����q�u��Xy�^��r�}B3�%\���ЖN�`1�/�,#}qɺ%���}��Dh���L�q���7�'[�_��:��T�|��7��e�W�_�Xc�5e)����n��!���
���`�x��8j�[�@ws��z��qfv�՗��f��,K[��?�F0��O������y�{����o:����<BA,ڢ_�=��f��a��Ph__�_�,7R�U�B��A���6GY?6e��=��. E@6)e)�$�k̔Kd�~�_
�5���:�0�LRc�郏�\d
��md)7
*Ec%��W�{U���&��i=�`�]S�'������s�MUή���Ӈ�m
Y����{��k7��nk:|�-�Q���.˚��=������_z��˧��}�K�J�EꢒuI{_"�Q��QV(�r����dh�*f���9�6���n�Y_�$�]t��2� �d���,��Nb�`Vd]X.�9�X��^����_�ο���a֌5S�C�,?Ĵ�wXS�Ƕm�Y���0�ܘYRK�~)���搵fs�,��6�iLU��y��T����8��•Q_�~��c�y����3���wo�Yíq�z��QIR��5��_�Ͷ�y�^�sѶH�A�15Q��N����`Hk[ܽ/wr}p�Z�ue�Ax��N�#s�g#�u�k#�-g��.��P���H��R$=�,�(�_��E��8'F�Nǜ����.���1WF|I��
�lH��]k}�l&q�>�ی��V�^�ŵ��]O|���N���ҁR��ik��߹ݠF��,��Xr�Ӎ��{�K �ޤ�Ԩ~�Z���ç��TZ�
T��&�ѕ1+}Pˑ@�ܱ�D���w3���t��G�	�k�Y=Yn��E{�&3P�|��…��"b�?6�hR'!9�j����7c&��/�)0&�5�4�b�X�[0�b6���	�������%��3�>Lel��2-�k�LmTE�
i�4�Xo`��S]̮9cv��=fW�W�����6)�q�:�����MV�ixڬ�f���*5$I狗�-���0���<��%�5��֗;z/���P�a��te��n1�
qSީeZ���(	�٥�\�d?L:���7���(�DӴ�ފ(f4������dЌS��Ӹ����%�;m��6�j�މ�"s��5�*!Cz$����j�:��x#Ur���:�Qq���U�*U-r��k
�O��a븲�I�c�|Ø!�+���7�C9s�
�-uH�k�����
.ܙ�A��'x3�Y6��5��ڪY�B�Qإk̒tłx��b_���Ü�F�+nP�2&;��%L¶��Q�ȢL�I�x�C�h}DЬ�z�JZ�1k�x���g�IҵD'u��)Ó��^�V��%k��\�'m9�u��0���z(g���깱��i�
e�@ְϷl�Ynº�S۹qG;�j�BW����c��-��(f�����v��[3���e/�f�43uQ�
夏�fc�j*N|�`��"���3�R5.N#㵙]�r@nݪ�'Fy_5mq׮�>2C���X��Ϝ<'Y������>�?��9���8,�Bw��o�dꬫ�G��L�-b"B�4�X�84��p���!�0 LS%e��j���TF�8XS-�z���m�BW��[�r<'���h�9�B���2!	�	T�N�_�5����*s�l�K��g
(�����u�#�<�+��<��d��Y���gYK6$�v�Q�.oB����5��e�t�X��(ߴ�l�r�aK�Yty`�_/[����0Q��
����]?�}���}���%JX�5�Y���;.6����"�0�=�P�;�q�@�z�f9����0�e��
ڸ���[�������0���W*�ugl�[3���%/0k+X�r�:ǰo�G�(K_�����F���>��Q��������1||^V0k�}jZ�*g%���'��Eݒul03�������ٝ�r[#���e�^V�r�3i�I�S�IH�@�[80�R����N�pF(�b6a�r 'f�†q���]b{����E9yl��/U̒���D.�����_��y���4i���x�v��TQkCh�o�W1���R��gPH-����F0�Ø�(�wG�;"Q̊u��`�?����SA�`lq�����
Jr�f��w
�L�<ٗ�vLwt�K\���ٜ(%v珺�oߺ3����ƌuQĺ$��
�Ƶ�g�X��yg�I��&_R[����H��ƖK#�əe�֛ �m_�r�?�ٿ3y����Ig�2��/�]J5,�~��}���r�`���8�6�(`��.����j�z	���v�+R�L;̅kb�e��2�j\9�.�
v�j�)q��(k�	fw��m��c�X�&#x����(̢ƅ��R�T�4#����\�=`���Rz4N�1�)]܄�e��L����]~b��d�2���ή���C֘5H�1�n�����l�)j+��(���3UeqI4�t7(�"}P��ͧv�5V�-�*���}5�/K9�n["z+���	���."^;Wx��E�cT��$E}�Z<\�䞣�5�����?J6�ă�p8��Pˤ�ZWW_†d��Z��?��Z�]���`&+D��I&ȃX��lӧlטu! ��4�QZ,��(��tL=�j�w)�&ov���?��ȍf�5�2����n0+�v�Ox����\�ԣ���7�����Ne$�����Ȣ��2���]gH�F�b�?�Y�T1���	aQV�,3���'nH�>�Z��̾����z+�=_^��g���}���t�`���p��8���cǯgZ��S��d@�ܗ^+�HU?=�M�T��Y�>�2��ښ~���5�����ư>
fw�ʭ��h]iھ�gi���Q���mȊ2���έ�VY�w åz��$ȼ�h�6�O���g�zܠҨ�R�z�%b���0�1���c$C��hh/l��E��<�����]�����"�t~
MEדq�S��׫C�^���K�˽����
!c�Z��d��랂L�z�b.�bq�+�ŷ���,���s:�x�<��ݼp�^ˁ�|7�H=IW��0�>|�r� [�}œg�g`ƺ����敪�9��	l��3M�>��,Ե��|i�"n8��Z/�����cr0C_��50��/F{��H��4���7��Y�/j^f2�;~��¿��ߜ��X��M>r�Em��������K�XWVmu9�i9MhW�_g�)��
U��~Rc��n�}Vִ���������<�/��R���хú�:K�Ǹ��k��W��}��1�2����f�lׇ��_�r
hl��pX�ޗ�Q����]�$$���Z�u���Z��]��)`*�I���WnA�ÈP��(89�hg��tE]o����Eg�S
���`B��tQ�NL`��SI�͵gfS��.5��r�Y�ŕQZ�k�"�5f�z��Zq����^��X"��
����Z\1~�:��xq�,7�@HUJ�&�?�D��G[UP�
Q�M	��e2@��M@��{�g�����|��Zw^��c�
]�3@'�i���UO��`� ��/$��k�R��m`j��ۨs�|W�1A���i~&ڣ?���n�l2@-��l�6��.����c���(0��ye�*fo4�d��f���_�h�CL=����G^OetIe�#��mP c�b�D����&M�(f�M��.
AL�bMs���y=� ��f���nEWF:&1�Ѵ-^���s���1��w�`v�[�:��.�(����ue�M֍)�����Zgja��8���;���e=?c^��b^td�S
?W];���v�q�V~�z4����x�/���V�6U̠���UP�Yf���w@�%����u��}�0�<�8̌˼����������������AY7��[Y������:���<δˮ���j%�G�<�e����T8�V������r��F�T��C������nz�c�6T�t�Y�hD-`���{��m��f_/���]�
��Q�<���<��јe���};_kN���2PI3)�c���Tp}d������@��Z&��G;�s�j��
T/D���D��aL0sp��dR� �Y&	��T�N�
�pUt����9K�,@�[N����@�2M�֭>����+66��&ҫ*Yf�kz,�]6���dpa�ǣ]g����'���lùMr|�}$��0{���̊�_���]������ԭٗ]��``���f��?��U0;Z5��6�l�}ѕ��Ը���Roj�\�Yf�1e�2:"�J�9�U�k�1(�i�>�c���ÈR�2Q�|���a�{m���!_l��%�e�!2��#2�#+#6��ݛ�#�DA�B1�]��/3��L�8syh��)2������D1�[ӛ��l3�T�ΡZ�O+!���̅?`o!j��{s��T���2w�*lf�f(�����]׊�+*�P�v��+L8�ǐ��e�.�qq���,�*�	�M��&w���v��!
��\��M����{G�L�"� ��l
f��2ɇ�g��6�l�˱a�Pf&�z�0���=�쏠��d0�pN���|[#c��jKoS>TkhA�m�w�D�/��n{7�l>�)𙍑�u ���H}?4;#3�엄r��a�2ZfP�4��3�yi���S��_O��������Ϭ������QtQ�<�>���g�g0{�K_Z'�XO��;<m>�gc�i�d��)�q�4&i�t��+����I[)[3N������`���߉FC��a�MQG�zW�lM��Ӵ�ݛ�Q]?L�_�?d�1��Wa#qhpe�"]>�i^Z
l����9'_<āk�я��1/{�3P��v�w�8��)�#�"����d|^�����	
	#t�̲HCBw�x/�B��\��f��C|0I:���5��ŗi�A�C�rs J
���E$L)��sG�G 6�Cb�̲>��(n��������f����W�`����~
���̏�ع�c�Cl̊'��z�,�5$+c�[�H�������a�WF2e6P���*~��f����>���b�m��fP�|��m6�p-nM0k�xN�S(��7�����8��3�Xx�����	dR�3[�m��(�5�m`c_�enט������M��ǡ��������_�~�ls�`vz�`���f/~�̌1RZO�N��6��&�0����=��l��.ո7¾��1�f�>�U]L�����,�Q���<�D+
f/�\��j&|Ҁ�b/�������H�G��
z<�<�d;�,��A𪁭X4��4�<s�=�_3D�p�k��Z�����'�Y@&
�fV�6r�6(r%�p"�ͦ4�!`�P>/�bR�BX���R(��_��
�$e�e
�	SW�{!������[8�',�JK?���M%�l0�pg�_Za!�U���,��#3M�c[�H�npA�Z�dC3�?ڲ���:��Z�R�b�~������/V��;E�6_��n��n6R5�ᬄ.n�k��ʠ�A9�	h�/|�2�53i7��p�qf8g��6ύK�@f�y &0V�0�ŬW�Z�LU�w0�����w�m�O�>F���a�C^�~䌓l�8�ǩ���������Z?0欳e���נ !�sQua;OРm�(�GX���o��9]2�Z��Y�._�N�j�Wy�ζM��`��ϱA���U%�8Eʄ7����9�A��~u_��Ro�-���J��)�X�c�`��6�b2j��j���ac��.��r���M��m[�b�M>TI��˞�T��l0�x��ަIˢ}�dV��Rg@\�#�U�6����\��G�li�������I�,�S�M��u�E�"�H=ak[Fn�te�A����Ɔ@��eۆq����r��og�ǡv�
k]�)�_�mn��o��f�^;5���f�|�#�ǘuHk]�l_
d.��2}N�
���N�f}�ehM"U�&8RA;=#@;<AH�����bl̢��3�����l?z���?�<��;��;�\�L�Wf�sc�D T�붬2y�^��!�a�T�\C�f:�N����H�.��*����YN�+C���i'9&c҄e�KU�H×��S[�xO)�9�b�u�l�m��<#m�K�F׋Q�$�$��f��]����u�zF{kӀ�˞�d��7��fmԓ��:���Y/4#M���sŴmvs�gf��y��b�w�$&.kf6�!O�L1w����i�5�e��~�;&���>x� �,�Y8#�S�O�.��BYhYƸ�R�I��D:#O�W�PQ/�	=�0&�(�
f���9�O��\�|��2�P��0J�����/�v��>����H\��V
fhW�Z���te�m	d��7�%�G�9���F5���(���,\ ������L�H�=AMl���^-��?�Vϛ"n�A�p��w����l?~�����������]3�e=Փ�Ԏg\�M8���,*,�.~��'�u�sQ�˴�t5�m}_	2�6� �`IwC��!u�y�/^ϲ�%0{��g�h��+pюiC�l[�dU�<W\���F��Yu2,N������$�ڕ��2�,��hJ�~�w��[�Z1[����7=鉽^�e6��_�*Wl��\h���jC��,�K�2�-�m�)5�3cR�c�Kҗl���V�wuS5�&#�c�a`�s���i?cVt�6U�|��l�S�\�%��L0�4���zV�D�Qά�]�U]Cb=����`�.���3�5�>ۜ\W�.6` �Mw����>0�&��t�}��1f�ed,R�7��U��!7�^����m��@��?n�1���?�?�6w3v�ӕ�M/�O^00{�y���שf}:y^���1�.�ZvM�@t�C6�^�ӊ�c��h�x�5m3Jl? �)c�O`�y
��U`v�\�g�ƌ��[#v�$!��ع~aB ��*���δ%��D�1rl1G�S}t1s�!e�����1S��uZ��bcSĔɭc3Q�鴕�=�	�r>@(Ǐ`�OM�#"a�M������+��&ן�'>�#��U�n_,��0�r�-��m�-��K�}8��W̳��	a�����د�9fe,*���,7�z�w�-��o��b
Y_o���3�b�r�T�:�lmci(e�l4�ǚ�F���C+�ͤ^�����6j���ֶ�Ͻ�b3k���e�H��ݚ��e�鋐�C�ǟg0{۷}�%0��fl�ݾk��l'����E+��5gժ�ҶO�=�g�l\+X-$b޴_�Mc�v'��4�쁯��F��T���#n�1q]��O<����qz�P2d�Xᮈr�31d�P�rqKg���Q��R�.Jyڰ����6�m�gN�
f�\��X�ߘ�q4��#'������|�O�\!gr�ܤ����7e�5��d[����>�c�#�Y&aCƏ5�L��-,�(�Rg.R�^�P��U��6��!���ul��g&e2k9��=o
9	f����!�?��`G��>��c��W���C���b��z�oY���d��eY6��󑮌P͚$ �5��ͨ�Q9;�P>̲�K��UWx��&��K��X�_E��.��^���7�笌�zֳ�J�!�Z���yKR�5��`�����j5���������+�����˯;`�V���g{��GqQT����j+,#��*˕�_��JG��$i�4!�f!`3B[��:��֕1���nG�[ǐ[�S�YwN���n��*a�嫦�pԽs:��?�.?�)�P}Yn�Qe����6M�g�Yh�~*$ه�3�6>��,��tr��RU�M4$�T�哮�Y��iz�/�d�֝cZ�l��U0��tY�EÖ��n����o�����u�`�l��1��Xwe$�qϲ��1=�.��o���N-��2֩��}Q��!�Qƚ�Xǹ��L�J�:��p{����-��P��"��ge�ϗ��.�>f7�g0{�3��?vh6E�o�Ġ�x�fP��ރ��_��}?�l��Ě����wWd3�f��z<��Þ�gDlڹǙ�r�m�/�!mÈ�^��p�l�?f���׊��V�L�x�܂fBg˪u�P�Bo/�	�G,)l/��z(RR`�uMs�� [X8�,��;Rԛi�}�0Q�<���y]g2�S��sΚ(��Q�b?6I�/s���fc.�Q�t�nݼ٤\l3m!��j�6nb"�f��fܣnc�z����h�&"���6��{������C{����Z�w��6]@�r�(��)�Yaj��^,VQ�(�-<'����,maѾ嬄w˷A�B�]�f�(�e?.�y����n�^�ټ�m�t�}b�&�b��H ��jY�/&�A5+�1�r�-ę��1g��YcV��Y��
���ۇ���3E4�7uqŕ��.�]w����Oz��is �䂋�{��x
�fZzӲ�+<0�`(��K�h��`�v̭�^e͠z<��Þ�yS�*�+S�Q)Bak�C�U<Y���?{ң@�#�L�|�D���5�E������r�'�Ynl���$���_ڛ��}��u�"۔�G@ԑ�J�fݧK�&��><�e�bA��L"�\�p���&�p�)�ن&��W�rdHeL��,��:a����$s�ԇ�����Ћ����;
(HJ1�U^�,\����������tM�jY	t�Z�:��h��dž|��r"��W�`#P�V��;Hť,��<
��g�6�ڞ��w��?��_���"�/���a�%��#��<�.cʼ��zci�Xk���yvе�c����:��e{�L�#���sH\�7˵�4�4&5Ѿ��5��4ܞy������c��zn�g'fۭ�3�a�t�1@��<��S��ԃ]tO���eN7?�.33�6ǫ�PwDU�d�1^�`WŦ�%�i���=��,c
l��J���m�6-�<u��Kl�AV)����jb���Y�����0v���-ua2a��4�BhP(S]��
�Lk1*�R�#Pܼj�e��^*f��#��i�u��>Vo�y��F
%m���&����̃*��p���0:R(&�k��y2hv(���:��x4��~b/�ۍ���l~G�]T�g���
f;�(C��~z�O��N�-4^l��I����Tc�X\*H�����v���ㅕ�j�e��L�1��'�R�Ԡ&�������;�ͯ�f�o�cʘ��R�؟e�y�m;��+6@&�zN����] [vi����d��&K#�uM��38�Y�=���<��������ݸc{̞p�~傁�c�3�=�)O�j�"��z�j`l�L�8$Y>/��573�:֍�'��2�!c;�=���S�=n�(��m2@]y��bH�B�@��A��<�uq��G�
Y��wأ,:5
`�8V��l�q�渑	yW�"�p�]]��ut{u�K���N�1ُ��زuO�w�)�'7��.�BJ�{`�G5��^�`��C���"�[a�i�I�DU�$�}��_�7F�	��W��T���+��,��H\�n����LOu[pޭ�>�?�͛t3�=�/}��!�G��cnPؼ�.���G9p��9x�����'�Y����j��7�o�pبDY����������1�ަڎz�/�,�z�NV�����5��DԺ@Y�e>�'ݮ��W���$��M��=�NU�+#�|^�7{]�J 5�Q5�:W��ǩn8�--�%�L�뮍��57J�-lg�J��v���mc��AO@7�ޞ�=����K�������{0k գ]a[^3�l�*�p��1�ֶ��a����{.�;6ـٓ�������9��^��F��=^�!p�8�0��<S�ˉ�H~�O1�o��TR�I�"�X��6�ƣt�(
��*X$�qB
�a1��я� H\�b炧�վ�0:�g��a�qQTд��إ�Q����p����,���J��΍�]��T)�i��y����y�rç�Ù�Y����cy���_6���/�BJ4=�m�\]�k5@�ita<DIS{�'�e�
�	SIs.�]3׌�d��
K
�myMQ�����u}��1�yT�&{ڼ{���<�ܮ�p��ټjX��ɹUȚ��H��J�B�h����@3�lՕq=�L��{���4�
Z��q[���k�U�۷[l���y綱�阮�����P��x�y�7|�7\3-�p�r���VZ���Bm��U�1�XfW4��T9�ڥ��_�^��x̞0�:��eY�@Ӳ2��m�Md�Ⱦ�o{�ID2����|�P*�	;&7�E�ƺ�׼�� ��71��T�|?h�KbH���z::�;c������n3��/���p��5U�4�9FŪ=#�!E�J��lX3f��7��Z��m�@�t�J_����_*�9>.��ZO�%��#ݧ���L�4��5���H��iљm����{�`չ/��
K
o���*6ܼǍ�xY�����E*���zŬ?��o������漐uq�d�;�
6z +�3Ӭ�G�26M��*ָ4�j�s�u���߃�¦�n��O�d��?��btL��.��f��l�y��1{�y����?�8ff�����n�O�io�d$*mײg�Z�e��(���)|�b�r��-��},���]3#�MZĐؘ��<m�m�3��d;0�����8zݨ����FB���I�JV����b�ڛ�ȼue�ͧ�b��EV*���0�6hP�"~�wU&�������bC�?̒�V\n���{���<Iy�p!Q�,D��_t�	*^����ҽ��C�~{�����J�I�7�u�+�xppO�O@dY"0w}���f.�?�	e�Ҟm���Q>�L�a����7Qx��:S�o|B��ڌ;ʲ"�K�od��`k���� ��&�E��hf��9��k�7�e�ͽ�ƚ�*j�	�9��-sFdb̳<M��Z�#��X�(4U���A����uĖ�Q{��q���73�lxG���"�\$�lk���a�u���a��^�^��Tm\�2�?�1s ������}ג{g{��Ր�g������a�5�иZG�aP�2[�����uU���-� v�Orɲ躟�.����8�P�@+�e�=`#���R���M�P8K�F��Y�p���=�jv�R���%ٱ܏���3ᜎyZ���yw����_�U� t�1
ȹ��! *���=�T�R�I@Rg�%�:��(c���K�nZw9'�	��~�2��M�4�|���T.���%�=��o n(ٛf0	�1�*�ICQ�E�x4�����'�fcs��w�h�V���cb3!.d�2�����L�����3�3*���f!k�v���ƀbV��06����/ۑ�������}�.���=�w.�=�<�����,ܤ�
��{�vML`Dښ���c��m�E�z��y��zn�w	�[��,K0�~أ�a����Ue^O�K�E�4���1��\bGxs��I����1����p�,�'��X�3NfN��6?KG�1�	i!�f�PF[��<�Q��P)A��6�Oj�Ϸn�!.����r��	��W�����_�f���+T��Ưc�]C�#ΌDzl(����"F����-Ǵ�V.3�m�S�~T%��ǣs�&�ɹz���xċ��JLl_�\�GS��S2��W��9c}��h�l��[�[&@&��t߲#�˖��ӝ�eI�!V(f��5�f���L�ZW��2��7�����̎��*&���s�݋fC>�Y����V�b_m`����!��q��Sd�D}
��Ⱥ�r��\a˾�X�c߇C\k0�n�#�ʘ+����)6�Y��^���7 pE�j+ 'oX�*~���N?L*f|�f���O�k�ϧ��Kʘx�ntvR0su�By��_�	8}�������Bt8��La6S�B�L�|�ŮO�vH�D��5�
�CR�F��Q>�3��Kb��9Ϝ�f��]Β�ڌl0J&�L��v�Q�@�_r=7��8!�W��(��Z'gbS���3;�{�M
Մ���,�@8V��|~�[���C(��J-��9>�2M>b�yҾ�&S��
��O/������0*�O�*d�/����`�_�*J�ƙ��e�*4����լ�,ּr�k��̎�w�q�b�,7��r.!�7��Cbˊ���vӳ��9�0J��bE5�myn�68+��Wf�a�h�;���ύL���;��=�/X���g0��kV\���ڱ�}lC�V��iM���Vkq��n�4?�y�\Ǹ1&�]��%z�#Ƹ���2���f�u��75�	���.$��2���'S�l+*YЕQ��E�Ȃ����0�c�����i���`]���&��>���jV⭤$U�~&�����*���J�a�U!^�f1!-��	Da|F�&U�h&������=�`�ݪ�u�o����%| �_�Ѧ��Ǔqcs�����u�rcG[���VU5��G�]�"č�.v�q�5�Ṵj���۾k~�,���O���(gT���Wc�5��-��2��?�@�2��>Hg��N癩��hu���cϚx3�YB�%�R9�~`V�ˣ����t�'�?�``���f�y�czPhb���8
��5P��$�i[�&��y]ʦ����
Q�ڶ�7k��1n�{/@@C��0�Cu��R,�����8�xCx��d�^M��<��͑�2F4ĉzk���#�����5������I�f�/{����E-I5E�)MUI�)�5-|�$��B�aj}�?��y��5��\�/sf�A�1�`��\�ks�	׉�]�d��v�%�s������ԍ��*��\{�:�'9]�ص��C��f������6�����I]��
,Lo��Ж���X3ՓC��Z�D�L[�buQ�4�L�����Y� $E�2��qe��UЦI?��GmL����U��"�N&O5�1�x�`ff��66Ą�e�'M���$U0Ɩэ�޷�;{W�*+cg&P&e������Y@!C�%0������dv�`��������R�it���~����G5p<�8V�W]��,ҵq��վ#渴�#@uu9�����8D�"�X~��q��yE�,\�Oq-r��d��q���E�������&�uT�B��mc�k2g���v.v�:@�S!㭥[�i
�X�rF��~��?�ݍ����n��dRF�ѩ*�Uh;s��g��n^�u̩ٜԅ1�_2��lU(/F��}�|$bT�k@�YG��N�)��0ǩ�S@3I�WGf~�]�C]w.�c�r�0�ƍ)��<�s)6�?9x�j�ֱOS�z(Eę�ClJ}���`vGy�a�K��v����@Vo*M��j��I�ߤ�g�|)׀&p&�4K�f�1�8i�T�N���N�b��[^����m�m��?�``v��f�x�#V@�����:-�E�
G�[���k�j�
6��:U���տ��G�=(!��p�k��e��C�Ek��6��L��,�"
���mC!HS�҉�(�At!toLpS0sY���ż��Y��T��;/8g�r:�9�Н�-����de��J4�2�NK��%r��[*8�������JΜ_�-������=�������~����NB�r5>���2".�h�?2��^Ї:�	sfq�1�_T��t�
V�L#*W�gꖨ	1�&+�[�����<c����G���f����j\ �MT3��
��Ч1f����L���`�|���b�f_�ƈvqc�����1(�dv��ُ̚�NI������,+��sV�Wz�WZ�ކYՆ.�e6�j\7��Y���U�Wo.���F̦hXC�T�Z7.p>������`	
������!��k����.���n��eT�.���d>�ua�\X��� L&j�7@���K��!�;S
$x�Y����Ya�����2��#��"�q/�u�e����B�$�Jld�}�8]���b�S,��y�9���gs^r=^C��v�#|M��V�5&�r��E�"9{�1eN�?���Mq]4�2]����{M22�������3��)��J���e��N�t?f����W]ک�	����Y9�0K�����,�U�"��,�_��������
��0����(i��1ᮩ�c>V\���/[K��g�?�u�F�f9��s�$��|c�;�%��|��0�~��ђ1C�q&�=�삁ٽ�3������Z�563�a��Y*S}���zU�e��R�1s��0���G�$�Pf���2ە,�ʸ��r/С����;����؆L���Q�E%H�
�A13D���W�K��u����}WDK�J���(�{��ʺ2A�|gh�?�_��OK:�dԏ
b��iPC�T�7Q�X��ue�V��2�,}2�\�
(Na1_�Y���*�N�N3��&�~�3��>c���
n�0$k�@ߟ����M���|���urNPP��D?����Zʘd^�zf��W��V?�Hr�"��5��_2[�%�4ԁ�EU�2)Q�������П�����������xOٟLbˠ�	�e=|�e
f^Ե��•v�+c
dcTʴ�{�A�߀�O�nh�����f�n1�V���q�2���l�1�m�l�w�����I�Jլ�m
�e��f�R:�����8��oڮȲ�6�E�r��h�'q�O�^@��H��e�L[SoA���=71�i��Q0Ѵ���9���"ׅ�r�x�L����B4���V`��W��n�&}�	��[�����l(�bi������:�B`�%պl\��!�'�H��|W%I�H;M����0K�"�������0a�T�]�-Y��x
g64�I�@1,���,�h���	�H����'�~]{�3��ΗR5�T5���Bڟ�ԏ]Y����y4`�2`�lh+�Q��1N���6u_�6�$� i��OS�*`�O
_媃}t�����@™̰�����h��|��; ɑ�
���1�������33333c���������c�ku��:��U�Ul��f��*�J�j�z�u�^��f�[d1H���Ad8���D�h����*c?���T�boZ;��^�l+�5��+�G���+f�UFhK�����9e�[�fo�6osE@�6B�1��)|�y��JB�����+u��7tga������`m�>�g�"���@�q�1����x��:H�l��JUƤ<>����`����;��,R��7��@a.蜗�:��̸AY���_�ϣ<��y�$Jui~�S/ǯ�)h�{�v%�ؤ�?|�u0����5��#`���E�	��g�9ƶV������))r��m��7�fJ����E8I��#li�܂���Z��Վ�Q�Rl�<rI���f���f�5�^2[Q�=�0@�@0�F���Nal�S�)���!R֏�Յ@r��0��3����Ł�b����̦S�z}���u�i��t˒�����(`A�]��4����u�:�ݑfI��Y8,�ʈYg]7ʲɤUmåZ�g;�.�'L!�Dz�?Ri��*Jb��G7B�P)+�z]�����c����OtY$-���sr�F=r��G���EE��%�E݈4���������6����P ��
���b���R��<��f+&#p�R�>~��w梥bh�5�s0/X��k!��#ʣu.VMDL��Z<UTu�Eʵd��!α-�=�'R w���YTk��l�{�
��om@���G�f|���f���ә6U��0�1T���0���e�Ė`�.��3�Q�l�l�<�}�`V�S��.} ;��G���Y�+�m*�p6W2��u�^�̠�ڬcZ����������߮�eD��]��̆��zǪ�7-Y���w;��^�/�/ї��i���g~�ܡ�`�>�<deA�P����ҲlYa��)l�fp��1wP̅��ܮ�-�
���~��u/IV��=<bF�TH�t1�%%D��Q1�����7;�TWb,�Y�R�i{�yeX_I�?x�
�3�'�8R ��#�	�.<�6R��J����R3`�i�[Ʊr�w�H3D�::.�ҮYr�:��4�VZ���}K��.r�|5)?ɰ.��d��~�`�Ž��HV�d�9�M��B�Lr�q�A
6[��0���'S\=�"��?�(�8ݣ�����6�ܬ_�a��d�n٠q�G� �OP��ʈ���X_���S]"�*#�@+r��w���A����8��̾�E_�����Sf7.���6��	�F[�w~گ�9�L���E��ݡ[��L�ف��o�>�vj�2��/���w�B� �(��C��Fա,��`&Y��D<�I4�@K�+�v��Xt���[6���1G=:U�,�R�=v�
�����,�kڭ�e?��	��tx^�G�PO9�����R��-����M�������k�|���_IA�����sE��06�G�}��QhTz��*̆�U��v�׵�,� �+Re朗�C{f�4���`h��gT�/�1�o��w�Ʊ�"g/�Y�O��J���������?��Pi$��4
g���{fͭ�f�;f��>AZѲ������?oV�j��˕!Z{�Xf�O�<f7,����}�?�s�8WلH�P��);�:��y~���MG����1Q\���9�9�L6BP�����ȗ�Ly�U�³U�;,Q_�����Ц��F�`��:H�Q���UXہl]Mr
Oe������V���nீ��Y���g�`�<��g�j��K�婒B�2N,&\�h��jIlp�=��� �ьV�%��y��5;vo*l�S�|����|�7$��_4��k����c�\qwJܹ��L�t�H}�\�����}��.I"�m๵)�,"f	�Fw<)�l�w��U���o��?F���o�=IKaD��)Cyۯ6�)/^�T~����4�5���E��$�!��ʍhc�(�Q��jS���Kb_i_�z`�y��Y�X��O�C�A���%��w��{�>޺�]R�	���ҍ���-�5�����1J�v�>�����2j��f��gP2�ɠ��	e�j��Oe
;S!� 9�=v���%�>�����Aa���@A�B��A!�Z��`�І$�w�s�zC'��i+�L���3�b)�87�i,���lel�P���M��Q���K�#G=���~�=�s�ɴH�D_�1}�~7y�`,;/m���"��e�k��7�k��3?ډ˂t���8&�s>���׮2����_I����[m�9��-��ˆU�Le�}�9����e��q��"��־�h{�.�}�2X���-��"��Yz���; ]X2��v�m�!`�����E@�I�>��I��Bd"��g�(/˳���#j����#o��t���E88l���K=��
�����$�I�!yP��v�G��leLe�:<������B�D�e��,5�>��0`2�S��-L$��s�ec��L�\v�W�";��Wg3��ఴ�T#-ю%II�,c��n��c�w��c��?/)H��*�xG�{h�\��w��b�sq�ҙj.�*��}�_��C�U03q�0:P�#f�-�+��z��v�� ��p��؇�S��Y�Un�{f�zgB ����e�����n���m��0+}�M�]���l�Rd%B�0S{�p69�Yr�%�{{mG�)���g�A�����WjOZ�}t�dM�6�p_�GO�<f痬��o���	G�6�,))v�sBi�R�(�i�;����3>�E� g��we�L�vn(�M������t9�_�X����Ӫ�2���d��d��L��Po6����@\�eߗ�́<~޾N�@Ja�B@�[�r�s�O��[�Ж��=�ي�p�ߚ�?��ŋ6�k�=v�R��c֏�s?��*E �6^�e%����٭���G~�{=�n-A'ULa4p3𲺨���LOD��.��$�!Җ�v�-��a� 7����� �]�@q `��f^�w��1�C7���W}�Ք*�l*�ֻf��{eө�m�J*�×�M��v�f�[���o��-�>H�_��u�����c���-���M�d���v��k�י��sR�O���Z[Fİm��9���BbM����д�|M�F�0��ѓ��Q�v?�t7ء]JF�خ�O�;�f�t�<��@�&��y�c����l�p�M`�����x��k^a��w� !�v�49��Je�s����S|ﻉm@Xs��D�6�����i��Q���a�M�gt��H
�@?5�.T������(�8|��SN����ygv��n��%������^�>|��f�aM@�f\��TƦ\~[$'ᬮ�8O>����W��S_���s�X�f�џ`z�;fߦ�O�*���K�7z�7�C�����a��_���vgnج��	j��H�J`�b-e��v��`�m��k#I�������d�5C�TD�t��1�I�8�I�O�	Zi�q;���ٳ}`y�\û�z����XL�r���H�|_	k���`�=.��x���a��/bH&$�qT�����Y*b-�&E沀X����6&4��y��E�Ău��ENyܷ5/��(�:�����K�m:���C�t�L�"gm���|5F���+�Ie���-�v�f�ͣ�+�_��_,��;�~����*7�w�Sfg�fo�op�P��>�α�>g���~0&Ô��F"�OL�D�$j`6���ZIg�~��Y�d�D0�S����$r����M��U�W��Pk{q���'l��1��SgΨ���Qݯ޾j�=
���_²��~�=`%��`G]�Ę҄HTY9�
�݁��[<~���}��	c��rY�l�>	i�H���%��~H5c0�lV��E�_�Ct.���R�w�∘�8�ݿ�gf�z��#h�;���ǣb��M�2��2�=��t*#!
`V@�_G�;W��X����Z.��%R�c�?��r?�'O�.�^��_����TX���iv�o�c��]}&g.H��,}�A JSH�@��π�p�ݰG�1��mh�@�_X�}�S�J|K���c����~��1�V��p��۞�F�~DEݝK(�Ƅ�A��@!�*Z�H���xR�ss
	�3x@U��M�(J�Q[��z0x�^za䢂��"���,uu�M��ۏ����?�k̄��*7ImZ5�a!�]�G��s4��C��i�	��)�cZCg��P���}:��󒠌�,
�z����0�oq��<�?s"�0rv%��(}�zyH��E@t����O@�/�_��es^�?�/ZI?0���g�|0{S�rG�!���S6��Uϟ?Š����8���ǰ���9'
"��s����•��Ӄ�.2�iZe�3M�$�*x)�6�,' ��.B��V�'����_e<z�oV�ڈ��t2�]F��
�ӛ�zy���2(�)��V�T�w�C�p\=#]UR�>�|��a�_mdW�9屦��&+m�N���~��N"�m��`��(��Jz�u���}�kǔ�h>"�p֍���� &��*�Gch�q�,0{m%��R�<����)���_2��={�X�`��\���>K8�<�D}��j0�n����{�qi�y�>�e	�~XoF���ȇ�m��|�:Fq��jt�*�1Jh$��IW�ǴV?���,�d׮�D��7<d{S�.����6�v�jzRjYz���䕩�Ya������!��89uo�3��O�~�p�E
���]���kq������{�z�a��S
Ȳ^ךӭVƘ������j1��~fC���sx�^��d��r����M����!K���I3B�k����7C/WKi\��JeT�x�~z%��f�������WV*wu4)~_�)��%����zKDP�=�<g������x����c�19���㋙}���:8�%v\����܋�G������H;J��C�,�l��m�U�oPFD�հ��yʢ;�&��T')�
�pɴ�Ҷ��s��O�V|��S
4B�3�v������c:�3j��8�3a�
�6�I:���������u��3�I�Tq\WO<��N�G��ɉ��1�������)�.^�q���C�'2:�d��i󾾬[5�V�]�Q���Q7��~�c�0��Jz�Qz��3��£�#S�2�/3$�̤�l�n�����Q��QZ�x�f/����~��?�-����˿�{�7�^�U^�ֻ�a�`vpp������_�����ۣ��%�a�O��Y�w�����u;�+�
�%������GD"�$[T}]Ìk4K��������b3<_q��Q��e|���Wg��vw�w���Q7C��v1����f�K^��:��g!��B��ԫ��[7�C���땾Z��hY]��G��V����o�����ܾ3��{ց�c/�.1�1�O��ҹ�Q��b�`�;�X2����i�����\�����Y��6sy��"�<�������h�D_�	���7g�hԛ~��H�͈�_B�ڲ+^<9��z\��^r&e�1���qe�%L�^"�<f����ç�4���o/�7C7��o2�^`�c��)��c�FI�~���7e�[�v0�U-�0s~vIEND�B`�.minicolors {
    position: relative;
}

.minicolors-sprite {
    background-image: url(data:image/png;base64,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);
}

.minicolors-no-data-uris .minicolors-sprite {
    background-image: url(jquery.minicolors.png);
}

.minicolors-swatch {
    position: absolute;
    vertical-align: middle;
    background-position: -80px 0;
    border: solid 1px #ccc;
    cursor: text;
    padding: 0;
    margin: 0;
    display: inline-block;
}

.minicolors-swatch-color {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}

.minicolors input[type=hidden] + .minicolors-swatch {
    width: 28px;
    position: static;
    cursor: pointer;
}

.minicolors input[type=hidden][disabled] + .minicolors-swatch {
    cursor: default;
}

/* Panel */
.minicolors-panel {
    position: absolute;
    width: 173px;
    height: 152px;
    background: white;
    border: solid 1px #CCC;
    box-shadow: 0 0 20px rgba(0, 0, 0, .2);
    z-index: 99999;
    box-sizing: content-box;
    display: none;
}

.minicolors-panel.minicolors-with-swatches {
	height: 182px;
}

.minicolors-panel.minicolors-visible {
    display: block;
}

/* Panel positioning */
.minicolors-position-top .minicolors-panel {
    top: -154px;
}

.minicolors-position-right .minicolors-panel {
    right: 0;
}

.minicolors-position-bottom .minicolors-panel {
    top: auto;
}

.minicolors-position-left .minicolors-panel {
    left: 0;
}

.minicolors-with-opacity .minicolors-panel {
    width: 194px;
}

.minicolors .minicolors-grid {
    position: absolute;
    top: 1px;
    left: 1px;
    width: 150px;
    height: 150px;
    background-position: -120px 0;
    cursor: crosshair;
}

.minicolors .minicolors-grid-inner {
    position: absolute;
    top: 0;
    left: 0;
    width: 150px;
    height: 150px;
}

.minicolors-slider-saturation .minicolors-grid {
    background-position: -420px 0;
}

.minicolors-slider-saturation .minicolors-grid-inner {
    background-position: -270px 0;
    background-image: inherit;
}

.minicolors-slider-brightness .minicolors-grid {
    background-position: -570px 0;
}

.minicolors-slider-brightness .minicolors-grid-inner {
    background-color: black;
}

.minicolors-slider-wheel .minicolors-grid {
    background-position: -720px 0;
}

.minicolors-slider,
.minicolors-opacity-slider {
    position: absolute;
    top: 1px;
    left: 152px;
    width: 20px;
    height: 150px;
    background-color: white;
    background-position: 0 0;
    cursor: row-resize;
}

.minicolors-slider-saturation .minicolors-slider {
    background-position: -60px 0;
}

.minicolors-slider-brightness .minicolors-slider {
    background-position: -20px 0;
}

.minicolors-slider-wheel .minicolors-slider {
    background-position: -20px 0;
}

.minicolors-opacity-slider {
    left: 173px;
    background-position: -40px 0;
    display: none;
}

.minicolors-with-opacity .minicolors-opacity-slider {
    display: block;
}

/* Pickers */
.minicolors-grid .minicolors-picker {
    position: absolute;
    top: 70px;
    left: 70px;
    width: 12px;
    height: 12px;
    border: solid 1px black;
    border-radius: 10px;
    margin-top: -6px;
    margin-left: -6px;
    background: none;
}

.minicolors-grid .minicolors-picker > div {
    position: absolute;
    top: 0;
    left: 0;
    width: 8px;
    height: 8px;
    border-radius: 8px;
    border: solid 2px white;
    box-sizing: content-box;
}

.minicolors-picker {
    position: absolute;
    top: 0;
    left: 0;
    width: 18px;
    height: 2px;
    background: white;
    border: solid 1px black;
    margin-top: -2px;
    box-sizing: content-box;
}

/* Swatches */
.minicolors-swatches,
.minicolors-swatches li {
	margin: 0;
	padding: 0;
	list-style: none;
	overflow: hidden;
	position: absolute;
	top: 157px;
	left: 5px;
}

.minicolors-swatches .minicolors-swatch {
	position: relative;
	float: left;
	cursor: pointer;
	margin:0 4px 0 0;
}

.minicolors-with-opacity .minicolors-swatches .minicolors-swatch {
	margin-right: 7px;
}

.minicolors-swatch.selected {
	border-color: #000;
}

/* Inline controls */
.minicolors-inline {
    display: inline-block;
}

.minicolors-inline .minicolors-input {
    display: none !important;
}

.minicolors-inline .minicolors-panel {
    position: relative;
    top: auto;
    left: auto;
    box-shadow: none;
    z-index: auto;
    display: inline-block;
}

/* Default theme */
.minicolors-theme-default .minicolors-swatch {
    top: 5px;
    left: 5px;
    width: 18px;
    height: 18px;
}
.minicolors-theme-default .minicolors-swatches .minicolors-swatch {
    top: 0;
    left: 0;
    width: 18px;
    height: 18px;
}
.minicolors-theme-default .minicolors-swatches {
	height: 20px;
}
.minicolors-theme-default.minicolors-position-right .minicolors-swatch {
    left: auto;
    right: 5px;
}
.minicolors-theme-default.minicolors {
    width: auto;
    display: inline-block;
}
.minicolors-theme-default .minicolors-input {
    height: 20px;
    width: auto;
    display: inline-block;
    padding-left: 26px;
}
.minicolors-theme-default.minicolors-position-right .minicolors-input {
    padding-right: 26px;
    padding-left: inherit;
}

/* Bootstrap theme */
.minicolors-theme-bootstrap .minicolors-swatch {
    z-index: 2;
    top: 3px;
    left: 3px;
    width: 28px;
    height: 28px;
    border-radius: 3px;
}
.minicolors-theme-bootstrap .minicolors-swatches .minicolors-swatch {
    top: 0;
    left: 0;
    width: 20px;
    height: 20px;
}
.minicolors-theme-bootstrap .minicolors-swatch-color {
    border-radius: inherit;
}
.minicolors-theme-bootstrap.minicolors-position-right > .minicolors-swatch {
    left: auto;
    right: 3px;
}
.minicolors-theme-bootstrap .minicolors-input {
    float: none;
    padding-left: 44px;
}
.minicolors-theme-bootstrap.minicolors-position-right .minicolors-input {
    padding-right: 44px;
    padding-left: 12px;
}
.minicolors-theme-bootstrap .minicolors-input.input-lg + .minicolors-swatch {
    top: 4px;
    left: 4px;
    width: 37px;
    height: 37px;
    border-radius: 5px;
}
.minicolors-theme-bootstrap .minicolors-input.input-sm + .minicolors-swatch {
    width: 24px;
    height: 24px;
}
.minicolors-theme-bootstrap .minicolors-input.input-xs + .minicolors-swatch {
    width: 18px;
    height: 18px;
}
.input-group .minicolors-theme-bootstrap:not(:first-child) .minicolors-input {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Semantic Ui theme */
.minicolors-theme-semanticui .minicolors-swatch {
    top: 0;
    left: 0;
    padding: 18px;
}
.minicolors-theme-semanticui input {
    text-indent: 30px;
}
# jQuery MiniColors: A tiny color picker built on jQuery

_Copyright Cory LaViska for A Beautiful Site, LLC: http://www.abeautifulsite.net/_

_Licensed under the MIT license_

## Demo & Documentation

http://labs.abeautifulsite.net/jquery-minicolors/

## Install via NPM

This is the official NPM version of MiniColors:

```
npm install --save @claviska/jquery-minicolors
```

**Note:** There is another version on NPM without the namespace that is out of date and not supported. I did not create it nor do I have control of it. Please use the official NPM version to ensure you have the latest updates.// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  CodeMirror.defineExtension("annotateScrollbar", function(options) {
    if (typeof options == "string") options = {className: options};
    return new Annotation(this, options);
  });

  CodeMirror.defineOption("scrollButtonHeight", 0);

  function Annotation(cm, options) {
    this.cm = cm;
    this.options = options;
    this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
    this.annotations = [];
    this.doRedraw = this.doUpdate = null;
    this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
    this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
    this.computeScale();

    function scheduleRedraw(delay) {
      clearTimeout(self.doRedraw);
      self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
    }

    var self = this;
    cm.on("refresh", this.resizeHandler = function() {
      clearTimeout(self.doUpdate);
      self.doUpdate = setTimeout(function() {
        if (self.computeScale()) scheduleRedraw(20);
      }, 100);
    });
    cm.on("markerAdded", this.resizeHandler);
    cm.on("markerCleared", this.resizeHandler);
    if (options.listenForChanges !== false)
      cm.on("change", this.changeHandler = function() {
        scheduleRedraw(250);
      });
  }

  Annotation.prototype.computeScale = function() {
    var cm = this.cm;
    var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
      cm.getScrollerElement().scrollHeight
    if (hScale != this.hScale) {
      this.hScale = hScale;
      return true;
    }
  };

  Annotation.prototype.update = function(annotations) {
    this.annotations = annotations;
    this.redraw();
  };

  Annotation.prototype.redraw = function(compute) {
    if (compute !== false) this.computeScale();
    var cm = this.cm, hScale = this.hScale;

    var frag = document.createDocumentFragment(), anns = this.annotations;

    var wrapping = cm.getOption("lineWrapping");
    var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
    var curLine = null, curLineObj = null;
    function getY(pos, top) {
      if (curLine != pos.line) {
        curLine = pos.line;
        curLineObj = cm.getLineHandle(curLine);
      }
      if ((curLineObj.widgets && curLineObj.widgets.length) ||
          (wrapping && curLineObj.height > singleLineH))
        return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
      var topY = cm.heightAtLine(curLineObj, "local");
      return topY + (top ? 0 : curLineObj.height);
    }

    var lastLine = cm.lastLine()
    if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
      var ann = anns[i];
      if (ann.to.line > lastLine) continue;
      var top = nextTop || getY(ann.from, true) * hScale;
      var bottom = getY(ann.to, false) * hScale;
      while (i < anns.length - 1) {
        if (anns[i + 1].to.line > lastLine) break;
        nextTop = getY(anns[i + 1].from, true) * hScale;
        if (nextTop > bottom + .9) break;
        ann = anns[++i];
        bottom = getY(ann.to, false) * hScale;
      }
      if (bottom == top) continue;
      var height = Math.max(bottom - top, 3);

      var elt = frag.appendChild(document.createElement("div"));
      elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
        + (top + this.buttonHeight) + "px; height: " + height + "px";
      elt.className = this.options.className;
      if (ann.id) {
        elt.setAttribute("annotation-id", ann.id);
      }
    }
    this.div.textContent = "";
    this.div.appendChild(frag);
  };

  Annotation.prototype.clear = function() {
    this.cm.off("refresh", this.resizeHandler);
    this.cm.off("markerAdded", this.resizeHandler);
    this.cm.off("markerCleared", this.resizeHandler);
    if (this.changeHandler) this.cm.off("change", this.changeHandler);
    this.div.parentNode.removeChild(this.div);
  };
});
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}((function(t){"use strict";function e(t,e){function i(t){clearTimeout(n.doRedraw),n.doRedraw=setTimeout((function(){n.redraw()}),t)}this.cm=t,this.options=e,this.buttonHeight=e.scrollButtonHeight||t.getOption("scrollButtonHeight"),this.annotations=[],this.doRedraw=this.doUpdate=null,this.div=t.getWrapperElement().appendChild(document.createElement("div")),this.div.style.cssText="position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none",this.computeScale();var n=this;t.on("refresh",this.resizeHandler=function(){clearTimeout(n.doUpdate),n.doUpdate=setTimeout((function(){n.computeScale()&&i(20)}),100)}),t.on("markerAdded",this.resizeHandler),t.on("markerCleared",this.resizeHandler),!1!==e.listenForChanges&&t.on("change",this.changeHandler=function(){i(250)})}t.defineExtension("annotateScrollbar",(function(t){return"string"==typeof t&&(t={className:t}),new e(this,t)})),t.defineOption("scrollButtonHeight",0),e.prototype.computeScale=function(){var t=this.cm,e=(t.getWrapperElement().clientHeight-t.display.barHeight-2*this.buttonHeight)/t.getScrollerElement().scrollHeight;if(e!=this.hScale)return this.hScale=e,!0},e.prototype.update=function(t){this.annotations=t,this.redraw()},e.prototype.redraw=function(t){!1!==t&&this.computeScale();var e=this.cm,i=this.hScale,n=document.createDocumentFragment(),o=this.annotations,r=e.getOption("lineWrapping"),a=r&&1.5*e.defaultTextHeight(),s=null,h=null;function l(t,i){return s!=t.line&&(s=t.line,h=e.getLineHandle(s)),h.widgets&&h.widgets.length||r&&h.height>a?e.charCoords(t,"local")[i?"top":"bottom"]:e.heightAtLine(h,"local")+(i?0:h.height)}var d=e.lastLine();if(e.display.barWidth)for(var c,p=0;p<o.length;p++){var u=o[p];if(!(u.to.line>d)){for(var f=c||l(u.from,!0)*i,m=l(u.to,!1)*i;p<o.length-1&&!(o[p+1].to.line>d)&&!((c=l(o[p+1].from,!0)*i)>m+.9);)m=l((u=o[++p]).to,!1)*i;if(m!=f){var g=Math.max(m-f,3),H=n.appendChild(document.createElement("div"));H.style.cssText="position: absolute; right: 0px; width: "+Math.max(e.display.barWidth-1,2)+"px; top: "+(f+this.buttonHeight)+"px; height: "+g+"px",H.className=this.options.className,u.id&&H.setAttribute("annotation-id",u.id)}}}this.div.textContent="",this.div.appendChild(n)},e.prototype.clear=function(){this.cm.off("refresh",this.resizeHandler),this.cm.off("markerAdded",this.resizeHandler),this.cm.off("markerCleared",this.resizeHandler),this.changeHandler&&this.cm.off("change",this.changeHandler),this.div.parentNode.removeChild(this.div)}}));!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";var r=/[\w$]+/;e.registerHelper("hint","anyword",(function(t,o){for(var i=o&&o.word||r,n=o&&o.range||500,f=t.getCursor(),s=t.getLine(f.line),a=f.ch,c=a;c&&i.test(s.charAt(c-1));)--c;for(var l=c!=a&&s.slice(c,a),d=o&&o.list||[],u={},p=new RegExp(i.source,"g"),g=-1;g<=1;g+=2)for(var h=f.line,m=Math.min(Math.max(h+g*n,t.firstLine()),t.lastLine())+g;h!=m;h+=g)for(var y,b=t.getLine(h);y=p.exec(b);)h==f.line&&y[0]===l||l&&0!=y[0].lastIndexOf(l,0)||Object.prototype.hasOwnProperty.call(u,y[0])||(u[y[0]]=!0,d.push(y[0]));return{list:d,from:e.Pos(f.line,c),to:e.Pos(f.line,a)}}))}));.CodeMirror-hints {
  position: absolute;
  z-index: 10;
  overflow: hidden;
  list-style: none;

  margin: 0;
  padding: 2px;

  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
  border-radius: 3px;
  border: 1px solid silver;

  background: white;
  font-size: 90%;
  font-family: monospace;

  max-height: 20em;
  overflow-y: auto;
}

.CodeMirror-hint {
  margin: 0;
  padding: 0 4px;
  border-radius: 2px;
  white-space: pre;
  color: black;
  cursor: pointer;
}

li.CodeMirror-hint-active {
  background: #08f;
  color: white;
}
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var tables;
  var defaultTable;
  var keywords;
  var identifierQuote;
  var CONS = {
    QUERY_DIV: ";",
    ALIAS_KEYWORD: "AS"
  };
  var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;

  function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }

  function getKeywords(editor) {
    var mode = editor.doc.modeOption;
    if (mode === "sql") mode = "text/x-sql";
    return CodeMirror.resolveMode(mode).keywords;
  }

  function getIdentifierQuote(editor) {
    var mode = editor.doc.modeOption;
    if (mode === "sql") mode = "text/x-sql";
    return CodeMirror.resolveMode(mode).identifierQuote || "`";
  }

  function getText(item) {
    return typeof item == "string" ? item : item.text;
  }

  function wrapTable(name, value) {
    if (isArray(value)) value = {columns: value}
    if (!value.text) value.text = name
    return value
  }

  function parseTables(input) {
    var result = {}
    if (isArray(input)) {
      for (var i = input.length - 1; i >= 0; i--) {
        var item = input[i]
        result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
      }
    } else if (input) {
      for (var name in input)
        result[name.toUpperCase()] = wrapTable(name, input[name])
    }
    return result
  }

  function getTable(name) {
    return tables[name.toUpperCase()]
  }

  function shallowClone(object) {
    var result = {};
    for (var key in object) if (object.hasOwnProperty(key))
      result[key] = object[key];
    return result;
  }

  function match(string, word) {
    var len = string.length;
    var sub = getText(word).substr(0, len);
    return string.toUpperCase() === sub.toUpperCase();
  }

  function addMatches(result, search, wordlist, formatter) {
    if (isArray(wordlist)) {
      for (var i = 0; i < wordlist.length; i++)
        if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
    } else {
      for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
        var val = wordlist[word]
        if (!val || val === true)
          val = word
        else
          val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
        if (match(search, val)) result.push(formatter(val))
      }
    }
  }

  function cleanName(name) {
    // Get rid name from identifierQuote and preceding dot(.)
    if (name.charAt(0) == ".") {
      name = name.substr(1);
    }
    // replace doublicated identifierQuotes with single identifierQuotes
    // and remove single identifierQuotes
    var nameParts = name.split(identifierQuote+identifierQuote);
    for (var i = 0; i < nameParts.length; i++)
      nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
    return nameParts.join(identifierQuote);
  }

  function insertIdentifierQuotes(name) {
    var nameParts = getText(name).split(".");
    for (var i = 0; i < nameParts.length; i++)
      nameParts[i] = identifierQuote +
        // doublicate identifierQuotes
        nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
        identifierQuote;
    var escaped = nameParts.join(".");
    if (typeof name == "string") return escaped;
    name = shallowClone(name);
    name.text = escaped;
    return name;
  }

  function nameCompletion(cur, token, result, editor) {
    // Try to complete table, column names and return start position of completion
    var useIdentifierQuotes = false;
    var nameParts = [];
    var start = token.start;
    var cont = true;
    while (cont) {
      cont = (token.string.charAt(0) == ".");
      useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);

      start = token.start;
      nameParts.unshift(cleanName(token.string));

      token = editor.getTokenAt(Pos(cur.line, token.start));
      if (token.string == ".") {
        cont = true;
        token = editor.getTokenAt(Pos(cur.line, token.start));
      }
    }

    // Try to complete table names
    var string = nameParts.join(".");
    addMatches(result, string, tables, function(w) {
      return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
    });

    // Try to complete columns from defaultTable
    addMatches(result, string, defaultTable, function(w) {
      return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
    });

    // Try to complete columns
    string = nameParts.pop();
    var table = nameParts.join(".");

    var alias = false;
    var aliasTable = table;
    // Check if table is available. If not, find table by Alias
    if (!getTable(table)) {
      var oldTable = table;
      table = findTableByAlias(table, editor);
      if (table !== oldTable) alias = true;
    }

    var columns = getTable(table);
    if (columns && columns.columns)
      columns = columns.columns;

    if (columns) {
      addMatches(result, string, columns, function(w) {
        var tableInsert = table;
        if (alias == true) tableInsert = aliasTable;
        if (typeof w == "string") {
          w = tableInsert + "." + w;
        } else {
          w = shallowClone(w);
          w.text = tableInsert + "." + w.text;
        }
        return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
      });
    }

    return start;
  }

  function eachWord(lineText, f) {
    if (!lineText) return;
    var excepted = /[,;]/g;
    var words = lineText.split(" ");
    for (var i = 0; i < words.length; i++) {
      f(words[i]?words[i].replace(excepted, '') : '');
    }
  }

  function findTableByAlias(alias, editor) {
    var doc = editor.doc;
    var fullQuery = doc.getValue();
    var aliasUpperCase = alias.toUpperCase();
    var previousWord = "";
    var table = "";
    var separator = [];
    var validRange = {
      start: Pos(0, 0),
      end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
    };

    //add separator
    var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
    while(indexOfSeparator != -1) {
      separator.push(doc.posFromIndex(indexOfSeparator));
      indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
    }
    separator.unshift(Pos(0, 0));
    separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));

    //find valid range
    var prevItem = null;
    var current = editor.getCursor()
    for (var i = 0; i < separator.length; i++) {
      if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
        validRange = {start: prevItem, end: separator[i]};
        break;
      }
      prevItem = separator[i];
    }

    var query = doc.getRange(validRange.start, validRange.end, false);

    for (var i = 0; i < query.length; i++) {
      var lineText = query[i];
      eachWord(lineText, function(word) {
        var wordUpperCase = word.toUpperCase();
        if (wordUpperCase === aliasUpperCase && getTable(previousWord))
          table = previousWord;
        if (wordUpperCase !== CONS.ALIAS_KEYWORD)
          previousWord = word;
      });
      if (table) break;
    }
    return table;
  }

  CodeMirror.registerHelper("hint", "sql", function(editor, options) {
    tables = parseTables(options && options.tables)
    var defaultTableName = options && options.defaultTable;
    var disableKeywords = options && options.disableKeywords;
    defaultTable = defaultTableName && getTable(defaultTableName);
    keywords = getKeywords(editor);
    identifierQuote = getIdentifierQuote(editor);

    if (defaultTableName && !defaultTable)
      defaultTable = findTableByAlias(defaultTableName, editor);

    defaultTable = defaultTable || [];

    if (defaultTable.columns)
      defaultTable = defaultTable.columns;

    var cur = editor.getCursor();
    var result = [];
    var token = editor.getTokenAt(cur), start, end, search;
    if (token.end > cur.ch) {
      token.end = cur.ch;
      token.string = token.string.slice(0, cur.ch - token.start);
    }

    if (token.string.match(/^[.`"\w@]\w*$/)) {
      search = token.string;
      start = token.start;
      end = token.end;
    } else {
      start = end = cur.ch;
      search = "";
    }
    if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
      start = nameCompletion(cur, token, result, editor);
    } else {
      addMatches(result, search, tables, function(w) {return w;});
      addMatches(result, search, defaultTable, function(w) {return w;});
      if (!disableKeywords)
        addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
    }

    return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
  });
});
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}((function(t){"use strict";var e=t.Pos;t.registerHelper("hint","xml",(function(r,s){var n=s&&s.schemaInfo,a=s&&s.quoteChar||'"';if(n){var i=r.getCursor(),o=r.getTokenAt(i);o.end>i.ch&&(o.end=i.ch,o.string=o.string.slice(0,i.ch-o.start));var l=t.innerMode(r.getMode(),o.state);if("xml"==l.mode.name){var f,g,c=[],h=!1,p=/\btag\b/.test(o.type)&&!/>$/.test(o.string),u=p&&/^\w/.test(o.string);if(u){var d=r.getLine(i.line).slice(Math.max(0,o.start-2),o.start),m=/<\/$/.test(d)?"close":/<$/.test(d)?"open":null;m&&(g=o.start-("close"==m?2:1))}else p&&"<"==o.string?m="open":p&&"</"==o.string&&(m="close");if(!p&&!l.state.tagName||m){u&&(f=o.string),h=m;var v=l.state.context,y=v&&n[v.tagName],x=v?y&&y.children:n["!top"];if(x&&"close"!=m)for(var O=0;O<x.length;++O)f&&0!=x[O].lastIndexOf(f,0)||c.push("<"+x[O]);else if("close"!=m)for(var b in n)!n.hasOwnProperty(b)||"!top"==b||"!attrs"==b||f&&0!=b.lastIndexOf(f,0)||c.push("<"+b);v&&(!f||"close"==m&&0==v.tagName.lastIndexOf(f,0))&&c.push("</"+v.tagName+">")}else{var w=(y=n[l.state.tagName])&&y.attrs,I=n["!attrs"];if(!w&&!I)return;if(w){if(I){var P={};for(var A in I)I.hasOwnProperty(A)&&(P[A]=I[A]);for(var A in w)w.hasOwnProperty(A)&&(P[A]=w[A]);w=P}}else w=I;if("string"==o.type||"="==o.string){var M,N=(d=r.getRange(e(i.line,Math.max(0,i.ch-60)),e(i.line,"string"==o.type?o.start:o.end))).match(/([^\s\u00a0=<>\"\']+)=$/);if(!N||!w.hasOwnProperty(N[1])||!(M=w[N[1]]))return;if("function"==typeof M&&(M=M.call(this,r)),"string"==o.type){f=o.string;var $=0;/['"]/.test(o.string.charAt(0))&&(a=o.string.charAt(0),f=o.string.slice(1),$++);var C=o.string.length;/['"]/.test(o.string.charAt(C-1))&&(a=o.string.charAt(C-1),f=o.string.substr($,C-2)),h=!0}for(O=0;O<M.length;++O)f&&0!=M[O].lastIndexOf(f,0)||c.push(a+M[O]+a)}else for(var j in"attribute"==o.type&&(f=o.string,h=!0),w)!w.hasOwnProperty(j)||f&&0!=j.lastIndexOf(f,0)||c.push(j)}return{list:c,from:h?e(i.line,null==g?o.start:g):i,to:h?e(i.line,o.end):i}}}}))}));!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}((function(t){"use strict";function i(t,i){this.cm=t,this.options=i,this.widget=null,this.debounce=0,this.tick=0,this.startPos=this.cm.getCursor("start"),this.startLen=this.cm.getLine(this.startPos.line).length-this.cm.getSelection().length;var e=this;t.on("cursorActivity",this.activityFunc=function(){e.cursorActivity()})}t.showHint=function(t,i,e){if(!i)return t.showHint(e);e&&e.async&&(i.async=!0);var n={hint:i};if(e)for(var o in e)n[o]=e[o];return t.showHint(n)},t.defineExtension("showHint",(function(e){e=function(t,i,e){var n=t.options.hintOptions,o={};for(var s in h)o[s]=h[s];if(n)for(var s in n)void 0!==n[s]&&(o[s]=n[s]);if(e)for(var s in e)void 0!==e[s]&&(o[s]=e[s]);o.hint.resolve&&(o.hint=o.hint.resolve(t,i));return o}(this,this.getCursor("start"),e);var n=this.listSelections();if(!(n.length>1)){if(this.somethingSelected()){if(!e.hint.supportsSelection)return;for(var o=0;o<n.length;o++)if(n[o].head.line!=n[o].anchor.line)return}this.state.completionActive&&this.state.completionActive.close();var s=this.state.completionActive=new i(this,e);s.options.hint&&(t.signal(this,"startCompletion",this),s.update(!0))}}));var e=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},n=window.cancelAnimationFrame||clearTimeout;function o(t){return"string"==typeof t?t:t.text}function s(t,i){for(;i&&i!=t;){if("LI"===i.nodeName.toUpperCase()&&i.parentNode==t)return i;i=i.parentNode}}function c(i,e){this.completion=i,this.data=e,this.picked=!1;var n=this,c=i.cm,r=this.hints=document.createElement("ul");r.className="CodeMirror-hints",this.selectedHint=e.selectedHint||0;for(var h=e.list,l=0;l<h.length;++l){var a=r.appendChild(document.createElement("li")),u=h[l],f="CodeMirror-hint"+(l!=this.selectedHint?"":" CodeMirror-hint-active");null!=u.className&&(f=u.className+" "+f),a.className=f,u.render?u.render(a,e,u):a.appendChild(document.createTextNode(u.displayText||o(u))),a.hintId=l}var d=c.cursorCoords(i.options.alignWithWord?e.from:null),p=d.left,m=d.bottom,g=!0;r.style.left=p+"px",r.style.top=m+"px";var v=window.innerWidth||Math.max(document.body.offsetWidth,document.documentElement.offsetWidth),y=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(i.options.container||document.body).appendChild(r);var w=r.getBoundingClientRect(),C=w.bottom-y,H=r.scrollHeight>r.clientHeight+1,k=c.getScrollInfo();if(C>0){var b=w.bottom-w.top;if(d.top-(d.bottom-w.top)-b>0)r.style.top=(m=d.top-b)+"px",g=!1;else if(b>y){r.style.height=y-5+"px",r.style.top=(m=d.bottom-w.top)+"px";var x=c.getCursor();e.from.ch!=x.ch&&(d=c.cursorCoords(x),r.style.left=(p=d.left)+"px",w=r.getBoundingClientRect())}}var A,S=w.right-v;if(S>0&&(w.right-w.left>v&&(r.style.width=v-5+"px",S-=w.right-w.left-v),r.style.left=(p=d.left-S)+"px"),H)for(var M=r.firstChild;M;M=M.nextSibling)M.style.paddingRight=c.display.nativeBarWidth+"px";(c.addKeyMap(this.keyMap=function(t,i){var e={Up:function(){i.moveFocus(-1)},Down:function(){i.moveFocus(1)},PageUp:function(){i.moveFocus(1-i.menuSize(),!0)},PageDown:function(){i.moveFocus(i.menuSize()-1,!0)},Home:function(){i.setFocus(0)},End:function(){i.setFocus(i.length-1)},Enter:i.pick,Tab:i.pick,Esc:i.close},n=t.options.customKeys,o=n?{}:e;function s(t,n){var s;s="string"!=typeof n?function(t){return n(t,i)}:e.hasOwnProperty(n)?e[n]:n,o[t]=s}if(n)for(var c in n)n.hasOwnProperty(c)&&s(c,n[c]);var r=t.options.extraKeys;if(r)for(var c in r)r.hasOwnProperty(c)&&s(c,r[c]);return o}(i,{moveFocus:function(t,i){n.changeActive(n.selectedHint+t,i)},setFocus:function(t){n.changeActive(t)},menuSize:function(){return n.screenAmount()},length:h.length,close:function(){i.close()},pick:function(){n.pick()},data:e})),i.options.closeOnUnfocus)&&(c.on("blur",this.onBlur=function(){A=setTimeout((function(){i.close()}),100)}),c.on("focus",this.onFocus=function(){clearTimeout(A)}));return c.on("scroll",this.onScroll=function(){var t=c.getScrollInfo(),e=c.getWrapperElement().getBoundingClientRect(),n=m+k.top-t.top,o=n-(window.pageYOffset||(document.documentElement||document.body).scrollTop);if(g||(o+=r.offsetHeight),o<=e.top||o>=e.bottom)return i.close();r.style.top=n+"px",r.style.left=p+k.left-t.left+"px"}),t.on(r,"dblclick",(function(t){var i=s(r,t.target||t.srcElement);i&&null!=i.hintId&&(n.changeActive(i.hintId),n.pick())})),t.on(r,"click",(function(t){var e=s(r,t.target||t.srcElement);e&&null!=e.hintId&&(n.changeActive(e.hintId),i.options.completeOnSingleClick&&n.pick())})),t.on(r,"mousedown",(function(){setTimeout((function(){c.focus()}),20)})),t.signal(e,"select",h[0],r.firstChild),!0}function r(t,i,e,n){if(t.async)t(i,n,e);else{var o=t(i,e);o&&o.then?o.then(n):n(o)}}i.prototype={close:function(){this.active()&&(this.cm.state.completionActive=null,this.tick=null,this.cm.off("cursorActivity",this.activityFunc),this.widget&&this.data&&t.signal(this.data,"close"),this.widget&&this.widget.close(),t.signal(this.cm,"endCompletion",this.cm))},active:function(){return this.cm.state.completionActive==this},pick:function(i,e){var n=i.list[e];n.hint?n.hint(this.cm,i,n):this.cm.replaceRange(o(n),n.from||i.from,n.to||i.to,"complete"),t.signal(i,"pick",n),this.close()},cursorActivity:function(){this.debounce&&(n(this.debounce),this.debounce=0);var t=this.cm.getCursor(),i=this.cm.getLine(t.line);if(t.line!=this.startPos.line||i.length-t.ch!=this.startLen-this.startPos.ch||t.ch<this.startPos.ch||this.cm.somethingSelected()||t.ch&&this.options.closeCharacters.test(i.charAt(t.ch-1)))this.close();else{var o=this;this.debounce=e((function(){o.update()})),this.widget&&this.widget.disable()}},update:function(t){if(null!=this.tick){var i=this,e=++this.tick;r(this.options.hint,this.cm,this.options,(function(n){i.tick==e&&i.finishUpdate(n,t)}))}},finishUpdate:function(i,e){this.data&&t.signal(this.data,"update");var n,o,s=this.widget&&this.widget.picked||e&&this.options.completeSingle;(this.widget&&this.widget.close(),i&&this.data&&(n=this.data,o=i,t.cmpPos(o.from,n.from)>0&&n.to.ch-n.from.ch!=o.to.ch-o.from.ch))||(this.data=i,i&&i.list.length&&(s&&1==i.list.length?this.pick(i,0):(this.widget=new c(this,i),t.signal(i,"shown"))))}},c.prototype={close:function(){if(this.completion.widget==this){this.completion.widget=null,this.hints.parentNode.removeChild(this.hints),this.completion.cm.removeKeyMap(this.keyMap);var t=this.completion.cm;this.completion.options.closeOnUnfocus&&(t.off("blur",this.onBlur),t.off("focus",this.onFocus)),t.off("scroll",this.onScroll)}},disable:function(){this.completion.cm.removeKeyMap(this.keyMap);var t=this;this.keyMap={Enter:function(){t.picked=!0}},this.completion.cm.addKeyMap(this.keyMap)},pick:function(){this.completion.pick(this.data,this.selectedHint)},changeActive:function(i,e){if(i>=this.data.list.length?i=e?this.data.list.length-1:0:i<0&&(i=e?0:this.data.list.length-1),this.selectedHint!=i){var n=this.hints.childNodes[this.selectedHint];n.className=n.className.replace(" CodeMirror-hint-active",""),(n=this.hints.childNodes[this.selectedHint=i]).className+=" CodeMirror-hint-active",n.offsetTop<this.hints.scrollTop?this.hints.scrollTop=n.offsetTop-3:n.offsetTop+n.offsetHeight>this.hints.scrollTop+this.hints.clientHeight&&(this.hints.scrollTop=n.offsetTop+n.offsetHeight-this.hints.clientHeight+3),t.signal(this.data,"select",this.data.list[this.selectedHint],n)}},screenAmount:function(){return Math.floor(this.hints.clientHeight/this.hints.firstChild.offsetHeight)||1}},t.registerHelper("hint","auto",{resolve:function(i,e){var n,o=i.getHelpers(e,"hint");if(o.length){var s=function(t,i,e){var n=function(t,i){if(!t.somethingSelected())return i;for(var e=[],n=0;n<i.length;n++)i[n].supportsSelection&&e.push(i[n]);return e}(t,o);!function o(s){if(s==n.length)return i(null);r(n[s],t,e,(function(t){t&&t.list.length>0?i(t):o(s+1)}))}(0)};return s.async=!0,s.supportsSelection=!0,s}return(n=i.getHelper(i.getCursor(),"hintWords"))?function(i){return t.hint.fromList(i,{words:n})}:t.hint.anyword?function(i,e){return t.hint.anyword(i,e)}:function(){}}}),t.registerHelper("hint","fromList",(function(i,e){var n=i.getCursor(),o=i.getTokenAt(n),s=t.Pos(n.line,o.end);if(o.string&&/\w/.test(o.string[o.string.length-1]))var c=o.string,r=t.Pos(n.line,o.start);else c="",r=s;for(var h=[],l=0;l<e.words.length;l++){var a=e.words[l];a.slice(0,c.length)==c&&h.push(a)}if(h.length)return{list:h,from:r,to:s}})),t.commands.autocomplete=t.showHint;var h={hint:t.hint.auto,completeSingle:!0,alignWithWord:!0,closeCharacters:/[\s()\[\]{};:>,]/,closeOnUnfocus:!0,completeOnSingleClick:!0,container:null,customKeys:null,extraKeys:null};t.defineOption("hintOptions",null)}));!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("../../mode/sql/sql")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../../mode/sql/sql"],t):t(CodeMirror)}((function(t){"use strict";var e,r,n,o,i=";",s="AS",a=t.Pos,u=t.cmpPos;function l(t){return"[object Array]"==Object.prototype.toString.call(t)}function f(t){return"string"==typeof t?t:t.text}function c(t,e){return l(e)&&(e={columns:e}),e.text||(e.text=t),e}function p(t){return e[t.toUpperCase()]}function g(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function d(t,e){var r=t.length,n=f(e).substr(0,r);return t.toUpperCase()===n.toUpperCase()}function v(t,e,r,n){if(l(r))for(var o=0;o<r.length;o++)d(e,r[o])&&t.push(n(r[o]));else for(var i in r)if(r.hasOwnProperty(i)){var s=r[i];d(e,s=s&&!0!==s?s.displayText?{text:s.text,displayText:s.displayText}:s.text:i)&&t.push(n(s))}}function h(t){"."==t.charAt(0)&&(t=t.substr(1));for(var e=t.split(o+o),r=0;r<e.length;r++)e[r]=e[r].replace(new RegExp(o,"g"),"");return e.join(o)}function x(t){for(var e=f(t).split("."),r=0;r<e.length;r++)e[r]=o+e[r].replace(new RegExp(o,"g"),o+o)+o;var n=e.join(".");return"string"==typeof t?n:((t=g(t)).text=n,t)}function m(t,e){if(t)for(var r=/[,;]/g,n=t.split(" "),o=0;o<n.length;o++)e(n[o]?n[o].replace(r,""):"")}function y(t,e){for(var r=e.doc,n=r.getValue(),o=t.toUpperCase(),l="",f="",c=[],g={start:a(0,0),end:a(e.lastLine(),e.getLineHandle(e.lastLine()).length)},d=n.indexOf(i);-1!=d;)c.push(r.posFromIndex(d)),d=n.indexOf(i,d+1);c.unshift(a(0,0)),c.push(a(e.lastLine(),e.getLineHandle(e.lastLine()).text.length));for(var v=null,h=e.getCursor(),x=0;x<c.length;x++){if((null==v||u(h,v)>0)&&u(h,c[x])<=0){g={start:v,end:c[x]};break}v=c[x]}var y=r.getRange(g.start,g.end,!1);for(x=0;x<y.length;x++){if(m(y[x],(function(t){var e=t.toUpperCase();e===o&&p(l)&&(f=l),e!==s&&(l=t)})),f)break}return f}t.registerHelper("hint","sql",(function(i,s){e=function(t){var e={};if(l(t))for(var r=t.length-1;r>=0;r--){var n=t[r];e[f(n).toUpperCase()]=c(f(n),n)}else if(t)for(var o in t)e[o.toUpperCase()]=c(o,t[o]);return e}(s&&s.tables);var u=s&&s.defaultTable,d=s&&s.disableKeywords;r=u&&p(u),n=function(e){var r=e.doc.modeOption;return"sql"===r&&(r="text/x-sql"),t.resolveMode(r).keywords}(i),o=function(e){var r=e.doc.modeOption;return"sql"===r&&(r="text/x-sql"),t.resolveMode(r).identifierQuote||"`"}(i),u&&!r&&(r=y(u,i)),(r=r||[]).columns&&(r=r.columns);var m,b,q,C=i.getCursor(),A=[],j=i.getTokenAt(C);return j.end>C.ch&&(j.end=C.ch,j.string=j.string.slice(0,C.ch-j.start)),j.string.match(/^[.`"\w@]\w*$/)?(q=j.string,m=j.start,b=j.end):(m=b=C.ch,q=""),"."==q.charAt(0)||q.charAt(0)==o?m=function(t,n,i,s){for(var u=!1,l=[],f=n.start,c=!0;c;)c="."==n.string.charAt(0),u=u||n.string.charAt(0)==o,f=n.start,l.unshift(h(n.string)),"."==(n=s.getTokenAt(a(t.line,n.start))).string&&(c=!0,n=s.getTokenAt(a(t.line,n.start)));var d=l.join(".");v(i,d,e,(function(t){return u?x(t):t})),v(i,d,r,(function(t){return u?x(t):t})),d=l.pop();var m=l.join("."),b=!1,q=m;if(!p(m)){var C=m;(m=y(m,s))!==C&&(b=!0)}var A=p(m);return A&&A.columns&&(A=A.columns),A&&v(i,d,A,(function(t){var e=m;return 1==b&&(e=q),"string"==typeof t?t=e+"."+t:(t=g(t)).text=e+"."+t.text,u?x(t):t})),f}(C,j,A,i):(v(A,q,e,(function(t){return t})),v(A,q,r,(function(t){return t})),d||v(A,q,n,(function(t){return t.toUpperCase()}))),{list:A,from:a(C.line,m),to:a(C.line,b)}}))}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";

  // This is the old interface, kept around for now to stay
  // backwards-compatible.
  CodeMirror.showHint = function(cm, getHints, options) {
    if (!getHints) return cm.showHint(options);
    if (options && options.async) getHints.async = true;
    var newOpts = {hint: getHints};
    if (options) for (var prop in options) newOpts[prop] = options[prop];
    return cm.showHint(newOpts);
  };

  CodeMirror.defineExtension("showHint", function(options) {
    options = parseOptions(this, this.getCursor("start"), options);
    var selections = this.listSelections()
    if (selections.length > 1) return;
    // By default, don't allow completion when something is selected.
    // A hint function can have a `supportsSelection` property to
    // indicate that it can handle selections.
    if (this.somethingSelected()) {
      if (!options.hint.supportsSelection) return;
      // Don't try with cross-line selections
      for (var i = 0; i < selections.length; i++)
        if (selections[i].head.line != selections[i].anchor.line) return;
    }

    if (this.state.completionActive) this.state.completionActive.close();
    var completion = this.state.completionActive = new Completion(this, options);
    if (!completion.options.hint) return;

    CodeMirror.signal(this, "startCompletion", this);
    completion.update(true);
  });

  function Completion(cm, options) {
    this.cm = cm;
    this.options = options;
    this.widget = null;
    this.debounce = 0;
    this.tick = 0;
    this.startPos = this.cm.getCursor("start");
    this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;

    var self = this;
    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
  }

  var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
    return setTimeout(fn, 1000/60);
  };
  var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;

  Completion.prototype = {
    close: function() {
      if (!this.active()) return;
      this.cm.state.completionActive = null;
      this.tick = null;
      this.cm.off("cursorActivity", this.activityFunc);

      if (this.widget && this.data) CodeMirror.signal(this.data, "close");
      if (this.widget) this.widget.close();
      CodeMirror.signal(this.cm, "endCompletion", this.cm);
    },

    active: function() {
      return this.cm.state.completionActive == this;
    },

    pick: function(data, i) {
      var completion = data.list[i];
      if (completion.hint) completion.hint(this.cm, data, completion);
      else this.cm.replaceRange(getText(completion), completion.from || data.from,
                                completion.to || data.to, "complete");
      CodeMirror.signal(data, "pick", completion);
      this.close();
    },

    cursorActivity: function() {
      if (this.debounce) {
        cancelAnimationFrame(this.debounce);
        this.debounce = 0;
      }

      var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
      if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
          pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
        this.close();
      } else {
        var self = this;
        this.debounce = requestAnimationFrame(function() {self.update();});
        if (this.widget) this.widget.disable();
      }
    },

    update: function(first) {
      if (this.tick == null) return
      var self = this, myTick = ++this.tick
      fetchHints(this.options.hint, this.cm, this.options, function(data) {
        if (self.tick == myTick) self.finishUpdate(data, first)
      })
    },

    finishUpdate: function(data, first) {
      if (this.data) CodeMirror.signal(this.data, "update");

      var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);
      if (this.widget) this.widget.close();

      if (data && this.data && isNewCompletion(this.data, data)) return;
      this.data = data;

      if (data && data.list.length) {
        if (picked && data.list.length == 1) {
          this.pick(data, 0);
        } else {
          this.widget = new Widget(this, data);
          CodeMirror.signal(data, "shown");
        }
      }
    }
  };

  function isNewCompletion(old, nw) {
    var moved = CodeMirror.cmpPos(nw.from, old.from)
    return moved > 0 && old.to.ch - old.from.ch != nw.to.ch - nw.from.ch
  }

  function parseOptions(cm, pos, options) {
    var editor = cm.options.hintOptions;
    var out = {};
    for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
    if (editor) for (var prop in editor)
      if (editor[prop] !== undefined) out[prop] = editor[prop];
    if (options) for (var prop in options)
      if (options[prop] !== undefined) out[prop] = options[prop];
    if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)
    return out;
  }

  function getText(completion) {
    if (typeof completion == "string") return completion;
    else return completion.text;
  }

  function buildKeyMap(completion, handle) {
    var baseMap = {
      Up: function() {handle.moveFocus(-1);},
      Down: function() {handle.moveFocus(1);},
      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
      Home: function() {handle.setFocus(0);},
      End: function() {handle.setFocus(handle.length - 1);},
      Enter: handle.pick,
      Tab: handle.pick,
      Esc: handle.close
    };
    var custom = completion.options.customKeys;
    var ourMap = custom ? {} : baseMap;
    function addBinding(key, val) {
      var bound;
      if (typeof val != "string")
        bound = function(cm) { return val(cm, handle); };
      // This mechanism is deprecated
      else if (baseMap.hasOwnProperty(val))
        bound = baseMap[val];
      else
        bound = val;
      ourMap[key] = bound;
    }
    if (custom)
      for (var key in custom) if (custom.hasOwnProperty(key))
        addBinding(key, custom[key]);
    var extra = completion.options.extraKeys;
    if (extra)
      for (var key in extra) if (extra.hasOwnProperty(key))
        addBinding(key, extra[key]);
    return ourMap;
  }

  function getHintElement(hintsElement, el) {
    while (el && el != hintsElement) {
      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
      el = el.parentNode;
    }
  }

  function Widget(completion, data) {
    this.completion = completion;
    this.data = data;
    this.picked = false;
    var widget = this, cm = completion.cm;

    var hints = this.hints = document.createElement("ul");
    hints.className = "CodeMirror-hints";
    this.selectedHint = data.selectedHint || 0;

    var completions = data.list;
    for (var i = 0; i < completions.length; ++i) {
      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
      if (cur.className != null) className = cur.className + " " + className;
      elt.className = className;
      if (cur.render) cur.render(elt, data, cur);
      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
      elt.hintId = i;
    }

    var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
    var left = pos.left, top = pos.bottom, below = true;
    hints.style.left = left + "px";
    hints.style.top = top + "px";
    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
    (completion.options.container || document.body).appendChild(hints);
    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
    var scrolls = hints.scrollHeight > hints.clientHeight + 1
    var startScroll = cm.getScrollInfo();

    if (overlapY > 0) {
      var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
      if (curTop - height > 0) { // Fits above cursor
        hints.style.top = (top = pos.top - height) + "px";
        below = false;
      } else if (height > winH) {
        hints.style.height = (winH - 5) + "px";
        hints.style.top = (top = pos.bottom - box.top) + "px";
        var cursor = cm.getCursor();
        if (data.from.ch != cursor.ch) {
          pos = cm.cursorCoords(cursor);
          hints.style.left = (left = pos.left) + "px";
          box = hints.getBoundingClientRect();
        }
      }
    }
    var overlapX = box.right - winW;
    if (overlapX > 0) {
      if (box.right - box.left > winW) {
        hints.style.width = (winW - 5) + "px";
        overlapX -= (box.right - box.left) - winW;
      }
      hints.style.left = (left = pos.left - overlapX) + "px";
    }
    if (scrolls) for (var node = hints.firstChild; node; node = node.nextSibling)
      node.style.paddingRight = cm.display.nativeBarWidth + "px"

    cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
      setFocus: function(n) { widget.changeActive(n); },
      menuSize: function() { return widget.screenAmount(); },
      length: completions.length,
      close: function() { completion.close(); },
      pick: function() { widget.pick(); },
      data: data
    }));

    if (completion.options.closeOnUnfocus) {
      var closingOnBlur;
      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
    }

    cm.on("scroll", this.onScroll = function() {
      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
      var newTop = top + startScroll.top - curScroll.top;
      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
      if (!below) point += hints.offsetHeight;
      if (point <= editor.top || point >= editor.bottom) return completion.close();
      hints.style.top = newTop + "px";
      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
    });

    CodeMirror.on(hints, "dblclick", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
    });

    CodeMirror.on(hints, "click", function(e) {
      var t = getHintElement(hints, e.target || e.srcElement);
      if (t && t.hintId != null) {
        widget.changeActive(t.hintId);
        if (completion.options.completeOnSingleClick) widget.pick();
      }
    });

    CodeMirror.on(hints, "mousedown", function() {
      setTimeout(function(){cm.focus();}, 20);
    });

    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
    return true;
  }

  Widget.prototype = {
    close: function() {
      if (this.completion.widget != this) return;
      this.completion.widget = null;
      this.hints.parentNode.removeChild(this.hints);
      this.completion.cm.removeKeyMap(this.keyMap);

      var cm = this.completion.cm;
      if (this.completion.options.closeOnUnfocus) {
        cm.off("blur", this.onBlur);
        cm.off("focus", this.onFocus);
      }
      cm.off("scroll", this.onScroll);
    },

    disable: function() {
      this.completion.cm.removeKeyMap(this.keyMap);
      var widget = this;
      this.keyMap = {Enter: function() { widget.picked = true; }};
      this.completion.cm.addKeyMap(this.keyMap);
    },

    pick: function() {
      this.completion.pick(this.data, this.selectedHint);
    },

    changeActive: function(i, avoidWrap) {
      if (i >= this.data.list.length)
        i = avoidWrap ? this.data.list.length - 1 : 0;
      else if (i < 0)
        i = avoidWrap ? 0  : this.data.list.length - 1;
      if (this.selectedHint == i) return;
      var node = this.hints.childNodes[this.selectedHint];
      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
      node = this.hints.childNodes[this.selectedHint = i];
      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
      if (node.offsetTop < this.hints.scrollTop)
        this.hints.scrollTop = node.offsetTop - 3;
      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
    },

    screenAmount: function() {
      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
    }
  };

  function applicableHelpers(cm, helpers) {
    if (!cm.somethingSelected()) return helpers
    var result = []
    for (var i = 0; i < helpers.length; i++)
      if (helpers[i].supportsSelection) result.push(helpers[i])
    return result
  }

  function fetchHints(hint, cm, options, callback) {
    if (hint.async) {
      hint(cm, callback, options)
    } else {
      var result = hint(cm, options)
      if (result && result.then) result.then(callback)
      else callback(result)
    }
  }

  function resolveAutoHints(cm, pos) {
    var helpers = cm.getHelpers(pos, "hint"), words
    if (helpers.length) {
      var resolved = function(cm, callback, options) {
        var app = applicableHelpers(cm, helpers);
        function run(i) {
          if (i == app.length) return callback(null)
          fetchHints(app[i], cm, options, function(result) {
            if (result && result.list.length > 0) callback(result)
            else run(i + 1)
          })
        }
        run(0)
      }
      resolved.async = true
      resolved.supportsSelection = true
      return resolved
    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
      return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }
    } else if (CodeMirror.hint.anyword) {
      return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }
    } else {
      return function() {}
    }
  }

  CodeMirror.registerHelper("hint", "auto", {
    resolve: resolveAutoHints
  });

  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
    var to = CodeMirror.Pos(cur.line, token.end);
    if (token.string && /\w/.test(token.string[token.string.length - 1])) {
      var term = token.string, from = CodeMirror.Pos(cur.line, token.start);
    } else {
      var term = "", from = to;
    }
    var found = [];
    for (var i = 0; i < options.words.length; i++) {
      var word = options.words[i];
      if (word.slice(0, term.length) == term)
        found.push(word);
    }

    if (found.length) return {list: found, from: from, to: to};
  });

  CodeMirror.commands.autocomplete = CodeMirror.showHint;

  var defaultOptions = {
    hint: CodeMirror.hint.auto,
    completeSingle: true,
    alignWithWord: true,
    closeCharacters: /[\s()\[\]{};:>,]/,
    closeOnUnfocus: true,
    completeOnSingleClick: true,
    container: null,
    customKeys: null,
    extraKeys: null
  };

  CodeMirror.defineOption("hintOptions", null);
});
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}((function(t){var e=t.Pos;function r(t,e){for(var r=0,n=t.length;r<n;++r)e(t[r])}function n(r,n,i,o){var s=r.getCursor(),a=i(r,s);if(!/\b(?:string|comment)\b/.test(a.type)){a.state=t.innerMode(r.getMode(),a.state).state,/^[\w$_]*$/.test(a.string)?a.end>s.ch&&(a.end=s.ch,a.string=a.string.slice(0,s.ch-a.start)):a={start:s.ch,end:s.ch,string:"",state:a.state,type:"."==a.string?"property":null};for(var f=a;"property"==f.type;){if("."!=(f=i(r,e(s.line,f.start))).string)return;if(f=i(r,e(s.line,f.start)),!l)var l=[];l.push(f)}return{list:c(a,l,n,o),from:e(s.line,a.start),to:e(s.line,a.end)}}}function i(t,e){var r=t.getTokenAt(e);return e.ch==r.start+1&&"."==r.string.charAt(0)?(r.end=r.start,r.string=".",r.type="property"):/^\.[\w$_]*$/.test(r.string)&&(r.type="property",r.start++,r.string=r.string.replace(/\./,"")),r}t.registerHelper("hint","javascript",(function(t,e){return n(t,f,(function(t,e){return t.getTokenAt(e)}),e)})),t.registerHelper("hint","coffeescript",(function(t,e){return n(t,l,i,e)}));var o="charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight toUpperCase toLowerCase split concat match replace search".split(" "),s="length concat join splice push pop shift unshift slice reverse sort indexOf lastIndexOf every some filter forEach map reduce reduceRight ".split(" "),a="prototype apply call bind".split(" "),f="break case catch continue debugger default delete do else false finally for function if in instanceof new null return switch throw true try typeof var void while with".split(" "),l="and break catch class continue delete do else extends false finally for if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes".split(" ");function c(t,e,n,i){var f=[],l=t.string,c=i&&i.globalScope||window;function p(t){0!=t.lastIndexOf(l,0)||function(t,e){if(!Array.prototype.indexOf){for(var r=t.length;r--;)if(t[r]===e)return!0;return!1}return-1!=t.indexOf(e)}(f,t)||f.push(t)}function u(t){"string"==typeof t?r(o,p):t instanceof Array?r(s,p):t instanceof Function&&r(a,p),function(t,e){if(Object.getOwnPropertyNames&&Object.getPrototypeOf)for(var r=t;r;r=Object.getPrototypeOf(r))Object.getOwnPropertyNames(r).forEach(e);else for(var n in t)e(n)}(t,p)}if(e&&e.length){var g,d=e.pop();for(d.type&&0===d.type.indexOf("variable")?(i&&i.additionalContext&&(g=i.additionalContext[d.string]),i&&!1===i.useGlobalScope||(g=g||c[d.string])):"string"==d.type?g="":"atom"==d.type?g=1:"function"==d.type&&(null==c.jQuery||"$"!=d.string&&"jQuery"!=d.string||"function"!=typeof c.jQuery?null!=c._&&"_"==d.string&&"function"==typeof c._&&(g=c._()):g=c.jQuery());null!=g&&e.length;)g=g[e.pop().string];null!=g&&u(g)}else{for(var y=t.state.localVars;y;y=y.next)p(y.name);for(y=t.state.globalVars;y;y=y.next)p(y.name);i&&!1===i.useGlobalScope||u(c),r(n,p)}return f}}));!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("../../mode/css/css")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../../mode/css/css"],e):e(CodeMirror)}((function(e){"use strict";var r={link:1,visited:1,active:1,hover:1,focus:1,"first-letter":1,"first-line":1,"first-child":1,before:1,after:1,lang:1};e.registerHelper("hint","css",(function(t){var o=t.getCursor(),s=t.getTokenAt(o),i=e.innerMode(t.getMode(),s.state);if("css"==i.mode.name){if("keyword"==s.type&&0=="!important".indexOf(s.string))return{list:["!important"],from:e.Pos(o.line,s.start),to:e.Pos(o.line,s.end)};var n=s.start,a=o.ch,d=s.string.slice(0,a-n);/[^\w$_-]/.test(d)&&(d="",n=a=o.ch);var c=e.resolveMode("text/css"),f=[],l=i.state.state;return"pseudo"==l||"variable-3"==s.type?p(r):"block"==l||"maybeprop"==l?p(c.propertyKeywords):"prop"==l||"parens"==l||"at"==l||"params"==l?(p(c.valueKeywords),p(c.colorKeywords)):"media"!=l&&"media_parens"!=l||(p(c.mediaTypes),p(c.mediaFeatures)),f.length?{list:f,from:e.Pos(o.line,n),to:e.Pos(o.line,a)}:void 0}function p(e){for(var r in e)d&&0!=r.lastIndexOf(d,0)||f.push(r)}}))}));!function(l){"object"==typeof exports&&"object"==typeof module?l(require("../../lib/codemirror"),require("./xml-hint")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./xml-hint"],l):l(CodeMirror)}((function(l){"use strict";var t="ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" "),e=["_blank","_self","_top","_parent"],a=["ascii","utf-8","utf-16","latin1","latin1"],n=["get","post","put","delete"],r=["application/x-www-form-urlencoded","multipart/form-data","text/plain"],o=["all","screen","print","embossed","braille","handheld","print","projection","screen","tty","tv","speech","3d-glasses","resolution [>][<][=] [X]","device-aspect-ratio: X/Y","orientation:portrait","orientation:landscape","device-height: [X]","device-width: [X]"],s={attrs:{}},u={a:{attrs:{href:null,ping:null,type:null,media:o,target:e,hreflang:t}},abbr:s,acronym:s,address:s,applet:s,area:{attrs:{alt:null,coords:null,href:null,target:null,ping:null,media:o,hreflang:t,type:null,shape:["default","rect","circle","poly"]}},article:s,aside:s,audio:{attrs:{src:null,mediagroup:null,crossorigin:["anonymous","use-credentials"],preload:["none","metadata","auto"],autoplay:["","autoplay"],loop:["","loop"],controls:["","controls"]}},b:s,base:{attrs:{href:null,target:e}},basefont:s,bdi:s,bdo:s,big:s,blockquote:{attrs:{cite:null}},body:s,br:s,button:{attrs:{form:null,formaction:null,name:null,value:null,autofocus:["","autofocus"],disabled:["","autofocus"],formenctype:r,formmethod:n,formnovalidate:["","novalidate"],formtarget:e,type:["submit","reset","button"]}},canvas:{attrs:{width:null,height:null}},caption:s,center:s,cite:s,code:s,col:{attrs:{span:null}},colgroup:{attrs:{span:null}},command:{attrs:{type:["command","checkbox","radio"],label:null,icon:null,radiogroup:null,command:null,title:null,disabled:["","disabled"],checked:["","checked"]}},data:{attrs:{value:null}},datagrid:{attrs:{disabled:["","disabled"],multiple:["","multiple"]}},datalist:{attrs:{data:null}},dd:s,del:{attrs:{cite:null,datetime:null}},details:{attrs:{open:["","open"]}},dfn:s,dir:s,div:s,dl:s,dt:s,em:s,embed:{attrs:{src:null,type:null,width:null,height:null}},eventsource:{attrs:{src:null}},fieldset:{attrs:{disabled:["","disabled"],form:null,name:null}},figcaption:s,figure:s,font:s,footer:s,form:{attrs:{action:null,name:null,"accept-charset":a,autocomplete:["on","off"],enctype:r,method:n,novalidate:["","novalidate"],target:e}},frame:s,frameset:s,h1:s,h2:s,h3:s,h4:s,h5:s,h6:s,head:{attrs:{},children:["title","base","link","style","meta","script","noscript","command"]},header:s,hgroup:s,hr:s,html:{attrs:{manifest:null},children:["head","body"]},i:s,iframe:{attrs:{src:null,srcdoc:null,name:null,width:null,height:null,sandbox:["allow-top-navigation","allow-same-origin","allow-forms","allow-scripts"],seamless:["","seamless"]}},img:{attrs:{alt:null,src:null,ismap:null,usemap:null,width:null,height:null,crossorigin:["anonymous","use-credentials"]}},input:{attrs:{alt:null,dirname:null,form:null,formaction:null,height:null,list:null,max:null,maxlength:null,min:null,name:null,pattern:null,placeholder:null,size:null,src:null,step:null,value:null,width:null,accept:["audio/*","video/*","image/*"],autocomplete:["on","off"],autofocus:["","autofocus"],checked:["","checked"],disabled:["","disabled"],formenctype:r,formmethod:n,formnovalidate:["","novalidate"],formtarget:e,multiple:["","multiple"],readonly:["","readonly"],required:["","required"],type:["hidden","text","search","tel","url","email","password","datetime","date","month","week","time","datetime-local","number","range","color","checkbox","radio","file","submit","image","reset","button"]}},ins:{attrs:{cite:null,datetime:null}},kbd:s,keygen:{attrs:{challenge:null,form:null,name:null,autofocus:["","autofocus"],disabled:["","disabled"],keytype:["RSA"]}},label:{attrs:{for:null,form:null}},legend:s,li:{attrs:{value:null}},link:{attrs:{href:null,type:null,hreflang:t,media:o,sizes:["all","16x16","16x16 32x32","16x16 32x32 64x64"]}},map:{attrs:{name:null}},mark:s,menu:{attrs:{label:null,type:["list","context","toolbar"]}},meta:{attrs:{content:null,charset:a,name:["viewport","application-name","author","description","generator","keywords"],"http-equiv":["content-language","content-type","default-style","refresh"]}},meter:{attrs:{value:null,min:null,low:null,high:null,max:null,optimum:null}},nav:s,noframes:s,noscript:s,object:{attrs:{data:null,type:null,name:null,usemap:null,form:null,width:null,height:null,typemustmatch:["","typemustmatch"]}},ol:{attrs:{reversed:["","reversed"],start:null,type:["1","a","A","i","I"]}},optgroup:{attrs:{disabled:["","disabled"],label:null}},option:{attrs:{disabled:["","disabled"],label:null,selected:["","selected"],value:null}},output:{attrs:{for:null,form:null,name:null}},p:s,param:{attrs:{name:null,value:null}},pre:s,progress:{attrs:{value:null,max:null}},q:{attrs:{cite:null}},rp:s,rt:s,ruby:s,s:s,samp:s,script:{attrs:{type:["text/javascript"],src:null,async:["","async"],defer:["","defer"],charset:a}},section:s,select:{attrs:{form:null,name:null,size:null,autofocus:["","autofocus"],disabled:["","disabled"],multiple:["","multiple"]}},small:s,source:{attrs:{src:null,type:null,media:null}},span:s,strike:s,strong:s,style:{attrs:{type:["text/css"],media:o,scoped:null}},sub:s,summary:s,sup:s,table:s,tbody:s,td:{attrs:{colspan:null,rowspan:null,headers:null}},textarea:{attrs:{dirname:null,form:null,maxlength:null,name:null,placeholder:null,rows:null,cols:null,autofocus:["","autofocus"],disabled:["","disabled"],readonly:["","readonly"],required:["","required"],wrap:["soft","hard"]}},tfoot:s,th:{attrs:{colspan:null,rowspan:null,headers:null,scope:["row","col","rowgroup","colgroup"]}},thead:s,time:{attrs:{datetime:null}},title:s,tr:s,track:{attrs:{src:null,label:null,default:null,kind:["subtitles","captions","descriptions","chapters","metadata"],srclang:t}},tt:s,u:s,ul:s,var:s,video:{attrs:{src:null,poster:null,width:null,height:null,crossorigin:["anonymous","use-credentials"],preload:["auto","metadata","none"],autoplay:["","autoplay"],mediagroup:["movie"],muted:["","muted"],controls:["","controls"]}},wbr:s},i={accesskey:["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"],class:null,contenteditable:["true","false"],contextmenu:null,dir:["ltr","rtl","auto"],draggable:["true","false","auto"],dropzone:["copy","move","link","string:","file:"],hidden:["hidden"],id:null,inert:["inert"],itemid:null,itemprop:null,itemref:null,itemscope:["itemscope"],itemtype:null,lang:["en","es"],spellcheck:["true","false"],style:null,tabindex:["1","2","3","4","5","6","7","8","9"],title:null,translate:["yes","no"],onclick:null,rel:["stylesheet","alternate","author","bookmark","help","license","next","nofollow","noreferrer","prefetch","prev","search","tag"]};function d(l){for(var t in i)i.hasOwnProperty(t)&&(l.attrs[t]=i[t])}for(var c in d(s),u)u.hasOwnProperty(c)&&u[c]!=s&&d(u[c]);l.htmlSchema=u,l.registerHelper("hint","html",(function(t,e){var a={schemaInfo:u};if(e)for(var n in e)a[n]=e[n];return l.hint.xml(t,a)}))}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("../../mode/css/css"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "../../mode/css/css"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var pseudoClasses = {link: 1, visited: 1, active: 1, hover: 1, focus: 1,
                       "first-letter": 1, "first-line": 1, "first-child": 1,
                       before: 1, after: 1, lang: 1};

  CodeMirror.registerHelper("hint", "css", function(cm) {
    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
    var inner = CodeMirror.innerMode(cm.getMode(), token.state);
    if (inner.mode.name != "css") return;

    if (token.type == "keyword" && "!important".indexOf(token.string) == 0)
      return {list: ["!important"], from: CodeMirror.Pos(cur.line, token.start),
              to: CodeMirror.Pos(cur.line, token.end)};

    var start = token.start, end = cur.ch, word = token.string.slice(0, end - start);
    if (/[^\w$_-]/.test(word)) {
      word = ""; start = end = cur.ch;
    }

    var spec = CodeMirror.resolveMode("text/css");

    var result = [];
    function add(keywords) {
      for (var name in keywords)
        if (!word || name.lastIndexOf(word, 0) == 0)
          result.push(name);
    }

    var st = inner.state.state;
    if (st == "pseudo" || token.type == "variable-3") {
      add(pseudoClasses);
    } else if (st == "block" || st == "maybeprop") {
      add(spec.propertyKeywords);
    } else if (st == "prop" || st == "parens" || st == "at" || st == "params") {
      add(spec.valueKeywords);
      add(spec.colorKeywords);
    } else if (st == "media" || st == "media_parens") {
      add(spec.mediaTypes);
      add(spec.mediaFeatures);
    }

    if (result.length) return {
      list: result,
      from: CodeMirror.Pos(cur.line, start),
      to: CodeMirror.Pos(cur.line, end)
    };
  });
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var Pos = CodeMirror.Pos;

  function getHints(cm, options) {
    var tags = options && options.schemaInfo;
    var quote = (options && options.quoteChar) || '"';
    if (!tags) return;
    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
    if (token.end > cur.ch) {
      token.end = cur.ch;
      token.string = token.string.slice(0, cur.ch - token.start);
    }
    var inner = CodeMirror.innerMode(cm.getMode(), token.state);
    if (inner.mode.name != "xml") return;
    var result = [], replaceToken = false, prefix;
    var tag = /\btag\b/.test(token.type) && !/>$/.test(token.string);
    var tagName = tag && /^\w/.test(token.string), tagStart;

    if (tagName) {
      var before = cm.getLine(cur.line).slice(Math.max(0, token.start - 2), token.start);
      var tagType = /<\/$/.test(before) ? "close" : /<$/.test(before) ? "open" : null;
      if (tagType) tagStart = token.start - (tagType == "close" ? 2 : 1);
    } else if (tag && token.string == "<") {
      tagType = "open";
    } else if (tag && token.string == "</") {
      tagType = "close";
    }

    if (!tag && !inner.state.tagName || tagType) {
      if (tagName)
        prefix = token.string;
      replaceToken = tagType;
      var cx = inner.state.context, curTag = cx && tags[cx.tagName];
      var childList = cx ? curTag && curTag.children : tags["!top"];
      if (childList && tagType != "close") {
        for (var i = 0; i < childList.length; ++i) if (!prefix || childList[i].lastIndexOf(prefix, 0) == 0)
          result.push("<" + childList[i]);
      } else if (tagType != "close") {
        for (var name in tags)
          if (tags.hasOwnProperty(name) && name != "!top" && name != "!attrs" && (!prefix || name.lastIndexOf(prefix, 0) == 0))
            result.push("<" + name);
      }
      if (cx && (!prefix || tagType == "close" && cx.tagName.lastIndexOf(prefix, 0) == 0))
        result.push("</" + cx.tagName + ">");
    } else {
      // Attribute completion
      var curTag = tags[inner.state.tagName], attrs = curTag && curTag.attrs;
      var globalAttrs = tags["!attrs"];
      if (!attrs && !globalAttrs) return;
      if (!attrs) {
        attrs = globalAttrs;
      } else if (globalAttrs) { // Combine tag-local and global attributes
        var set = {};
        for (var nm in globalAttrs) if (globalAttrs.hasOwnProperty(nm)) set[nm] = globalAttrs[nm];
        for (var nm in attrs) if (attrs.hasOwnProperty(nm)) set[nm] = attrs[nm];
        attrs = set;
      }
      if (token.type == "string" || token.string == "=") { // A value
        var before = cm.getRange(Pos(cur.line, Math.max(0, cur.ch - 60)),
                                 Pos(cur.line, token.type == "string" ? token.start : token.end));
        var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues;
        if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return;
        if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget
        if (token.type == "string") {
          prefix = token.string;
          var n = 0;
          if (/['"]/.test(token.string.charAt(0))) {
            quote = token.string.charAt(0);
            prefix = token.string.slice(1);
            n++;
          }
          var len = token.string.length;
          if (/['"]/.test(token.string.charAt(len - 1))) {
            quote = token.string.charAt(len - 1);
            prefix = token.string.substr(n, len - 2);
          }
          replaceToken = true;
        }
        for (var i = 0; i < atValues.length; ++i) if (!prefix || atValues[i].lastIndexOf(prefix, 0) == 0)
          result.push(quote + atValues[i] + quote);
      } else { // An attribute name
        if (token.type == "attribute") {
          prefix = token.string;
          replaceToken = true;
        }
        for (var attr in attrs) if (attrs.hasOwnProperty(attr) && (!prefix || attr.lastIndexOf(prefix, 0) == 0))
          result.push(attr);
      }
    }
    return {
      list: result,
      from: replaceToken ? Pos(cur.line, tagStart == null ? token.start : tagStart) : cur,
      to: replaceToken ? Pos(cur.line, token.end) : cur
    };
  }

  CodeMirror.registerHelper("hint", "xml", getHints);
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  var Pos = CodeMirror.Pos;

  function forEach(arr, f) {
    for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
  }

  function arrayContains(arr, item) {
    if (!Array.prototype.indexOf) {
      var i = arr.length;
      while (i--) {
        if (arr[i] === item) {
          return true;
        }
      }
      return false;
    }
    return arr.indexOf(item) != -1;
  }

  function scriptHint(editor, keywords, getToken, options) {
    // Find the token at the cursor
    var cur = editor.getCursor(), token = getToken(editor, cur);
    if (/\b(?:string|comment)\b/.test(token.type)) return;
    token.state = CodeMirror.innerMode(editor.getMode(), token.state).state;

    // If it's not a 'word-style' token, ignore the token.
    if (!/^[\w$_]*$/.test(token.string)) {
      token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
               type: token.string == "." ? "property" : null};
    } else if (token.end > cur.ch) {
      token.end = cur.ch;
      token.string = token.string.slice(0, cur.ch - token.start);
    }

    var tprop = token;
    // If it is a property, find out what it is a property of.
    while (tprop.type == "property") {
      tprop = getToken(editor, Pos(cur.line, tprop.start));
      if (tprop.string != ".") return;
      tprop = getToken(editor, Pos(cur.line, tprop.start));
      if (!context) var context = [];
      context.push(tprop);
    }
    return {list: getCompletions(token, context, keywords, options),
            from: Pos(cur.line, token.start),
            to: Pos(cur.line, token.end)};
  }

  function javascriptHint(editor, options) {
    return scriptHint(editor, javascriptKeywords,
                      function (e, cur) {return e.getTokenAt(cur);},
                      options);
  };
  CodeMirror.registerHelper("hint", "javascript", javascriptHint);

  function getCoffeeScriptToken(editor, cur) {
  // This getToken, it is for coffeescript, imitates the behavior of
  // getTokenAt method in javascript.js, that is, returning "property"
  // type and treat "." as indepenent token.
    var token = editor.getTokenAt(cur);
    if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
      token.end = token.start;
      token.string = '.';
      token.type = "property";
    }
    else if (/^\.[\w$_]*$/.test(token.string)) {
      token.type = "property";
      token.start++;
      token.string = token.string.replace(/\./, '');
    }
    return token;
  }

  function coffeescriptHint(editor, options) {
    return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
  }
  CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);

  var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
                     "toUpperCase toLowerCase split concat match replace search").split(" ");
  var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
                    "lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
  var funcProps = "prototype apply call bind".split(" ");
  var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
                  "if in instanceof new null return switch throw true try typeof var void while with").split(" ");
  var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
                  "if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");

  function forAllProps(obj, callback) {
    if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
      for (var name in obj) callback(name)
    } else {
      for (var o = obj; o; o = Object.getPrototypeOf(o))
        Object.getOwnPropertyNames(o).forEach(callback)
    }
  }

  function getCompletions(token, context, keywords, options) {
    var found = [], start = token.string, global = options && options.globalScope || window;
    function maybeAdd(str) {
      if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
    }
    function gatherCompletions(obj) {
      if (typeof obj == "string") forEach(stringProps, maybeAdd);
      else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
      else if (obj instanceof Function) forEach(funcProps, maybeAdd);
      forAllProps(obj, maybeAdd)
    }

    if (context && context.length) {
      // If this is a property, see if it belongs to some object we can
      // find in the current environment.
      var obj = context.pop(), base;
      if (obj.type && obj.type.indexOf("variable") === 0) {
        if (options && options.additionalContext)
          base = options.additionalContext[obj.string];
        if (!options || options.useGlobalScope !== false)
          base = base || global[obj.string];
      } else if (obj.type == "string") {
        base = "";
      } else if (obj.type == "atom") {
        base = 1;
      } else if (obj.type == "function") {
        if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
            (typeof global.jQuery == 'function'))
          base = global.jQuery();
        else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
          base = global._();
      }
      while (base != null && context.length)
        base = base[context.pop().string];
      if (base != null) gatherCompletions(base);
    } else {
      // If not, just look in the global object and any local scope
      // (reading into JS mode internals to get at the local and global variables)
      for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
      for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
      if (!options || options.useGlobalScope !== false)
        gatherCompletions(global);
      forEach(keywords, maybeAdd);
    }
    return found;
  }
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("./xml-hint"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "./xml-hint"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var langs = "ab aa af ak sq am ar an hy as av ae ay az bm ba eu be bn bh bi bs br bg my ca ch ce ny zh cv kw co cr hr cs da dv nl dz en eo et ee fo fj fi fr ff gl ka de el gn gu ht ha he hz hi ho hu ia id ie ga ig ik io is it iu ja jv kl kn kr ks kk km ki rw ky kv kg ko ku kj la lb lg li ln lo lt lu lv gv mk mg ms ml mt mi mr mh mn na nv nb nd ne ng nn no ii nr oc oj cu om or os pa pi fa pl ps pt qu rm rn ro ru sa sc sd se sm sg sr gd sn si sk sl so st es su sw ss sv ta te tg th ti bo tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa cy wo fy xh yi yo za zu".split(" ");
  var targets = ["_blank", "_self", "_top", "_parent"];
  var charsets = ["ascii", "utf-8", "utf-16", "latin1", "latin1"];
  var methods = ["get", "post", "put", "delete"];
  var encs = ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"];
  var media = ["all", "screen", "print", "embossed", "braille", "handheld", "print", "projection", "screen", "tty", "tv", "speech",
               "3d-glasses", "resolution [>][<][=] [X]", "device-aspect-ratio: X/Y", "orientation:portrait",
               "orientation:landscape", "device-height: [X]", "device-width: [X]"];
  var s = { attrs: {} }; // Simple tag, reused for a whole lot of tags

  var data = {
    a: {
      attrs: {
        href: null, ping: null, type: null,
        media: media,
        target: targets,
        hreflang: langs
      }
    },
    abbr: s,
    acronym: s,
    address: s,
    applet: s,
    area: {
      attrs: {
        alt: null, coords: null, href: null, target: null, ping: null,
        media: media, hreflang: langs, type: null,
        shape: ["default", "rect", "circle", "poly"]
      }
    },
    article: s,
    aside: s,
    audio: {
      attrs: {
        src: null, mediagroup: null,
        crossorigin: ["anonymous", "use-credentials"],
        preload: ["none", "metadata", "auto"],
        autoplay: ["", "autoplay"],
        loop: ["", "loop"],
        controls: ["", "controls"]
      }
    },
    b: s,
    base: { attrs: { href: null, target: targets } },
    basefont: s,
    bdi: s,
    bdo: s,
    big: s,
    blockquote: { attrs: { cite: null } },
    body: s,
    br: s,
    button: {
      attrs: {
        form: null, formaction: null, name: null, value: null,
        autofocus: ["", "autofocus"],
        disabled: ["", "autofocus"],
        formenctype: encs,
        formmethod: methods,
        formnovalidate: ["", "novalidate"],
        formtarget: targets,
        type: ["submit", "reset", "button"]
      }
    },
    canvas: { attrs: { width: null, height: null } },
    caption: s,
    center: s,
    cite: s,
    code: s,
    col: { attrs: { span: null } },
    colgroup: { attrs: { span: null } },
    command: {
      attrs: {
        type: ["command", "checkbox", "radio"],
        label: null, icon: null, radiogroup: null, command: null, title: null,
        disabled: ["", "disabled"],
        checked: ["", "checked"]
      }
    },
    data: { attrs: { value: null } },
    datagrid: { attrs: { disabled: ["", "disabled"], multiple: ["", "multiple"] } },
    datalist: { attrs: { data: null } },
    dd: s,
    del: { attrs: { cite: null, datetime: null } },
    details: { attrs: { open: ["", "open"] } },
    dfn: s,
    dir: s,
    div: s,
    dl: s,
    dt: s,
    em: s,
    embed: { attrs: { src: null, type: null, width: null, height: null } },
    eventsource: { attrs: { src: null } },
    fieldset: { attrs: { disabled: ["", "disabled"], form: null, name: null } },
    figcaption: s,
    figure: s,
    font: s,
    footer: s,
    form: {
      attrs: {
        action: null, name: null,
        "accept-charset": charsets,
        autocomplete: ["on", "off"],
        enctype: encs,
        method: methods,
        novalidate: ["", "novalidate"],
        target: targets
      }
    },
    frame: s,
    frameset: s,
    h1: s, h2: s, h3: s, h4: s, h5: s, h6: s,
    head: {
      attrs: {},
      children: ["title", "base", "link", "style", "meta", "script", "noscript", "command"]
    },
    header: s,
    hgroup: s,
    hr: s,
    html: {
      attrs: { manifest: null },
      children: ["head", "body"]
    },
    i: s,
    iframe: {
      attrs: {
        src: null, srcdoc: null, name: null, width: null, height: null,
        sandbox: ["allow-top-navigation", "allow-same-origin", "allow-forms", "allow-scripts"],
        seamless: ["", "seamless"]
      }
    },
    img: {
      attrs: {
        alt: null, src: null, ismap: null, usemap: null, width: null, height: null,
        crossorigin: ["anonymous", "use-credentials"]
      }
    },
    input: {
      attrs: {
        alt: null, dirname: null, form: null, formaction: null,
        height: null, list: null, max: null, maxlength: null, min: null,
        name: null, pattern: null, placeholder: null, size: null, src: null,
        step: null, value: null, width: null,
        accept: ["audio/*", "video/*", "image/*"],
        autocomplete: ["on", "off"],
        autofocus: ["", "autofocus"],
        checked: ["", "checked"],
        disabled: ["", "disabled"],
        formenctype: encs,
        formmethod: methods,
        formnovalidate: ["", "novalidate"],
        formtarget: targets,
        multiple: ["", "multiple"],
        readonly: ["", "readonly"],
        required: ["", "required"],
        type: ["hidden", "text", "search", "tel", "url", "email", "password", "datetime", "date", "month",
               "week", "time", "datetime-local", "number", "range", "color", "checkbox", "radio",
               "file", "submit", "image", "reset", "button"]
      }
    },
    ins: { attrs: { cite: null, datetime: null } },
    kbd: s,
    keygen: {
      attrs: {
        challenge: null, form: null, name: null,
        autofocus: ["", "autofocus"],
        disabled: ["", "disabled"],
        keytype: ["RSA"]
      }
    },
    label: { attrs: { "for": null, form: null } },
    legend: s,
    li: { attrs: { value: null } },
    link: {
      attrs: {
        href: null, type: null,
        hreflang: langs,
        media: media,
        sizes: ["all", "16x16", "16x16 32x32", "16x16 32x32 64x64"]
      }
    },
    map: { attrs: { name: null } },
    mark: s,
    menu: { attrs: { label: null, type: ["list", "context", "toolbar"] } },
    meta: {
      attrs: {
        content: null,
        charset: charsets,
        name: ["viewport", "application-name", "author", "description", "generator", "keywords"],
        "http-equiv": ["content-language", "content-type", "default-style", "refresh"]
      }
    },
    meter: { attrs: { value: null, min: null, low: null, high: null, max: null, optimum: null } },
    nav: s,
    noframes: s,
    noscript: s,
    object: {
      attrs: {
        data: null, type: null, name: null, usemap: null, form: null, width: null, height: null,
        typemustmatch: ["", "typemustmatch"]
      }
    },
    ol: { attrs: { reversed: ["", "reversed"], start: null, type: ["1", "a", "A", "i", "I"] } },
    optgroup: { attrs: { disabled: ["", "disabled"], label: null } },
    option: { attrs: { disabled: ["", "disabled"], label: null, selected: ["", "selected"], value: null } },
    output: { attrs: { "for": null, form: null, name: null } },
    p: s,
    param: { attrs: { name: null, value: null } },
    pre: s,
    progress: { attrs: { value: null, max: null } },
    q: { attrs: { cite: null } },
    rp: s,
    rt: s,
    ruby: s,
    s: s,
    samp: s,
    script: {
      attrs: {
        type: ["text/javascript"],
        src: null,
        async: ["", "async"],
        defer: ["", "defer"],
        charset: charsets
      }
    },
    section: s,
    select: {
      attrs: {
        form: null, name: null, size: null,
        autofocus: ["", "autofocus"],
        disabled: ["", "disabled"],
        multiple: ["", "multiple"]
      }
    },
    small: s,
    source: { attrs: { src: null, type: null, media: null } },
    span: s,
    strike: s,
    strong: s,
    style: {
      attrs: {
        type: ["text/css"],
        media: media,
        scoped: null
      }
    },
    sub: s,
    summary: s,
    sup: s,
    table: s,
    tbody: s,
    td: { attrs: { colspan: null, rowspan: null, headers: null } },
    textarea: {
      attrs: {
        dirname: null, form: null, maxlength: null, name: null, placeholder: null,
        rows: null, cols: null,
        autofocus: ["", "autofocus"],
        disabled: ["", "disabled"],
        readonly: ["", "readonly"],
        required: ["", "required"],
        wrap: ["soft", "hard"]
      }
    },
    tfoot: s,
    th: { attrs: { colspan: null, rowspan: null, headers: null, scope: ["row", "col", "rowgroup", "colgroup"] } },
    thead: s,
    time: { attrs: { datetime: null } },
    title: s,
    tr: s,
    track: {
      attrs: {
        src: null, label: null, "default": null,
        kind: ["subtitles", "captions", "descriptions", "chapters", "metadata"],
        srclang: langs
      }
    },
    tt: s,
    u: s,
    ul: s,
    "var": s,
    video: {
      attrs: {
        src: null, poster: null, width: null, height: null,
        crossorigin: ["anonymous", "use-credentials"],
        preload: ["auto", "metadata", "none"],
        autoplay: ["", "autoplay"],
        mediagroup: ["movie"],
        muted: ["", "muted"],
        controls: ["", "controls"]
      }
    },
    wbr: s
  };

  var globalAttrs = {
    accesskey: ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
    "class": null,
    contenteditable: ["true", "false"],
    contextmenu: null,
    dir: ["ltr", "rtl", "auto"],
    draggable: ["true", "false", "auto"],
    dropzone: ["copy", "move", "link", "string:", "file:"],
    hidden: ["hidden"],
    id: null,
    inert: ["inert"],
    itemid: null,
    itemprop: null,
    itemref: null,
    itemscope: ["itemscope"],
    itemtype: null,
    lang: ["en", "es"],
    spellcheck: ["true", "false"],
    style: null,
    tabindex: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
    title: null,
    translate: ["yes", "no"],
    onclick: null,
    rel: ["stylesheet", "alternate", "author", "bookmark", "help", "license", "next", "nofollow", "noreferrer", "prefetch", "prev", "search", "tag"]
  };
  function populate(obj) {
    for (var attr in globalAttrs) if (globalAttrs.hasOwnProperty(attr))
      obj.attrs[attr] = globalAttrs[attr];
  }

  populate(s);
  for (var tag in data) if (data.hasOwnProperty(tag) && data[tag] != s)
    populate(data[tag]);

  CodeMirror.htmlSchema = data;
  function htmlHint(cm, options) {
    var local = {schemaInfo: data};
    if (options) for (var opt in options) local[opt] = options[opt];
    return CodeMirror.hint.xml(cm, local);
  }
  CodeMirror.registerHelper("hint", "html", htmlHint);
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var WORD = /[\w$]+/, RANGE = 500;

  CodeMirror.registerHelper("hint", "anyword", function(editor, options) {
    var word = options && options.word || WORD;
    var range = options && options.range || RANGE;
    var cur = editor.getCursor(), curLine = editor.getLine(cur.line);
    var end = cur.ch, start = end;
    while (start && word.test(curLine.charAt(start - 1))) --start;
    var curWord = start != end && curLine.slice(start, end);

    var list = options && options.list || [], seen = {};
    var re = new RegExp(word.source, "g");
    for (var dir = -1; dir <= 1; dir += 2) {
      var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir;
      for (; line != endLine; line += dir) {
        var text = editor.getLine(line), m;
        while (m = re.exec(text)) {
          if (line == cur.line && m[0] === curWord) continue;
          if ((!curWord || m[0].lastIndexOf(curWord, 0) == 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) {
            seen[m[0]] = true;
            list.push(m[0]);
          }
        }
      }
    }
    return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)};
  });
});
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";function n(n,t){var i=n.getLine(t),o=i.search(/\S/);return-1==o||/\bcomment\b/.test(n.getTokenTypeAt(e.Pos(t,o+1)))?-1:e.countColumn(i,null,n.getOption("tabSize"))}e.registerHelper("fold","indent",(function(t,i){var o=n(t,i.line);if(!(o<0)){for(var r=null,l=i.line+1,f=t.lastLine();l<=f;++l){var u=n(t,l);if(-1==u);else{if(!(u>o))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}}))}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.registerHelper("fold", "markdown", function(cm, start) {
  var maxDepth = 100;

  function isHeader(lineNo) {
    var tokentype = cm.getTokenTypeAt(CodeMirror.Pos(lineNo, 0));
    return tokentype && /\bheader\b/.test(tokentype);
  }

  function headerLevel(lineNo, line, nextLine) {
    var match = line && line.match(/^#+/);
    if (match && isHeader(lineNo)) return match[0].length;
    match = nextLine && nextLine.match(/^[=\-]+\s*$/);
    if (match && isHeader(lineNo + 1)) return nextLine[0] == "=" ? 1 : 2;
    return maxDepth;
  }

  var firstLine = cm.getLine(start.line), nextLine = cm.getLine(start.line + 1);
  var level = headerLevel(start.line, firstLine, nextLine);
  if (level === maxDepth) return undefined;

  var lastLineNo = cm.lastLine();
  var end = start.line, nextNextLine = cm.getLine(end + 2);
  while (end < lastLineNo) {
    if (headerLevel(end + 1, nextLine, nextNextLine) <= level) break;
    ++end;
    nextLine = nextNextLine;
    nextNextLine = cm.getLine(end + 2);
  }

  return {
    from: CodeMirror.Pos(start.line, firstLine.length),
    to: CodeMirror.Pos(end, cm.getLine(end).length)
  };
});

});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

function lineIndent(cm, lineNo) {
  var text = cm.getLine(lineNo)
  var spaceTo = text.search(/\S/)
  if (spaceTo == -1 || /\bcomment\b/.test(cm.getTokenTypeAt(CodeMirror.Pos(lineNo, spaceTo + 1))))
    return -1
  return CodeMirror.countColumn(text, null, cm.getOption("tabSize"))
}
               !
CodeMirror.registerHelper("fold", "indent", function(cm, start) {
  var myIndent = lineIndent(cm, start.line)
  if (myIndent < 0) return
  var lastLineInFold = null

  // Go through lines until we find a line that definitely doesn't belong in
  // the block we're folding, or to the end.
  for (var i = start.line + 1, end = cm.lastLine(); i <= end; ++i) {
    var indent = lineIndent(cm, i)
    if (indent == -1) {
    } else if (indent > myIndent) {
      // Lines with a greater indent are considered part of the block.
      lastLineInFold = i;
    } else {
      // If this line has non-space, non-comment content, and is
      // indented less or equal to the start line, it is the start of
      // another block.
      break;
    }
  }
  if (lastLineInFold) return {
    from: CodeMirror.Pos(start.line, cm.getLine(start.line).length),
    to: CodeMirror.Pos(lastLineInFold, cm.getLine(lastLineInFold).length)
  };
});

});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var Pos = CodeMirror.Pos;
  function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }

  var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
  var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
  var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");

  function Iter(cm, line, ch, range) {
    this.line = line; this.ch = ch;
    this.cm = cm; this.text = cm.getLine(line);
    this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine();
    this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine();
  }

  function tagAt(iter, ch) {
    var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));
    return type && /\btag\b/.test(type);
  }

  function nextLine(iter) {
    if (iter.line >= iter.max) return;
    iter.ch = 0;
    iter.text = iter.cm.getLine(++iter.line);
    return true;
  }
  function prevLine(iter) {
    if (iter.line <= iter.min) return;
    iter.text = iter.cm.getLine(--iter.line);
    iter.ch = iter.text.length;
    return true;
  }

  function toTagEnd(iter) {
    for (;;) {
      var gt = iter.text.indexOf(">", iter.ch);
      if (gt == -1) { if (nextLine(iter)) continue; else return; }
      if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }
      var lastSlash = iter.text.lastIndexOf("/", gt);
      var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
      iter.ch = gt + 1;
      return selfClose ? "selfClose" : "regular";
    }
  }
  function toTagStart(iter) {
    for (;;) {
      var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
      if (lt == -1) { if (prevLine(iter)) continue; else return; }
      if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
      xmlTagStart.lastIndex = lt;
      iter.ch = lt;
      var match = xmlTagStart.exec(iter.text);
      if (match && match.index == lt) return match;
    }
  }

  function toNextTag(iter) {
    for (;;) {
      xmlTagStart.lastIndex = iter.ch;
      var found = xmlTagStart.exec(iter.text);
      if (!found) { if (nextLine(iter)) continue; else return; }
      if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }
      iter.ch = found.index + found[0].length;
      return found;
    }
  }
  function toPrevTag(iter) {
    for (;;) {
      var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
      if (gt == -1) { if (prevLine(iter)) continue; else return; }
      if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
      var lastSlash = iter.text.lastIndexOf("/", gt);
      var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
      iter.ch = gt + 1;
      return selfClose ? "selfClose" : "regular";
    }
  }

  function findMatchingClose(iter, tag) {
    var stack = [];
    for (;;) {
      var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);
      if (!next || !(end = toTagEnd(iter))) return;
      if (end == "selfClose") continue;
      if (next[1]) { // closing tag
        for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
          stack.length = i;
          break;
        }
        if (i < 0 && (!tag || tag == next[2])) return {
          tag: next[2],
          from: Pos(startLine, startCh),
          to: Pos(iter.line, iter.ch)
        };
      } else { // opening tag
        stack.push(next[2]);
      }
    }
  }
  function findMatchingOpen(iter, tag) {
    var stack = [];
    for (;;) {
      var prev = toPrevTag(iter);
      if (!prev) return;
      if (prev == "selfClose") { toTagStart(iter); continue; }
      var endLine = iter.line, endCh = iter.ch;
      var start = toTagStart(iter);
      if (!start) return;
      if (start[1]) { // closing tag
        stack.push(start[2]);
      } else { // opening tag
        for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {
          stack.length = i;
          break;
        }
        if (i < 0 && (!tag || tag == start[2])) return {
          tag: start[2],
          from: Pos(iter.line, iter.ch),
          to: Pos(endLine, endCh)
        };
      }
    }
  }

  CodeMirror.registerHelper("fold", "xml", function(cm, start) {
    var iter = new Iter(cm, start.line, 0);
    for (;;) {
      var openTag = toNextTag(iter), end;
      if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;
      if (!openTag[1] && end != "selfClose") {
        var startPos = Pos(iter.line, iter.ch);
        var endPos = findMatchingClose(iter, openTag[2]);
        return endPos && {from: startPos, to: endPos.from};
      }
    }
  });
  CodeMirror.findMatchingTag = function(cm, pos, range) {
    var iter = new Iter(cm, pos.line, pos.ch, range);
    if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
    var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
    var start = end && toTagStart(iter);
    if (!end || !start || cmp(iter, pos) > 0) return;
    var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
    if (end == "selfClose") return {open: here, close: null, at: "open"};

    if (start[1]) { // closing tag
      return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
    } else { // opening tag
      iter = new Iter(cm, to.line, to.ch, range);
      return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
    }
  };

  CodeMirror.findEnclosingTag = function(cm, pos, range, tag) {
    var iter = new Iter(cm, pos.line, pos.ch, range);
    for (;;) {
      var open = findMatchingOpen(iter, tag);
      if (!open) break;
      var forward = new Iter(cm, pos.line, pos.ch, range);
      var close = findMatchingClose(forward, open.tag);
      if (close) return {open: open, close: close};
    }
  };

  // Used by addon/edit/closetag.js
  CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
    var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
    return findMatchingClose(iter, name);
  };
});
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";var n=e.Pos;var t="A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",i=new RegExp("<(/?)(["+t+"][A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD-:.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*)","g");function r(e,n,t,i){this.line=n,this.ch=t,this.cm=e,this.text=e.getLine(n),this.min=i?Math.max(i.from,e.firstLine()):e.firstLine(),this.max=i?Math.min(i.to-1,e.lastLine()):e.lastLine()}function u(e,t){var i=e.cm.getTokenTypeAt(n(e.line,t));return i&&/\btag\b/.test(i)}function f(e){if(!(e.line>=e.max))return e.ch=0,e.text=e.cm.getLine(++e.line),!0}function o(e){if(!(e.line<=e.min))return e.text=e.cm.getLine(--e.line),e.ch=e.text.length,!0}function l(e){for(;;){var n=e.text.indexOf(">",e.ch);if(-1==n){if(f(e))continue;return}if(u(e,n+1)){var t=e.text.lastIndexOf("/",n),i=t>-1&&!/\S/.test(e.text.slice(t+1,n));return e.ch=n+1,i?"selfClose":"regular"}e.ch=n+1}}function c(e){for(;;){var n=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==n){if(o(e))continue;return}if(u(e,n+1)){i.lastIndex=n,e.ch=n;var t=i.exec(e.text);if(t&&t.index==n)return t}else e.ch=n}}function a(e){for(;;){i.lastIndex=e.ch;var n=i.exec(e.text);if(!n){if(f(e))continue;return}if(u(e,n.index+1))return e.ch=n.index+n[0].length,n;e.ch=n.index+1}}function s(e){for(;;){var n=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==n){if(o(e))continue;return}if(u(e,n+1)){var t=e.text.lastIndexOf("/",n),i=t>-1&&!/\S/.test(e.text.slice(t+1,n));return e.ch=n+1,i?"selfClose":"regular"}e.ch=n}}function h(e,t){for(var i=[];;){var r,u=a(e),f=e.line,o=e.ch-(u?u[0].length:0);if(!u||!(r=l(e)))return;if("selfClose"!=r)if(u[1]){for(var c=i.length-1;c>=0;--c)if(i[c]==u[2]){i.length=c;break}if(c<0&&(!t||t==u[2]))return{tag:u[2],from:n(f,o),to:n(e.line,e.ch)}}else i.push(u[2])}}function F(e,t){for(var i=[];;){var r=s(e);if(!r)return;if("selfClose"!=r){var u=e.line,f=e.ch,o=c(e);if(!o)return;if(o[1])i.push(o[2]);else{for(var l=i.length-1;l>=0;--l)if(i[l]==o[2]){i.length=l;break}if(l<0&&(!t||t==o[2]))return{tag:o[2],from:n(e.line,e.ch),to:n(u,f)}}}else c(e)}}e.registerHelper("fold","xml",(function(e,t){for(var i=new r(e,t.line,0);;){var u,f=a(i);if(!f||i.line!=t.line||!(u=l(i)))return;if(!f[1]&&"selfClose"!=u){var o=n(i.line,i.ch),c=h(i,f[2]);return c&&{from:o,to:c.from}}}})),e.findMatchingTag=function(e,t,i){var u=new r(e,t.line,t.ch,i);if(-1!=u.text.indexOf(">")||-1!=u.text.indexOf("<")){var f=l(u),o=f&&n(u.line,u.ch),a=f&&c(u);if(f&&a&&(x=t,!(((s=u).line-x.line||s.ch-x.ch)>0))){var s,x,g={from:n(u.line,u.ch),to:o,tag:a[2]};return"selfClose"==f?{open:g,close:null,at:"open"}:a[1]?{open:F(u,a[2]),close:g,at:"close"}:{open:g,close:h(u=new r(e,o.line,o.ch,i),a[2]),at:"open"}}}},e.findEnclosingTag=function(e,n,t,i){for(var u=new r(e,n.line,n.ch,t);;){var f=F(u,i);if(!f)break;var o=h(new r(e,n.line,n.ch,t),f.tag);if(o)return{open:f,close:o}}},e.scanForClosingTag=function(e,n,t,i){return h(new r(e,n.line,n.ch,i?{from:0,to:i}:null),t)}}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("./foldcode"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "./foldcode"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
    if (old && old != CodeMirror.Init) {
      cm.clearGutter(cm.state.foldGutter.options.gutter);
      cm.state.foldGutter = null;
      cm.off("gutterClick", onGutterClick);
      cm.off("change", onChange);
      cm.off("viewportChange", onViewportChange);
      cm.off("fold", onFold);
      cm.off("unfold", onFold);
      cm.off("swapDoc", onChange);
    }
    if (val) {
      cm.state.foldGutter = new State(parseOptions(val));
      updateInViewport(cm);
      cm.on("gutterClick", onGutterClick);
      cm.on("change", onChange);
      cm.on("viewportChange", onViewportChange);
      cm.on("fold", onFold);
      cm.on("unfold", onFold);
      cm.on("swapDoc", onChange);
    }
  });

  var Pos = CodeMirror.Pos;

  function State(options) {
    this.options = options;
    this.from = this.to = 0;
  }

  function parseOptions(opts) {
    if (opts === true) opts = {};
    if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
    if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
    if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
    return opts;
  }

  function isFolded(cm, line) {
    var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
    for (var i = 0; i < marks.length; ++i)
      if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];
  }

  function marker(spec) {
    if (typeof spec == "string") {
      var elt = document.createElement("div");
      elt.className = spec + " CodeMirror-guttermarker-subtle";
      return elt;
    } else {
      return spec.cloneNode(true);
    }
  }

  function updateFoldInfo(cm, from, to) {
    var opts = cm.state.foldGutter.options, cur = from;
    var minSize = cm.foldOption(opts, "minFoldSize");
    var func = cm.foldOption(opts, "rangeFinder");
    cm.eachLine(from, to, function(line) {
      var mark = null;
      if (isFolded(cm, cur)) {
        mark = marker(opts.indicatorFolded);
      } else {
        var pos = Pos(cur, 0);
        var range = func && func(cm, pos);
        if (range && range.to.line - range.from.line >= minSize)
          mark = marker(opts.indicatorOpen);
      }
      cm.setGutterMarker(line, opts.gutter, mark);
      ++cur;
    });
  }

  function updateInViewport(cm) {
    var vp = cm.getViewport(), state = cm.state.foldGutter;
    if (!state) return;
    cm.operation(function() {
      updateFoldInfo(cm, vp.from, vp.to);
    });
    state.from = vp.from; state.to = vp.to;
  }

  function onGutterClick(cm, line, gutter) {
    var state = cm.state.foldGutter;
    if (!state) return;
    var opts = state.options;
    if (gutter != opts.gutter) return;
    var folded = isFolded(cm, line);
    if (folded) folded.clear();
    else cm.foldCode(Pos(line, 0), opts.rangeFinder);
  }

  function onChange(cm) {
    var state = cm.state.foldGutter;
    if (!state) return;
    var opts = state.options;
    state.from = state.to = 0;
    clearTimeout(state.changeUpdate);
    state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
  }

  function onViewportChange(cm) {
    var state = cm.state.foldGutter;
    if (!state) return;
    var opts = state.options;
    clearTimeout(state.changeUpdate);
    state.changeUpdate = setTimeout(function() {
      var vp = cm.getViewport();
      if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
        updateInViewport(cm);
      } else {
        cm.operation(function() {
          if (vp.from < state.from) {
            updateFoldInfo(cm, vp.from, state.from);
            state.from = vp.from;
          }
          if (vp.to > state.to) {
            updateFoldInfo(cm, state.to, vp.to);
            state.to = vp.to;
          }
        });
      }
    }, opts.updateViewportTimeSpan || 400);
  }

  function onFold(cm, from) {
    var state = cm.state.foldGutter;
    if (!state) return;
    var line = from.line;
    if (line >= state.from && line < state.to)
      updateFoldInfo(cm, line, line + 1);
  }
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  function doFold(cm, pos, options, force) {
    if (options && options.call) {
      var finder = options;
      options = null;
    } else {
      var finder = getOption(cm, options, "rangeFinder");
    }
    if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
    var minSize = getOption(cm, options, "minFoldSize");

    function getRange(allowFolded) {
      var range = finder(cm, pos);
      if (!range || range.to.line - range.from.line < minSize) return null;
      var marks = cm.findMarksAt(range.from);
      for (var i = 0; i < marks.length; ++i) {
        if (marks[i].__isFold && force !== "fold") {
          if (!allowFolded) return null;
          range.cleared = true;
          marks[i].clear();
        }
      }
      return range;
    }

    var range = getRange(true);
    if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
      pos = CodeMirror.Pos(pos.line - 1, 0);
      range = getRange(false);
    }
    if (!range || range.cleared || force === "unfold") return;

    var myWidget = makeWidget(cm, options);
    CodeMirror.on(myWidget, "mousedown", function(e) {
      myRange.clear();
      CodeMirror.e_preventDefault(e);
    });
    var myRange = cm.markText(range.from, range.to, {
      replacedWith: myWidget,
      clearOnEnter: getOption(cm, options, "clearOnEnter"),
      __isFold: true
    });
    myRange.on("clear", function(from, to) {
      CodeMirror.signal(cm, "unfold", cm, from, to);
    });
    CodeMirror.signal(cm, "fold", cm, range.from, range.to);
  }

  function makeWidget(cm, options) {
    var widget = getOption(cm, options, "widget");
    if (typeof widget == "string") {
      var text = document.createTextNode(widget);
      widget = document.createElement("span");
      widget.appendChild(text);
      widget.className = "CodeMirror-foldmarker";
    }
    return widget;
  }

  // Clumsy backwards-compatible interface
  CodeMirror.newFoldFunction = function(rangeFinder, widget) {
    return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
  };

  // New-style interface
  CodeMirror.defineExtension("foldCode", function(pos, options, force) {
    doFold(this, pos, options, force);
  });

  CodeMirror.defineExtension("isFolded", function(pos) {
    var marks = this.findMarksAt(pos);
    for (var i = 0; i < marks.length; ++i)
      if (marks[i].__isFold) return true;
  });

  CodeMirror.commands.toggleFold = function(cm) {
    cm.foldCode(cm.getCursor());
  };
  CodeMirror.commands.fold = function(cm) {
    cm.foldCode(cm.getCursor(), null, "fold");
  };
  CodeMirror.commands.unfold = function(cm) {
    cm.foldCode(cm.getCursor(), null, "unfold");
  };
  CodeMirror.commands.foldAll = function(cm) {
    cm.operation(function() {
      for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
        cm.foldCode(CodeMirror.Pos(i, 0), null, "fold");
    });
  };
  CodeMirror.commands.unfoldAll = function(cm) {
    cm.operation(function() {
      for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
        cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold");
    });
  };

  CodeMirror.registerHelper("fold", "combine", function() {
    var funcs = Array.prototype.slice.call(arguments, 0);
    return function(cm, start) {
      for (var i = 0; i < funcs.length; ++i) {
        var found = funcs[i](cm, start);
        if (found) return found;
      }
    };
  });

  CodeMirror.registerHelper("fold", "auto", function(cm, start) {
    var helpers = cm.getHelpers(start, "fold");
    for (var i = 0; i < helpers.length; i++) {
      var cur = helpers[i](cm, start);
      if (cur) return cur;
    }
  });

  var defaultOptions = {
    rangeFinder: CodeMirror.fold.auto,
    widget: "\u2194",
    minFoldSize: 0,
    scanUp: false,
    clearOnEnter: true
  };

  CodeMirror.defineOption("foldOptions", null);

  function getOption(cm, options, name) {
    if (options && options[name] !== undefined)
      return options[name];
    var editorOptions = cm.options.foldOptions;
    if (editorOptions && editorOptions[name] !== undefined)
      return editorOptions[name];
    return defaultOptions[name];
  }

  CodeMirror.defineExtension("foldOption", function(options, name) {
    return getOption(this, options, name);
  });
});
!function(o){"object"==typeof exports&&"object"==typeof module?o(require("../../lib/codemirror"),require("./foldcode")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./foldcode"],o):o(CodeMirror)}((function(o){"use strict";o.defineOption("foldGutter",!1,(function(t,r,n){n&&n!=o.Init&&(t.clearGutter(t.state.foldGutter.options.gutter),t.state.foldGutter=null,t.off("gutterClick",d),t.off("change",a),t.off("viewportChange",u),t.off("fold",l),t.off("unfold",l),t.off("swapDoc",a)),r&&(t.state.foldGutter=new e(function(o){!0===o&&(o={});null==o.gutter&&(o.gutter="CodeMirror-foldgutter");null==o.indicatorOpen&&(o.indicatorOpen="CodeMirror-foldgutter-open");null==o.indicatorFolded&&(o.indicatorFolded="CodeMirror-foldgutter-folded");return o}(r)),f(t),t.on("gutterClick",d),t.on("change",a),t.on("viewportChange",u),t.on("fold",l),t.on("unfold",l),t.on("swapDoc",a))}));var t=o.Pos;function e(o){this.options=o,this.from=this.to=0}function r(o,e){for(var r=o.findMarks(t(e,0),t(e+1,0)),n=0;n<r.length;++n)if(r[n].__isFold&&r[n].find().from.line==e)return r[n]}function n(o){if("string"==typeof o){var t=document.createElement("div");return t.className=o+" CodeMirror-guttermarker-subtle",t}return o.cloneNode(!0)}function i(o,e,i){var f=o.state.foldGutter.options,d=e,a=o.foldOption(f,"minFoldSize"),u=o.foldOption(f,"rangeFinder");o.eachLine(e,i,(function(e){var i=null;if(r(o,d))i=n(f.indicatorFolded);else{var l=t(d,0),c=u&&u(o,l);c&&c.to.line-c.from.line>=a&&(i=n(f.indicatorOpen))}o.setGutterMarker(e,f.gutter,i),++d}))}function f(o){var t=o.getViewport(),e=o.state.foldGutter;e&&(o.operation((function(){i(o,t.from,t.to)})),e.from=t.from,e.to=t.to)}function d(o,e,n){var i=o.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var d=r(o,e);d?d.clear():o.foldCode(t(e,0),f.rangeFinder)}}}function a(o){var t=o.state.foldGutter;if(t){var e=t.options;t.from=t.to=0,clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout((function(){f(o)}),e.foldOnChangeTimeSpan||600)}}function u(o){var t=o.state.foldGutter;if(t){var e=t.options;clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout((function(){var e=o.getViewport();t.from==t.to||e.from-t.to>20||t.from-e.to>20?f(o):o.operation((function(){e.from<t.from&&(i(o,e.from,t.from),t.from=e.from),e.to>t.to&&(i(o,t.to,e.to),t.to=e.to)}))}),e.updateViewportTimeSpan||400)}}function l(o,t){var e=o.state.foldGutter;if(e){var r=t.line;r>=e.from&&r<e.to&&i(o,r,r+1)}}}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.registerHelper("fold", "brace", function(cm, start) {
  var line = start.line, lineText = cm.getLine(line);
  var tokenType;

  function findOpening(openCh) {
    for (var at = start.ch, pass = 0;;) {
      var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);
      if (found == -1) {
        if (pass == 1) break;
        pass = 1;
        at = lineText.length;
        continue;
      }
      if (pass == 1 && found < start.ch) break;
      tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
      if (!/^(comment|string)/.test(tokenType)) return found + 1;
      at = found - 1;
    }
  }

  var startToken = "{", endToken = "}", startCh = findOpening("{");
  if (startCh == null) {
    startToken = "[", endToken = "]";
    startCh = findOpening("[");
  }

  if (startCh == null) return;
  var count = 1, lastLine = cm.lastLine(), end, endCh;
  outer: for (var i = line; i <= lastLine; ++i) {
    var text = cm.getLine(i), pos = i == line ? startCh : 0;
    for (;;) {
      var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
      if (nextOpen < 0) nextOpen = text.length;
      if (nextClose < 0) nextClose = text.length;
      pos = Math.min(nextOpen, nextClose);
      if (pos == text.length) break;
      if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {
        if (pos == nextOpen) ++count;
        else if (!--count) { end = i; endCh = pos; break outer; }
      }
      ++pos;
    }
  }
  if (end == null || line == end && endCh == startCh) return;
  return {from: CodeMirror.Pos(line, startCh),
          to: CodeMirror.Pos(end, endCh)};
});

CodeMirror.registerHelper("fold", "import", function(cm, start) {
  function hasImport(line) {
    if (line < cm.firstLine() || line > cm.lastLine()) return null;
    var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
    if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
    if (start.type != "keyword" || start.string != "import") return null;
    // Now find closing semicolon, return its position
    for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
      var text = cm.getLine(i), semi = text.indexOf(";");
      if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
    }
  }

  var startLine = start.line, has = hasImport(startLine), prev;
  if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
    return null;
  for (var end = has.end;;) {
    var next = hasImport(end.line + 1);
    if (next == null) break;
    end = next.end;
  }
  return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
});

CodeMirror.registerHelper("fold", "include", function(cm, start) {
  function hasInclude(line) {
    if (line < cm.firstLine() || line > cm.lastLine()) return null;
    var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
    if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
    if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
  }

  var startLine = start.line, has = hasInclude(startLine);
  if (has == null || hasInclude(startLine - 1) != null) return null;
  for (var end = startLine;;) {
    var next = hasInclude(end + 1);
    if (next == null) break;
    ++end;
  }
  return {from: CodeMirror.Pos(startLine, has + 1),
          to: cm.clipPos(CodeMirror.Pos(end))};
});

});
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.registerHelper("fold","markdown",(function(n,t){function r(t){var r=n.getTokenTypeAt(e.Pos(t,0));return r&&/\bheader\b/.test(r)}function i(e,n,t){var i=n&&n.match(/^#+/);return i&&r(e)?i[0].length:(i=t&&t.match(/^[=\-]+\s*$/))&&r(e+1)?"="==t[0]?1:2:100}var o=n.getLine(t.line),f=n.getLine(t.line+1),l=i(t.line,o,f);if(100!==l){for(var c=n.lastLine(),u=t.line,d=n.getLine(u+2);u<c&&!(i(u+1,f,d)<=l);)++u,f=d,d=n.getLine(u+2);return{from:e.Pos(t.line,o.length),to:e.Pos(u,n.getLine(u).length)}}}))}));!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.registerHelper("fold","brace",(function(r,n){var t,i=n.line,o=r.getLine(i);function l(l){for(var f=n.ch,s=0;;){var u=f<=0?-1:o.lastIndexOf(l,f-1);if(-1!=u){if(1==s&&u<n.ch)break;if(t=r.getTokenTypeAt(e.Pos(i,u+1)),!/^(comment|string)/.test(t))return u+1;f=u-1}else{if(1==s)break;s=1,f=o.length}}}var f="{",s="}",u=l("{");if(null==u&&(f="[",s="]",u=l("[")),null!=u){var a,d,c=1,g=r.lastLine();e:for(var v=i;v<=g;++v)for(var p=r.getLine(v),m=v==i?u:0;;){var P=p.indexOf(f,m),k=p.indexOf(s,m);if(P<0&&(P=p.length),k<0&&(k=p.length),(m=Math.min(P,k))==p.length)break;if(r.getTokenTypeAt(e.Pos(v,m+1))==t)if(m==P)++c;else if(!--c){a=v,d=m;break e}++m}if(null!=a&&(i!=a||d!=u))return{from:e.Pos(i,u),to:e.Pos(a,d)}}})),e.registerHelper("fold","import",(function(r,n){function t(n){if(n<r.firstLine()||n>r.lastLine())return null;var t=r.getTokenAt(e.Pos(n,1));if(/\S/.test(t.string)||(t=r.getTokenAt(e.Pos(n,t.end+1))),"keyword"!=t.type||"import"!=t.string)return null;for(var i=n,o=Math.min(r.lastLine(),n+10);i<=o;++i){var l=r.getLine(i).indexOf(";");if(-1!=l)return{startCh:t.end,end:e.Pos(i,l)}}}var i,o=n.line,l=t(o);if(!l||t(o-1)||(i=t(o-2))&&i.end.line==o-1)return null;for(var f=l.end;;){var s=t(f.line+1);if(null==s)break;f=s.end}return{from:r.clipPos(e.Pos(o,l.startCh+1)),to:f}})),e.registerHelper("fold","include",(function(r,n){function t(n){if(n<r.firstLine()||n>r.lastLine())return null;var t=r.getTokenAt(e.Pos(n,1));return/\S/.test(t.string)||(t=r.getTokenAt(e.Pos(n,t.end+1))),"meta"==t.type&&"#include"==t.string.slice(0,8)?t.start+8:void 0}var i=n.line,o=t(i);if(null==o||null!=t(i-1))return null;for(var l=i;;){if(null==t(l+1))break;++l}return{from:e.Pos(i,o+1),to:r.clipPos(e.Pos(l))}}))}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.registerGlobalHelper("fold", "comment", function(mode) {
  return mode.blockCommentStart && mode.blockCommentEnd;
}, function(cm, start) {
  var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd;
  if (!startToken || !endToken) return;
  var line = start.line, lineText = cm.getLine(line);

  var startCh;
  for (var at = start.ch, pass = 0;;) {
    var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1);
    if (found == -1) {
      if (pass == 1) return;
      pass = 1;
      at = lineText.length;
      continue;
    }
    if (pass == 1 && found < start.ch) return;
    if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1))) &&
        (found == 0 || lineText.slice(found - endToken.length, found) == endToken ||
         !/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found))))) {
      startCh = found + startToken.length;
      break;
    }
    at = found - 1;
  }

  var depth = 1, lastLine = cm.lastLine(), end, endCh;
  outer: for (var i = line; i <= lastLine; ++i) {
    var text = cm.getLine(i), pos = i == line ? startCh : 0;
    for (;;) {
      var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);
      if (nextOpen < 0) nextOpen = text.length;
      if (nextClose < 0) nextClose = text.length;
      pos = Math.min(nextOpen, nextClose);
      if (pos == text.length) break;
      if (pos == nextOpen) ++depth;
      else if (!--depth) { end = i; endCh = pos; break outer; }
      ++pos;
    }
  }
  if (end == null || line == end && endCh == startCh) return;
  return {from: CodeMirror.Pos(line, startCh),
          to: CodeMirror.Pos(end, endCh)};
});

});
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.registerGlobalHelper("fold","comment",(function(e){return e.blockCommentStart&&e.blockCommentEnd}),(function(t,n){var o=t.getModeAt(n),r=o.blockCommentStart,i=o.blockCommentEnd;if(r&&i){for(var f,l=n.line,c=t.getLine(l),m=n.ch,a=0;;){var d=m<=0?-1:c.lastIndexOf(r,m-1);if(-1!=d){if(1==a&&d<n.ch)return;if(/comment/.test(t.getTokenTypeAt(e.Pos(l,d+1)))&&(0==d||c.slice(d-i.length,d)==i||!/comment/.test(t.getTokenTypeAt(e.Pos(l,d))))){f=d+r.length;break}m=d-1}else{if(1==a)return;a=1,m=c.length}}var s,u,b=1,g=t.lastLine();e:for(var h=l;h<=g;++h)for(var k=t.getLine(h),p=h==l?f:0;;){var v=k.indexOf(r,p),y=k.indexOf(i,p);if(v<0&&(v=k.length),y<0&&(y=k.length),(p=Math.min(v,y))==k.length)break;if(p==v)++b;else if(!--b){s=h,u=p;break e}++p}if(null!=s&&(l!=s||u!=f))return{from:e.Pos(l,f),to:e.Pos(s,u)}}}))}));!function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}((function(n){"use strict";function o(o,e,i,t){if(i&&i.call){var l=i;i=null}else l=r(o,i,"rangeFinder");"number"==typeof e&&(e=n.Pos(e,0));var f=r(o,i,"minFoldSize");function d(n){var r=l(o,e);if(!r||r.to.line-r.from.line<f)return null;for(var i=o.findMarksAt(r.from),d=0;d<i.length;++d)if(i[d].__isFold&&"fold"!==t){if(!n)return null;r.cleared=!0,i[d].clear()}return r}var u=d(!0);if(r(o,i,"scanUp"))for(;!u&&e.line>o.firstLine();)e=n.Pos(e.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,o){var e=r(n,o,"widget");if("string"==typeof e){var i=document.createTextNode(e);(e=document.createElement("span")).appendChild(i),e.className="CodeMirror-foldmarker"}return e}(o,i);n.on(a,"mousedown",(function(o){c.clear(),n.e_preventDefault(o)}));var c=o.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(o,i,"clearOnEnter"),__isFold:!0});c.on("clear",(function(e,r){n.signal(o,"unfold",o,e,r)})),n.signal(o,"fold",o,u.from,u.to)}}n.newFoldFunction=function(n,e){return function(r,i){o(r,i,{rangeFinder:n,widget:e})}},n.defineExtension("foldCode",(function(n,e,r){o(this,n,e,r)})),n.defineExtension("isFolded",(function(n){for(var o=this.findMarksAt(n),e=0;e<o.length;++e)if(o[e].__isFold)return!0})),n.commands.toggleFold=function(n){n.foldCode(n.getCursor())},n.commands.fold=function(n){n.foldCode(n.getCursor(),null,"fold")},n.commands.unfold=function(n){n.foldCode(n.getCursor(),null,"unfold")},n.commands.foldAll=function(o){o.operation((function(){for(var e=o.firstLine(),r=o.lastLine();e<=r;e++)o.foldCode(n.Pos(e,0),null,"fold")}))},n.commands.unfoldAll=function(o){o.operation((function(){for(var e=o.firstLine(),r=o.lastLine();e<=r;e++)o.foldCode(n.Pos(e,0),null,"unfold")}))},n.registerHelper("fold","combine",(function(){var n=Array.prototype.slice.call(arguments,0);return function(o,e){for(var r=0;r<n.length;++r){var i=n[r](o,e);if(i)return i}}})),n.registerHelper("fold","auto",(function(n,o){for(var e=n.getHelpers(o,"fold"),r=0;r<e.length;r++){var i=e[r](n,o);if(i)return i}}));var e={rangeFinder:n.fold.auto,widget:"↔",minFoldSize:0,scanUp:!1,clearOnEnter:!0};function r(n,o,r){if(o&&void 0!==o[r])return o[r];var i=n.options.foldOptions;return i&&void 0!==i[r]?i[r]:e[r]}n.defineOption("foldOptions",null),n.defineExtension("foldOption",(function(n,o){return r(this,n,o)}))}));.CodeMirror-foldmarker {
  color: blue;
  text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
  font-family: arial;
  line-height: .3;
  cursor: pointer;
}
.CodeMirror-foldgutter {
  width: .7em;
}
.CodeMirror-foldgutter-open,
.CodeMirror-foldgutter-folded {
  cursor: pointer;
}
.CodeMirror-foldgutter-open:after {
  content: "\25BE";
}
.CodeMirror-foldgutter-folded:after {
  content: "\25B8";
}
.CodeMirror-merge {
  position: relative;
  border: 1px solid #ddd;
  white-space: pre;
}

.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
  height: 350px;
}

.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }

.CodeMirror-merge-pane {
  display: inline-block;
  white-space: normal;
  vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
  position: absolute;
  right: 0px;
  z-index: 1;
}

.CodeMirror-merge-gap {
  z-index: 2;
  display: inline-block;
  height: 100%;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  overflow: hidden;
  border-left: 1px solid #ddd;
  border-right: 1px solid #ddd;
  position: relative;
  background: #f8f8f8;
}

.CodeMirror-merge-scrolllock-wrap {
  position: absolute;
  bottom: 0; left: 50%;
}
.CodeMirror-merge-scrolllock {
  position: relative;
  left: -50%;
  cursor: pointer;
  color: #555;
  line-height: 1;
}

.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
  position: absolute;
  left: 0; top: 0;
  right: 0; bottom: 0;
  line-height: 1;
}

.CodeMirror-merge-copy {
  position: absolute;
  cursor: pointer;
  color: #44c;
  z-index: 3;
}

.CodeMirror-merge-copy-reverse {
  position: absolute;
  cursor: pointer;
  color: #44c;
}

.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }

.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
  background-position: bottom left;
  background-repeat: repeat-x;
}

.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
  background-position: bottom left;
  background-repeat: repeat-x;
}

.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }

.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }

.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }

.CodeMirror-merge-collapsed-widget:before {
  content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
  cursor: pointer;
  color: #88b;
  background: #eef;
  border: 1px solid #ddf;
  font-size: 90%;
  padding: 0 3px;
  border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","diff_match_patch"],e):e(CodeMirror)}((function(e){"use strict";var t=e.Pos,i="http://www.w3.org/2000/svg";function r(e,t){this.mv=e,this.type=t,this.classes="left"==t?{chunk:"CodeMirror-merge-l-chunk",start:"CodeMirror-merge-l-chunk-start",end:"CodeMirror-merge-l-chunk-end",insert:"CodeMirror-merge-l-inserted",del:"CodeMirror-merge-l-deleted",connect:"CodeMirror-merge-l-connect"}:{chunk:"CodeMirror-merge-r-chunk",start:"CodeMirror-merge-r-chunk-start",end:"CodeMirror-merge-r-chunk-end",insert:"CodeMirror-merge-r-inserted",del:"CodeMirror-merge-r-deleted",connect:"CodeMirror-merge-r-connect"}}function n(t){t.diffOutOfDate&&(t.diff=L(t.orig.getValue(),t.edit.getValue(),t.mv.options.ignoreWhitespace),t.chunks=D(t.diff),t.diffOutOfDate=!1,e.signal(t.edit,"updateDiff",t.diff))}r.prototype={constructor:r,init:function(t,i,r){this.edit=this.mv.edit,(this.edit.state.diffViews||(this.edit.state.diffViews=[])).push(this),this.orig=e(t,W({value:i,readOnly:!this.mv.options.allowEditingOriginals},W(r))),"align"==this.mv.options.connect&&(this.edit.state.trackAlignable||(this.edit.state.trackAlignable=new _(this.edit)),this.orig.state.trackAlignable=new _(this.orig)),this.orig.state.diffViews=[this];var n=r.chunkClassLocation||"background";"[object Array]"!=Object.prototype.toString.call(n)&&(n=[n]),this.classes.classLocation=n,this.diff=L(S(i),S(r.value),this.mv.options.ignoreWhitespace),this.chunks=D(this.diff),this.diffOutOfDate=this.dealigned=!1,this.needsScrollSync=null,this.showDifferences=!1!==r.showDifferences},registerEvents:function(t){this.forceUpdate=function(t){var i,r={from:0,to:0,marked:[]},a={from:0,to:0,marked:[]},s=!1;function c(e){o=!0,s=!1,"full"==e&&(t.svg&&N(t.svg),t.copyButtons&&N(t.copyButtons),h(t.edit,r.marked,t.classes),h(t.orig,a.marked,t.classes),r.from=r.to=a.from=a.to=0),n(t),t.showDifferences&&(f(t.edit,t.diff,r,DIFF_INSERT,t.classes),f(t.orig,t.diff,a,DIFF_DELETE,t.classes)),"align"==t.mv.options.connect&&k(t),u(t),null!=t.needsScrollSync&&l(t,t.needsScrollSync),o=!1}function g(e){o||(t.dealigned=!0,d(e))}function d(e){o||s||(clearTimeout(i),!0===e&&(s=!0),i=setTimeout(c,!0===e?20:250))}function m(e,i){t.diffOutOfDate||(t.diffOutOfDate=!0,r.from=r.to=a.from=a.to=0),g(i.text.length-1!=i.to.line-i.from.line)}function v(){t.diffOutOfDate=!0,t.dealigned=!0,c("full")}t.edit.on("change",m),t.orig.on("change",m),t.edit.on("swapDoc",v),t.orig.on("swapDoc",v),"align"==t.mv.options.connect&&(e.on(t.edit.state.trackAlignable,"realign",g),e.on(t.orig.state.trackAlignable,"realign",g));return t.edit.on("viewportChange",(function(){d(!1)})),t.orig.on("viewportChange",(function(){d(!1)})),c(),c}(this),s(this,!0,!1),function(e,t){e.edit.on("scroll",(function(){l(e,!0)&&u(e)})),e.orig.on("scroll",(function(){l(e,!1)&&u(e),t&&l(t,!0)&&u(t)}))}(this,t)},setShowDifferences:function(e){(e=!1!==e)!=this.showDifferences&&(this.showDifferences=e,this.forceUpdate("full"))}};var o=!1;function l(e,t){if(e.diffOutOfDate)return e.lockScroll&&null==e.needsScrollSync&&(e.needsScrollSync=t),!1;if(e.needsScrollSync=null,!e.lockScroll)return!0;var i,r,n=+new Date;if(t?(i=e.edit,r=e.orig):(i=e.orig,r=e.edit),i.state.scrollSetBy==e&&(i.state.scrollSetAt||0)+250>n)return!1;var o=i.getScrollInfo();if("align"==e.mv.options.connect)v=o.top;else{var l,s,c=.5*o.clientHeight,h=o.top+c,f=i.lineAtHeight(h,"local"),g=function(e,t,i){for(var r,n,o,l,a=0;a<e.length;a++){var s=e[a],c=i?s.editFrom:s.origFrom,h=i?s.editTo:s.origTo;null==n&&(c>t?(n=s.editFrom,l=s.origFrom):h>t&&(n=s.editTo,l=s.origTo)),h<=t?(r=s.editTo,o=s.origTo):c<=t&&(r=s.editFrom,o=s.origFrom)}return{edit:{before:r,after:n},orig:{before:o,after:l}}}(e.chunks,f,t),d=a(i,t?g.edit:g.orig),u=a(r,t?g.orig:g.edit),m=(h-d.top)/(d.bot-d.top),v=u.top-c+m*(u.bot-u.top);if(v>o.top&&(s=o.top/c)<1)v=v*s+o.top*(1-s);else if((l=o.height-o.clientHeight-o.top)<c){var p=r.getScrollInfo();p.height-p.clientHeight-v>l&&(s=l/c)<1&&(v=v*s+(p.height-p.clientHeight-l)*(1-s))}}return r.scrollTo(o.left,v),r.state.scrollSetAt=n,r.state.scrollSetBy=e,!0}function a(e,t){var i=t.after;return null==i&&(i=e.lastLine()+1),{top:e.heightAtLine(t.before||0,"local"),bot:e.heightAtLine(i,"local")}}function s(e,t,i){e.lockScroll=t,t&&0!=i&&l(e,DIFF_INSERT)&&u(e),e.lockButton.innerHTML=t?"⇛⇚":"⇛&nbsp;&nbsp;⇚"}function c(e,t,i){for(var r=i.classLocation,n=0;n<r.length;n++)e.removeLineClass(t,r[n],i.chunk),e.removeLineClass(t,r[n],i.start),e.removeLineClass(t,r[n],i.end)}function h(t,i,r){for(var n=0;n<i.length;++n){var o=i[n];o instanceof e.TextMarker?o.clear():o.parent&&c(t,o,r)}i.length=0}function f(e,t,i,r,n){var o=e.getViewport();e.operation((function(){i.from==i.to||o.from-i.to>20||i.from-o.to>20?(h(e,i.marked,n),d(e,t,r,i.marked,o.from,o.to,n),i.from=o.from,i.to=o.to):(o.from<i.from&&(d(e,t,r,i.marked,o.from,i.from,n),i.from=o.from),o.to>i.to&&(d(e,t,r,i.marked,i.to,o.to,n),i.to=o.to))}))}function g(e,t,i,r,n,o){for(var l=i.classLocation,a=e.getLineHandle(t),s=0;s<l.length;s++)r&&e.addLineClass(a,l[s],i.chunk),n&&e.addLineClass(a,l[s],i.start),o&&e.addLineClass(a,l[s],i.end);return a}function d(e,i,r,n,o,l,a){var s=t(0,0),c=t(o,0),h=e.clipPos(t(l-1)),f=r==DIFF_DELETE?a.del:a.insert;function d(t,i){for(var r=Math.max(o,t),s=Math.min(l,i),c=r;c<s;++c)n.push(g(e,c,a,!0,c==t,c==i-1));t==i&&r==i&&s==i&&(r?n.push(g(e,r-1,a,!1,!1,!0)):n.push(g(e,r,a,!1,!0,!1)))}for(var u=0,m=!1,v=0;v<i.length;++v){var p=i[v],k=p[0],C=p[1];if(k==DIFF_EQUAL){var b=s.line+(E(i,v)?0:1);V(s,C);var w=s.line+(A(i,v)?1:0);w>b&&(m&&(d(u,b),m=!1),u=w)}else if(m=!0,k==r){var T=V(s,C,!0),F=P(c,s),y=H(h,T);j(F,y)||n.push(e.markText(F,y,{className:f})),s=T}}m&&d(u,s.line+1)}function u(e){if(e.showDifferences){if(e.svg){N(e.svg);var t=e.gap.offsetWidth;R(e.svg,"width",t,"height",e.gap.offsetHeight)}e.copyButtons&&N(e.copyButtons);for(var i=e.edit.getViewport(),r=e.orig.getViewport(),n=e.mv.wrap.getBoundingClientRect().top,o=n-e.edit.getScrollerElement().getBoundingClientRect().top+e.edit.getScrollInfo().top,l=n-e.orig.getScrollerElement().getBoundingClientRect().top+e.orig.getScrollInfo().top,a=0;a<e.chunks.length;a++){var s=e.chunks[a];s.editFrom<=i.to&&s.editTo>=i.from&&s.origFrom<=r.to&&s.origTo>=r.from&&w(e,s,l,o,t)}}}function m(e,t){for(var i=0,r=0,n=0;n<t.length;n++){var o=t[n];if(o.editTo>e&&o.editFrom<=e)return null;if(o.editFrom>e)break;i=o.editTo,r=o.origTo}return r+(e-i)}function v(e,t,i){for(var r=e.state.trackAlignable,n=e.firstLine(),o=0,l=[],a=0;;a++){for(var s=t[a],c=s?i?s.origFrom:s.editFrom:1e9;o<r.alignable.length;o+=2){var h=r.alignable[o]+1;if(!(h<=n)){if(!(h<=c))break;l.push(h)}}if(!s)break;l.push(n=i?s.origTo:s.editTo)}return l}function p(e,t,i,r){var n=0,o=0,l=0,a=0;e:for(;;n++){var s=e[n],c=t[o];if(!s&&null==c)break;for(var h=s?s[0]:1e9,f=null==c?1e9:c;l<i.length;){var g=i[l];if(g.origFrom<=f&&g.origTo>f){o++,n--;continue e}if(g.editTo>h){if(g.editFrom<=h)continue e;break}a+=g.origTo-g.origFrom-(g.editTo-g.editFrom),l++}if(h==f-a)s[r]=f,o++;else if(h<f-a)s[r]=h+a;else{var d=[f-a,null,null];d[r]=f,e.splice(n,0,d),o++}}}function k(e,t){if(e.dealigned||t){if(!e.orig.curOp)return e.orig.operation((function(){k(e,t)}));e.dealigned=!1;var i=e.mv.left==e?e.mv.right:e.mv.left;i&&(n(i),i.dealigned=!1);for(var r=function(e,t){var i=v(e.edit,e.chunks,!1),r=[];if(t)for(var n=0,o=0;n<t.chunks.length;n++){for(var l=t.chunks[n].editTo;o<i.length&&i[o]<l;)o++;o!=i.length&&i[o]==l||i.splice(o++,0,l)}for(n=0;n<i.length;n++)r.push([i[n],null,null]);return p(r,v(e.orig,e.chunks,!0),e.chunks,1),t&&p(r,v(t.orig,t.chunks,!0),t.chunks,2),r}(e,i),o=e.mv.aligners,l=0;l<o.length;l++)o[l].clear();o.length=0;var a=[e.edit,e.orig],s=[];i&&a.push(i.orig);for(l=0;l<a.length;l++)s.push(a[l].getScrollInfo().top);for(var c=0;c<r.length;c++)C(a,r[c],o);for(l=0;l<a.length;l++)a[l].scrollTo(null,s[l])}}function C(e,t,i){for(var r=0,n=[],o=0;o<e.length;o++)if(null!=t[o]){var l=e[o].heightAtLine(t[o],"local");n[o]=l,r=Math.max(r,l)}for(o=0;o<e.length;o++)if(null!=t[o]){var a=r-n[o];a>1&&i.push(b(e[o],t[o],a))}}function b(e,t,i){var r=!0;t>e.lastLine()&&(t--,r=!1);var n=document.createElement("div");return n.className="CodeMirror-merge-spacer",n.style.height=i+"px",n.style.minWidth="1px",e.addLineWidget(t,n,{height:i,above:r,mergeSpacer:!0,handleMouseEvents:!0})}function w(e,t,r,n,o){var l="left"==e.type,a=e.orig.heightAtLine(t.origFrom,"local",!0)-r;if(e.svg){var s=a,c=e.edit.heightAtLine(t.editFrom,"local",!0)-n;if(l){var h=s;s=c,c=h}var f=e.orig.heightAtLine(t.origTo,"local",!0)-r,g=e.edit.heightAtLine(t.editTo,"local",!0)-n;if(l){h=f;f=g,g=h}var d=" C "+o/2+" "+c+" "+o/2+" "+s+" "+(o+2)+" "+s,u=" C "+o/2+" "+f+" "+o/2+" "+g+" -1 "+g;R(e.svg.appendChild(document.createElementNS(i,"path")),"d","M -1 "+c+d+" L "+(o+2)+" "+f+u+" z","class",e.classes.connect)}if(e.copyButtons){var m=e.copyButtons.appendChild(I("div","left"==e.type?"⇝":"⇜","CodeMirror-merge-copy")),v=e.mv.options.allowEditingOriginals;if(m.title=v?"Push to left":"Revert chunk",m.chunk=t,m.style.top=(t.origTo>t.origFrom?a:e.edit.heightAtLine(t.editFrom,"local")-n)+"px",v){var p=e.edit.heightAtLine(t.editFrom,"local")-n,k=e.copyButtons.appendChild(I("div","right"==e.type?"⇝":"⇜","CodeMirror-merge-copy-reverse"));k.title="Push to right",k.chunk={editFrom:t.origFrom,editTo:t.origTo,origFrom:t.editFrom,origTo:t.editTo},k.style.top=p+"px","right"==e.type?k.style.left="2px":k.style.right="2px"}}}function T(e,i,r,n){if(!e.diffOutOfDate){var o=n.origTo>r.lastLine()?t(n.origFrom-1):t(n.origFrom,0),l=t(n.origTo,0),a=n.editTo>i.lastLine()?t(n.editFrom-1):t(n.editFrom,0),s=t(n.editTo,0),c=e.mv.options.revertChunk;c?c(e.mv,r,o,l,i,a,s):i.replaceRange(r.getRange(o,l),a,s)}}var F=e.MergeView=function(t,i){if(!(this instanceof F))return new F(t,i);this.options=i;var n=i.origLeft,o=null==i.origRight?i.orig:i.origRight,l=null!=n,a=null!=o,s=1+(l?1:0)+(a?1:0),c=[],h=this.left=null,f=this.right=null,g=this;if(l){h=this.left=new r(this,"left");var d=I("div",null,"CodeMirror-merge-pane CodeMirror-merge-left");c.push(d),c.push(y(h))}var v=I("div",null,"CodeMirror-merge-pane CodeMirror-merge-editor");if(c.push(v),a){f=this.right=new r(this,"right"),c.push(y(f));var p=I("div",null,"CodeMirror-merge-pane CodeMirror-merge-right");c.push(p)}(a?p:v).className+=" CodeMirror-merge-pane-rightmost",c.push(I("div",null,null,"height: 0; clear: both;"));var C=this.wrap=t.appendChild(I("div",c,"CodeMirror-merge CodeMirror-merge-"+s+"pane"));this.edit=e(v,W(i)),h&&h.init(d,n,i),f&&f.init(p,o,i),i.collapseIdentical&&this.editor().operation((function(){!function(e,t){"number"!=typeof t&&(t=2);for(var i=[],r=e.editor(),n=r.firstLine(),o=n,l=r.lastLine();o<=l;o++)i.push(!0);e.left&&B(e.left,t,n,i);e.right&&B(e.right,t,n,i);for(var a=0;a<i.length;a++)if(i[a]){for(var s=a+n,c=1;a<i.length-1&&i[a+1];a++,c++);if(c>t){var h=[{line:s,cm:r}];e.left&&h.push({line:m(s,e.left.chunks),cm:e.left.orig}),e.right&&h.push({line:m(s,e.right.chunks),cm:e.right.orig});var f=x(c,h);e.options.onCollapse&&e.options.onCollapse(e,s,c,f)}}}(g,i.collapseIdentical)})),"align"==i.connect&&(this.aligners=[],k(this.left||this.right,!0)),h&&h.registerEvents(f),f&&f.registerEvents(h);var b=function(){h&&u(h),f&&u(f)};e.on(window,"resize",b);var w=setInterval((function(){for(var t=C.parentNode;t&&t!=document.body;t=t.parentNode);t||(clearInterval(w),e.off(window,"resize",b))}),5e3)};function y(t){var r=t.lockButton=I("div",null,"CodeMirror-merge-scrolllock");r.title="Toggle locked scrolling";var n=I("div",[r],"CodeMirror-merge-scrolllock-wrap");e.on(r,"click",(function(){s(t,!t.lockScroll)}));var o=[n];if(!1!==t.mv.options.revertButtons&&(t.copyButtons=I("div",null,"CodeMirror-merge-copybuttons-"+t.type),e.on(t.copyButtons,"click",(function(e){var i=e.target||e.srcElement;i.chunk&&("CodeMirror-merge-copy-reverse"!=i.className?T(t,t.edit,t.orig,i.chunk):T(t,t.orig,t.edit,i.chunk))})),o.unshift(t.copyButtons)),"align"!=t.mv.options.connect){var l=document.createElementNS&&document.createElementNS(i,"svg");l&&!l.createSVGRect&&(l=null),t.svg=l,l&&o.push(l)}return t.gap=I("div",o,"CodeMirror-merge-gap")}function S(e){return"string"==typeof e?e:e.getValue()}F.prototype={constructor:F,editor:function(){return this.edit},rightOriginal:function(){return this.right&&this.right.orig},leftOriginal:function(){return this.left&&this.left.orig},setShowDifferences:function(e){this.right&&this.right.setShowDifferences(e),this.left&&this.left.setShowDifferences(e)},rightChunks:function(){if(this.right)return n(this.right),this.right.chunks},leftChunks:function(){if(this.left)return n(this.left),this.left.chunks}};var M=new diff_match_patch;function L(e,t,i){for(var r=M.diff_main(e,t),n=0;n<r.length;++n){var o=r[n];(i?/[^ \t]/.test(o[1]):o[1])?n&&r[n-1][0]==o[0]&&(r.splice(n--,1),r[n][1]+=o[1]):r.splice(n--,1)}return r}function D(e){for(var i=[],r=0,n=0,o=t(0,0),l=t(0,0),a=0;a<e.length;++a){var s=e[a],c=s[0];if(c==DIFF_EQUAL){var h=!E(e,a)||o.line<r||l.line<n?1:0,f=o.line+h,g=l.line+h;V(o,s[1],null,l);var d=A(e,a)?1:0,u=o.line+d,m=l.line+d;u>f&&(a&&i.push({origFrom:n,origTo:g,editFrom:r,editTo:f}),r=u,n=m)}else V(c==DIFF_INSERT?o:l,s[1])}return(r<=o.line||n<=l.line)&&i.push({origFrom:n,origTo:l.line+1,editFrom:r,editTo:o.line+1}),i}function A(e,t){if(t==e.length-1)return!0;var i=e[t+1][1];return!(1==i.length&&t<e.length-2||10!=i.charCodeAt(0))&&(t==e.length-2||((i=e[t+2][1]).length>1||t==e.length-3)&&10==i.charCodeAt(0))}function E(e,t){if(0==t)return!0;var i=e[t-1][1];return 10==i.charCodeAt(i.length-1)&&(1==t||10==(i=e[t-2][1]).charCodeAt(i.length-1))}function O(i,r,n){i.addLineClass(r,"wrap","CodeMirror-merge-collapsed-line");var o=document.createElement("span");o.className="CodeMirror-merge-collapsed-widget",o.title="Identical text collapsed. Click to expand.";var l=i.markText(t(r,0),t(n-1),{inclusiveLeft:!0,inclusiveRight:!0,replacedWith:o,clearOnEnter:!0});function a(){l.clear(),i.removeLineClass(r,"wrap","CodeMirror-merge-collapsed-line")}return e.on(o,"click",a),{mark:l,clear:a}}function x(e,t){var i=[];function r(){for(var e=0;e<i.length;e++)i[e].clear()}for(var n=0;n<t.length;n++){var o=t[n],l=O(o.cm,o.line,o.line+e);i.push(l),l.mark.on("clear",r)}return i[0].mark}function B(e,t,i,r){for(var n=0;n<e.chunks.length;n++)for(var o=e.chunks[n],l=o.editFrom-t;l<o.editTo+t;l++){var a=l+i;a>=0&&a<r.length&&(r[a]=!1)}}function I(e,t,i,r){var n=document.createElement(e);if(i&&(n.className=i),r&&(n.style.cssText=r),"string"==typeof t)n.appendChild(document.createTextNode(t));else if(t)for(var o=0;o<t.length;++o)n.appendChild(t[o]);return n}function N(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild)}function R(e){for(var t=1;t<arguments.length;t+=2)e.setAttribute(arguments[t],arguments[t+1])}function W(e,t){for(var i in t||(t={}),e)e.hasOwnProperty(i)&&(t[i]=e[i]);return t}function V(e,i,r,n){for(var o=r?t(e.line,e.ch):e,l=0;;){var a=i.indexOf("\n",l);if(-1==a)break;++o.line,n&&++n.line,l=a+1}return o.ch=(l?0:o.ch)+(i.length-l),n&&(n.ch=(l?0:n.ch)+(i.length-l)),o}function _(e){this.cm=e,this.alignable=[],this.height=e.doc.height;var t=this;e.on("markerAdded",(function(e,i){if(i.collapsed){var r=i.find(1);null!=r&&t.set(r.line,4)}})),e.on("markerCleared",(function(e,i,r,n){null!=n&&i.collapsed&&t.check(n,4,t.hasMarker)})),e.on("markerChanged",this.signal.bind(this)),e.on("lineWidgetAdded",(function(e,i,r){i.mergeSpacer||(i.above?t.set(r-1,2):t.set(r,1))})),e.on("lineWidgetCleared",(function(e,i,r){i.mergeSpacer||(i.above?t.check(r-1,2,t.hasWidgetBelow):t.check(r,1,t.hasWidget))})),e.on("lineWidgetChanged",this.signal.bind(this)),e.on("change",(function(e,i){var r=i.from.line,n=i.to.line-i.from.line,o=i.text.length-1,l=r+o;(n||o)&&t.map(r,n,o),t.check(l,4,t.hasMarker),(n||o)&&t.check(i.from.line,4,t.hasMarker)})),e.on("viewportChange",(function(){t.cm.doc.height!=t.height&&t.signal()}))}function H(e,t){return(e.line-t.line||e.ch-t.ch)<0?e:t}function P(e,t){return(e.line-t.line||e.ch-t.ch)>0?e:t}function j(e,t){return e.line==t.line&&e.ch==t.ch}function U(e,t,i){for(var r=e.length-1;r>=0;r--){var n=e[r],o=(i?n.origTo:n.editTo)-1;if(o<t)return o}}function z(e,t,i){for(var r=0;r<e.length;r++){var n=e[r],o=i?n.origFrom:n.editFrom;if(o>t)return o}}function Q(t,i){var r=null,o=t.state.diffViews,l=t.getCursor().line;if(o)for(var a=0;a<o.length;a++){var s=o[a],c=t==s.orig;n(s);var h=i<0?U(s.chunks,l,c):z(s.chunks,l,c);null==h||null!=r&&!(i<0?h>r:h<r)||(r=h)}if(null==r)return e.Pass;t.setCursor(r,0)}_.prototype={signal:function(){e.signal(this,"realign"),this.height=this.cm.doc.height},set:function(e,t){for(var i=-1;i<this.alignable.length;i+=2){var r=this.alignable[i]-e;if(0==r){if((this.alignable[i+1]&t)==t)return;return this.alignable[i+1]|=t,void this.signal()}if(r>0)break}this.signal(),this.alignable.splice(i,0,e,t)},find:function(e){for(var t=0;t<this.alignable.length;t+=2)if(this.alignable[t]==e)return t;return-1},check:function(e,t,i){var r=this.find(e);if(-1!=r&&this.alignable[r+1]&t&&!i.call(this,e)){this.signal();var n=this.alignable[r+1]&~t;n?this.alignable[r+1]=n:this.alignable.splice(r,2)}},hasMarker:function(e){var t=this.cm.getLineHandle(e);if(t.markedSpans)for(var i=0;i<t.markedSpans.length;i++)if(t.markedSpans[i].mark.collapsed&&null!=t.markedSpans[i].to)return!0;return!1},hasWidget:function(e){var t=this.cm.getLineHandle(e);if(t.widgets)for(var i=0;i<t.widgets.length;i++)if(!t.widgets[i].above&&!t.widgets[i].mergeSpacer)return!0;return!1},hasWidgetBelow:function(e){if(e==this.cm.lastLine())return!1;var t=this.cm.getLineHandle(e+1);if(t.widgets)for(var i=0;i<t.widgets.length;i++)if(t.widgets[i].above&&!t.widgets[i].mergeSpacer)return!0;return!1},map:function(e,t,i){for(var r=i-t,n=e+t,o=-1,l=-1,a=0;a<this.alignable.length;a+=2){var s=this.alignable[a];s==e&&2&this.alignable[a+1]&&(o=a),s==n&&2&this.alignable[a+1]&&(l=a),s<=e||(s<n?this.alignable.splice(a--,2):this.alignable[a]+=r)}if(o>-1){var c=this.alignable[o+1];2==c?this.alignable.splice(o,2):this.alignable[o+1]=-3&c}l>-1&&i&&this.set(e+i,2)}},e.commands.goNextDiff=function(e){return Q(e,1)},e.commands.goPrevDiff=function(e){return Q(e,-1)}}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// declare global: diff_match_patch, DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror")); // Note non-packaged dependency diff_match_patch
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "diff_match_patch"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";
  var Pos = CodeMirror.Pos;
  var svgNS = "http://www.w3.org/2000/svg";

  function DiffView(mv, type) {
    this.mv = mv;
    this.type = type;
    this.classes = type == "left"
      ? {chunk: "CodeMirror-merge-l-chunk",
         start: "CodeMirror-merge-l-chunk-start",
         end: "CodeMirror-merge-l-chunk-end",
         insert: "CodeMirror-merge-l-inserted",
         del: "CodeMirror-merge-l-deleted",
         connect: "CodeMirror-merge-l-connect"}
      : {chunk: "CodeMirror-merge-r-chunk",
         start: "CodeMirror-merge-r-chunk-start",
         end: "CodeMirror-merge-r-chunk-end",
         insert: "CodeMirror-merge-r-inserted",
         del: "CodeMirror-merge-r-deleted",
         connect: "CodeMirror-merge-r-connect"};
  }

  DiffView.prototype = {
    constructor: DiffView,
    init: function(pane, orig, options) {
      this.edit = this.mv.edit;
      ;(this.edit.state.diffViews || (this.edit.state.diffViews = [])).push(this);
      this.orig = CodeMirror(pane, copyObj({value: orig, readOnly: !this.mv.options.allowEditingOriginals}, copyObj(options)));
      if (this.mv.options.connect == "align") {
        if (!this.edit.state.trackAlignable) this.edit.state.trackAlignable = new TrackAlignable(this.edit)
        this.orig.state.trackAlignable = new TrackAlignable(this.orig)
      }

      this.orig.state.diffViews = [this];
      var classLocation = options.chunkClassLocation || "background";
      if (Object.prototype.toString.call(classLocation) != "[object Array]") classLocation = [classLocation]
      this.classes.classLocation = classLocation

      this.diff = getDiff(asString(orig), asString(options.value), this.mv.options.ignoreWhitespace);
      this.chunks = getChunks(this.diff);
      this.diffOutOfDate = this.dealigned = false;
      this.needsScrollSync = null

      this.showDifferences = options.showDifferences !== false;
    },
    registerEvents: function(otherDv) {
      this.forceUpdate = registerUpdate(this);
      setScrollLock(this, true, false);
      registerScroll(this, otherDv);
    },
    setShowDifferences: function(val) {
      val = val !== false;
      if (val != this.showDifferences) {
        this.showDifferences = val;
        this.forceUpdate("full");
      }
    }
  };

  function ensureDiff(dv) {
    if (dv.diffOutOfDate) {
      dv.diff = getDiff(dv.orig.getValue(), dv.edit.getValue(), dv.mv.options.ignoreWhitespace);
      dv.chunks = getChunks(dv.diff);
      dv.diffOutOfDate = false;
      CodeMirror.signal(dv.edit, "updateDiff", dv.diff);
    }
  }

  var updating = false;
  function registerUpdate(dv) {
    var edit = {from: 0, to: 0, marked: []};
    var orig = {from: 0, to: 0, marked: []};
    var debounceChange, updatingFast = false;
    function update(mode) {
      updating = true;
      updatingFast = false;
      if (mode == "full") {
        if (dv.svg) clear(dv.svg);
        if (dv.copyButtons) clear(dv.copyButtons);
        clearMarks(dv.edit, edit.marked, dv.classes);
        clearMarks(dv.orig, orig.marked, dv.classes);
        edit.from = edit.to = orig.from = orig.to = 0;
      }
      ensureDiff(dv);
      if (dv.showDifferences) {
        updateMarks(dv.edit, dv.diff, edit, DIFF_INSERT, dv.classes);
        updateMarks(dv.orig, dv.diff, orig, DIFF_DELETE, dv.classes);
      }

      if (dv.mv.options.connect == "align")
        alignChunks(dv);
      makeConnections(dv);
      if (dv.needsScrollSync != null) syncScroll(dv, dv.needsScrollSync)

      updating = false;
    }
    function setDealign(fast) {
      if (updating) return;
      dv.dealigned = true;
      set(fast);
    }
    function set(fast) {
      if (updating || updatingFast) return;
      clearTimeout(debounceChange);
      if (fast === true) updatingFast = true;
      debounceChange = setTimeout(update, fast === true ? 20 : 250);
    }
    function change(_cm, change) {
      if (!dv.diffOutOfDate) {
        dv.diffOutOfDate = true;
        edit.from = edit.to = orig.from = orig.to = 0;
      }
      // Update faster when a line was added/removed
      setDealign(change.text.length - 1 != change.to.line - change.from.line);
    }
    function swapDoc() {
      dv.diffOutOfDate = true;
      dv.dealigned = true;
      update("full");
    }
    dv.edit.on("change", change);
    dv.orig.on("change", change);
    dv.edit.on("swapDoc", swapDoc);
    dv.orig.on("swapDoc", swapDoc);
    if (dv.mv.options.connect == "align") {
      CodeMirror.on(dv.edit.state.trackAlignable, "realign", setDealign)
      CodeMirror.on(dv.orig.state.trackAlignable, "realign", setDealign)
    }
    dv.edit.on("viewportChange", function() { set(false); });
    dv.orig.on("viewportChange", function() { set(false); });
    update();
    return update;
  }

  function registerScroll(dv, otherDv) {
    dv.edit.on("scroll", function() {
      syncScroll(dv, true) && makeConnections(dv);
    });
    dv.orig.on("scroll", function() {
      syncScroll(dv, false) && makeConnections(dv);
      if (otherDv) syncScroll(otherDv, true) && makeConnections(otherDv);
    });
  }

  function syncScroll(dv, toOrig) {
    // Change handler will do a refresh after a timeout when diff is out of date
    if (dv.diffOutOfDate) {
      if (dv.lockScroll && dv.needsScrollSync == null) dv.needsScrollSync = toOrig
      return false
    }
    dv.needsScrollSync = null
    if (!dv.lockScroll) return true;
    var editor, other, now = +new Date;
    if (toOrig) { editor = dv.edit; other = dv.orig; }
    else { editor = dv.orig; other = dv.edit; }
    // Don't take action if the position of this editor was recently set
    // (to prevent feedback loops)
    if (editor.state.scrollSetBy == dv && (editor.state.scrollSetAt || 0) + 250 > now) return false;

    var sInfo = editor.getScrollInfo();
    if (dv.mv.options.connect == "align") {
      targetPos = sInfo.top;
    } else {
      var halfScreen = .5 * sInfo.clientHeight, midY = sInfo.top + halfScreen;
      var mid = editor.lineAtHeight(midY, "local");
      var around = chunkBoundariesAround(dv.chunks, mid, toOrig);
      var off = getOffsets(editor, toOrig ? around.edit : around.orig);
      var offOther = getOffsets(other, toOrig ? around.orig : around.edit);
      var ratio = (midY - off.top) / (off.bot - off.top);
      var targetPos = (offOther.top - halfScreen) + ratio * (offOther.bot - offOther.top);

      var botDist, mix;
      // Some careful tweaking to make sure no space is left out of view
      // when scrolling to top or bottom.
      if (targetPos > sInfo.top && (mix = sInfo.top / halfScreen) < 1) {
        targetPos = targetPos * mix + sInfo.top * (1 - mix);
      } else if ((botDist = sInfo.height - sInfo.clientHeight - sInfo.top) < halfScreen) {
        var otherInfo = other.getScrollInfo();
        var botDistOther = otherInfo.height - otherInfo.clientHeight - targetPos;
        if (botDistOther > botDist && (mix = botDist / halfScreen) < 1)
          targetPos = targetPos * mix + (otherInfo.height - otherInfo.clientHeight - botDist) * (1 - mix);
      }
    }

    other.scrollTo(sInfo.left, targetPos);
    other.state.scrollSetAt = now;
    other.state.scrollSetBy = dv;
    return true;
  }

  function getOffsets(editor, around) {
    var bot = around.after;
    if (bot == null) bot = editor.lastLine() + 1;
    return {top: editor.heightAtLine(around.before || 0, "local"),
            bot: editor.heightAtLine(bot, "local")};
  }

  function setScrollLock(dv, val, action) {
    dv.lockScroll = val;
    if (val && action != false) syncScroll(dv, DIFF_INSERT) && makeConnections(dv);
    dv.lockButton.innerHTML = val ? "\u21db\u21da" : "\u21db&nbsp;&nbsp;\u21da";
  }

  // Updating the marks for editor content

  function removeClass(editor, line, classes) {
    var locs = classes.classLocation
    for (var i = 0; i < locs.length; i++) {
      editor.removeLineClass(line, locs[i], classes.chunk);
      editor.removeLineClass(line, locs[i], classes.start);
      editor.removeLineClass(line, locs[i], classes.end);
    }
  }

  function clearMarks(editor, arr, classes) {
    for (var i = 0; i < arr.length; ++i) {
      var mark = arr[i];
      if (mark instanceof CodeMirror.TextMarker)
        mark.clear();
      else if (mark.parent)
        removeClass(editor, mark, classes);
    }
    arr.length = 0;
  }

  // FIXME maybe add a margin around viewport to prevent too many updates
  function updateMarks(editor, diff, state, type, classes) {
    var vp = editor.getViewport();
    editor.operation(function() {
      if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
        clearMarks(editor, state.marked, classes);
        markChanges(editor, diff, type, state.marked, vp.from, vp.to, classes);
        state.from = vp.from; state.to = vp.to;
      } else {
        if (vp.from < state.from) {
          markChanges(editor, diff, type, state.marked, vp.from, state.from, classes);
          state.from = vp.from;
        }
        if (vp.to > state.to) {
          markChanges(editor, diff, type, state.marked, state.to, vp.to, classes);
          state.to = vp.to;
        }
      }
    });
  }

  function addClass(editor, lineNr, classes, main, start, end) {
    var locs = classes.classLocation, line = editor.getLineHandle(lineNr);
    for (var i = 0; i < locs.length; i++) {
      if (main) editor.addLineClass(line, locs[i], classes.chunk);
      if (start) editor.addLineClass(line, locs[i], classes.start);
      if (end) editor.addLineClass(line, locs[i], classes.end);
    }
    return line;
  }

  function markChanges(editor, diff, type, marks, from, to, classes) {
    var pos = Pos(0, 0);
    var top = Pos(from, 0), bot = editor.clipPos(Pos(to - 1));
    var cls = type == DIFF_DELETE ? classes.del : classes.insert;
    function markChunk(start, end) {
      var bfrom = Math.max(from, start), bto = Math.min(to, end);
      for (var i = bfrom; i < bto; ++i)
        marks.push(addClass(editor, i, classes, true, i == start, i == end - 1));
      // When the chunk is empty, make sure a horizontal line shows up
      if (start == end && bfrom == end && bto == end) {
        if (bfrom)
          marks.push(addClass(editor, bfrom - 1, classes, false, false, true));
        else
          marks.push(addClass(editor, bfrom, classes, false, true, false));
      }
    }

    var chunkStart = 0, pending = false;
    for (var i = 0; i < diff.length; ++i) {
      var part = diff[i], tp = part[0], str = part[1];
      if (tp == DIFF_EQUAL) {
        var cleanFrom = pos.line + (startOfLineClean(diff, i) ? 0 : 1);
        moveOver(pos, str);
        var cleanTo = pos.line + (endOfLineClean(diff, i) ? 1 : 0);
        if (cleanTo > cleanFrom) {
          if (pending) { markChunk(chunkStart, cleanFrom); pending = false }
          chunkStart = cleanTo;
        }
      } else {
        pending = true
        if (tp == type) {
          var end = moveOver(pos, str, true);
          var a = posMax(top, pos), b = posMin(bot, end);
          if (!posEq(a, b))
            marks.push(editor.markText(a, b, {className: cls}));
          pos = end;
        }
      }
    }
    if (pending) markChunk(chunkStart, pos.line + 1);
  }

  // Updating the gap between editor and original

  function makeConnections(dv) {
    if (!dv.showDifferences) return;

    if (dv.svg) {
      clear(dv.svg);
      var w = dv.gap.offsetWidth;
      attrs(dv.svg, "width", w, "height", dv.gap.offsetHeight);
    }
    if (dv.copyButtons) clear(dv.copyButtons);

    var vpEdit = dv.edit.getViewport(), vpOrig = dv.orig.getViewport();
    var outerTop = dv.mv.wrap.getBoundingClientRect().top
    var sTopEdit = outerTop - dv.edit.getScrollerElement().getBoundingClientRect().top + dv.edit.getScrollInfo().top
    var sTopOrig = outerTop - dv.orig.getScrollerElement().getBoundingClientRect().top + dv.orig.getScrollInfo().top;
    for (var i = 0; i < dv.chunks.length; i++) {
      var ch = dv.chunks[i];
      if (ch.editFrom <= vpEdit.to && ch.editTo >= vpEdit.from &&
          ch.origFrom <= vpOrig.to && ch.origTo >= vpOrig.from)
        drawConnectorsForChunk(dv, ch, sTopOrig, sTopEdit, w);
    }
  }

  function getMatchingOrigLine(editLine, chunks) {
    var editStart = 0, origStart = 0;
    for (var i = 0; i < chunks.length; i++) {
      var chunk = chunks[i];
      if (chunk.editTo > editLine && chunk.editFrom <= editLine) return null;
      if (chunk.editFrom > editLine) break;
      editStart = chunk.editTo;
      origStart = chunk.origTo;
    }
    return origStart + (editLine - editStart);
  }

  // Combines information about chunks and widgets/markers to return
  // an array of lines, in a single editor, that probably need to be
  // aligned with their counterparts in the editor next to it.
  function alignableFor(cm, chunks, isOrig) {
    var tracker = cm.state.trackAlignable
    var start = cm.firstLine(), trackI = 0
    var result = []
    for (var i = 0;; i++) {
      var chunk = chunks[i]
      var chunkStart = !chunk ? 1e9 : isOrig ? chunk.origFrom : chunk.editFrom
      for (; trackI < tracker.alignable.length; trackI += 2) {
        var n = tracker.alignable[trackI] + 1
        if (n <= start) continue
        if (n <= chunkStart) result.push(n)
        else break
      }
      if (!chunk) break
      result.push(start = isOrig ? chunk.origTo : chunk.editTo)
    }
    return result
  }

  // Given information about alignable lines in two editors, fill in
  // the result (an array of three-element arrays) to reflect the
  // lines that need to be aligned with each other.
  function mergeAlignable(result, origAlignable, chunks, setIndex) {
    var rI = 0, origI = 0, chunkI = 0, diff = 0
    outer: for (;; rI++) {
      var nextR = result[rI], nextO = origAlignable[origI]
      if (!nextR && nextO == null) break

      var rLine = nextR ? nextR[0] : 1e9, oLine = nextO == null ? 1e9 : nextO
      while (chunkI < chunks.length) {
        var chunk = chunks[chunkI]
        if (chunk.origFrom <= oLine && chunk.origTo > oLine) {
          origI++
          rI--
          continue outer;
        }
        if (chunk.editTo > rLine) {
          if (chunk.editFrom <= rLine) continue outer;
          break
        }
        diff += (chunk.origTo - chunk.origFrom) - (chunk.editTo - chunk.editFrom)
        chunkI++
      }
      if (rLine == oLine - diff) {
        nextR[setIndex] = oLine
        origI++
      } else if (rLine < oLine - diff) {
        nextR[setIndex] = rLine + diff
      } else {
        var record = [oLine - diff, null, null]
        record[setIndex] = oLine
        result.splice(rI, 0, record)
        origI++
      }
    }
  }

  function findAlignedLines(dv, other) {
    var alignable = alignableFor(dv.edit, dv.chunks, false), result = []
    if (other) for (var i = 0, j = 0; i < other.chunks.length; i++) {
      var n = other.chunks[i].editTo
      while (j < alignable.length && alignable[j] < n) j++
      if (j == alignable.length || alignable[j] != n) alignable.splice(j++, 0, n)
    }
    for (var i = 0; i < alignable.length; i++)
      result.push([alignable[i], null, null])

    mergeAlignable(result, alignableFor(dv.orig, dv.chunks, true), dv.chunks, 1)
    if (other)
      mergeAlignable(result, alignableFor(other.orig, other.chunks, true), other.chunks, 2)

    return result
  }

  function alignChunks(dv, force) {
    if (!dv.dealigned && !force) return;
    if (!dv.orig.curOp) return dv.orig.operation(function() {
      alignChunks(dv, force);
    });

    dv.dealigned = false;
    var other = dv.mv.left == dv ? dv.mv.right : dv.mv.left;
    if (other) {
      ensureDiff(other);
      other.dealigned = false;
    }
    var linesToAlign = findAlignedLines(dv, other);

    // Clear old aligners
    var aligners = dv.mv.aligners;
    for (var i = 0; i < aligners.length; i++)
      aligners[i].clear();
    aligners.length = 0;

    var cm = [dv.edit, dv.orig], scroll = [];
    if (other) cm.push(other.orig);
    for (var i = 0; i < cm.length; i++)
      scroll.push(cm[i].getScrollInfo().top);

    for (var ln = 0; ln < linesToAlign.length; ln++)
      alignLines(cm, linesToAlign[ln], aligners);

    for (var i = 0; i < cm.length; i++)
      cm[i].scrollTo(null, scroll[i]);
  }

  function alignLines(cm, lines, aligners) {
    var maxOffset = 0, offset = [];
    for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
      var off = cm[i].heightAtLine(lines[i], "local");
      offset[i] = off;
      maxOffset = Math.max(maxOffset, off);
    }
    for (var i = 0; i < cm.length; i++) if (lines[i] != null) {
      var diff = maxOffset - offset[i];
      if (diff > 1)
        aligners.push(padAbove(cm[i], lines[i], diff));
    }
  }

  function padAbove(cm, line, size) {
    var above = true;
    if (line > cm.lastLine()) {
      line--;
      above = false;
    }
    var elt = document.createElement("div");
    elt.className = "CodeMirror-merge-spacer";
    elt.style.height = size + "px"; elt.style.minWidth = "1px";
    return cm.addLineWidget(line, elt, {height: size, above: above, mergeSpacer: true, handleMouseEvents: true});
  }

  function drawConnectorsForChunk(dv, chunk, sTopOrig, sTopEdit, w) {
    var flip = dv.type == "left";
    var top = dv.orig.heightAtLine(chunk.origFrom, "local", true) - sTopOrig;
    if (dv.svg) {
      var topLpx = top;
      var topRpx = dv.edit.heightAtLine(chunk.editFrom, "local", true) - sTopEdit;
      if (flip) { var tmp = topLpx; topLpx = topRpx; topRpx = tmp; }
      var botLpx = dv.orig.heightAtLine(chunk.origTo, "local", true) - sTopOrig;
      var botRpx = dv.edit.heightAtLine(chunk.editTo, "local", true) - sTopEdit;
      if (flip) { var tmp = botLpx; botLpx = botRpx; botRpx = tmp; }
      var curveTop = " C " + w/2 + " " + topRpx + " " + w/2 + " " + topLpx + " " + (w + 2) + " " + topLpx;
      var curveBot = " C " + w/2 + " " + botLpx + " " + w/2 + " " + botRpx + " -1 " + botRpx;
      attrs(dv.svg.appendChild(document.createElementNS(svgNS, "path")),
            "d", "M -1 " + topRpx + curveTop + " L " + (w + 2) + " " + botLpx + curveBot + " z",
            "class", dv.classes.connect);
    }
    if (dv.copyButtons) {
      var copy = dv.copyButtons.appendChild(elt("div", dv.type == "left" ? "\u21dd" : "\u21dc",
                                                "CodeMirror-merge-copy"));
      var editOriginals = dv.mv.options.allowEditingOriginals;
      copy.title = editOriginals ? "Push to left" : "Revert chunk";
      copy.chunk = chunk;
      copy.style.top = (chunk.origTo > chunk.origFrom ? top : dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit) + "px";

      if (editOriginals) {
        var topReverse = dv.edit.heightAtLine(chunk.editFrom, "local") - sTopEdit;
        var copyReverse = dv.copyButtons.appendChild(elt("div", dv.type == "right" ? "\u21dd" : "\u21dc",
                                                         "CodeMirror-merge-copy-reverse"));
        copyReverse.title = "Push to right";
        copyReverse.chunk = {editFrom: chunk.origFrom, editTo: chunk.origTo,
                             origFrom: chunk.editFrom, origTo: chunk.editTo};
        copyReverse.style.top = topReverse + "px";
        dv.type == "right" ? copyReverse.style.left = "2px" : copyReverse.style.right = "2px";
      }
    }
  }

  function copyChunk(dv, to, from, chunk) {
    if (dv.diffOutOfDate) return;
    var origStart = chunk.origTo > from.lastLine() ? Pos(chunk.origFrom - 1) : Pos(chunk.origFrom, 0)
    var origEnd = Pos(chunk.origTo, 0)
    var editStart = chunk.editTo > to.lastLine() ? Pos(chunk.editFrom - 1) : Pos(chunk.editFrom, 0)
    var editEnd = Pos(chunk.editTo, 0)
    var handler = dv.mv.options.revertChunk
    if (handler)
      handler(dv.mv, from, origStart, origEnd, to, editStart, editEnd)
    else
      to.replaceRange(from.getRange(origStart, origEnd), editStart, editEnd)
  }

  // Merge view, containing 0, 1, or 2 diff views.

  var MergeView = CodeMirror.MergeView = function(node, options) {
    if (!(this instanceof MergeView)) return new MergeView(node, options);

    this.options = options;
    var origLeft = options.origLeft, origRight = options.origRight == null ? options.orig : options.origRight;

    var hasLeft = origLeft != null, hasRight = origRight != null;
    var panes = 1 + (hasLeft ? 1 : 0) + (hasRight ? 1 : 0);
    var wrap = [], left = this.left = null, right = this.right = null;
    var self = this;

    if (hasLeft) {
      left = this.left = new DiffView(this, "left");
      var leftPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-left");
      wrap.push(leftPane);
      wrap.push(buildGap(left));
    }

    var editPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-editor");
    wrap.push(editPane);

    if (hasRight) {
      right = this.right = new DiffView(this, "right");
      wrap.push(buildGap(right));
      var rightPane = elt("div", null, "CodeMirror-merge-pane CodeMirror-merge-right");
      wrap.push(rightPane);
    }

    (hasRight ? rightPane : editPane).className += " CodeMirror-merge-pane-rightmost";

    wrap.push(elt("div", null, null, "height: 0; clear: both;"));

    var wrapElt = this.wrap = node.appendChild(elt("div", wrap, "CodeMirror-merge CodeMirror-merge-" + panes + "pane"));
    this.edit = CodeMirror(editPane, copyObj(options));

    if (left) left.init(leftPane, origLeft, options);
    if (right) right.init(rightPane, origRight, options);
    if (options.collapseIdentical)
      this.editor().operation(function() {
        collapseIdenticalStretches(self, options.collapseIdentical);
      });
    if (options.connect == "align") {
      this.aligners = [];
      alignChunks(this.left || this.right, true);
    }
    if (left) left.registerEvents(right)
    if (right) right.registerEvents(left)


    var onResize = function() {
      if (left) makeConnections(left);
      if (right) makeConnections(right);
    };
    CodeMirror.on(window, "resize", onResize);
    var resizeInterval = setInterval(function() {
      for (var p = wrapElt.parentNode; p && p != document.body; p = p.parentNode) {}
      if (!p) { clearInterval(resizeInterval); CodeMirror.off(window, "resize", onResize); }
    }, 5000);
  };

  function buildGap(dv) {
    var lock = dv.lockButton = elt("div", null, "CodeMirror-merge-scrolllock");
    lock.title = "Toggle locked scrolling";
    var lockWrap = elt("div", [lock], "CodeMirror-merge-scrolllock-wrap");
    CodeMirror.on(lock, "click", function() { setScrollLock(dv, !dv.lockScroll); });
    var gapElts = [lockWrap];
    if (dv.mv.options.revertButtons !== false) {
      dv.copyButtons = elt("div", null, "CodeMirror-merge-copybuttons-" + dv.type);
      CodeMirror.on(dv.copyButtons, "click", function(e) {
        var node = e.target || e.srcElement;
        if (!node.chunk) return;
        if (node.className == "CodeMirror-merge-copy-reverse") {
          copyChunk(dv, dv.orig, dv.edit, node.chunk);
          return;
        }
        copyChunk(dv, dv.edit, dv.orig, node.chunk);
      });
      gapElts.unshift(dv.copyButtons);
    }
    if (dv.mv.options.connect != "align") {
      var svg = document.createElementNS && document.createElementNS(svgNS, "svg");
      if (svg && !svg.createSVGRect) svg = null;
      dv.svg = svg;
      if (svg) gapElts.push(svg);
    }

    return dv.gap = elt("div", gapElts, "CodeMirror-merge-gap");
  }

  MergeView.prototype = {
    constructor: MergeView,
    editor: function() { return this.edit; },
    rightOriginal: function() { return this.right && this.right.orig; },
    leftOriginal: function() { return this.left && this.left.orig; },
    setShowDifferences: function(val) {
      if (this.right) this.right.setShowDifferences(val);
      if (this.left) this.left.setShowDifferences(val);
    },
    rightChunks: function() {
      if (this.right) { ensureDiff(this.right); return this.right.chunks; }
    },
    leftChunks: function() {
      if (this.left) { ensureDiff(this.left); return this.left.chunks; }
    }
  };

  function asString(obj) {
    if (typeof obj == "string") return obj;
    else return obj.getValue();
  }

  // Operations on diffs

  var dmp = new diff_match_patch();
  function getDiff(a, b, ignoreWhitespace) {
    var diff = dmp.diff_main(a, b);
    // The library sometimes leaves in empty parts, which confuse the algorithm
    for (var i = 0; i < diff.length; ++i) {
      var part = diff[i];
      if (ignoreWhitespace ? !/[^ \t]/.test(part[1]) : !part[1]) {
        diff.splice(i--, 1);
      } else if (i && diff[i - 1][0] == part[0]) {
        diff.splice(i--, 1);
        diff[i][1] += part[1];
      }
    }
    return diff;
  }

  function getChunks(diff) {
    var chunks = [];
    var startEdit = 0, startOrig = 0;
    var edit = Pos(0, 0), orig = Pos(0, 0);
    for (var i = 0; i < diff.length; ++i) {
      var part = diff[i], tp = part[0];
      if (tp == DIFF_EQUAL) {
        var startOff = !startOfLineClean(diff, i) || edit.line < startEdit || orig.line < startOrig ? 1 : 0;
        var cleanFromEdit = edit.line + startOff, cleanFromOrig = orig.line + startOff;
        moveOver(edit, part[1], null, orig);
        var endOff = endOfLineClean(diff, i) ? 1 : 0;
        var cleanToEdit = edit.line + endOff, cleanToOrig = orig.line + endOff;
        if (cleanToEdit > cleanFromEdit) {
          if (i) chunks.push({origFrom: startOrig, origTo: cleanFromOrig,
                              editFrom: startEdit, editTo: cleanFromEdit});
          startEdit = cleanToEdit; startOrig = cleanToOrig;
        }
      } else {
        moveOver(tp == DIFF_INSERT ? edit : orig, part[1]);
      }
    }
    if (startEdit <= edit.line || startOrig <= orig.line)
      chunks.push({origFrom: startOrig, origTo: orig.line + 1,
                   editFrom: startEdit, editTo: edit.line + 1});
    return chunks;
  }

  function endOfLineClean(diff, i) {
    if (i == diff.length - 1) return true;
    var next = diff[i + 1][1];
    if ((next.length == 1 && i < diff.length - 2) || next.charCodeAt(0) != 10) return false;
    if (i == diff.length - 2) return true;
    next = diff[i + 2][1];
    return (next.length > 1 || i == diff.length - 3) && next.charCodeAt(0) == 10;
  }

  function startOfLineClean(diff, i) {
    if (i == 0) return true;
    var last = diff[i - 1][1];
    if (last.charCodeAt(last.length - 1) != 10) return false;
    if (i == 1) return true;
    last = diff[i - 2][1];
    return last.charCodeAt(last.length - 1) == 10;
  }

  function chunkBoundariesAround(chunks, n, nInEdit) {
    var beforeE, afterE, beforeO, afterO;
    for (var i = 0; i < chunks.length; i++) {
      var chunk = chunks[i];
      var fromLocal = nInEdit ? chunk.editFrom : chunk.origFrom;
      var toLocal = nInEdit ? chunk.editTo : chunk.origTo;
      if (afterE == null) {
        if (fromLocal > n) { afterE = chunk.editFrom; afterO = chunk.origFrom; }
        else if (toLocal > n) { afterE = chunk.editTo; afterO = chunk.origTo; }
      }
      if (toLocal <= n) { beforeE = chunk.editTo; beforeO = chunk.origTo; }
      else if (fromLocal <= n) { beforeE = chunk.editFrom; beforeO = chunk.origFrom; }
    }
    return {edit: {before: beforeE, after: afterE}, orig: {before: beforeO, after: afterO}};
  }

  function collapseSingle(cm, from, to) {
    cm.addLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
    var widget = document.createElement("span");
    widget.className = "CodeMirror-merge-collapsed-widget";
    widget.title = "Identical text collapsed. Click to expand.";
    var mark = cm.markText(Pos(from, 0), Pos(to - 1), {
      inclusiveLeft: true,
      inclusiveRight: true,
      replacedWith: widget,
      clearOnEnter: true
    });
    function clear() {
      mark.clear();
      cm.removeLineClass(from, "wrap", "CodeMirror-merge-collapsed-line");
    }
    CodeMirror.on(widget, "click", clear);
    return {mark: mark, clear: clear};
  }

  function collapseStretch(size, editors) {
    var marks = [];
    function clear() {
      for (var i = 0; i < marks.length; i++) marks[i].clear();
    }
    for (var i = 0; i < editors.length; i++) {
      var editor = editors[i];
      var mark = collapseSingle(editor.cm, editor.line, editor.line + size);
      marks.push(mark);
      mark.mark.on("clear", clear);
    }
    return marks[0].mark;
  }

  function unclearNearChunks(dv, margin, off, clear) {
    for (var i = 0; i < dv.chunks.length; i++) {
      var chunk = dv.chunks[i];
      for (var l = chunk.editFrom - margin; l < chunk.editTo + margin; l++) {
        var pos = l + off;
        if (pos >= 0 && pos < clear.length) clear[pos] = false;
      }
    }
  }

  function collapseIdenticalStretches(mv, margin) {
    if (typeof margin != "number") margin = 2;
    var clear = [], edit = mv.editor(), off = edit.firstLine();
    for (var l = off, e = edit.lastLine(); l <= e; l++) clear.push(true);
    if (mv.left) unclearNearChunks(mv.left, margin, off, clear);
    if (mv.right) unclearNearChunks(mv.right, margin, off, clear);

    for (var i = 0; i < clear.length; i++) {
      if (clear[i]) {
        var line = i + off;
        for (var size = 1; i < clear.length - 1 && clear[i + 1]; i++, size++) {}
        if (size > margin) {
          var editors = [{line: line, cm: edit}];
          if (mv.left) editors.push({line: getMatchingOrigLine(line, mv.left.chunks), cm: mv.left.orig});
          if (mv.right) editors.push({line: getMatchingOrigLine(line, mv.right.chunks), cm: mv.right.orig});
          var mark = collapseStretch(size, editors);
          if (mv.options.onCollapse) mv.options.onCollapse(mv, line, size, mark);
        }
      }
    }
  }

  // General utilities

  function elt(tag, content, className, style) {
    var e = document.createElement(tag);
    if (className) e.className = className;
    if (style) e.style.cssText = style;
    if (typeof content == "string") e.appendChild(document.createTextNode(content));
    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
    return e;
  }

  function clear(node) {
    for (var count = node.childNodes.length; count > 0; --count)
      node.removeChild(node.firstChild);
  }

  function attrs(elt) {
    for (var i = 1; i < arguments.length; i += 2)
      elt.setAttribute(arguments[i], arguments[i+1]);
  }

  function copyObj(obj, target) {
    if (!target) target = {};
    for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
    return target;
  }

  function moveOver(pos, str, copy, other) {
    var out = copy ? Pos(pos.line, pos.ch) : pos, at = 0;
    for (;;) {
      var nl = str.indexOf("\n", at);
      if (nl == -1) break;
      ++out.line;
      if (other) ++other.line;
      at = nl + 1;
    }
    out.ch = (at ? 0 : out.ch) + (str.length - at);
    if (other) other.ch = (at ? 0 : other.ch) + (str.length - at);
    return out;
  }

  // Tracks collapsed markers and line widgets, in order to be able to
  // accurately align the content of two editors.

  var F_WIDGET = 1, F_WIDGET_BELOW = 2, F_MARKER = 4

  function TrackAlignable(cm) {
    this.cm = cm
    this.alignable = []
    this.height = cm.doc.height
    var self = this
    cm.on("markerAdded", function(_, marker) {
      if (!marker.collapsed) return
      var found = marker.find(1)
      if (found != null) self.set(found.line, F_MARKER)
    })
    cm.on("markerCleared", function(_, marker, _min, max) {
      if (max != null && marker.collapsed)
        self.check(max, F_MARKER, self.hasMarker)
    })
    cm.on("markerChanged", this.signal.bind(this))
    cm.on("lineWidgetAdded", function(_, widget, lineNo) {
      if (widget.mergeSpacer) return
      if (widget.above) self.set(lineNo - 1, F_WIDGET_BELOW)
      else self.set(lineNo, F_WIDGET)
    })
    cm.on("lineWidgetCleared", function(_, widget, lineNo) {
      if (widget.mergeSpacer) return
      if (widget.above) self.check(lineNo - 1, F_WIDGET_BELOW, self.hasWidgetBelow)
      else self.check(lineNo, F_WIDGET, self.hasWidget)
    })
    cm.on("lineWidgetChanged", this.signal.bind(this))
    cm.on("change", function(_, change) {
      var start = change.from.line, nBefore = change.to.line - change.from.line
      var nAfter = change.text.length - 1, end = start + nAfter
      if (nBefore || nAfter) self.map(start, nBefore, nAfter)
      self.check(end, F_MARKER, self.hasMarker)
      if (nBefore || nAfter) self.check(change.from.line, F_MARKER, self.hasMarker)
    })
    cm.on("viewportChange", function() {
      if (self.cm.doc.height != self.height) self.signal()
    })
  }

  TrackAlignable.prototype = {
    signal: function() {
      CodeMirror.signal(this, "realign")
      this.height = this.cm.doc.height
    },

    set: function(n, flags) {
      var pos = -1
      for (; pos < this.alignable.length; pos += 2) {
        var diff = this.alignable[pos] - n
        if (diff == 0) {
          if ((this.alignable[pos + 1] & flags) == flags) return
          this.alignable[pos + 1] |= flags
          this.signal()
          return
        }
        if (diff > 0) break
      }
      this.signal()
      this.alignable.splice(pos, 0, n, flags)
    },

    find: function(n) {
      for (var i = 0; i < this.alignable.length; i += 2)
        if (this.alignable[i] == n) return i
      return -1
    },

    check: function(n, flag, pred) {
      var found = this.find(n)
      if (found == -1 || !(this.alignable[found + 1] & flag)) return
      if (!pred.call(this, n)) {
        this.signal()
        var flags = this.alignable[found + 1] & ~flag
        if (flags) this.alignable[found + 1] = flags
        else this.alignable.splice(found, 2)
      }
    },

    hasMarker: function(n) {
      var handle = this.cm.getLineHandle(n)
      if (handle.markedSpans) for (var i = 0; i < handle.markedSpans.length; i++)
        if (handle.markedSpans[i].mark.collapsed && handle.markedSpans[i].to != null)
          return true
      return false
    },

    hasWidget: function(n) {
      var handle = this.cm.getLineHandle(n)
      if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++)
        if (!handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true
      return false
    },

    hasWidgetBelow: function(n) {
      if (n == this.cm.lastLine()) return false
      var handle = this.cm.getLineHandle(n + 1)
      if (handle.widgets) for (var i = 0; i < handle.widgets.length; i++)
        if (handle.widgets[i].above && !handle.widgets[i].mergeSpacer) return true
      return false
    },

    map: function(from, nBefore, nAfter) {
      var diff = nAfter - nBefore, to = from + nBefore, widgetFrom = -1, widgetTo = -1
      for (var i = 0; i < this.alignable.length; i += 2) {
        var n = this.alignable[i]
        if (n == from && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetFrom = i
        if (n == to && (this.alignable[i + 1] & F_WIDGET_BELOW)) widgetTo = i
        if (n <= from) continue
        else if (n < to) this.alignable.splice(i--, 2)
        else this.alignable[i] += diff
      }
      if (widgetFrom > -1) {
        var flags = this.alignable[widgetFrom + 1]
        if (flags == F_WIDGET_BELOW) this.alignable.splice(widgetFrom, 2)
        else this.alignable[widgetFrom + 1] = flags & ~F_WIDGET_BELOW
      }
      if (widgetTo > -1 && nAfter)
        this.set(from + nAfter, F_WIDGET_BELOW)
    }
  }

  function posMin(a, b) { return (a.line - b.line || a.ch - b.ch) < 0 ? a : b; }
  function posMax(a, b) { return (a.line - b.line || a.ch - b.ch) > 0 ? a : b; }
  function posEq(a, b) { return a.line == b.line && a.ch == b.ch; }

  function findPrevDiff(chunks, start, isOrig) {
    for (var i = chunks.length - 1; i >= 0; i--) {
      var chunk = chunks[i];
      var to = (isOrig ? chunk.origTo : chunk.editTo) - 1;
      if (to < start) return to;
    }
  }

  function findNextDiff(chunks, start, isOrig) {
    for (var i = 0; i < chunks.length; i++) {
      var chunk = chunks[i];
      var from = (isOrig ? chunk.origFrom : chunk.editFrom);
      if (from > start) return from;
    }
  }

  function goNearbyDiff(cm, dir) {
    var found = null, views = cm.state.diffViews, line = cm.getCursor().line;
    if (views) for (var i = 0; i < views.length; i++) {
      var dv = views[i], isOrig = cm == dv.orig;
      ensureDiff(dv);
      var pos = dir < 0 ? findPrevDiff(dv.chunks, line, isOrig) : findNextDiff(dv.chunks, line, isOrig);
      if (pos != null && (found == null || (dir < 0 ? pos > found : pos < found)))
        found = pos;
    }
    if (found != null)
      cm.setCursor(found, 0);
    else
      return CodeMirror.Pass;
  }

  CodeMirror.commands.goNextDiff = function(cm) {
    return goNearbyDiff(cm, 1);
  };
  CodeMirror.commands.goPrevDiff = function(cm) {
    return goNearbyDiff(cm, -1);
  };
});
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Depends on htmlhint.js from http://htmlhint.com/js/htmlhint.js

// declare global: HTMLHint

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"), require("htmlhint"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror", "htmlhint"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
  "use strict";

  var defaultRules = {
    "tagname-lowercase": true,
    "attr-lowercase": true,
    "attr-value-double-quotes": true,
    "doctype-first": false,
    "tag-pair": true,
    "spec-char-escape": true,
    "id-unique": true,
    "src-not-empty": true,
    "attr-no-duplication": true
  };

  CodeMirror.registerHelper("lint", "html", function(text, options) {
    var found = [];
    if (!window.HTMLHint) return found;
    var messages = HTMLHint.verify(text, options && options.rules || defaultRules);
    for (var i = 0; i < messages.length; i++) {
      var message = messages[i];
      var startLine = message.line - 1, endLine = message.line - 1, startCol = message.col - 1, endCol = message.col;
      found.push({
        from: CodeMirror.Pos(startLine, startCol),
        to: CodeMirror.Pos(endLine, endCol),
        message: message.message,
        severity : message.type
      });
    }
    return found;
  });
});
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror"),require("htmlhint")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","htmlhint"],e):e(CodeMirror)}((function(e){"use strict";var t={"tagname-lowercase":!0,"attr-lowercase":!0,"attr-value-double-quotes":!0,"doctype-first":!1,"tag-pair":!0,"spec-char-escape":!0,"id-unique":!0,"src-not-empty":!0,"attr-no-duplication":!0};e.registerHelper("lint","html",(function(r,i){var o=[];if(!window.HTMLHint)return o;for(var n=HTMLHint.verify(r,i&&i.rules||t),a=0;a<n.length;a++){var s=n[a],c=s.line-1,l=s.line-1,u=s.col-1,f=s.col;o.push({from:e.Pos(c,u),to:e.Pos(l,f),message:s.message,severity:s.type})}return o}))}));!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}((function(e){"use strict";e.registerHelper("lint","yaml",(function(o){var r=[];try{jsyaml.load(o)}catch(o){var t=o.mark,i=t?e.Pos(t.line,t.column):e.Pos(0,0),n=i;r.push({from:i,to:n,message:o.message})}return r}))}));// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

// Depends on js-yaml.js from https://github.com/nodeca/js-yaml

// declare global: jsyaml

CodeMirror.registerHelper("lint", "yaml", function(text) {
  var found = [];
  try { jsyaml.load(text); }
  catch(e) {
      var loc = e.mark,
          // js-yaml YAMLException doesn't always provide an accurate lineno
          // e.g., when there are multiple yaml docs
          // ---
          // ---
          // foo:bar
          from = loc ? CodeMirror.Pos(loc.line, loc.column) : CodeMirror.Pos(0, 0),
          to = from;
      found.push({ from: from, to: to, message: e.message });
  }
  return found;
});

});
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],t):t(CodeMirror)}((function(t){"use strict";var e="CodeMirror-lint-markers";function n(t){t.parentNode&&t.parentNode.removeChild(t)}function o(e,o,r){var i=function(e,n){var o=document.createElement("div");function r(e){if(!o.parentNode)return t.off(document,"mousemove",r);o.style.top=Math.max(0,e.clientY-o.offsetHeight-5)+"px",o.style.left=e.clientX+5+"px"}return o.className="CodeMirror-lint-tooltip",o.appendChild(n.cloneNode(!0)),document.body.appendChild(o),t.on(document,"mousemove",r),r(e),null!=o.style.opacity&&(o.style.opacity=1),o}(e,o);function a(){var e;t.off(r,"mouseout",a),i&&((e=i).parentNode&&(null==e.style.opacity&&n(e),e.style.opacity=0,setTimeout((function(){n(e)}),600)),i=null)}var l=setInterval((function(){if(i)for(var t=r;;t=t.parentNode){if(t&&11==t.nodeType&&(t=t.host),t==document.body)return;if(!t){a();break}}if(!i)return clearInterval(l)}),400);t.on(r,"mouseout",a)}function r(t,e,n){this.marked=[],this.options=e,this.timeout=null,this.hasGutter=n,this.onMouseOver=function(e){!function(t,e){var n=e.target||e.srcElement;if(!/\bCodeMirror-lint-mark-/.test(n.className))return;for(var r=n.getBoundingClientRect(),i=(r.left+r.right)/2,a=(r.top+r.bottom)/2,s=t.findMarksAt(t.coordsChar({left:i,top:a},"client")),u=[],c=0;c<s.length;++c){var f=s[c].__annotation;f&&u.push(f)}u.length&&function(t,e){for(var n=e.target||e.srcElement,r=document.createDocumentFragment(),i=0;i<t.length;i++){var a=t[i];r.appendChild(l(a))}o(e,r,n)}(u,e)}(t,e)},this.waitingFor=0}function i(t){var n=t.state.lint;n.hasGutter&&t.clearGutter(e);for(var o=0;o<n.marked.length;++o)n.marked[o].clear();n.marked.length=0}function a(e,n,r,i){var a=document.createElement("div"),l=a;return a.className="CodeMirror-lint-marker-"+n,r&&((l=a.appendChild(document.createElement("div"))).className="CodeMirror-lint-marker-multiple"),0!=i&&t.on(l,"mouseover",(function(t){o(t,e,l)})),a}function l(t){var e=t.severity;e||(e="error");var n=document.createElement("div");return n.className="CodeMirror-lint-message-"+e,n.appendChild(document.createTextNode(t.message)),n}function s(e){var n=e.state.lint.options,o=n.options||n,r=n.getAnnotations||e.getHelper(t.Pos(0,0),"lint");if(r)if(n.async||r.async)!function(e,n,o){var r=e.state.lint,i=++r.waitingFor;function a(){i=-1,e.off("change",a)}e.on("change",a),n(e.getValue(),(function(n,o){e.off("change",a),r.waitingFor==i&&(o&&n instanceof t&&(n=o),u(e,n))}),o,e)}(e,r,o);else{var i=r(e.getValue(),o,e);if(!i)return;i.then?i.then((function(t){u(e,t)})):u(e,i)}}function u(t,n){i(t);for(var o,r,s=t.state.lint,u=s.options,c=function(t){for(var e=[],n=0;n<t.length;++n){var o=t[n],r=o.from.line;(e[r]||(e[r]=[])).push(o)}return e}(n),f=0;f<c.length;++f){var m=c[f];if(m){for(var d=null,p=s.hasGutter&&document.createDocumentFragment(),h=0;h<m.length;++h){var v=m[h],g=v.severity;g||(g="error"),r=g,d="error"==(o=d)?o:r,u.formatAnnotation&&(v=u.formatAnnotation(v)),s.hasGutter&&p.appendChild(l(v)),v.to&&s.marked.push(t.markText(v.from,v.to,{className:"CodeMirror-lint-mark-"+g,__annotation:v}))}s.hasGutter&&t.setGutterMarker(f,e,a(p,d,m.length>1,s.options.tooltips))}}u.onUpdateLinting&&u.onUpdateLinting(n,c,t)}function c(t){var e=t.state.lint;e&&(clearTimeout(e.timeout),e.timeout=setTimeout((function(){s(t)}),e.options.delay||500))}t.defineOption("lint",!1,(function(n,o,a){if(a&&a!=t.Init&&(i(n),!1!==n.state.lint.options.lintOnChange&&n.off("change",c),t.off(n.getWrapperElement(),"mouseover",n.state.lint.onMouseOver),clearTimeout(n.state.lint.timeout),delete n.state.lint),o){for(var l=n.getOption("gutters"),u=!1,f=0;f<l.length;++f)l[f]==e&&(u=!0);var m=n.state.lint=new r(n,(d=o)instanceof Function?{getAnnotations:d}:(d&&!0!==d||(d={}),d),u);!1!==m.options.lintOnChange&&n.on("change",c),0!=m.options.tooltips&&"gutter"!=m.options.tooltips&&t.on(n.getWrapperElement(),"mouseover",m.onMouseOver),s(n)}var d})),t.defineExtension("performLint",(function(){this.state.lint&&s(this)}))}));

F1le Man4ger