6 | * Licensed under the Apache v2 License.
7 | *
8 | */
9 |
10 | /** * @license Apache v2
11 | */
12 |
13 | !function(a,b){function c(b){return a.less[b.split("/")[1]]}function d(a,b){"undefined"!=typeof console&&w.logLevel>=b&&console.log("less: "+a)}function e(a){return a.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function f(a,c){var e="{line} {content}",f=a.filename||c,g=[],h=(a.type||"Syntax")+"Error: "+(a.message||"There is an error in your .less file")+" in "+f+" ",i=function(a,c,d){a.extract[c]!==b&&g.push(e.replace(/\{line\}/,(parseInt(a.line,10)||0)+(c-1)).replace(/\{class\}/,d).replace(/\{content\}/,a.extract[c]))};a.extract?(i(a,0,""),i(a,1,"line"),i(a,2,""),h+="on line "+a.line+", column "+(a.column+1)+":\n"+g.join("\n")):a.stack&&(h+=a.stack),d(h,z.errors)}function g(a,b,c){var f=b.href||"",g="less:"+(b.title||e(f)),h=document.getElementById(g),i=!1,j=document.createElement("style");if(j.setAttribute("type","text/css"),b.media&&j.setAttribute("media",b.media),j.id=g,j.styleSheet)try{j.styleSheet.cssText=a}catch(k){throw new Error("Couldn't reassign styleSheet.cssText.")}else j.appendChild(document.createTextNode(a)),i=null!==h&&h.childNodes.length>0&&j.childNodes.length>0&&h.firstChild.nodeValue===j.firstChild.nodeValue;var l=document.getElementsByTagName("head")[0];if(null===h||i===!1){var m=b&&b.nextSibling||null;m?m.parentNode.insertBefore(j,m):l.appendChild(j)}if(h&&i===!1&&h.parentNode.removeChild(h),c&&D){d("saving "+f+" to cache.",z.info);try{D.setItem(f,a),D.setItem(f+":timestamp",c)}catch(k){d("failed to save",z.errors)}}}function h(a){return w.postProcessor&&"function"==typeof w.postProcessor&&(a=w.postProcessor.call(a,a)||a),a}function i(a,c){var d,f,h="less-error-message:"+e(c||""),i='{line} {content} ',j=document.createElement("div"),k=[],l=a.filename||c,m=l.match(/([^\/]+(\?.*)?)$/)[1];j.id=h,j.className="less-error-message",f=""+(a.type||"Syntax")+"Error: "+(a.message||"There is an error in your .less file")+' in '+m+" ";var n=function(a,c,d){a.extract[c]!==b&&k.push(i.replace(/\{line\}/,(parseInt(a.line,10)||0)+(c-1)).replace(/\{class\}/,d).replace(/\{content\}/,a.extract[c]))};a.extract?(n(a,0,""),n(a,1,"line"),n(a,2,""),f+="on line "+a.line+", column "+(a.column+1)+":
"):a.stack&&(f+=" "+a.stack.split("\n").slice(1).join(" ")),j.innerHTML=f,g([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),j.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),"development"==w.env&&(d=setInterval(function(){document.body&&(document.getElementById(h)?document.body.replaceChild(j,document.getElementById(h)):document.body.insertBefore(j,document.body.firstChild),clearInterval(d))},10))}function j(a,b){w.errorReporting&&"html"!==w.errorReporting?"console"===w.errorReporting?f(a,b):"function"==typeof w.errorReporting&&w.errorReporting("add",a,b):i(a,b)}function k(a){var b=document.getElementById("less-error-message:"+e(a));b&&b.parentNode.removeChild(b)}function l(){}function m(a){w.errorReporting&&"html"!==w.errorReporting?"console"===w.errorReporting?l(a):"function"==typeof w.errorReporting&&w.errorReporting("remove",a):k(a)}function n(a){for(var b,c=document.getElementsByTagName("style"),d=0;d0&&(h.splice(c-1,2),c-=2)}return g.hostPart=f[1],g.directories=h,g.path=f[1]+h.join("/"),g.fileUrl=g.path+(f[4]||""),g.url=g.fileUrl+(f[5]||""),g}function p(a,b){var c,d,e,f,g=o(a),h=o(b),i="";if(g.hostPart!==h.hostPart)return"";for(d=Math.max(h.directories.length,g.directories.length),c=0;d>c&&h.directories[c]===g.directories[c];c++);for(f=h.directories.slice(c),e=g.directories.slice(c),c=0;c=200&&b.status<300?c(b.responseText,b.getResponseHeader("Last-Modified")):"function"==typeof d&&d(b.status,a)}var g=q(),h=y?w.fileAsync:w.async;"function"==typeof g.overrideMimeType&&g.overrideMimeType("text/css"),d("XHR: Getting '"+a+"'",z.debug),g.open("GET",a,h),g.setRequestHeader("Accept",b||"text/x-less, text/css; q=0.9, */*; q=0.5"),g.send(null),y&&!w.fileAsync?0===g.status||g.status>=200&&g.status<300?c(g.responseText):e(g.status,a):h?g.onreadystatechange=function(){4==g.readyState&&f(g,c,e)}:f(g,c,e)}function s(b,c,d,e){c&&c.currentDirectory&&!/^([a-z-]+:)?\//.test(b)&&(b=c.currentDirectory+b);var f=o(b,a.location.href),g=f.url,h={currentDirectory:f.path,filename:g};if(c?(h.entryPath=c.entryPath,h.rootpath=c.rootpath,h.rootFilename=c.rootFilename,h.relativeUrls=c.relativeUrls):(h.entryPath=f.path,h.rootpath=w.rootpath||f.path,h.rootFilename=g,h.relativeUrls=e.relativeUrls),h.relativeUrls&&(h.rootpath=e.rootpath?o(e.rootpath+p(f.path,h.entryPath)).path:f.path),e.useFileCache&&E[g])try{var i=E[g];d(null,i,g,h,{lastModified:new Date})}catch(j){d(j,null,g)}else r(g,e.mime,function(a,b){E[g]=a;try{d(null,a,g,h,{lastModified:b})}catch(c){d(c,null,g)}},function(a,b){d({type:"File",message:"'"+b+"' wasn't found ("+a+")"},null,g)})}function t(a,b,c,d,e){var f=new w.tree.parseEnv(w);f.mime=a.type,(e||w.globalVars)&&(f.useFileCache=!0),s(a.href,null,function(h,i,j,k,l){if(l){l.remaining=d;var n=D&&D.getItem(j),o=D&&D.getItem(j+":timestamp");if(!c&&o&&l.lastModified&&new Date(l.lastModified).valueOf()===new Date(o).valueOf())return g(n,a),l.local=!0,void b(null,null,i,a,l,j)}m(j),i?(f.currentFileInfo=k,new w.Parser(f).parse(i,function(c,d){if(c)return b(c,null,null,a);try{b(c,d,i,a,l,j)}catch(c){b(c,null,null,a)}},{modifyVars:e,globalVars:w.globalVars})):b(h,null,null,a,l,j)},f,e)}function u(a,b,c){for(var d=0;dD&&(C=C.slice(y-D),D=y)}function h(a,b){var c=a.charCodeAt(0|b);return 32>=c&&(32===c||10===c||9===c)}function i(a){var b,c,d=typeof a;return"string"===d?v.charAt(y)!==a?null:(l(1),a):(g(),(b=a.exec(C))?(c=b[0].length,l(c),"string"==typeof b?b:1===b.length?b[0]:b):null)}function j(a){y>D&&(C=C.slice(y-D),D=y);var b=a.exec(C);return b?(l(b[0].length),"string"==typeof b?b:1===b.length?b[0]:b):null}function k(a){return v.charAt(y)!==a?null:(l(1),a)}function l(a){for(var b,c=y,d=z,e=y-D,f=y+C.length-e,g=y+=a,h=v;f>y&&(b=h.charCodeAt(y),!(b>32))&&(32===b||10===b||9===b||13===b);y++);return C=C.slice(a+y-g+e),D=y,!C.length&&z=0&&"\n"!==b.charAt(c);)e++;return"number"==typeof a&&(d=(b.slice(0,a).match(/\n/g)||"").length),{line:d,column:e}}function t(a,b,d){var e=d.currentFileInfo.filename;return"browser"!==w.mode&&"rhino"!==w.mode&&(e=c("path").resolve(e)),{lineNumber:s(a,b).line+1,fileName:e}}function u(a,b){var c=r(a,b),d=s(a.index,c),e=d.line,f=d.column,g=a.call&&s(a.call,c).line,h=c.split("\n");this.type=a.type||"Syntax",this.message=a.message,this.filename=a.filename||b.currentFileInfo.filename,this.index=a.index,this.line="number"==typeof e?e+1:null,this.callLine=g+1,this.callExtract=h[g],this.stack=a.stack,this.column=f,this.extract=[h[e-1],h[e],h[e+1]]}var v,y,z,A,B,C,D,E,F,G=[],H=a&&a.filename;a instanceof x.parseEnv||(a=new x.parseEnv(a));var I=this.imports={paths:a.paths||[],queue:[],files:a.files,contents:a.contents,contentsIgnoredChars:a.contentsIgnoredChars,mime:a.mime,error:null,push:function(b,c,d,e){var f=this;this.queue.push(b);var g=function(a,c,d){f.queue.splice(f.queue.indexOf(b),1);var g=d===H;f.files[d]=c,a&&!f.error&&(f.error=a),e(a,c,g,d)};w.Parser.importer?w.Parser.importer(b,c,g,a):w.Parser.fileLoader(b,c,function(b,e,f,h){if(b)return void g(b);var i=new x.parseEnv(a);i.currentFileInfo=h,i.processImports=!1,i.contents[f]=e,(c.reference||d.reference)&&(h.reference=!0),d.inline?g(null,e,f):new w.Parser(i).parse(e,function(a,b){g(a,b,f)})},a)}},J=j;return u.prototype=new Error,u.prototype.constructor=u,this.env=a=a||{},this.optimization="optimization"in this.env?this.env.optimization:1,E={imports:I,parse:function(d,e,f){var g,h,i,j,k,l=null,m="";if(y=z=D=A=0,j=f&&f.globalVars?w.Parser.serializeVars(f.globalVars)+"\n":"",k=f&&f.modifyVars?"\n"+w.Parser.serializeVars(f.modifyVars):"",(j||f&&f.banner)&&(m=(f&&f.banner?f.banner:"")+j,E.imports.contentsIgnoredChars[a.currentFileInfo.filename]=m.length),d=d.replace(/\r\n/g,"\n"),v=d=m+d.replace(/^\uFEFF/,"")+k,E.imports.contents[a.currentFileInfo.filename]=d,B=function(b){function c(b,c){l=new u({index:c||i,type:"Parse",message:b,filename:a.currentFileInfo.filename},a)}function d(a){var c=i-s;512>c&&!a||!c||(r.push(b.slice(s,i+1)),s=i+1)}var e,f,g,h,i,j,k,m,n,o=b.length,p=0,q=0,r=[],s=0;for(i=0;o>i;i++)if(k=b.charCodeAt(i),!(k>=97&&122>=k||34>k))switch(k){case 40:q++,f=i;continue;case 41:if(--q<0)return c("missing opening `(`");continue;case 59:q||d();continue;case 123:p++,e=i;continue;case 125:if(--p<0)return c("missing opening `{`");p||q||d();continue;case 92:if(o-1>i){i++;continue}return c("unescaped `\\`");case 34:case 39:case 96:for(n=0,j=i,i+=1;o>i;i++)if(m=b.charCodeAt(i),!(m>96)){if(m==k){n=1;break}if(92==m){if(i==o-1)return c("unescaped `\\`");i++}}if(n)continue;return c("unmatched `"+String.fromCharCode(k)+"`",j);case 47:if(q||i==o-1)continue;if(m=b.charCodeAt(i+1),47==m)for(i+=2;o>i&&(m=b.charCodeAt(i),!(13>=m)||10!=m&&13!=m);i++);else if(42==m){for(g=j=i,i+=2;o-1>i&&(m=b.charCodeAt(i),125==m&&(h=i),42!=m||47!=b.charCodeAt(i+1));i++);if(i==o-1)return c("missing closing `*/`",j);i++}continue;case 42:if(o-1>i&&47==b.charCodeAt(i+1))return c("unmatched `/*`");continue}return 0!==p?g>e&&h>g?c("missing closing `}` or `*/`",e):c("missing closing `}`",e):0!==q?c("missing closing `)`",f):(d(!0),r)}(d),l)return e(new u(l,a));C=B[0];try{g=new x.Ruleset(null,this.parsers.primary()),g.root=!0,g.firstRoot=!0}catch(n){return e(new u(n,a))}if(g.toCSS=function(d){return function(e,f){e=e||{};var g,h,i=new x.evalEnv(e);"object"!=typeof f||Array.isArray(f)||(f=Object.keys(f).map(function(a){var b=f[a];return b instanceof x.Value||(b instanceof x.Expression||(b=new x.Expression([b])),b=new x.Value([b])),new x.Rule("@"+a,b,!1,null,0)}),i.frames=[new x.Ruleset(null,f)]);try{var j,k=[],l=[new x.joinSelectorVisitor,new x.processExtendsVisitor,new x.toCSSVisitor({compress:Boolean(e.compress)})],m=this;if(e.plugins)for(j=0;j57||43>b||47===b||44==b))return a=j(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/),a?new x.Dimension(a[1],a[2]):void 0},unicodeDescriptor:function(){var a;return a=j(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/),a?new x.UnicodeDescriptor(a[0]):void 0},javascript:function(){var c,d,e=y;return"~"===v.charAt(e)&&(e++,d=!0),"`"===v.charAt(e)?(a.javascriptEnabled===b||a.javascriptEnabled||o("You are using JavaScript, which has been disabled."),d&&k("~"),c=j(/^`([^`]*)`/),c?new x.JavaScript(c[1],y,d):void 0):void 0}},variable:function(){var a;return"@"===v.charAt(y)&&(a=j(/^(@[\w-]+)\s*:/))?a[1]:void 0},rulesetCall:function(){var a;return"@"===v.charAt(y)&&(a=j(/^(@[\w-]+)\s*\(\s*\)\s*;/))?new x.RulesetCall(a[1]):void 0},extend:function(a){var b,c,d,e,f,g=y;if(j(a?/^&:extend\(/:/^:extend\(/)){do{for(d=null,b=null;!(d=j(/^(all)(?=\s*(\)|,))/))&&(c=this.element());)b?b.push(c):b=[c];d=d&&d[1],f=new x.Extend(new x.Selector(b),d,g),e?e.push(f):e=[f]}while(k(","));return m(/^\)/),a&&m(/^;/),e}},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var b,c,g,h,i,l,m=v.charAt(y),o=!1,p=y;if("."===m||"#"===m){for(d();;){if(b=y,h=j(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/),!h)break;g=new x.Element(i,h,b,a.currentFileInfo),c?c.push(g):c=[g],i=k(">")}return c&&(k("(")&&(l=this.args(!0).args,n(")")),F.important()&&(o=!0),F.end())?(f(),new x.mixin.Call(c,l,p,a.currentFileInfo,o)):void e()}},args:function(a){var b,c,g,h,i,l,m=E.parsers,n=m.entities,p={args:null,variadic:!1},q=[],r=[],s=[];for(d();;){if(a)l=m.detachedRuleset()||m.expression();else{if(m.comments(),"."===v.charAt(y)&&j(/^\.{3}/)){p.variadic=!0,k(";")&&!b&&(b=!0),(b?r:s).push({variadic:!0});break}l=n.variable()||n.literal()||n.keyword()}if(!l)break;h=null,l.throwAwayComments&&l.throwAwayComments(),i=l;var t=null;if(a?l.value&&1==l.value.length&&(t=l.value[0]):t=l,t&&t instanceof x.Variable)if(k(":")){if(q.length>0&&(b&&o("Cannot mix ; and , as delimiter types"),c=!0),i=a&&m.detachedRuleset()||m.expression(),!i){if(!a)return e(),p.args=[],p;o("could not understand value for named argument")}h=g=t.name}else{if(!a&&j(/^\.{3}/)){p.variadic=!0,k(";")&&!b&&(b=!0),(b?r:s).push({name:l.name,variadic:!0});break}a||(g=h=t.name,i=null)}i&&q.push(i),s.push({name:h,value:i}),k(",")||(k(";")||b)&&(c&&o("Cannot mix ; and , as delimiter types"),b=!0,q.length>1&&(i=new x.Value(q)),r.push({name:g,value:i}),g=null,q=[],c=!1)}return f(),p.args=b?r:s,p},definition:function(){var a,b,c,g,h=[],i=!1;if(!("."!==v.charAt(y)&&"#"!==v.charAt(y)||p(/^[^{]*\}/)))if(d(),b=j(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){a=b[1];var l=this.args(!1);if(h=l.args,i=l.variadic,!k(")"))return A=y,void e();if(F.comments(),j(/^when/)&&(g=m(F.conditions,"expected condition")),c=F.block())return f(),new x.mixin.Definition(a,h,c,g,i);e()}else f()}},entity:function(){var a=this.entities;return a.literal()||a.variable()||a.url()||a.call()||a.keyword()||a.javascript()||this.comment()},end:function(){return k(";")||q("}")},alpha:function(){var a;if(j(/^\(opacity=/i))return a=j(/^\d+/)||this.entities.variable(),a?(n(")"),new x.Alpha(a)):void 0},element:function(){var b,c,g,h=y;return c=this.combinator(),b=j(/^(?:\d+\.\d+|\d+)%/)||j(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||k("*")||k("&")||this.attribute()||j(/^\([^()@]+\)/)||j(/^[\.#](?=@)/)||this.entities.variableCurly(),b||(d(),k("(")?(g=this.selector())&&k(")")?(b=new x.Paren(g),f()):e():f()),b?new x.Element(c,b,h,a.currentFileInfo):void 0},combinator:function(){var a=v.charAt(y);if(">"===a||"+"===a||"~"===a||"|"===a||"^"===a){for(y++,"^"===v.charAt(y)&&(a="^^",y++);h(v,y);)y++;return new x.Combinator(a)}return new x.Combinator(h(v,y-1)?" ":null)},lessSelector:function(){return this.selector(!0)},selector:function(b){for(var c,d,e,f,g,h,i,j=y,k=J;(b&&(g=this.extend())||b&&(h=k(/^when/))||(f=this.element()))&&(h?i=m(this.conditions,"expected condition"):i?o("CSS guard can only be used at the end of selector"):g?d?d.push(g):d=[g]:(d&&o("Extend can only be used at the end of selector"),e=v.charAt(y),c?c.push(f):c=[f],f=null),"{"!==e&&"}"!==e&&";"!==e&&","!==e&&")"!==e););return c?new x.Selector(c,d,i,j,a.currentFileInfo):void(d&&o("Extend must be used to extend a selector, it cannot be used on its own"))},attribute:function(){if(k("[")){var a,b,c,d=this.entities;return(a=d.variableCurly())||(a=m(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/)),c=j(/^[|~*$^]?=/),c&&(b=d.quoted()||j(/^[0-9]+%/)||j(/^[\w-]+/)||d.variableCurly()),n("]"),new x.Attribute(a,c,b)}},block:function(){var a;return k("{")&&(a=this.primary())&&k("}")?a:void 0},blockRuleset:function(){var a=this.block();return a&&(a=new x.Ruleset(null,a)),a},detachedRuleset:function(){var a=this.blockRuleset();return a?new x.DetachedRuleset(a):void 0},ruleset:function(){var b,c,g,h;for(d(),a.dumpLineNumbers&&(h=t(y,v,a));;){if(c=this.lessSelector(),!c)break;if(b?b.push(c):b=[c],this.comments(),c.condition&&b.length>1&&o("Guards are only currently allowed on a single selector."),!k(","))break;c.condition&&o("Guards are only currently allowed on a single selector."),this.comments()}if(b&&(g=this.block())){f();var i=new x.Ruleset(b,g,a.strictImports);return a.dumpLineNumbers&&(i.debugInfo=h),i}A=y,e()},rule:function(b){var c,g,h,i,j,k=y,l=v.charAt(k);if("."!==l&&"#"!==l&&"&"!==l)if(d(),c=this.variable()||this.ruleProperty()){if(j="string"==typeof c,j&&(g=this.detachedRuleset()),g||(g=b||!a.compress&&!j?this.anonymousValue()||this.value():this.value()||this.anonymousValue(),h=this.important(),i=!j&&c.pop().value),g&&this.end())return f(),new x.Rule(c,g,h,i,k,a.currentFileInfo);if(A=y,e(),g&&!b)return this.rule(!0)}else f()},anonymousValue:function(){var a;return a=/^([^@+\/'"*`(;{}-]*);/.exec(C),a?(y+=a[0].length-1,new x.Anonymous(a[1])):void 0},"import":function(){var b,c,g=y;d();var h=j(/^@import?\s+/),i=(h?this.importOptions():null)||{};return h&&(b=this.entities.quoted()||this.entities.url())&&(c=this.mediaFeatures(),k(";"))?(f(),c=c&&new x.Value(c),new x.Import(b,c,i,g,a.currentFileInfo)):void e()},importOptions:function(){var a,b,c,d={};if(!k("("))return null;do if(a=this.importOption()){switch(b=a,c=!0,b){case"css":b="less",c=!1;break;case"once":b="multiple",c=!1}if(d[b]=c,!k(","))break}while(a);return n(")"),d},importOption:function(){var a=j(/^(less|css|multiple|once|inline|reference)/);return a?a[1]:void 0},mediaFeature:function(){var b,c,d=this.entities,e=[];do if(b=d.keyword()||d.variable())e.push(b);else if(k("(")){if(c=this.property(),b=this.value(),!k(")"))return null;if(c&&b)e.push(new x.Paren(new x.Rule(c,b,null,null,y,a.currentFileInfo,!0)));else{if(!b)return null;e.push(new x.Paren(b))}}while(b);return e.length>0?new x.Expression(e):void 0},mediaFeatures:function(){var a,b=this.entities,c=[];do if(a=this.mediaFeature()){if(c.push(a),!k(","))break}else if(a=b.variable(),a&&(c.push(a),!k(",")))break;while(a);return c.length>0?c:null},media:function(){var b,c,d,e;return a.dumpLineNumbers&&(e=t(y,v,a)),j(/^@media/)&&(b=this.mediaFeatures(),c=this.block())?(d=new x.Media(c,b,y,a.currentFileInfo),a.dumpLineNumbers&&(d.debugInfo=e),d):void 0},directive:function(){var b,c,g,h,i,l,m,n=y,p=!0;if("@"===v.charAt(y)){if(c=this["import"]()||this.media())return c;if(d(),b=j(/^@[a-z-]+/)){switch(h=b,"-"==b.charAt(1)&&b.indexOf("-",2)>0&&(h="@"+b.slice(b.indexOf("-",2)+1)),h){case"@charset":i=!0,p=!1;break;case"@namespace":l=!0,p=!1;break;case"@keyframes":i=!0;break;case"@host":case"@page":case"@document":case"@supports":m=!0}return i?(c=this.entity(),c||o("expected "+b+" identifier")):l?(c=this.expression(),c||o("expected "+b+" expression")):m&&(c=(j(/^[^{;]+/)||"").trim(),c&&(c=new x.Anonymous(c))),p&&(g=this.blockRuleset()),g||!p&&c&&k(";")?(f(),new x.Directive(b,c,g,n,a.currentFileInfo,a.dumpLineNumbers?t(n,v,a):null)):void e()}}},value:function(){var a,b=[];do if(a=this.expression(),a&&(b.push(a),!k(",")))break;while(a);return b.length>0?new x.Value(b):void 0},important:function(){return"!"===v.charAt(y)?j(/^! *important/):void 0},sub:function(){var a,b;return k("(")&&(a=this.addition())?(b=new x.Expression([a]),n(")"),b.parens=!0,b):void 0},multiplication:function(){var a,b,c,d,e;if(a=this.operand()){for(e=h(v,y-1);;){if(p(/^\/[*\/]/))break;if(c=k("/")||k("*"),!c)break;if(b=this.operand(),!b)break;a.parensInOp=!0,b.parensInOp=!0,d=new x.Operation(c,[d||a,b],e),e=h(v,y-1)}return d||a}},addition:function(){var a,b,c,d,e;if(a=this.multiplication()){for(e=h(v,y-1);;){if(c=j(/^[-+]\s+/)||!e&&(k("+")||k("-")),!c)break;if(b=this.multiplication(),!b)break;a.parensInOp=!0,b.parensInOp=!0,d=new x.Operation(c,[d||a,b],e),e=h(v,y-1)}return d||a}},conditions:function(){var a,b,c,d=y;if(a=this.condition()){for(;;){if(!p(/^,\s*(not\s*)?\(/)||!k(","))break;if(b=this.condition(),!b)break;c=new x.Condition("or",c||a,b,d)}return c||a}},condition:function(){var a,b,c,d,e=this.entities,f=y,g=!1;return j(/^not/)&&(g=!0),n("("),a=this.addition()||e.keyword()||e.quoted(),a?(d=j(/^(?:>=|<=|=<|[<=>])/),d?(b=this.addition()||e.keyword()||e.quoted(),b?c=new x.Condition(d,a,b,f,g):o("expected expression")):c=new x.Condition("=",a,new x.Keyword("true"),f,g),n(")"),j(/^and/)?new x.Condition("and",c,this.condition()):c):void 0},operand:function(){var a,b=this.entities,c=v.charAt(y+1);"-"!==v.charAt(y)||"@"!==c&&"("!==c||(a=k("-"));var d=this.sub()||b.dimension()||b.color()||b.variable()||b.call();return a&&(d.parensInOp=!0,d=new x.Negative(d)),d},expression:function(){var a,b,c=[];do a=this.addition()||this.entity(),a&&(c.push(a),p(/^\/[\/*]/)||(b=k("/"),b&&c.push(new x.Anonymous(b))));while(a);return c.length>0?new x.Expression(c):void 0},property:function(){var a=j(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);return a?a[1]:void 0},ruleProperty:function(){function b(a){var b=a.exec(e);return b?(g.push(y+h),h+=b[0].length,e=e.slice(b[1].length),f.push(b[1])):void 0}var c,d,e=C,f=[],g=[],h=0;for(b(/^(\*?)/);b(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/););if(f.length>1&&b(/^\s*((?:\+_|\+)?)\s*:/)){for(l(h),""===f[0]&&(f.shift(),g.shift()),d=0;dl;l++)e=b.rgb[l]/255,f=c.rgb[l]/255,h=a(e,f),g&&(h=(j*f+i*(e-j*(e+f-h)))/g),k[l]=255*h;return new d.Color(k,g)}function g(){var a,b=d.functions;for(a in l)l.hasOwnProperty(a)&&(b[a]=e.bind(null,Math[a],l[a]));for(a in m)m.hasOwnProperty(a)&&(b[a]=f.bind(null,m[a]));a=d.defaultFunc,b["default"]=a.eval.bind(a)}function h(a){return d.functions.hsla(a.h,a.s,a.l,a.a)}function i(a,b){return a instanceof d.Dimension&&a.unit.is("%")?parseFloat(a.value*b/100):j(a)}function j(a){if(a instanceof d.Dimension)return parseFloat(a.unit.is("%")?a.value/100:a.value);if("number"==typeof a)return a;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function k(a){return Math.min(1,Math.max(0,a))}d.functions={rgb:function(a,b,c){return this.rgba(a,b,c,1)},rgba:function(a,b,c,e){var f=[a,b,c].map(function(a){return i(a,255)});return e=j(e),new d.Color(f,e)},hsl:function(a,b,c){return this.hsla(a,b,c,1)},hsla:function(a,b,c,d){function e(a){return a=0>a?a+1:a>1?a-1:a,1>6*a?g+(f-g)*a*6:1>2*a?f:2>3*a?g+(f-g)*(2/3-a)*6:g}a=j(a)%360/360,b=k(j(b)),c=k(j(c)),d=k(j(d));var f=.5>=c?c*(b+1):c+b-c*b,g=2*c-f;return this.rgba(255*e(a+1/3),255*e(a),255*e(a-1/3),d)},hsv:function(a,b,c){return this.hsva(a,b,c,1)},hsva:function(a,b,c,d){a=j(a)%360/360*360,b=j(b),c=j(c),d=j(d);var e,f;e=Math.floor(a/60%6),f=a/60-e;var g=[c,c*(1-b),c*(1-f*b),c*(1-(1-f)*b)],h=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(255*g[h[e][0]],255*g[h[e][1]],255*g[h[e][2]],d)},hue:function(a){return new d.Dimension(Math.round(a.toHSL().h))},saturation:function(a){return new d.Dimension(Math.round(100*a.toHSL().s),"%")},lightness:function(a){return new d.Dimension(Math.round(100*a.toHSL().l),"%")},hsvhue:function(a){return new d.Dimension(Math.round(a.toHSV().h))},hsvsaturation:function(a){return new d.Dimension(Math.round(100*a.toHSV().s),"%")},hsvvalue:function(a){return new d.Dimension(Math.round(100*a.toHSV().v),"%")},red:function(a){return new d.Dimension(a.rgb[0])},green:function(a){return new d.Dimension(a.rgb[1])},blue:function(a){return new d.Dimension(a.rgb[2])},alpha:function(a){return new d.Dimension(a.toHSL().a)},luma:function(a){return new d.Dimension(Math.round(a.luma()*a.alpha*100),"%")},luminance:function(a){var b=.2126*a.rgb[0]/255+.7152*a.rgb[1]/255+.0722*a.rgb[2]/255;return new d.Dimension(Math.round(b*a.alpha*100),"%")},saturate:function(a,b){if(!a.rgb)return null;var c=a.toHSL();return c.s+=b.value/100,c.s=k(c.s),h(c)},desaturate:function(a,b){var c=a.toHSL();return c.s-=b.value/100,c.s=k(c.s),h(c)},lighten:function(a,b){var c=a.toHSL();return c.l+=b.value/100,c.l=k(c.l),h(c)},darken:function(a,b){var c=a.toHSL();return c.l-=b.value/100,c.l=k(c.l),h(c)},fadein:function(a,b){var c=a.toHSL();return c.a+=b.value/100,c.a=k(c.a),h(c)},fadeout:function(a,b){var c=a.toHSL();return c.a-=b.value/100,c.a=k(c.a),h(c)},fade:function(a,b){var c=a.toHSL();return c.a=b.value/100,c.a=k(c.a),h(c)},spin:function(a,b){var c=a.toHSL(),d=(c.h+b.value)%360;return c.h=0>d?360+d:d,h(c)},mix:function(a,b,c){c||(c=new d.Dimension(50));var e=c.value/100,f=2*e-1,g=a.toHSL().a-b.toHSL().a,h=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,i=1-h,j=[a.rgb[0]*h+b.rgb[0]*i,a.rgb[1]*h+b.rgb[1]*i,a.rgb[2]*h+b.rgb[2]*i],k=a.alpha*e+b.alpha*(1-e);return new d.Color(j,k)},greyscale:function(a){return this.desaturate(a,new d.Dimension(100))},contrast:function(a,b,c,d){if(!a.rgb)return null;if("undefined"==typeof c&&(c=this.rgba(255,255,255,1)),"undefined"==typeof b&&(b=this.rgba(0,0,0,1)),b.luma()>c.luma()){var e=c;c=b,b=e}return d="undefined"==typeof d?.43:j(d),a.luma()i.value)&&(m[f]=g);else{if(k!==b&&j!==k)throw{type:"Argument",message:"incompatible types"};n[j]=m.length,m.push(g)}else Array.isArray(c[e].value)&&Array.prototype.push.apply(c,Array.prototype.slice.call(c[e].value));return 1==m.length?m[0]:(c=m.map(function(a){return a.toCSS(this.env)}).join(this.env.compress?",":", "),new d.Anonymous((a?"min":"max")+"("+c+")"))},min:function(){return this._minmax(!0,arguments)},max:function(){return this._minmax(!1,arguments)},"get-unit":function(a){return new d.Anonymous(a.unit)},argb:function(a){return new d.Anonymous(a.toARGB())},percentage:function(a){return new d.Dimension(100*a.value,"%")},color:function(a){if(a instanceof d.Quoted){var b,c=a.value;if(b=d.Color.fromKeyword(c))return b;if(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/.test(c))return new d.Color(c.slice(1));throw{type:"Argument",message:"argument must be a color keyword or 3/6 digit hex e.g. #FFF"}}throw{type:"Argument",message:"argument must be a string"}},iscolor:function(a){return this._isa(a,d.Color)},isnumber:function(a){return this._isa(a,d.Dimension)},isstring:function(a){return this._isa(a,d.Quoted)},iskeyword:function(a){return this._isa(a,d.Keyword)},isurl:function(a){return this._isa(a,d.URL)},ispixel:function(a){return this.isunit(a,"px")},ispercentage:function(a){return this.isunit(a,"%")},isem:function(a){return this.isunit(a,"em")},isunit:function(a,b){return a instanceof d.Dimension&&a.unit.is(b.value||b)?d.True:d.False},_isa:function(a,b){return a instanceof b?d.True:d.False},tint:function(a,b){return this.mix(this.rgb(255,255,255),a,b)},shade:function(a,b){return this.mix(this.rgb(0,0,0),a,b)},extract:function(a,b){return b=b.value-1,Array.isArray(a.value)?a.value[b]:Array(a)[b]},length:function(a){var b=Array.isArray(a.value)?a.value.length:1;return new d.Dimension(b)},"data-uri":function(b,e){if("undefined"!=typeof a)return new d.URL(e||b,this.currentFileInfo).eval(this.env);var f=b.value,g=e&&e.value,h=c("fs"),i=c("path"),j=!1;if(arguments.length<2&&(g=f),this.env.isPathRelative(g)&&(g=this.currentFileInfo.relativeUrls?i.join(this.currentFileInfo.currentDirectory,g):i.join(this.currentFileInfo.entryPath,g)),arguments.length<2){var k;try{k=c("mime")}catch(l){k=d._mime}f=k.lookup(g);var m=k.charsets.lookup(f);j=["US-ASCII","UTF-8"].indexOf(m)<0,j&&(f+=";base64")}else j=/;base64$/.test(f);var n=h.readFileSync(g),o=32,p=parseInt(n.length/1024,10);if(p>=o&&this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",g,p,o),new d.URL(e||b,this.currentFileInfo).eval(this.env);n=j?n.toString("base64"):encodeURIComponent(n);var q='"data:'+f+","+n+'"';return new d.URL(new d.Anonymous(q))},"svg-gradient":function(a){function e(){throw{type:"Argument",message:"svg-gradient expects direction, start_color [start_position], [color position,]..., end_color [end_position]"}}arguments.length<3&&e();var f,g,h,i,j,k,l,m=Array.prototype.slice.call(arguments,1),n="linear",o='x="0" y="0" width="1" height="1"',p=!0,q={compress:!1},r=a.toCSS(q);switch(r){case"to bottom":f='x1="0%" y1="0%" x2="0%" y2="100%"';break;case"to right":f='x1="0%" y1="0%" x2="100%" y2="0%"';break;case"to bottom right":f='x1="0%" y1="0%" x2="100%" y2="100%"';break;case"to top right":f='x1="0%" y1="100%" x2="100%" y2="0%"';break;case"ellipse":case"ellipse at center":n="radial",f='cx="50%" cy="50%" r="75%"',o='x="-50" y="-50" width="101" height="101"';break;default:throw{type:"Argument",message:"svg-gradient direction must be 'to bottom', 'to right', 'to bottom right', 'to top right' or 'ellipse at center'"}}for(g='<'+n+'Gradient id="gradient" gradientUnits="userSpaceOnUse" '+f+">",h=0;hl?' stop-opacity="'+l+'"':"")+"/>";if(g+=""+n+"Gradient> ',p)try{g=c("./encoder").encodeBase64(g)}catch(s){p=!1}return g="'data:image/svg+xml"+(p?";base64":"")+","+g+"'",new d.URL(new d.Anonymous(g))}},d._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(a){var e=c("path").extname(a),f=d._mime._types[e];if(f===b)throw new Error('Optional dependency "mime" is required for '+e);return f},charsets:{lookup:function(a){return a&&/^text\//.test(a)?"UTF-8":""}}};var l={ceil:null,floor:null,sqrt:null,abs:null,tan:"",sin:"",cos:"",atan:"rad",asin:"rad",acos:"rad"},m={multiply:function(a,b){return a*b},screen:function(a,b){return a+b-a*b},overlay:function(a,b){return a*=2,1>=a?m.multiply(a,b):m.screen(a-1,b)},softlight:function(a,b){var c=1,d=a;return b>.5&&(d=1,c=a>.25?Math.sqrt(a):((16*a-12)*a+4)*a),a-(1-2*b)*d*(c-a)},hardlight:function(a,b){return m.overlay(b,a)},difference:function(a,b){return Math.abs(a-b)},exclusion:function(a,b){return a+b-2*a*b},average:function(a,b){return(a+b)/2},negation:function(a,b){return 1-Math.abs(a+b-1)}};d.defaultFunc={eval:function(){var a=this.value_,b=this.error_;if(b)throw b;return null!=a?a?d.True:d.False:void 0},value:function(a){this.value_=a},error:function(a){this.error_=a},reset:function(){this.value_=this.error_=null}},g(),d.fround=function(a,b){var c;return a&&null!=a.numPrecision?(c=Math.pow(10,a.numPrecision),Math.round(b*c)/c):b},d.functionCall=function(a,b){this.env=a,this.currentFileInfo=b},d.functionCall.prototype=d.functions}(c("./tree")),function(a){a.colors={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"}}(c("./tree")),function(a){a.debugInfo=function(b,c,d){var e="";if(b.dumpLineNumbers&&!b.compress)switch(b.dumpLineNumbers){case"comments":e=a.debugInfo.asComment(c);break;case"mediaquery":e=a.debugInfo.asMediaQuery(c);break;case"all":e=a.debugInfo.asComment(c)+(d||"")+a.debugInfo.asMediaQuery(c)}return e},a.debugInfo.asComment=function(a){return"/* line "+a.debugInfo.lineNumber+", "+a.debugInfo.fileName+" */\n"},a.debugInfo.asMediaQuery=function(a){return"@media -sass-debug-info{filename{font-family:"+("file://"+a.debugInfo.fileName).replace(/([.:\/\\])/g,function(a){return"\\"==a&&(a="/"),"\\"+a})+"}line{font-family:\\00003"+a.debugInfo.lineNumber+"}}\n"},a.find=function(a,b){for(var c,d=0;d1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)},a.toCSS=function(a){var b=[];return this.genCSS(a,{add:function(a){b.push(a)},isEmpty:function(){return 0===b.length}}),b.join("")},a.outputRuleset=function(a,b,c){var d,e=c.length;if(a.tabLevel=(0|a.tabLevel)+1,a.compress){for(b.add("{"),d=0;e>d;d++)c[d].genCSS(a,b);return b.add("}"),void a.tabLevel--}var f="\n"+Array(a.tabLevel).join(" "),g=f+" ";if(e){for(b.add(" {"+g),c[0].genCSS(a,b),d=1;e>d;d++)b.add(g),c[d].genCSS(a,b);b.add(f+"}")}else b.add(" {"+f+"}");a.tabLevel--}}(c("./tree")),function(a){a.Alpha=function(a){this.value=a},a.Alpha.prototype={type:"Alpha",accept:function(a){this.value=a.visit(this.value)},eval:function(b){return this.value.eval?new a.Alpha(this.value.eval(b)):this},genCSS:function(a,b){b.add("alpha(opacity="),this.value.genCSS?this.value.genCSS(a,b):b.add(this.value),b.add(")")},toCSS:a.toCSS}}(c("../tree")),function(a){a.Anonymous=function(a,b,c,d){this.value=a.value||a,this.index=b,this.mapLines=d,this.currentFileInfo=c},a.Anonymous.prototype={type:"Anonymous",eval:function(){return new a.Anonymous(this.value,this.index,this.currentFileInfo,this.mapLines)},compare:function(a){if(!a.toCSS)return-1;var b=this.toCSS(),c=a.toCSS();return b===c?0:c>b?-1:1},genCSS:function(a,b){b.add(this.value,this.currentFileInfo,this.index,this.mapLines)},toCSS:a.toCSS}}(c("../tree")),function(a){a.Assignment=function(a,b){this.key=a,this.value=b},a.Assignment.prototype={type:"Assignment",accept:function(a){this.value=a.visit(this.value)},eval:function(b){return this.value.eval?new a.Assignment(this.key,this.value.eval(b)):this},genCSS:function(a,b){b.add(this.key+"="),this.value.genCSS?this.value.genCSS(a,b):b.add(this.value)},toCSS:a.toCSS}}(c("../tree")),function(a){a.Call=function(a,b,c,d){this.name=a,this.args=b,this.index=c,this.currentFileInfo=d},a.Call.prototype={type:"Call",accept:function(a){this.args&&(this.args=a.visitArray(this.args))},eval:function(b){var c,d,e=this.args.map(function(a){return a.eval(b)}),f=this.name.toLowerCase();if(f in a.functions)try{if(d=new a.functionCall(b,this.currentFileInfo),c=d[f].apply(d,e),null!=c)return c}catch(g){throw{type:g.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(g.message?": "+g.message:""),index:this.index,filename:this.currentFileInfo.filename}}return new a.Call(this.name,e,this.index,this.currentFileInfo)},genCSS:function(a,b){b.add(this.name+"(",this.currentFileInfo,this.index);for(var c=0;ca?"0":"")+a.toString(16)}).join("")}function c(a,b){return Math.min(Math.max(a,0),b)}a.Color=function(a,b){this.rgb=Array.isArray(a)?a:6==a.length?a.match(/.{2}/g).map(function(a){return parseInt(a,16)}):a.split("").map(function(a){return parseInt(a+a,16)}),this.alpha="number"==typeof b?b:1};var d="transparent";a.Color.prototype={type:"Color",eval:function(){return this},luma:function(){var a=this.rgb[0]/255,b=this.rgb[1]/255,c=this.rgb[2]/255;return a=.03928>=a?a/12.92:Math.pow((a+.055)/1.055,2.4),b=.03928>=b?b/12.92:Math.pow((b+.055)/1.055,2.4),c=.03928>=c?c/12.92:Math.pow((c+.055)/1.055,2.4),.2126*a+.7152*b+.0722*c},genCSS:function(a,b){b.add(this.toCSS(a))},toCSS:function(b,e){var f=b&&b.compress&&!e,g=a.fround(b,this.alpha);if(1>g)return 0===g&&this.isTransparentKeyword?d:"rgba("+this.rgb.map(function(a){return c(Math.round(a),255)}).concat(c(g,1)).join(","+(f?"":" "))+")";var h=this.toRGB();if(f){var i=h.split("");i[1]===i[2]&&i[3]===i[4]&&i[5]===i[6]&&(h="#"+i[1]+i[3]+i[5])}return h},operate:function(b,c,d){for(var e=[],f=this.alpha*(1-d.alpha)+d.alpha,g=0;3>g;g++)e[g]=a.operate(b,c,this.rgb[g],d.rgb[g]);return new a.Color(e,f)},toRGB:function(){return b(this.rgb)},toHSL:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=(g+h)/2,j=g-h;if(g===h)a=b=0;else{switch(b=i>.5?j/(2-g-h):j/(g+h),g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,l:i,a:f}},toHSV:function(){var a,b,c=this.rgb[0]/255,d=this.rgb[1]/255,e=this.rgb[2]/255,f=this.alpha,g=Math.max(c,d,e),h=Math.min(c,d,e),i=g,j=g-h;if(b=0===g?0:j/g,g===h)a=0;else{switch(g){case c:a=(d-e)/j+(e>d?6:0);break;case d:a=(e-c)/j+2;break;case e:a=(c-d)/j+4}a/=6}return{h:360*a,s:b,v:i,a:f}},toARGB:function(){return b([255*this.alpha].concat(this.rgb))},compare:function(a){return a.rgb?a.rgb[0]===this.rgb[0]&&a.rgb[1]===this.rgb[1]&&a.rgb[2]===this.rgb[2]&&a.alpha===this.alpha?0:-1:-1}},a.Color.fromKeyword=function(b){if(b=b.toLowerCase(),a.colors.hasOwnProperty(b))return new a.Color(a.colors[b].slice(1));if(b===d){var c=new a.Color([0,0,0],0);return c.isTransparentKeyword=!0,c}}}(c("../tree")),function(a){a.Comment=function(a,b,c,d){this.value=a,this.silent=!!b,this.currentFileInfo=d},a.Comment.prototype={type:"Comment",genCSS:function(b,c){this.debugInfo&&c.add(a.debugInfo(b,this),this.currentFileInfo,this.index),c.add(this.value.trim())},toCSS:a.toCSS,isSilent:function(a){var b=this.currentFileInfo&&this.currentFileInfo.reference&&!this.isReferenced,c=a.compress&&!this.value.match(/^\/\*!/);return this.silent||b||c},eval:function(){return this},markReferenced:function(){this.isReferenced=!0}}}(c("../tree")),function(a){a.Condition=function(a,b,c,d,e){this.op=a.trim(),this.lvalue=b,this.rvalue=c,this.index=d,this.negate=e},a.Condition.prototype={type:"Condition",accept:function(a){this.lvalue=a.visit(this.lvalue),this.rvalue=a.visit(this.rvalue)},eval:function(a){var b,c=this.lvalue.eval(a),d=this.rvalue.eval(a),e=this.index;return b=function(a){switch(a){case"and":return c&&d;case"or":return c||d;default:if(c.compare)b=c.compare(d);else{if(!d.compare)throw{type:"Type",message:"Unable to perform comparison",index:e};b=d.compare(c)}switch(b){case-1:return"<"===a||"=<"===a||"<="===a;case 0:return"="===a||">="===a||"=<"===a||"<="===a;case 1:return">"===a||">="===a}}}(this.op),this.negate?!b:b}}}(c("../tree")),function(a){a.DetachedRuleset=function(a,b){this.ruleset=a,this.frames=b},a.DetachedRuleset.prototype={type:"DetachedRuleset",accept:function(a){this.ruleset=a.visit(this.ruleset)},eval:function(b){var c=this.frames||b.frames.slice(0);return new a.DetachedRuleset(this.ruleset,c)},callEval:function(b){return this.ruleset.eval(this.frames?new a.evalEnv(b,this.frames.concat(b.frames)):b)}}}(c("../tree")),function(a){a.Dimension=function(c,d){this.value=parseFloat(c),this.unit=d&&d instanceof a.Unit?d:new a.Unit(d?[d]:b)},a.Dimension.prototype={type:"Dimension",accept:function(a){this.unit=a.visit(this.unit)},eval:function(){return this},toColor:function(){return new a.Color([this.value,this.value,this.value])},genCSS:function(b,c){if(b&&b.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var d=a.fround(b,this.value),e=String(d);if(0!==d&&1e-6>d&&d>-1e-6&&(e=d.toFixed(20).replace(/0+$/,"")),b&&b.compress){if(0===d&&this.unit.isLength())return void c.add(e);d>0&&1>d&&(e=e.substr(1))}c.add(e),this.unit.genCSS(b,c)},toCSS:a.toCSS,operate:function(b,c,d){var e=a.operate(b,c,this.value,d.value),f=this.unit.clone();if("+"===c||"-"===c)if(0===f.numerator.length&&0===f.denominator.length)f.numerator=d.unit.numerator.slice(0),f.denominator=d.unit.denominator.slice(0);else if(0===d.unit.numerator.length&&0===f.denominator.length);else{if(d=d.convertTo(this.unit.usedUnits()),b.strictUnits&&d.unit.toString()!==f.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+f.toString()+"' and '"+d.unit.toString()+"'.");e=a.operate(b,c,this.value,d.value)}else"*"===c?(f.numerator=f.numerator.concat(d.unit.numerator).sort(),f.denominator=f.denominator.concat(d.unit.denominator).sort(),f.cancel()):"/"===c&&(f.numerator=f.numerator.concat(d.unit.denominator).sort(),f.denominator=f.denominator.concat(d.unit.numerator).sort(),f.cancel());return new a.Dimension(e,f)},compare:function(b){if(b instanceof a.Dimension){var c,d,e,f;if(this.unit.isEmpty()||b.unit.isEmpty())c=this,d=b;else if(c=this.unify(),d=b.unify(),0!==c.unit.compare(d.unit))return-1;return e=c.value,f=d.value,f>e?-1:e>f?1:0}return-1},unify:function(){return this.convertTo({length:"px",duration:"s",angle:"rad"})},convertTo:function(b){var c,d,e,f,g,h=this.value,i=this.unit.clone(),j={};if("string"==typeof b){for(c in a.UnitConversions)a.UnitConversions[c].hasOwnProperty(b)&&(j={},j[c]=b);b=j}g=function(a,b){return e.hasOwnProperty(a)?(b?h/=e[a]/e[f]:h*=e[a]/e[f],f):a};for(d in b)b.hasOwnProperty(d)&&(f=b[d],e=a.UnitConversions[d],i.map(g));return i.cancel(),new a.Dimension(h,i)}},a.UnitConversions={length:{m:1,cm:.01,mm:.001,"in":.0254,px:.0254/96,pt:.0254/72,pc:.0254/72*12},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:.0025,turn:1}},a.Unit=function(a,b,c){this.numerator=a?a.slice(0).sort():[],this.denominator=b?b.slice(0).sort():[],this.backupUnit=c},a.Unit.prototype={type:"Unit",clone:function(){return new a.Unit(this.numerator.slice(0),this.denominator.slice(0),this.backupUnit)},genCSS:function(a,b){this.numerator.length>=1?b.add(this.numerator[0]):this.denominator.length>=1?b.add(this.denominator[0]):a&&a.strictUnits||!this.backupUnit||b.add(this.backupUnit)},toCSS:a.toCSS,toString:function(){var a,b=this.numerator.join("*");for(a=0;a0)for(b=0;e>b;b++)this.numerator.push(a);else if(0>e)for(b=0;-e>b;b++)this.denominator.push(a)}0===this.numerator.length&&0===this.denominator.length&&c&&(this.backupUnit=c),this.numerator.sort(),this.denominator.sort()}}}(c("../tree")),function(a){a.Directive=function(a,b,c,d,e,f){this.name=a,this.value=b,c&&(this.rules=c,this.rules.allowImports=!0),this.index=d,this.currentFileInfo=e,this.debugInfo=f},a.Directive.prototype={type:"Directive",accept:function(a){var b=this.value,c=this.rules;c&&(c=a.visit(c)),b&&(b=a.visit(b))},genCSS:function(b,c){var d=this.value,e=this.rules;c.add(this.name,this.currentFileInfo,this.index),d&&(c.add(" "),d.genCSS(b,c)),e?a.outputRuleset(b,c,[e]):c.add(";")},toCSS:a.toCSS,eval:function(b){var c=this.value,d=this.rules;return c&&(c=c.eval(b)),d&&(d=d.eval(b),d.root=!0),new a.Directive(this.name,c,d,this.index,this.currentFileInfo,this.debugInfo)},variable:function(b){return this.rules?a.Ruleset.prototype.variable.call(this.rules,b):void 0},find:function(){return this.rules?a.Ruleset.prototype.find.apply(this.rules,arguments):void 0},rulesets:function(){return this.rules?a.Ruleset.prototype.rulesets.apply(this.rules):void 0},markReferenced:function(){var a,b;if(this.isReferenced=!0,this.rules)for(b=this.rules.rules,a=0;a":" > ","|":"|","^":" ^ ","^^":" ^^ "},_outputMapCompressed:{"":""," ":" ",":":" :","+":"+","~":"~",">":">","|":"|","^":"^","^^":"^^"},genCSS:function(a,b){b.add((a.compress?this._outputMapCompressed:this._outputMap)[this.value])},toCSS:a.toCSS}}(c("../tree")),function(a){a.Expression=function(a){this.value=a},a.Expression.prototype={type:"Expression",accept:function(a){this.value&&(this.value=a.visitArray(this.value))},eval:function(b){var c,d=this.parens&&!this.parensInOp,e=!1;return d&&b.inParenthesis(),this.value.length>1?c=new a.Expression(this.value.map(function(a){return a.eval(b)})):1===this.value.length?(this.value[0].parens&&!this.value[0].parensInOp&&(e=!0),c=this.value[0].eval(b)):c=this,d&&b.outOfParenthesis(),this.parens&&this.parensInOp&&!b.isMathOn()&&!e&&(c=new a.Paren(c)),c},genCSS:function(a,b){for(var c=0;c0&&c.length&&""===c[0].combinator.value&&(c[0].combinator.value=" "),d=d.concat(a[b].elements);this.selfSelectors=[{elements:d}]}}}(c("../tree")),function(a){a.Import=function(a,c,d,e,f){if(this.options=d,this.index=e,this.path=a,this.features=c,this.currentFileInfo=f,this.options.less!==b||this.options.inline)this.css=!this.options.less||this.options.inline;else{var g=this.getPath();g&&/css([\?;].*)?$/.test(g)&&(this.css=!0)}},a.Import.prototype={type:"Import",accept:function(a){this.features&&(this.features=a.visit(this.features)),this.path=a.visit(this.path),!this.options.inline&&this.root&&(this.root=a.visit(this.root))},genCSS:function(a,b){this.css&&(b.add("@import ",this.currentFileInfo,this.index),this.path.genCSS(a,b),this.features&&(b.add(" "),this.features.genCSS(a,b)),b.add(";"))},toCSS:a.toCSS,getPath:function(){if(this.path instanceof a.Quoted){var c=this.path.value;return this.css!==b||/(\.[a-z]*$)|([\?;].*)$/.test(c)?c:c+".less"}return this.path instanceof a.URL?this.path.value.value:null},evalForImport:function(b){return new a.Import(this.path.eval(b),this.features,this.options,this.index,this.currentFileInfo)},evalPath:function(b){var c=this.path.eval(b),d=this.currentFileInfo&&this.currentFileInfo.rootpath;if(!(c instanceof a.URL)){if(d){var e=c.value;e&&b.isPathRelative(e)&&(c.value=d+e)}c.value=b.normalizePath(c.value)}return c},eval:function(b){var c,d=this.features&&this.features.eval(b);if(this.skip&&("function"==typeof this.skip&&(this.skip=this.skip()),this.skip))return[];if(this.options.inline){var e=new a.Anonymous(this.root,0,{filename:this.importedFilename},!0);return this.features?new a.Media([e],this.features.value):[e]}if(this.css){var f=new a.Import(this.evalPath(b),d,this.options,this.index);if(!f.css&&this.error)throw this.error;return f}return c=new a.Ruleset(null,this.root.rules.slice(0)),c.evalImports(b),this.features?new a.Media(c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={type:"JavaScript",eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify(new a.Variable("@"+e,d.index).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: "+g.message+" from `"+f+"`",index:this.index}}var h=b.frames[0].variables();for(var i in h)h.hasOwnProperty(i)&&(e[i.slice(1)]={value:h[i].value,toJS:function(){return this.value.eval(b).toCSS()}});try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message.replace(/["]/g,"'")+"'",index:this.index}}return"number"==typeof c?new a.Dimension(c):"string"==typeof c?new a.Quoted('"'+c+'"',c,this.escaped,this.index):new a.Anonymous(Array.isArray(c)?c.join(", "):c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={type:"Keyword",eval:function(){return this},genCSS:function(a,b){if("%"===this.value)throw{type:"Syntax",message:"Invalid % without number"};b.add(this.value)},toCSS:a.toCSS,compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")),function(a){a.Media=function(b,c,d,e){this.index=d,this.currentFileInfo=e;var f=this.emptySelectors();this.features=new a.Value(c),this.rules=[new a.Ruleset(f,b)],this.rules[0].allowImports=!0},a.Media.prototype={type:"Media",accept:function(a){this.features&&(this.features=a.visit(this.features)),this.rules&&(this.rules=a.visitArray(this.rules))},genCSS:function(b,c){c.add("@media ",this.currentFileInfo,this.index),this.features.genCSS(b,c),a.outputRuleset(b,c,this.rules)},toCSS:a.toCSS,eval:function(b){b.mediaBlocks||(b.mediaBlocks=[],b.mediaPath=[]);var c=new a.Media(null,[],this.index,this.currentFileInfo);this.debugInfo&&(this.rules[0].debugInfo=this.debugInfo,c.debugInfo=this.debugInfo);var d=!1;b.strictMath||(d=!0,b.strictMath=!0);try{c.features=this.features.eval(b)}finally{d&&(b.strictMath=!1)}return b.mediaPath.push(c),b.mediaBlocks.push(c),b.frames.unshift(this.rules[0]),c.rules=[this.rules[0].eval(b)],b.frames.shift(),b.mediaPath.pop(),0===b.mediaPath.length?c.evalTop(b):c.evalNested(b)},variable:function(b){return a.Ruleset.prototype.variable.call(this.rules[0],b)},find:function(){return a.Ruleset.prototype.find.apply(this.rules[0],arguments)},rulesets:function(){return a.Ruleset.prototype.rulesets.apply(this.rules[0])},emptySelectors:function(){var b=new a.Element("","&",this.index,this.currentFileInfo),c=[new a.Selector([b],null,null,this.index,this.currentFileInfo)];return c[0].mediaEmpty=!0,c},markReferenced:function(){var a,b=this.rules[0].rules;for(this.rules[0].markReferenced(),this.isReferenced=!0,a=0;a1){var d=this.emptySelectors();c=new a.Ruleset(d,b.mediaBlocks),c.multiMedia=!0}return delete b.mediaBlocks,delete b.mediaPath,c},evalNested:function(b){var c,d,e=b.mediaPath.concat([this]);for(c=0;c0;c--)b.splice(c,0,new a.Anonymous("and"));return new a.Expression(b)})),new a.Ruleset([],[])},permute:function(a){if(0===a.length)return[];if(1===a.length)return a[0];for(var b=[],c=this.permute(a.slice(1)),d=0;d0){for(j=!0,g=0;gh;h++)s.value(h),r[h]=d.matchCondition(e,b);(r[0]||r[1])&&(r[0]!=r[1]&&(l.group=r[1]?u:v),q.push(l))}else q.push(l);p=!0}}for(s.reset(),n=[0,0,0],g=0;g0)m=v;else if(m=u,n[u]+n[v]>1)throw{type:"Runtime",message:"Ambiguous use of `default()` found when matching for `"+this.format(e)+"`",index:this.index,filename:this.currentFileInfo.filename};for(g=0;gh;h++)if(g=d[h],k=g&&g.name){for(l=!1,i=0;ii;i++)f.push(d[i].value.eval(b));n.prependRule(new a.Rule(k,new a.Expression(f).eval(b)))}else{if(j=g&&g.value)j=j.eval(b);else{if(!o[h].value)throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+p+" for "+this.arity+")"};j=o[h].value.eval(c),n.resetCache()}n.prependRule(new a.Rule(k,j)),e[h]=j}if(o[h].variadic&&d)for(i=m;p>i;i++)e[i]=d[i].value.eval(b);m++}return n},eval:function(b){return new a.mixin.Definition(this.name,this.params,this.rules,this.condition,this.variadic,this.frames||b.frames.slice(0))},evalCall:function(b,c,d){var e,f,g=[],h=this.frames?this.frames.concat(b.frames):b.frames,i=this.evalParams(b,new a.evalEnv(b,h),c,g);return i.prependRule(new a.Rule("@arguments",new a.Expression(g).eval(b))),e=this.rules.slice(0),f=new a.Ruleset(null,e),f.originalRuleset=this,f=f.eval(new a.evalEnv(b,[this,i].concat(h))),d&&(f=this.parent.makeImportant.apply(f)),f},matchCondition:function(b,c){return this.condition&&!this.condition.eval(new a.evalEnv(c,[this.evalParams(c,new a.evalEnv(c,this.frames.concat(c.frames)),b,[])].concat(this.frames).concat(c.frames)))?!1:!0},matchArgs:function(a,b){var c,d=a&&a.length||0;if(this.variadic){if(dthis.params.length)return!1}c=Math.min(d,this.arity);for(var e=0;c>e;e++)if(!this.params[e].name&&!this.params[e].variadic&&a[e].value.eval(b).toCSS()!=this.params[e].value.eval(b).toCSS())return!1;return!0}}}(c("../tree")),function(a){a.Negative=function(a){this.value=a},a.Negative.prototype={type:"Negative",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add("-"),this.value.genCSS(a,b)},toCSS:a.toCSS,eval:function(b){return b.isMathOn()?new a.Operation("*",[new a.Dimension(-1),this.value]).eval(b):new a.Negative(this.value.eval(b))}}}(c("../tree")),function(a){a.Operation=function(a,b,c){this.op=a.trim(),this.operands=b,this.isSpaced=c},a.Operation.prototype={type:"Operation",accept:function(a){this.operands=a.visit(this.operands)},eval:function(b){var c=this.operands[0].eval(b),d=this.operands[1].eval(b);if(b.isMathOn()){if(c instanceof a.Dimension&&d instanceof a.Color&&(c=c.toColor()),d instanceof a.Dimension&&c instanceof a.Color&&(d=d.toColor()),!c.operate)throw{type:"Operation",message:"Operation on an invalid type"};return c.operate(b,this.op,d)}return new a.Operation(this.op,[c,d],this.isSpaced)},genCSS:function(a,b){this.operands[0].genCSS(a,b),this.isSpaced&&b.add(" "),b.add(this.op),this.isSpaced&&b.add(" "),this.operands[1].genCSS(a,b)},toCSS:a.toCSS},a.operate=function(a,b,c,d){switch(b){case"+":return c+d;case"-":return c-d;case"*":return c*d;case"/":return c/d}}}(c("../tree")),function(a){a.Paren=function(a){this.value=a},a.Paren.prototype={type:"Paren",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add("("),this.value.genCSS(a,b),b.add(")")},toCSS:a.toCSS,eval:function(b){return new a.Paren(this.value.eval(b))}}}(c("../tree")),function(a){a.Quoted=function(a,b,c,d,e){this.escaped=c,this.value=b||"",this.quote=a.charAt(0),this.index=d,this.currentFileInfo=e},a.Quoted.prototype={type:"Quoted",genCSS:function(a,b){this.escaped||b.add(this.quote,this.currentFileInfo,this.index),b.add(this.value),this.escaped||b.add(this.quote)},toCSS:a.toCSS,eval:function(b){var c=this,d=this.value.replace(/`([^`]+)`/g,function(d,e){return new a.JavaScript(e,c.index,!0).eval(b).value}).replace(/@\{([\w-]+)\}/g,function(d,e){var f=new a.Variable("@"+e,c.index,c.currentFileInfo).eval(b,!0);return f instanceof a.Quoted?f.value:f.toCSS()});return new a.Quoted(this.quote+d+this.quote,d,this.escaped,this.index,this.currentFileInfo)},compare:function(a){if(!a.toCSS)return-1;var b=this.toCSS(),c=a.toCSS();return b===c?0:c>b?-1:1}}}(c("../tree")),function(a){function b(a,b){var c,d="",e=b.length,f={add:function(a){d+=a}};for(c=0;e>c;c++)b[c].eval(a).genCSS(a,f);return d}a.Rule=function(b,c,d,e,f,g,h){this.name=b,this.value=c instanceof a.Value||c instanceof a.Ruleset?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.merge=e,this.index=f,this.currentFileInfo=g,this.inline=h||!1,this.variable=b.charAt&&"@"===b.charAt(0)},a.Rule.prototype={type:"Rule",accept:function(a){this.value=a.visit(this.value)},genCSS:function(a,b){b.add(this.name+(a.compress?":":": "),this.currentFileInfo,this.index);try{this.value.genCSS(a,b)}catch(c){throw c.index=this.index,c.filename=this.currentFileInfo.filename,c}b.add(this.important+(this.inline||a.lastRule&&a.compress?"":";"),this.currentFileInfo,this.index)},toCSS:a.toCSS,eval:function(c){var d,e=!1,f=this.name;"string"!=typeof f&&(f=1===f.length&&f[0]instanceof a.Keyword?f[0].value:b(c,f)),"font"!==f||c.strictMath||(e=!0,c.strictMath=!0);try{if(d=this.value.eval(c),!this.variable&&"DetachedRuleset"===d.type)throw{message:"Rulesets cannot be evaluated on a property.",index:this.index,filename:this.currentFileInfo.filename};return new a.Rule(f,d,this.important,this.merge,this.index,this.currentFileInfo,this.inline)}catch(g){throw"number"!=typeof g.index&&(g.index=this.index,g.filename=this.currentFileInfo.filename),g}finally{e&&(c.strictMath=!1)}},makeImportant:function(){return new a.Rule(this.name,this.value,"!important",this.merge,this.index,this.currentFileInfo,this.inline)}}}(c("../tree")),function(a){a.RulesetCall=function(a){this.variable=a},a.RulesetCall.prototype={type:"RulesetCall",accept:function(){},eval:function(b){var c=new a.Variable(this.variable).eval(b);return c.callEval(b)}}}(c("../tree")),function(a){a.Ruleset=function(a,b,c){this.selectors=a,this.rules=b,this._lookups={},this.strictImports=c},a.Ruleset.prototype={type:"Ruleset",accept:function(a){this.paths?a.visitArray(this.paths,!0):this.selectors&&(this.selectors=a.visitArray(this.selectors)),this.rules&&this.rules.length&&(this.rules=a.visitArray(this.rules))},eval:function(b){var c,d,e,f,g=this.selectors,h=a.defaultFunc,i=!1;if(g&&(d=g.length)){for(c=[],h.error({type:"Syntax",message:"it is currently only allowed in parametric mixin guards,"}),f=0;d>f;f++)e=g[f].eval(b),c.push(e),e.evaldCondition&&(i=!0);h.reset()}else i=!0;var j,k,l=this.rules?this.rules.slice(0):null,m=new a.Ruleset(c,l,this.strictImports);m.originalRuleset=this,m.root=this.root,m.firstRoot=this.firstRoot,m.allowImports=this.allowImports,this.debugInfo&&(m.debugInfo=this.debugInfo),i||(l.length=0);var n=b.frames;n.unshift(m);var o=b.selectors;o||(b.selectors=o=[]),o.unshift(this.selectors),(m.root||m.allowImports||!m.strictImports)&&m.evalImports(b);var p=m.rules,q=p?p.length:0;for(f=0;q>f;f++)(p[f]instanceof a.mixin.Definition||p[f]instanceof a.DetachedRuleset)&&(p[f]=p[f].eval(b));var r=b.mediaBlocks&&b.mediaBlocks.length||0;for(f=0;q>f;f++)p[f]instanceof a.mixin.Call?(l=p[f].eval(b).filter(function(b){return b instanceof a.Rule&&b.variable?!m.variable(b.name):!0}),p.splice.apply(p,[f,1].concat(l)),q+=l.length-1,f+=l.length-1,m.resetCache()):p[f]instanceof a.RulesetCall&&(l=p[f].eval(b).rules.filter(function(b){return b instanceof a.Rule&&b.variable?!1:!0}),p.splice.apply(p,[f,1].concat(l)),q+=l.length-1,f+=l.length-1,m.resetCache());for(f=0;fb;b++)c=g[b],(c instanceof d||c instanceof e)&&f.push(c);return f},prependRule:function(a){var b=this.rules;b?b.unshift(a):this.rules=[a]},find:function(b,c){c=c||this;var d,e=[],f=b.toCSS();return f in this._lookups?this._lookups[f]:(this.rulesets().forEach(function(f){if(f!==c)for(var g=0;gd?Array.prototype.push.apply(e,f.find(new a.Selector(b.elements.slice(d)),c)):e.push(f);break}}),this._lookups[f]=e,e)},genCSS:function(b,c){var d,e,f,g,h,i,j=[],k=[];b.tabLevel=b.tabLevel||0,this.root||b.tabLevel++;var l,m=b.compress?"":Array(b.tabLevel+1).join(" "),n=b.compress?"":Array(b.tabLevel).join(" ");for(d=0;dd;d++)if(i=p[d],o=i.length)for(d>0&&c.add(l),b.firstSelector=!0,i[0].genCSS(b,c),b.firstSelector=!1,e=1;o>e;e++)i[e].genCSS(b,c);c.add((b.compress?"{":" {\n")+m)}for(d=0;dd;d++)l&&c.add(l),k[d].genCSS(b,c);c.isEmpty()||b.compress||!this.firstRoot||c.add("\n")},toCSS:a.toCSS,markReferenced:function(){if(this.selectors)for(var a=0;a0&&this.mergeElementsOnToSelectors(r,i),f=0;f0&&(k[0].elements=k[0].elements.slice(0),k[0].elements.push(new a.Element(j.combinator,"",j.index,j.currentFileInfo))),s.push(k);else for(g=0;g0?(m=k.slice(0),q=m.pop(),o=d.createDerived(q.elements.slice(0)),p=!1):o=d.createDerived([]),l.length>1&&(n=n.concat(l.slice(1))),l.length>0&&(p=!1,o.elements.push(new a.Element(j.combinator,l[0].elements[0].value,j.index,j.currentFileInfo)),o.elements=o.elements.concat(l[0].elements.slice(1))),p||m.push(o),m=m.concat(n),s.push(m);i=s,r=[]}for(r.length>0&&this.mergeElementsOnToSelectors(r,i),e=0;e0&&b.push(i[e])}else if(c.length>0)for(e=0;e0?e[e.length-1]=e[e.length-1].createDerived(e[e.length-1].elements.concat(b)):e.push(new a.Selector(b))}}}(c("../tree")),function(a){a.Selector=function(a,b,c,d,e,f){this.elements=a,this.extendList=b,this.condition=c,this.currentFileInfo=e||{},this.isReferenced=f,c||(this.evaldCondition=!0)},a.Selector.prototype={type:"Selector",accept:function(a){this.elements&&(this.elements=a.visitArray(this.elements)),this.extendList&&(this.extendList=a.visitArray(this.extendList)),this.condition&&(this.condition=a.visit(this.condition))},createDerived:function(b,c,d){d=null!=d?d:this.evaldCondition;var e=new a.Selector(b,c||this.extendList,null,this.index,this.currentFileInfo,this.isReferenced);return e.evaldCondition=d,e.mediaEmpty=this.mediaEmpty,e},match:function(a){var b,c,d=this.elements,e=d.length;if(a.CacheElements(),b=a._elements.length,0===b||b>e)return 0;for(c=0;b>c;c++)if(d[c].value!==a._elements[c])return 0;return b},CacheElements:function(){var a,b,c,d="";if(!this._elements){for(a=this.elements.length,c=0;a>c;c++)if(b=this.elements[c],d+=b.combinator.value,b.value.value){if("string"!=typeof b.value.value){d="";break}d+=b.value.value}else d+=b.value;this._elements=d.match(/[,\.\w-]([\w-]|(\\.))*/g),this._elements?"&"===this._elements[0]&&this._elements.shift():this._elements=[]}},isJustParentSelector:function(){return!this.mediaEmpty&&1===this.elements.length&&"&"===this.elements[0].value&&(" "===this.elements[0].combinator.value||""===this.elements[0].combinator.value)},eval:function(a){var b=this.condition&&this.condition.eval(a),c=this.elements,d=this.extendList;return c=c&&c.map(function(b){return b.eval(a)}),d=d&&d.map(function(b){return b.eval(a)}),this.createDerived(c,d,b)},genCSS:function(a,b){var c,d;if(a&&a.firstSelector||""!==this.elements[0].combinator.value||b.add(" ",this.currentFileInfo,this.index),!this._css)for(c=0;cc;c++)this.visit(a[c]);return a}var e=[];for(c=0;d>c;c++){var f=this.visit(a[c]);f.splice?f.length&&this.flatten(f,e):e.push(f)}return e},flatten:function(a,b){b||(b=[]);var c,d,e,f,g,h;for(d=0,c=a.length;c>d;d++)if(e=a[d],e.splice)for(g=0,f=e.length;f>g;g++)h=e[g],h.splice?h.length&&this.flatten(h,b):b.push(h);else b.push(e);return b}}}(c("./tree")),function(a){a.importVisitor=function(b,c,d,e,f){if(this._visitor=new a.visitor(this),this._importer=b,this._finish=c,this.env=d||new a.evalEnv,this.importCount=0,this.onceFileDetectionMap=e||{},this.recursionDetector={},f)for(var g in f)f.hasOwnProperty(g)&&(this.recursionDetector[g]=!0)},a.importVisitor.prototype={isReplacing:!0,run:function(a){var b;try{this._visitor.visit(a)}catch(c){b=c}this.isFinished=!0,0===this.importCount&&this._finish(b)},visitImport:function(b,c){var d,e=this,f=b.options.inline;if(!b.css||f){try{d=b.evalForImport(this.env)}catch(g){g.filename||(g.index=b.index,g.filename=b.currentFileInfo.filename),b.css=!0,b.error=g}if(d&&(!d.css||f)){b=d,this.importCount++;var h=new a.evalEnv(this.env,this.env.frames.slice(0));b.options.multiple&&(h.importMultiple=!0),this._importer.push(b.getPath(),b.currentFileInfo,b.options,function(c,d,g,i){c&&!c.filename&&(c.index=b.index,c.filename=b.currentFileInfo.filename),h.importMultiple||(b.skip=g?!0:function(){return i in e.onceFileDetectionMap?!0:(e.onceFileDetectionMap[i]=!0,!1)});var j=function(a){e.importCount--,0===e.importCount&&e.isFinished&&e._finish(a)};if(d){b.root=d,b.importedFilename=i;var k=g||i in e.recursionDetector;if(!f&&(h.importMultiple||!k))return e.recursionDetector[i]=!0,void new a.importVisitor(e._importer,j,h,e.onceFileDetectionMap,e.recursionDetector).run(d)}j()})}}return c.visitDeeper=!1,b},visitRule:function(a,b){return b.visitDeeper=!1,a},visitDirective:function(a){return this.env.frames.unshift(a),a},visitDirectiveOut:function(){this.env.frames.shift()},visitMixinDefinition:function(a){return this.env.frames.unshift(a),a},visitMixinDefinitionOut:function(){this.env.frames.shift()},visitRuleset:function(a){return this.env.frames.unshift(a),a},visitRulesetOut:function(){this.env.frames.shift()},visitMedia:function(a){return this.env.frames.unshift(a.ruleset),a},visitMediaOut:function(){this.env.frames.shift()}}}(c("./tree")),function(a){a.joinSelectorVisitor=function(){this.contexts=[[]],this._visitor=new a.visitor(this)},a.joinSelectorVisitor.prototype={run:function(a){return this._visitor.visit(a)},visitRule:function(a,b){b.visitDeeper=!1},visitMixinDefinition:function(a,b){b.visitDeeper=!1},visitRuleset:function(a){var b,c=this.contexts[this.contexts.length-1],d=[];this.contexts.push(d),a.root||(b=a.selectors,b&&(b=b.filter(function(a){return a.getIsOutput()}),a.selectors=b.length?b:b=null,b&&a.joinSelectors(d,c,b)),b||(a.rules=null),a.paths=d)},visitRulesetOut:function(){this.contexts.length=this.contexts.length-1},visitMedia:function(a){var b=this.contexts[this.contexts.length-1];a.rules[0].root=0===b.length||b[0].multiMedia}}}(c("./tree")),function(a){a.toCSSVisitor=function(b){this._visitor=new a.visitor(this),this._env=b},a.toCSSVisitor.prototype={isReplacing:!0,run:function(a){return this._visitor.visit(a)},visitRule:function(a){return a.variable?[]:a},visitMixinDefinition:function(a){return a.frames=[],[]},visitExtend:function(){return[]},visitComment:function(a){return a.isSilent(this._env)?[]:a},visitMedia:function(a,b){return a.accept(this._visitor),b.visitDeeper=!1,a.rules.length?a:[]},visitDirective:function(b){if(b.currentFileInfo.reference&&!b.isReferenced)return[];if("@charset"===b.name){if(this.charset){if(b.debugInfo){var c=new a.Comment("/* "+b.toCSS(this._env).replace(/\n/g,"")+" */\n");return c.debugInfo=b.debugInfo,this._visitor.visit(c)}return[]}this.charset=!0}return b},checkPropertiesInRoot:function(b){for(var c,d=0;d0)&&e.splice(0,0,b);else{b.paths&&(b.paths=b.paths.filter(function(b){var c;for(" "===b[0].elements[0].combinator.value&&(b[0].elements[0].combinator=new a.Combinator("")),c=0;ch;)d=f[h],d&&d.rules?(e.push(this._visitor.visit(d)),f.splice(h,1),g--):h++;g>0?b.accept(this._visitor):b.rules=null,c.visitDeeper=!1,f=b.rules,f&&(this._mergeRules(f),f=b.rules),f&&(this._removeDuplicateRules(f),f=b.rules),f&&f.length>0&&b.paths.length>0&&e.splice(0,0,b)}return 1===e.length?e[0]:e},_removeDuplicateRules:function(b){if(b){var c,d,e,f={};for(e=b.length-1;e>=0;e--)if(d=b[e],d instanceof a.Rule)if(f[d.name]){c=f[d.name],c instanceof a.Rule&&(c=f[d.name]=[f[d.name].toCSS(this._env)]);var g=d.toCSS(this._env);-1!==c.indexOf(g)?b.splice(e,1):c.push(g)}else f[d.name]=d}},_mergeRules:function(b){if(b){for(var c,d,e,f={},g=0;g1){d=c[0];var h=[],i=[];c.map(function(a){"+"===a.merge&&(i.length>0&&h.push(e(i)),i=[]),i.push(a)}),h.push(e(i)),d.value=g(h)}})}}}}(c("./tree")),function(a){a.extendFinderVisitor=function(){this._visitor=new a.visitor(this),this.contexts=[],this.allExtendsStack=[[]]},a.extendFinderVisitor.prototype={run:function(a){return a=this._visitor.visit(a),a.allExtends=this.allExtendsStack[0],a},visitRule:function(a,b){b.visitDeeper=!1},visitMixinDefinition:function(a,b){b.visitDeeper=!1},visitRuleset:function(b){if(!b.root){var c,d,e,f,g=[],h=b.rules,i=h?h.length:0;for(c=0;i>c;c++)b.rules[c]instanceof a.Extend&&(g.push(h[c]),b.extendOnEveryPath=!0);var j=b.paths;for(c=0;c=0||(i=[k.selfSelectors[0]],g=n.findMatch(j,i),g.length&&j.selfSelectors.forEach(function(b){h=n.extendSelector(g,i,b),l=new a.Extend(k.selector,k.option,0),l.selfSelectors=h,h[h.length-1].extendList=[l],m.push(l),l.ruleset=k.ruleset,l.parent_ids=l.parent_ids.concat(k.parent_ids,j.parent_ids),k.firstExtendOnThisSelectorPath&&(l.firstExtendOnThisSelectorPath=!0,k.ruleset.paths.push(h))}));if(m.length){if(this.extendChainCount++,d>100){var o="{unable to calculate}",p="{unable to calculate}";try{o=m[0].selfSelectors[0].toCSS(),p=m[0].selector.toCSS()}catch(q){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+o+":extend("+p+")"}}return m.concat(n.doExtendChaining(m,c,d+1))}return m},visitRule:function(a,b){b.visitDeeper=!1},visitMixinDefinition:function(a,b){b.visitDeeper=!1},visitSelector:function(a,b){b.visitDeeper=!1},visitRuleset:function(a){if(!a.root){var b,c,d,e,f=this.allExtendsStack[this.allExtendsStack.length-1],g=[],h=this;for(d=0;d0&&k[i.matched].combinator.value!==g?i=null:i.matched++,i&&(i.finished=i.matched===k.length,i.finished&&!a.allowAfter&&(e+1j&&k>0&&(l[l.length-1].elements=l[l.length-1].elements.concat(c[j].elements.slice(k)),k=0,j++),i=f.elements.slice(k,h.index).concat([g]).concat(d.elements.slice(1)),j===h.pathIndex&&e>0?l[l.length-1].elements=l[l.length-1].elements.concat(i):(l=l.concat(c.slice(j,h.pathIndex)),l.push(new a.Selector(i))),j=h.endPathIndex,k=h.endPathElementIndex,k>=c[j].elements.length&&(k=0,j++);
16 | return j0&&(l[l.length-1].elements=l[l.length-1].elements.concat(c[j].elements.slice(k)),j++),l=l.concat(c.slice(j,c.length))},visitRulesetOut:function(){},visitMedia:function(a){var b=a.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);b=b.concat(this.doExtendChaining(b,a.allExtends)),this.allExtendsStack.push(b)},visitMediaOut:function(){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(a){var b=a.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);b=b.concat(this.doExtendChaining(b,a.allExtends)),this.allExtendsStack.push(b)},visitDirectiveOut:function(){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(c("./tree")),function(a){a.sourceMapOutput=function(a){this._css=[],this._rootNode=a.rootNode,this._writeSourceMap=a.writeSourceMap,this._contentsMap=a.contentsMap,this._contentsIgnoredCharsMap=a.contentsIgnoredCharsMap,this._sourceMapFilename=a.sourceMapFilename,this._outputFilename=a.outputFilename,this._sourceMapURL=a.sourceMapURL,a.sourceMapBasepath&&(this._sourceMapBasepath=a.sourceMapBasepath.replace(/\\/g,"/")),this._sourceMapRootpath=a.sourceMapRootpath,this._outputSourceFiles=a.outputSourceFiles,this._sourceMapGeneratorConstructor=a.sourceMapGenerator||c("source-map").SourceMapGenerator,this._sourceMapRootpath&&"/"!==this._sourceMapRootpath.charAt(this._sourceMapRootpath.length-1)&&(this._sourceMapRootpath+="/"),this._lineNumber=0,this._column=0},a.sourceMapOutput.prototype.normalizeFilename=function(a){return a=a.replace(/\\/g,"/"),this._sourceMapBasepath&&0===a.indexOf(this._sourceMapBasepath)&&(a=a.substring(this._sourceMapBasepath.length),("\\"===a.charAt(0)||"/"===a.charAt(0))&&(a=a.substring(1))),(this._sourceMapRootpath||"")+a},a.sourceMapOutput.prototype.add=function(a,b,c,d){if(a){var e,f,g,h,i;if(b){var j=this._contentsMap[b.filename];this._contentsIgnoredCharsMap[b.filename]&&(c-=this._contentsIgnoredCharsMap[b.filename],0>c&&(c=0),j=j.slice(this._contentsIgnoredCharsMap[b.filename])),j=j.substring(0,c),f=j.split("\n"),h=f[f.length-1]}if(e=a.split("\n"),g=e[e.length-1],b)if(d)for(i=0;i0){var d,e=JSON.stringify(this._sourceMapGenerator.toJSON());this._sourceMapURL?d=this._sourceMapURL:this._sourceMapFilename&&(d=this.normalizeFilename(this._sourceMapFilename)),this._writeSourceMap?this._writeSourceMap(e):d="data:application/json,"+encodeURIComponent(e),d&&this._css.push("/*# sourceMappingURL="+d+" */")}return this._css.join("")}}(c("./tree"));var y=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);w.env=w.env||("127.0.0.1"==location.hostname||"0.0.0.0"==location.hostname||"localhost"==location.hostname||location.port&&location.port.length>0||y?"development":"production");var z={debug:3,info:2,errors:1,none:0};if(w.logLevel="undefined"!=typeof w.logLevel?w.logLevel:"development"===w.env?z.debug:z.errors,w.async=w.async||!1,w.fileAsync=w.fileAsync||!1,w.poll=w.poll||(y?1e3:1500),w.functions)for(var A in w.functions)w.functions.hasOwnProperty(A)&&(w.tree.functions[A]=w.functions[A]);var B=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);B&&(w.dumpLineNumbers=B[1]);var C=/^text\/(x-)?less$/,D=null,E={};if(w.watch=function(){return w.watchMode||(w.env="development",v()),this.watchMode=!0,!0},w.unwatch=function(){return clearInterval(w.watchTimer),this.watchMode=!1,!1},/!watch/.test(location.hash)&&w.watch(),"development"!=w.env)try{D="undefined"==typeof a.localStorage?null:a.localStorage}catch(F){}var G=document.getElementsByTagName("link");w.sheets=[];for(var H=0;H"+(!title?""+message+" ":""+title+" "+message+"
")+"",
29 | type: "notice",
30 | position: "bottom-right",
31 | inEffectDuration: 200,
32 | outEffectDuration: 200,
33 | stayTime: 1900
34 | },options);
35 |
36 | $().toastmessage("showToast", settings);
37 | }
38 | };
39 | })
40 |
41 | .factory('JobsFactory', function($resource) {
42 | return $resource(location.pathname + 'api/job', {}, {});
43 | })
44 |
45 | .factory('JobFactory', function($resource) {
46 | return $resource(location.pathname + 'api/job/:id', {}, {
47 | query: {method: 'GET', params: {id: '@id'}},
48 | });
49 | });
--------------------------------------------------------------------------------
/src/less/style.less:
--------------------------------------------------------------------------------
1 | @white: #ffffff;
2 | @blue: #33cccc;
3 | @black: #181818;
4 | @grey: #777777;
5 | @red: #cc1600;
6 | @sand: #DBC6A9;
7 | @darkgrey: #4F514E;
8 | @lightgrey: lighten(@darkgrey, 55%);
9 | @almond: lighten(@lightgrey, 11%);
10 | @smoke: lighten(@lightgrey, 6%);
11 | @celeste: #85D9F1;
12 | @oil: lighten(#347385, 10%);
13 | @brown: #AB4A37;
14 |
15 |
16 | @ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
17 | @ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
18 |
19 | @module: 10px;
20 | @margin: @module*2;
21 |
22 | @sidebar-width: 180px;
23 |
24 | /*
25 |
26 | mixins
27 | ======
28 |
29 | */
30 | .transition(@property:all, @duration:.4s, @easing:ease-in-out){
31 | -webkit-transition: @arguments;
32 | -moz-transition: @arguments;
33 | -ms-transition: @arguments;
34 | -o-transition: @arguments;
35 | transition: @arguments;
36 | }
37 |
38 | .clear{
39 | clear: both;
40 | }
41 |
42 |
43 | body {
44 | color: @black;
45 | background: #f5f5f5;
46 | font-size: 13px;
47 | line-height: 18px;
48 | }
49 |
50 | h1, h2, h3{
51 | font-family: 'Varela Round', sans-serif;
52 | }
53 |
54 | h1{
55 | font-size: 40px;
56 | line-height: 1em;
57 |
58 | }
59 |
60 |
61 | header{
62 | padding-top: 42px;
63 | >.inner{
64 | width: 960px;
65 | margin: 0px auto;
66 | }
67 |
68 | #logo{
69 | text-align: center;
70 | }
71 |
72 |
73 | }
74 |
75 | #main{
76 | >.inner{
77 | width: 500px;
78 | margin: 0px auto;
79 |
80 | }
81 |
82 | h1, h2, h3, h4{
83 | text-align: center;
84 | text-transform: uppercase;
85 | font-weight: none;
86 | }
87 |
88 | h1{
89 | margin: @margin 0 0 0;
90 | color: #df4d54;
91 | text-align: center;
92 | }
93 |
94 | h3{
95 | font-size: 15px;
96 | margin:0;
97 | margin-top: 5px;
98 | margin-bottom: 15px;
99 | }
100 |
101 | h2{
102 | font-size: 30px;
103 | margin:0;
104 | }
105 |
106 | h4{
107 | font-size: 10px;
108 | }
109 |
110 |
111 | }
112 |
113 | label{
114 | font-size: 14px;
115 | font-family: 'Varela Round', sans-serif;
116 | line-height: 30px;
117 | display: block;
118 | text-align:center;
119 | }
120 |
121 | .number{
122 | width: 30px;
123 | height: 30px;
124 | border-radius: 40px;
125 | background-color: #666;
126 | text-align: center;
127 | line-height: 30px;
128 | color: white;
129 | font-size: 14px;
130 | font-family: 'Varela Round', sans-serif;
131 | text-align: center;
132 | margin: 0 auto;
133 | }
134 |
135 | .group{
136 | margin-bottom: 25px;
137 | }
138 |
139 |
140 | #working-area{
141 | >.inner{
142 | width: 500px;
143 | margin: 0px auto;
144 | }
145 |
146 | #textarea-container{
147 | //padding-left: 25px;
148 | //background-color: #e2e2e2;
149 | border: 1px solid #ccc;
150 | }
151 |
152 | textarea, input{
153 | font-family: 'Inconsolata';
154 | line-height: 18px;
155 | font-size: 15px;
156 | box-shadow: none;
157 | border-radius: 0px;
158 | }
159 |
160 | textarea{
161 | border-radius: 0px;
162 | font-family: 'Inconsolata';
163 | line-height:15px;
164 | font-size:12px;
165 | border-radius: 0px;
166 |
167 | border-width: 0px;
168 | border-left: 1px solid #ccc;
169 | }
170 |
171 | #jobs-container{
172 | //padding-left: 25px;
173 | //background-color: #e2e2e2;
174 | border: 1px solid #ccc;
175 | height: 100px;
176 | overflow: auto;
177 | }
178 | }
179 |
180 |
181 |
182 |
183 | .bombo{
184 | height: 5px;
185 | border-radius: 5px;
186 | background-color: #60c2d4;
187 | /* margin: 25px 25px 0 0; */
188 | width: 100%;
189 | line-height: 7px;
190 | margin: 0;
191 | margin-top: 35px;
192 |
193 | &.inferiore{
194 | margin-top: 20px;
195 | }
196 | }
197 |
198 | .job{
199 | position: relative;
200 | background: #f7f7f7;
201 | clear: both;
202 | }
203 |
204 |
205 | .job-status{
206 | float: left;
207 | width:26px;
208 | line-height:14px;
209 | font-size:12px;
210 | margin: 2px;
211 | text-align: center;
212 |
213 | &.REA{
214 | background-color: #c96e1c;
215 |
216 |
217 | color: white;
218 | }
219 | &.ERR{
220 | background-color: #cc1600;
221 | color:white;
222 | }
223 |
224 | &.END{
225 | background-color: #65b665;
226 |
227 |
228 | color: white;
229 | }
230 |
231 | }
232 |
233 | .job-url{
234 | font-family: 'Inconsolata';
235 | line-height:18px;
236 | font-size:13px;
237 | margin-left: 30px;
238 | background: #fff;
239 | word-break:break-all;
240 | padding: 0 4px;
241 | border-left: 1px solid #ddd;
242 | }
243 |
244 |
245 | .CodeMirror {
246 | /* Set height, width, borders, and global font properties here */
247 | font-family:'Inconsolata';
248 | height: 100px;
249 | }
250 |
251 |
252 | /* #Toastmessage JQUERYPlugin css
253 | ================================================== */
254 |
255 | .toast-container{z-index:9999;}
256 | * html .toast-container{position:absolute;}
257 | .toast-item{
258 | height:auto;
259 | background:#181818;
260 | opacity:.9;
261 | border-radius: 2px;
262 | -moz-border-radius:2px;
263 | -webkit-border-radius:2px;
264 | color:white;
265 | padding: 8px 12px;
266 | display:block;
267 | position:relative;
268 | margin:0 0 12px 0;
269 | }
270 | .toast-item h1{
271 | font-size:1.3rem;
272 | font-weight: normal;
273 | text-transform: uppercase;
274 | color: white;
275 | text-align: center;
276 | margin:0;
277 | }
278 | .toast-item p{
279 | text-align:left;margin:0px;
280 | font-size:1.2rem;
281 | }
282 | .toast-item-image{display:none}
283 | .toast-type-notice{color:white;}
284 | .toast-type-success{color:white;}
285 | .toast-type-warning{color:white;border-color:#FCBD57;}
286 | .toast-type-error{color:white;border-color:#B32B2B;}
287 | .toast-position-bottom-right{position:fixed;bottom:36px;right:18px;}
288 | .toast-position-middle-center {
289 | position: fixed;
290 | left: 50%;
291 | margin-left: -140px;
292 | margin-top: -40px;
293 | top: 50%;
294 | }
--------------------------------------------------------------------------------
/templates/zup/index.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {% if DEBUG %}
21 |
22 |
23 | {% else %}
24 |
25 | {% endif %}
26 |
27 |
28 |
29 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
60 |
61 |
62 |
63 |
64 | Zup
65 |
66 |
67 |
68 |
69 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | A simple interface for extracting the full text
79 |
80 |
81 |
82 | from any url *
83 |
84 |
85 |
86 | * almost any: no facebook, no twitter, no ...
87 |
88 |
89 |
90 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/test/urls.tsv:
--------------------------------------------------------------------------------
1 | urls
2 | http://www.corriere.it/cronache/14_luglio_07/estate-ritirata-piogge-temporali-8e993fc8-0607-11e4-9ae2-2d514cff7f8f.shtml
3 | http://www.theguardian.com/news/datablog/2014/jul/07/which-phones-battery-life-stop-boarding-flight
4 | http://www.corrieredellosport.it/calcio/mondiali_2014/2014/07/11-368890/Roma%2C+visite+mediche+per+Emanuelson
--------------------------------------------------------------------------------
/zup.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medialab/zup/c53c0d67d830ea679952053344d0e6e9b53c4b28/zup.gif
--------------------------------------------------------------------------------
/zup/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medialab/zup/c53c0d67d830ea679952053344d0e6e9b53c4b28/zup/__init__.py
--------------------------------------------------------------------------------
/zup/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from zup.models import Url, Job
3 |
4 | class JobAdmin(admin.ModelAdmin):
5 | search_fields = ['name']
6 |
7 |
8 | class UrlAdmin(admin.ModelAdmin):
9 | search_fields = ['url']
10 |
11 |
12 | admin.site.register(Job, JobAdmin)
13 | admin.site.register(Url, UrlAdmin)
--------------------------------------------------------------------------------
/zup/api.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.db import transaction
3 | from glue import Epoxy, API_EXCEPTION_AUTH, API_EXCEPTION_FORMERRORS, API_EXCEPTION_DOESNOTEXIST
4 | from zup.forms import JobForm
5 | from zup.models import Url, Job
6 |
7 | # api
8 | def home(request):
9 | '''
10 | Help or manual should be placed here
11 | '''
12 | result = Epoxy(request)
13 | return result.json()
14 |
15 |
16 | def job(request, pk):
17 | epoxy = Epoxy(request)
18 | try:
19 | epoxy.item(Job.objects.get(pk=pk), deep=True)
20 | except Job.DoesNotExist, e:
21 | return epoxy.throw_error(code=API_EXCEPTION_DOESNOTEXIST, error=e).json()
22 |
23 | return epoxy.json()
24 |
25 |
26 |
27 | def jobs(request):
28 | epoxy = Epoxy(request)
29 |
30 | if epoxy.is_POST():
31 | form = JobForm(epoxy.data)
32 |
33 | if not form.is_valid():
34 | return epoxy.throw_error(error=form.errors).json()
35 |
36 | with transaction.atomic():
37 | job = form.save()
38 | # Cfr forms.py claened data is here a list of (not yet) valid url
39 | urllist = form.cleaned_data['url_list']
40 | # limit on url list
41 | if not request.user.is_staff:
42 | urllist = urllist[:settings.URLS_LIMIT]
43 |
44 | for url in urllist:
45 | u = Url(url=url)
46 | u.save()
47 | job.urls.add(u)
48 |
49 | job.start(cmd='scrape')
50 | epoxy.item(job)
51 |
52 | return epoxy.json()
53 |
54 |
55 |
56 | def job_download(request, pk):
57 | import os
58 | from mimetypes import guess_type
59 | from django.core.servers.basehttp import FileWrapper
60 | from django.http import HttpResponse
61 |
62 | epoxy = Epoxy(request) # useful to handle errors
63 | try:
64 | j = Job.objects.get(pk=pk)
65 | except Job.DoesNotExist, e:
66 | return epoxy.throw_error(code=API_EXCEPTION_DOESNOTEXIST, error=e).json()
67 |
68 | filepath = os.path.join(j.get_path(), 'urls_to_zip.zip')
69 |
70 | if not os.path.exists(filepath):
71 | return epoxy.throw_error(code=API_EXCEPTION_DOESNOTEXIST, error='Job does not seem to have any downloadable file associated').json()
72 |
73 | content_type = guess_type(filepath)
74 | wrapper = FileWrapper(file(filepath))
75 | response = HttpResponse(wrapper, content_type=content_type[0])
76 | response['Content-Length'] = os.path.getsize(filepath)
77 | response['Content-Disposition'] = 'attachment; filename=%s--%s[zup].zip' % (j.slug, j.date_created.strftime('%Y-%m-%d--%H-%M-%S'))
78 | return response
79 |
--------------------------------------------------------------------------------
/zup/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 | from zup.models import Job, Url
3 |
4 |
5 | class JobForm(forms.ModelForm):
6 | url_list = forms.CharField()
7 |
8 | def clean_url_list(self):
9 | urls = filter(None, self.cleaned_data['url_list'].split('\n'))
10 | return urls
11 |
12 | class Meta:
13 | model = Job
14 | fields = ['name', 'url_list']
--------------------------------------------------------------------------------
/zup/local_settings.py.example:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | DEBUG = True
4 | ALLOWED_HOSTS = [] # change this according to the documentation
5 |
6 | BASE_DIR = os.path.dirname(os.path.dirname(__file__))
7 |
8 | TITLE = 'ZUP'
9 | SECRET_KEY = 'your own generated secret key'
10 |
11 | # limit on url number (not applicable for admin staff)
12 | URLS_LIMIT=100
13 |
14 | DB_ENGINE = 'django.db.backends.sqlite3'
15 | DB_NAME = os.path.join(BASE_DIR, 'sqlite/db.sqlite3') # given as example
16 |
17 | LANGUAGE_CODE = 'en-us'
18 |
19 | STATIC_ROOT = os.path.join(BASE_DIR, '../static')
20 | STATIC_URL = '/static/'
21 |
22 | MEDIA_ROOT = os.path.join(BASE_DIR, '../media')
23 | MEDIA_URL = '/media/'
24 |
25 | TMP_ROOT = os.path.join(BASE_DIR, 'tmp')
26 |
27 | PYTHON_INTERPRETER = '/home/daniele/.virtualenvs/zup/bin/python' # mine, given as exemple. Cfr virtualenv doc.
28 |
29 | ENABLE_CDN_SERVICES = False # set to true if you want to use CDN. This const will be used in templates
30 |
31 | CLEANING_AFTER_SECONDS = 30 * 60
--------------------------------------------------------------------------------
/zup/management/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medialab/zup/c53c0d67d830ea679952053344d0e6e9b53c4b28/zup/management/__init__.py
--------------------------------------------------------------------------------
/zup/management/commands/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/medialab/zup/c53c0d67d830ea679952053344d0e6e9b53c4b28/zup/management/commands/__init__.py
--------------------------------------------------------------------------------
/zup/management/commands/clean.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import logging, datetime
4 |
5 | from django.conf import settings
6 | from django.core.management.base import BaseCommand, CommandError
7 | from django.utils import timezone
8 | from zup.models import Job
9 |
10 |
11 | logger = logging.getLogger('zup.clean')
12 |
13 |
14 | # usage type:
15 | #
16 | # python manage.py clean
17 | #
18 | class Command(BaseCommand):
19 |
20 | args = ''
21 | help = 'execute some job on corpus.'
22 | option_list = BaseCommand.option_list
23 |
24 | def handle(self, *args, **options):
25 | logger.info('doing some cleaning')
26 |
27 | now = timezone.now()
28 |
29 | for job in Job.objects.exclude(status=Job.RUNNING):
30 | try:
31 | if (now - job.date_last_modified).total_seconds() > settings.CLEANING_AFTER_SECONDS: # more than two days ago
32 | logger.info('removing job "%s" because of its obsolesence of %s seconds' % (job.name, (now - job.date_last_modified).total_seconds()))
33 | job.delete()
34 | except Exception, e:
35 | logger.info('problem during cleaning ...')
36 | logger.exception(e)
37 |
38 | logger.info('cleaning complete')
--------------------------------------------------------------------------------
/zup/management/commands/start_job.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import os, csv, time, codecs, shutil, urllib2, logging
4 | from optparse import make_option
5 | from datetime import datetime
6 |
7 | from django.core.management.base import BaseCommand, CommandError
8 | from django.utils.text import slugify
9 |
10 | from zipfile import ZipFile
11 | from zup.utils import gooseapi, unicode_dict_reader, unique_mkdir
12 | from zup.models import Job, Url
13 |
14 |
15 | logger = logging.getLogger('zup')
16 |
17 |
18 | class Command(BaseCommand):
19 | '''
20 | usage type:
21 |
22 | python manage.py start_job --job=1 --cmd=test
23 | '''
24 | args = ''
25 | help = 'execute some job on corpus.'
26 | option_list = BaseCommand.option_list + (
27 | make_option('--job',
28 | action='store',
29 | dest='job_pk',
30 | default=False,
31 | help='job primary key'),
32 |
33 | make_option('--cmd',
34 | action='store',
35 | dest='cmd',
36 | default=False,
37 | help='manage.py command to be executed'),
38 | )
39 |
40 |
41 | def _test(self, job):
42 | job.status = Job.RUNNING
43 | job.save()
44 | time.sleep(15)
45 | job.status = Job.COMPLETED
46 | job.save()
47 |
48 |
49 | def _scrape(self, job, fields=['title', 'tags', 'meta_keywords']):
50 | logger.debug('starting command "scrape"')
51 | job.status = Job.RUNNING
52 | job.save()
53 |
54 | job_path = job.get_path()
55 | path = unique_mkdir(os.path.join(job_path, 'files'))
56 |
57 | urls = job.urls.all()
58 | # create zip filename and remove previous one
59 | zip_path = os.path.join(job_path, 'urls_to_zip.zip')
60 | if os.path.exists(zip_path):
61 | os.remove(zip_path)
62 |
63 | # create csv report
64 | rep_path = os.path.join(path, 'report.csv')
65 | reports = []
66 |
67 | logger.debug('zip path: %s' % zip_path)
68 |
69 |
70 | # filename length
71 | max_length = 64
72 |
73 | with ZipFile(zip_path, 'w') as zip_file:
74 | for i,url in enumerate(urls): # sync or not async
75 | index = '%0*d' % (5, int(i) + 1)
76 | url.status= Url.READY
77 | url.save()
78 |
79 | try:
80 | g = gooseapi(url=url.url)
81 | except urllib2.HTTPError, e:
82 | url.status= Url.ERROR
83 | url.log = '%s' % e
84 | url.save()
85 | continue
86 | except urllib2.URLError, e:
87 | url.status= Url.ERROR
88 | url.log = '%s' % e
89 | url.save()
90 | continue
91 | except ValueError, e: # that is, url is not a valid url
92 | url.status= Url.ERROR
93 | url.log = '%s' % e
94 | url.save()
95 | continue
96 | except IOError, e: # probably the stopword file was not found, skip this url
97 | url.status= Url.ERROR
98 | url.log = '%s' % e
99 | url.save()
100 | continue
101 | except Exception, e:
102 | logger.exception(e)
103 | continue
104 |
105 | logger.debug('title: %s', g.title)
106 | logger.debug('url: %s', url.url)
107 | # handling not found title stuff
108 | slug = '%s-%s' % (index,slugify(g.title if g.title else url.url)[:max_length])
109 | slug_base = slug
110 |
111 | textified = os.path.join(path, slug)
112 |
113 | c = 1
114 | while os.path.exists(textified):
115 |
116 | candidate = '%s-%s-%s' % (index, slug_base, c)
117 |
118 | if len(candidate) > max_length:
119 | slug = slug[:max_length-len('-%s' % c)]
120 | slug = re.sub('\-+','-',candidate)
121 | textified = os.path.join(path, slug)
122 | c += 1
123 |
124 | textified = "%s.txt" % textified
125 |
126 | with codecs.open(textified, encoding='utf-8', mode='w') as f:
127 | f.write('\n\n%s\n\n\n\n' % g.title)
128 | f.write(g.cleaned_text)
129 |
130 | # completed url scraping
131 | url.status= Url.COMPLETED
132 | url.save()
133 |
134 | zip_file.write(textified, os.path.basename(textified))
135 |
136 | # WRITE SOME REPORT
137 | result = {
138 | 'id': index,
139 | 'path': os.path.basename(textified),
140 | 'url': url.url
141 | }
142 |
143 | for i in fields:
144 | if i == 'tags':
145 | result[i] = ', '.join(getattr(g, i))
146 | else:
147 | result[i] = getattr(g, i)
148 | result[i]=result[i].encode('utf8')
149 | reports.append(result)
150 |
151 | # JOB FINISHED, WRITING REPORT
152 | with open(rep_path, 'w') as report:
153 | writer = csv.DictWriter(report, ['id', 'path', 'url'] + fields)
154 | writer.writeheader()
155 | for report in reports:
156 | writer.writerow(report)
157 |
158 | zip_file.write(rep_path, os.path.basename(rep_path))
159 |
160 | shutil.rmtree(path)
161 | # close job
162 | job.status = Job.COMPLETED
163 | job.save()
164 |
165 |
166 | def handle(self, *args, **options):
167 | if not options['cmd']:
168 | raise CommandError("\n ouch. You should specify a valid function as cmd param")
169 | if not options['job_pk']:
170 | raise CommandError("\n ouch. please provide a job id to record logs and other stuff")
171 |
172 | # maximum 5 jobs at the same time
173 | try:
174 | job = Job.objects.get(pk=options['job_pk'])
175 | except Job.DoesNotExist, e:
176 | raise CommandError("\n ouch. Try again, job pk=%s does not exist!" % options['job_pk'])
177 |
178 | cmd = '_%s' % options['cmd']
179 |
180 | getattr(self, cmd)(job=job) # no job will be charged!
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/zup/management/commands/urls_to_zip.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import os, csv
4 | from optparse import make_option
5 | from datetime import datetime
6 |
7 | from django.core.management.base import BaseCommand, CommandError
8 | from zup.utils import urls_to_zip, unicode_dict_reader
9 |
10 |
11 | class Command(BaseCommand):
12 | '''
13 | usage type
14 |
15 |
16 | '''
17 | args = ''
18 | help = 'From a list of urls (one per line) get the title and the plaintext content.'
19 | option_list = BaseCommand.option_list + (
20 | make_option('--tsv',
21 | action='store',
22 | dest='tsv',
23 | type='string',
24 | default=None,
25 | help='tsv file for the list. Header "urls" has to be provided'),
26 | )
27 |
28 | def handle(self, *args, **options):
29 | # set default owner if ldap is not
30 | self.stdout.write("\n * .--.\n / / `\n + | |\n ' \\ \\__,\n * + '--' *\n + /\\\n + .' '. *\n * /======\\ +\n ;:. _ ;\n |:. (_) |\n |:. _ |\n + |:. (_) | *\n ;:. ;\n .' \:. / `.\n / .-'':._.'`-. \\\n |/ /||\\ \\|\n jgs _..--\"\"\"````\"\"\"--.._\n _.-'`` ``'-._\n -' '-\n\n")
31 |
32 | if not options['tsv']:
33 | self.stderr.write(" csv file must be specified")
34 | return
35 |
36 | self.stdout.write(" opening file: '%s'" % options['tsv'])
37 |
38 | f = open(options['tsv'], 'rb')
39 | d = unicode_dict_reader(f, delimiter='\t')
40 |
41 |
42 | # check fields
43 | urls = [row['urls'] for i,row in enumerate(d)]
44 |
45 | urls_to_zip(urls=urls)
46 |
47 |
48 | self.stdout.write(" done!")
49 | self.stdout.write('''
50 |
51 | +
52 | + *
53 |
54 | *
55 |
56 |
57 | _..--"""````"""--.._
58 | _.-'`` ``'-._
59 | -' '-
60 |
61 | ''')
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/zup/models.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import re, os, shutil, subprocess
4 |
5 | from django.conf import settings
6 | from django.db import models
7 | from django.db.models.signals import pre_delete, post_save
8 | from django.contrib.auth.models import User
9 | from django.dispatch import receiver
10 | from django.utils.text import slugify
11 |
12 | def helper_uuslug(model, instance, value, max_length=128):
13 | '''
14 | create a unique slug key for a specific value, according to other model instances.
15 | instance should be provided not to change instance's own name.
16 |
17 | '''
18 | slug = slugify(value)[:max_length] # safe autolimiting
19 | slug_base = slug
20 | i = 1;
21 |
22 | while model.objects.exclude(pk=instance.pk).filter(slug=slug).count():
23 | candidate = '%s-%s' % (slug_base, i)
24 | if len(candidate) > max_length:
25 | slug = slug[:max_length-len('-%s' % i)]
26 | slug = re.sub('\-+','-',candidate)
27 | i += 1
28 |
29 | return slug
30 |
31 |
32 |
33 | class Url(models.Model):
34 | STARTED = 'BOO'
35 | READY = 'REA'
36 | ERROR = 'ERR'
37 | COMPLETED = 'END'
38 |
39 | STATUS_CHOICES = (
40 | (STARTED, u'started'),
41 | (READY, u'ready'),
42 | (ERROR, u'error'),
43 | (COMPLETED, u'job completed')
44 | )
45 |
46 | url = models.URLField()
47 | log = models.TextField() # solo errore
48 |
49 | date_created = models.DateTimeField(auto_now_add=True)
50 | date_last_modified = models.DateTimeField(auto_now=True)
51 |
52 | status = models.CharField(max_length=3, choices=STATUS_CHOICES, default=STARTED)
53 |
54 |
55 | def json(self, deep=False):
56 | d = {
57 | 'id': self.id,
58 | 'url': self.url,
59 | 'status': self.status,
60 | 'date_created': self.date_created.isoformat(),
61 | 'date_last_modified': self.date_last_modified.isoformat() if self.date_last_modified else None
62 | }
63 |
64 | if self.date_last_modified is not None:
65 | elapsedTime = self.date_created - self.date_last_modified
66 | d['elapsed'] = elapsedTime.total_seconds()
67 | else:
68 | d['elapsed'] = 0
69 | return d
70 |
71 |
72 |
73 | class Job(models.Model):
74 | STARTED = 'BOO'
75 | RUNNING = 'RUN'
76 | LOST = 'RIP'
77 | COMPLETED = 'END'
78 | TOBEREMOVED = 'RIP'
79 |
80 | STATUS_CHOICES = (
81 | (STARTED, u'started'),
82 | (RUNNING, u'running'),
83 | (LOST, u'process not found'),
84 | (COMPLETED, u'job completed'),
85 | (TOBEREMOVED, u'to be deleted')
86 | )
87 |
88 | name = models.CharField(max_length=64)
89 | slug = models.CharField(max_length=64, unique=True)
90 |
91 | date_created = models.DateTimeField(auto_now_add=True)
92 | date_last_modified = models.DateTimeField(auto_now=True)
93 |
94 | urls = models.ManyToManyField(Url)
95 | command = models.TextField()
96 |
97 | status = models.CharField(max_length=3, choices=STATUS_CHOICES, default=STARTED)
98 |
99 |
100 | def __unicode__(self):
101 | return '%s %s' % (self.name, self.status)
102 |
103 |
104 | def json(self, deep=False):
105 | d = {
106 | 'id': self.id,
107 | 'name': self.name,
108 | 'status': self.status,
109 | 'date_created': self.date_created.isoformat(),
110 | 'date_last_modified': self.date_last_modified.isoformat() if self.date_last_modified else None,
111 | }
112 | if deep:
113 | d.update({
114 | 'urls': [u.json() for u in self.urls.all()]
115 | })
116 | completed = 0.0;
117 | for url in d['urls']:
118 | completed += 1 if url['status'] != Url.STARTED else 0
119 |
120 | d['completion'] = completed / len(d['urls'])
121 |
122 | d['completion_label'] = '%s of %s' % (completed, len(d['urls']))
123 | return d
124 |
125 |
126 | def get_path(self):
127 | index = '%0*d' % (5, int(self.pk) + 1)
128 | path = os.path.join(settings.TMP_ROOT, "job-%s-%s" % (self.pk, self.slug))
129 | if not os.path.exists(path):
130 | os.makedirs(path)
131 | return path
132 |
133 |
134 | def save(self, **kwargs):
135 | if self.pk is None:
136 | self.slug = helper_uuslug(model=Job, instance=self, value=self.name)
137 |
138 | super(Job, self).save()
139 |
140 | # get_path makes use of newborn slug
141 | path = self.get_path()
142 |
143 |
144 | def start(self, cmd=''):
145 | popen_args = [
146 | settings.PYTHON_INTERPRETER,
147 | os.path.join(settings.BASE_DIR,'manage.py'),
148 | 'start_job',
149 | '--cmd','scrape',
150 | '--job', str(self.pk)]
151 | if self.status == Job.STARTED:
152 | subprocess.Popen(popen_args, stdout=None, stderr=None, close_fds=True)
153 |
154 | print popen_args
155 |
156 |
157 | @receiver(pre_delete, sender=Job)
158 | def delete_job(sender, instance, **kwargs):
159 | '''
160 | rename or delete the job path linked to the corpus instance.
161 | We should provide a zip with the whole text content under the name ..zip, @todo
162 | '''
163 | path = instance.get_path()
164 | shutil.rmtree(path)
165 |
166 |
--------------------------------------------------------------------------------
/zup/settings.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | """
4 | Django settings for zup project.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.6/ref/settings/
11 | """
12 |
13 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 | import os
15 | import local_settings
16 | BASE_DIR = os.path.dirname(os.path.dirname(__file__))
17 |
18 |
19 | # Quick-start development settings - unsuitable for production
20 | # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
21 |
22 | # SECURITY WARNING: keep the secret key used in production secret!
23 | SECRET_KEY = local_settings.SECRET_KEY
24 |
25 | # SECURITY WARNING: don't run with debug turned on in production!
26 | DEBUG = local_settings.DEBUG
27 |
28 | TEMPLATE_DEBUG = True
29 |
30 | ALLOWED_HOSTS = []
31 |
32 |
33 | # Application definition
34 |
35 | INSTALLED_APPS = (
36 | 'django.contrib.admin',
37 | 'django.contrib.auth',
38 | 'django.contrib.contenttypes',
39 | 'django.contrib.sessions',
40 | 'django.contrib.messages',
41 | 'django.contrib.staticfiles',
42 |
43 | 'glue',
44 | 'zup'
45 | )
46 |
47 | MIDDLEWARE_CLASSES = (
48 | 'django.contrib.sessions.middleware.SessionMiddleware',
49 | 'django.middleware.common.CommonMiddleware',
50 | 'django.middleware.csrf.CsrfViewMiddleware',
51 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
52 | 'django.contrib.messages.middleware.MessageMiddleware',
53 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
54 | 'django.middleware.locale.LocaleMiddleware',
55 | )
56 |
57 | ROOT_URLCONF = 'zup.urls'
58 |
59 | WSGI_APPLICATION = 'zup.wsgi.application'
60 |
61 |
62 | # Database
63 | # https://docs.djangoproject.com/en/1.6/ref/settings/#databases
64 |
65 | DATABASES = {
66 | 'default': {
67 | 'ENGINE': local_settings.DB_ENGINE,
68 | 'NAME': local_settings.DB_NAME,
69 | }
70 | }
71 |
72 | # Internationalization
73 | # https://docs.djangoproject.com/en/1.6/topics/i18n/
74 |
75 | LANGUAGE_CODE = local_settings.LANGUAGE_CODE
76 |
77 | TIME_ZONE = 'UTC'
78 |
79 | USE_I18N = True
80 |
81 | USE_L10N = True
82 |
83 | USE_TZ = True
84 |
85 |
86 | # Static files (CSS, JavaScript, Images)
87 | # https://docs.djangoproject.com/en/1.6/howto/static-files/
88 |
89 | STATIC_URL = '/static/'
90 |
91 |
92 | TITLE = local_settings.TITLE
93 | STATIC_URL = local_settings.STATIC_URL
94 | STATIC_ROOT = local_settings.STATIC_ROOT
95 | MEDIA_ROOT = local_settings.MEDIA_ROOT
96 | MEDIA_URL = local_settings.MEDIA_URL
97 | TMP_ROOT = local_settings.TMP_ROOT
98 | URLS_LIMIT = local_settings.URLS_LIMIT
99 |
100 | STATICFILES_DIRS = (
101 | os.path.join(BASE_DIR, 'src'),
102 | )
103 |
104 | TEMPLATE_DIRS = (
105 | os.path.join(BASE_DIR, 'templates'),
106 | )
107 |
108 | ENABLE_CDN_SERVICES = local_settings.ENABLE_CDN_SERVICES
109 |
110 | PYTHON_INTERPRETER = local_settings.PYTHON_INTERPRETER
111 |
112 | EN = 'en'
113 | IT = 'it'
114 | FR = 'fr'
115 | NL = 'nl'
116 |
117 | LANGUAGE_CHOICES = (
118 | (EN, u'english'),
119 | (FR, u'french'),
120 | (NL, u'dutch'),
121 | (IT, u'italian'),
122 | )
123 |
124 | LOGGING_ROOT = os.path.join(BASE_DIR, 'logs')
125 |
126 | LOGGING = {
127 | 'version': 1,
128 | 'disable_existing_loggers': False,
129 | 'formatters': {
130 | 'verbose': {
131 | 'format': u'%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d «%(message)s»'
132 | },
133 | 'simple': {
134 | 'format': u'%(asctime)s «%(message)s» %(module)s.%(funcName)s (%(lineno)s)'
135 | },
136 | },
137 | 'handlers': {
138 | 'file': {
139 | 'level': 'DEBUG',
140 | 'class': 'logging.FileHandler',
141 | 'filename': os.path.join(LOGGING_ROOT, 'debug.log'),
142 | 'formatter': 'simple'
143 | },
144 | 'file.clean': {
145 | 'level': 'DEBUG',
146 | 'class': 'logging.FileHandler',
147 | 'filename': os.path.join(LOGGING_ROOT, 'clean.log'),
148 | 'formatter': 'simple'
149 | },
150 | },
151 | 'loggers': {
152 | 'zup': {
153 | 'handlers': ['file'],
154 | 'level': 'DEBUG',
155 | 'propagate': True,
156 | },
157 | 'zup.clean': {
158 | 'handlers': ['file.clean'],
159 | 'level': 'DEBUG',
160 | 'propagate': True,
161 | },
162 | },
163 | }
164 |
165 |
166 | LOG_FILE = LOGGING['handlers']['file']['filename']
167 |
168 | CLEANING_AFTER_SECONDS = local_settings.CLEANING_AFTER_SECONDS
--------------------------------------------------------------------------------
/zup/tests.py:
--------------------------------------------------------------------------------
1 | import os, logging
2 | from django.conf import settings
3 | from django.test import TestCase
4 | from utils import urls_to_zip
5 |
6 |
7 |
8 | logger = logging.getLogger('zup')
9 |
10 |
11 |
12 |
13 | class LoggerTest(TestCase):
14 | def setUp(self):
15 | '''
16 | it will create LOGGING_ROOT
17 | '''
18 | if not os.path.exists(settings.LOGGING_ROOT):
19 | os.mkdir(settings.LOGGING_ROOT)
20 |
21 |
22 | def test_check_permissions(selft):
23 | '''
24 | verify that logger has the right to write to logger folder...
25 | '''
26 | logger.debug('logger test is working as expected')
27 |
28 |
29 |
30 | class UtilsTest(TestCase):
31 | def setUp(self):
32 | '''
33 | it will create TMP_ROOT and MEDIA_ROOT
34 | '''
35 | if not os.path.exists(settings.TMP_ROOT):
36 | os.mkdir(settings.TMP_ROOT)
37 | if not os.path.exists(settings.MEDIA_ROOT):
38 | os.mkdir(settings.MEDIA_ROOT)
39 |
40 | def test_urls_to_zip(self):
41 | zipified = urls_to_zip([
42 | "http://www.nytimes.com/2014/07/07/us/mayor-mike-duggans-pledges-echo-in-detroits-north-end.html?hp&action=click&pgtype=Homepage&version=LargeMediaHeadlineSum&module=photo-spot-region®ion=photo-spot&WT.nav=photo-spot&_r=0",
43 | "http://www.nytimes.com/2014/07/08/world/europe/eduard-shevardnadze-soviet-foreign-minister-under-gorbachev-is-dead-at-86.html?rref=homepage&module=Ribbon&version=origin®ion=Header&action=click&contentCollection=Home%20Page&pgtype=article",
44 | "http://www.corriere.it/cronache/14_luglio_07/estate-ritirata-piogge-temporali-8e993fc8-0607-11e4-9ae2-2d514cff7f8f.shtml",
45 | "http://www.theguardian.com/news/datablog/2014/jul/07/which-phones-battery-life-stop-boarding-flight",
46 | "http://www.corrieredellosport.it/calcio/mondiali_2014/2014/07/11-368890/Roma%2C+visite+mediche+per+Emanuelson",
47 | "http://gasexchange.com/questions/do-labor-epidurals-increase-the-risk-of-instrumental-or-surgical-delivery/",
48 | "http://ghsm.hms.harvard.edu/uploads/pdf/PGSSC_Publications_2012.pdf",
49 | "http://guidance.nice.org.uk/CG/Published",
50 | "http://volunteermovement.org/ehsen-amri-activism-in-tunisia/"
51 | ])
52 | self.assertEqual(os.path.exists(zipified), True)
53 | if os.path.exists(zipified):
54 | os.remove(zipified)
--------------------------------------------------------------------------------
/zup/urls.py:
--------------------------------------------------------------------------------
1 | from django.conf.urls import patterns, include, url
2 | from django.contrib import admin
3 |
4 |
5 |
6 | admin.autodiscover()
7 |
8 |
9 |
10 | apipatterns = patterns('zup.api',
11 | url(r'^$', 'home', name='zup_api_home'),
12 |
13 | url(r'^job$', 'jobs', name='zup_api_jobs'),
14 | url(r'^job/(?P\d+)$', 'job', name='zup_api_job'),
15 | url(r'^job/(?P\d+)/download$', 'job_download', name='zup_api_job_download'),
16 | )
17 |
18 | urlpatterns = patterns('',
19 | url(r'^$', 'zup.views.home', name='home'),
20 | url(r'^api/', include(apipatterns)),
21 |
22 | url(r'^admin/', include(admin.site.urls)),
23 | )
24 |
--------------------------------------------------------------------------------
/zup/utils.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | import os, csv, urllib2, re, codecs, shutil, unicodecsv, logging
4 | from goose import Goose
5 | from zipfile import ZipFile
6 |
7 | from django.conf import settings
8 | from django.utils.text import slugify
9 |
10 |
11 |
12 | logger = logging.getLogger('zup')
13 |
14 |
15 |
16 | def unicode_dict_reader(utf8_data, **kwargs):
17 | '''
18 | Smart csv reader for unicode chars
19 | '''
20 | csv_reader = csv.DictReader(utf8_data, **kwargs)
21 | for row in csv_reader:
22 | yield dict([(key, unicode(value, 'utf-8')) for key, value in row.iteritems()])
23 |
24 |
25 |
26 | def gooseapi(url):
27 | '''
28 | Return a goose instance for the given url. Goose instance brings together title and content from the pointed page body.
29 | '''
30 | logger.debug('fetching url: %s' % url);
31 | goo = Goose({'browser_user_agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36'})
32 |
33 | opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
34 | opener.addheaders = [('User-agent', 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36'), ('Accept', '*/*')]
35 | response = opener.open(url)
36 |
37 | raw_html = response.read()
38 | return goo.extract(raw_html=raw_html)
39 |
40 |
41 |
42 | def unique_mkdir(path):
43 | '''
44 | Return a unique filename for a given path
45 | '''
46 | base_path = path
47 | c = 1
48 | while os.path.exists(path):
49 | candidate = '%s-%s' % (base_path, c)
50 | path = os.path.join(base_path, candidate)
51 | c += 1
52 | os.mkdir(path)
53 | return path
54 |
55 |
56 | def urls_to_zip(urls=[], path=None, max_length=64, fields=['title', 'tags', 'meta_keywords']):
57 | '''
58 | Given a list of urls, try to extract the body content from each url and put it in a txt file.
59 | The files are zipped together and delivered as filepath at the end.
60 | Cfr Goose documentation and gooseapi function as well.
61 | '''
62 | if path is None:
63 | path = "untitled"
64 |
65 | # create unique folder
66 | path = unique_mkdir(os.path.join(settings.TMP_ROOT, os.path.basename(path)))
67 | # create zip filename
68 | zipfied = os.path.join(settings.TMP_ROOT, 'urls_to_zip.zip')
69 | # create csv report filename
70 | report_path = os.path.join(path, 'report.csv')
71 |
72 | c = 1
73 | while os.path.exists(zipfied):
74 | candidate = '%s-%s.zip' % ('urls_to_zip', c)
75 | zipfied = os.path.join(settings.TMP_ROOT, candidate)
76 | c += 1
77 |
78 | reports = []
79 |
80 | with ZipFile(zipfied, 'w') as myzip:
81 | logger.debug('zip file opened to bring %s urls' % len(urls))
82 |
83 | # 1 of 2. fill zip with each page body
84 | for i,url in enumerate(urls):
85 | index = '%0*d' % (5, int(i) + 1)
86 | logger.debug('url %s of %s' % (i+1, len(urls)))
87 | try:
88 | g = gooseapi(url=url)
89 | except urllib2.HTTPError, e:
90 | logger.debug('HTTPError %s for url %s'% (e, url))
91 | except Exception, e:
92 | logger.exception(e)
93 | continue
94 |
95 | slug = '%s-%s' % (index,slugify(g.title)[:max_length])
96 | slug_base = slug
97 |
98 | textified = os.path.join(path, slug)
99 |
100 | c = 1 # unique filename for the text file
101 | while os.path.exists(textified):
102 | candidate = '%s-%s-%s' % (index, slug_base, c)
103 | print "writing on %s" % candidate
104 | if len(candidate) > max_length:
105 | slug = slug[:max_length-len('-%s' % c)]
106 | slug = re.sub('\-+','-',candidate)
107 | textified = os.path.join(path, slug)
108 | c += 1
109 |
110 | textified = "%s.txt" % textified
111 |
112 | # open textified file and write goose body content, with title.
113 | with codecs.open(textified, encoding='utf-8', mode='w') as f:
114 | f.write('\n\n%s\n\n\n\n' % g.title)
115 | f.write(g.cleaned_text)
116 | # the row dict to be written as csv row
117 | result = {
118 | 'id': i,
119 | 'path': os.path.basename(textified),
120 | 'url': url
121 | }
122 | # if there are tags given from goose, they are given as a list. We join it with nice commas.
123 | for field in fields:
124 | if field == 'tags':
125 | result[field] = ', '.join(getattr(g, field))
126 | else:
127 | result[field] = getattr(g, field)
128 | # push our line with the others
129 | reports.append(result)
130 | logger.debug('txt file added to zip file')
131 |
132 | myzip.write(textified, os.path.basename(textified))
133 |
134 | # 2 of 2. write csv data
135 | logger.debug('writing csv report for %s url of %s' % (len(reports), len(urls)))
136 | with open(report_path, 'w') as report:
137 | writer = unicodecsv.DictWriter(report, ['id', 'path', 'url'] + fields)
138 | writer.writeheader()
139 | for report in reports:
140 | writer.writerow(report)
141 |
142 | myzip.write(report_path, os.path.basename(report_path))
143 | logger.debug('csv report added to zipfile %s' % zipfied)
144 |
145 | shutil.rmtree(path)
146 | logger.debug('------------- END OF TASK ------------')
147 | return zipfied
148 |
149 |
150 |
--------------------------------------------------------------------------------
/zup/views.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | from django.conf import settings
4 | from django.shortcuts import render_to_response
5 | from django.utils.translation import ugettext as _
6 | from django.template import RequestContext
7 | from django.contrib.admin.views.decorators import staff_member_required
8 |
9 |
10 | def home(request):
11 | d = _helper_shared_context(request)
12 | return render_to_response("zup/index.html", RequestContext(request, d))
13 |
14 |
15 |
16 | def _helper_shared_context(request, tags=[], d={}):
17 | '''
18 | Return an happy shared contex for your view
19 | '''
20 | d.update({
21 | 'TITLE': settings.TITLE,
22 | 'DEBUG': settings.DEBUG,
23 | 'ENABLE_CDN_SERVICES': settings.ENABLE_CDN_SERVICES,
24 | 'LANGUAGE': request.LANGUAGE_CODE,
25 | 'URLS_LIMIT': settings.URLS_LIMIT,
26 | 'URLS_LIMIT_ENABLE': not request.user.is_staff
27 | })
28 | return d
--------------------------------------------------------------------------------
/zup/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for zup project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zup.settings")
12 |
13 | from django.core.wsgi import get_wsgi_application
14 | application = get_wsgi_application()
15 |
--------------------------------------------------------------------------------