").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/language.js b/main/app/sprinkles/core/assets/SiteAssets/js/language.js
index abe6a65..ca1d41c 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/js/language.js
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/language.js
@@ -1,36 +1,36 @@
-function Translate() {
- //initialization
- this.init = function (lng) {
- this.attribute = 'data-lang';
- this.lng = lng;
- };
- //translate
- this.process = function () {
- var _self = this;
- var xrhFile = new XMLHttpRequest();
- //load content data
- xrhFile.open("GET", "assets/languages/json/Translations.json", true);
- xrhFile.onreadystatechange = function () {
- if (xrhFile.readyState === 4) {
- if (xrhFile.status === 200 || xrhFile.status === 0) {
- var LngObject = JSON.parse(xrhFile.responseText);
- var allDom = document.getElementsByTagName("*");
- for (var i = 0; i < allDom.length; i++) {
- var elem = allDom[i];
- var key = elem.getAttribute(_self.attribute);
-
- if (key != null) {
- //console.log("Language initialized with language pack: " + _self.lng);
- elem.innerHTML = LngObject[_self.lng][key];
- }
- }
- }
- }
- };
- xrhFile.send();
- }
-}
-
-$(document).ready(function () {
- initiateLanguage();
-});
+function Translate() {
+ //initialization
+ this.init = function (lng) {
+ this.attribute = 'data-lang';
+ this.lng = lng;
+ };
+ //translate
+ this.process = function () {
+ var _self = this;
+ var xrhFile = new XMLHttpRequest();
+ //load content data
+ xrhFile.open("GET", "assets/languages/json/Translations.json", true);
+ xrhFile.onreadystatechange = function () {
+ if (xrhFile.readyState === 4) {
+ if (xrhFile.status === 200 || xrhFile.status === 0) {
+ var LngObject = JSON.parse(xrhFile.responseText);
+ var allDom = document.getElementsByTagName("*");
+ for (var i = 0; i < allDom.length; i++) {
+ var elem = allDom[i];
+ var key = elem.getAttribute(_self.attribute);
+
+ if (key != null) {
+ //console.log("Language initialized with language pack: " + _self.lng);
+ elem.innerHTML = LngObject[_self.lng][key];
+ }
+ }
+ }
+ }
+ };
+ xrhFile.send();
+ }
+}
+
+$(document).ready(function () {
+ initiateLanguage();
+});
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js b/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js
index 2778a90..f685524 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/linkify.js
@@ -1,369 +1,369 @@
-!function () {
- "use strict";
- var n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (n) {
- return typeof n
- } : function (n) {
- return n && "function" == typeof Symbol && n.constructor === Symbol && n !== Symbol.prototype ? "symbol" : typeof n
- };
- !function (e) {
- function a(n, e) {
- var a = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, t = Object.create(n.prototype);
- for (var o in a) t[o] = a[o];
- return t.constructor = e, e.prototype = t, e
- }
-
- function t(n) {
- n = n || {}, this.defaultProtocol = n.hasOwnProperty("defaultProtocol") ? n.defaultProtocol : h.defaultProtocol, this.events = n.hasOwnProperty("events") ? n.events : h.events, this.format = n.hasOwnProperty("format") ? n.format : h.format, this.formatHref = n.hasOwnProperty("formatHref") ? n.formatHref : h.formatHref, this.nl2br = n.hasOwnProperty("nl2br") ? n.nl2br : h.nl2br, this.tagName = n.hasOwnProperty("tagName") ? n.tagName : h.tagName, this.target = n.hasOwnProperty("target") ? n.target : h.target, this.validate = n.hasOwnProperty("validate") ? n.validate : h.validate, this.ignoreTags = [], this.attributes = n.attributes || n.linkAttributes || h.attributes, this.className = n.hasOwnProperty("className") ? n.className : n.linkClass || h.className;
- for (var e = n.hasOwnProperty("ignoreTags") ? n.ignoreTags : h.ignoreTags, a = 0; a < e.length; a++) this.ignoreTags.push(e[a].toUpperCase())
- }
-
- function o(n, e) {
- for (var a = 0; a < n.length; a++) if (n[a] === e) return !0;
- return !1
- }
-
- function r(n) {
- return n
- }
-
- function i(n, e) {
- return "url" === e ? "_blank" : null
- }
-
- function s() {
- return function (n) {
- this.j = [], this.T = n || null
- }
- }
-
- function c(n, e, a, t) {
- for (var o = 0, r = n.length, i = e, s = [], c = void 0; o < r && (c = i.next(n[o]));) i = c, o++;
- if (o >= r) return [];
- for (; o < r - 1;) c = new m(t), s.push(c), i.on(n[o], c), i = c, o++;
- return c = new m(a), s.push(c), i.on(n[r - 1], c), s
- }
-
- function l() {
- return function (n) {
- n && (this.v = n)
- }
- }
-
- function u(n) {
- var e = n ? {v: n} : {};
- return a(d, l(), e)
- }
-
- function g(n) {
- return n instanceof x || n instanceof C
- }
-
- var h = {
- defaultProtocol: "http",
- events: null,
- format: r,
- formatHref: r,
- nl2br: !1,
- tagName: "a",
- target: i,
- validate: !0,
- ignoreTags: [],
- attributes: null,
- className: "linkified"
- };
- t.prototype = {
- resolve: function (n) {
- var e = n.toHref(this.defaultProtocol);
- return {
- formatted: this.get("format", n.toString(), n),
- formattedHref: this.get("formatHref", e, n),
- tagName: this.get("tagName", e, n),
- className: this.get("className", e, n),
- target: this.get("target", e, n),
- events: this.getObject("events", e, n),
- attributes: this.getObject("attributes", e, n)
- }
- }, check: function (n) {
- return this.get("validate", n.toString(), n)
- }, get: function (e, a, t) {
- var o = void 0, r = this[e];
- if (!r) return r;
- switch ("undefined" == typeof r ? "undefined" : n(r)) {
- case"function":
- return r(a, t.type);
- case"object":
- return o = r.hasOwnProperty(t.type) ? r[t.type] : h[e], "function" == typeof o ? o(a, t.type) : o
- }
- return r
- }, getObject: function (n, e, a) {
- var t = this[n];
- return "function" == typeof t ? t(e, a.type) : t
- }
- };
- var b = Object.freeze({defaults: h, Options: t, contains: o}), p = s();
- p.prototype = {
- defaultTransition: !1, on: function (n, e) {
- if (n instanceof Array) {
- for (var a = 0; a < n.length; a++) this.j.push([n[a], e]);
- return this
- }
- return this.j.push([n, e]), this
- }, next: function (n) {
- for (var e = 0; e < this.j.length; e++) {
- var a = this.j[e], t = a[0], o = a[1];
- if (this.test(n, t)) return o
- }
- return this.defaultTransition
- }, accepts: function () {
- return !!this.T
- }, test: function (n, e) {
- return n === e
- }, emit: function () {
- return this.T
- }
- };
- var m = a(p, s(), {
- test: function (n, e) {
- return n === e || e instanceof RegExp && e.test(n)
- }
- }), f = a(p, s(), {
- jump: function (n) {
- var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = this.next(new n(""));
- return a === this.defaultTransition ? (a = new this.constructor(e), this.on(n, a)) : e && (a.T = e), a
- }, test: function (n, e) {
- return n instanceof e
- }
- }), d = l();
- d.prototype = {
- toString: function () {
- return this.v + ""
- }
- };
- var x = u(), y = u("@"), v = u(":"), k = u("."), w = u(), j = u(), z = u("\n"), O = u(), q = u("+"), N = u("#"),
- S = u(), T = u("mailto:"), A = u("?"), L = u("/"), P = u("_"), E = u(), C = u(), R = u(), H = u("{"),
- B = u("["), U = u("<"), M = u("("), D = u("}"), I = u("]"), K = u(">"), _ = u(")"), G = u("&"),
- Y = Object.freeze({
- Base: d,
- DOMAIN: x,
- AT: y,
- COLON: v,
- DOT: k,
- PUNCTUATION: w,
- LOCALHOST: j,
- NL: z,
- NUM: O,
- PLUS: q,
- POUND: N,
- QUERY: A,
- PROTOCOL: S,
- MAILTO: T,
- SLASH: L,
- UNDERSCORE: P,
- SYM: E,
- TLD: C,
- WS: R,
- OPENBRACE: H,
- OPENBRACKET: B,
- OPENANGLEBRACKET: U,
- OPENPAREN: M,
- CLOSEBRACE: D,
- CLOSEBRACKET: I,
- CLOSEANGLEBRACKET: K,
- CLOSEPAREN: _,
- AMPERSAND: G
- }),
- Q = "aaa|aarp|abarth|abb|abbott|abbvie|abc|able|abogado|abudhabi|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|aetna|af|afamilycompany|afl|africa|ag|agakhan|agency|ai|aig|aigo|airbus|airforce|airtel|akdn|al|alfaromeo|alibaba|alipay|allfinanz|allstate|ally|alsace|alstom|am|americanexpress|americanfamily|amex|amfam|amica|amsterdam|analytics|android|anquan|anz|ao|aol|apartments|app|apple|aq|aquarelle|ar|arab|aramco|archi|army|arpa|art|arte|as|asda|asia|associates|at|athleta|attorney|au|auction|audi|audible|audio|auspost|author|auto|autos|avianca|aw|aws|ax|axa|az|azure|ba|baby|baidu|banamex|bananarepublic|band|bank|bar|barcelona|barclaycard|barclays|barefoot|bargains|baseball|basketball|bauhaus|bayern|bb|bbc|bbt|bbva|bcg|bcn|bd|be|beats|beauty|beer|bentley|berlin|best|bestbuy|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|blanco|blockbuster|blog|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bofa|bom|bond|boo|book|booking|boots|bosch|bostik|boston|bot|boutique|box|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|calvinklein|cam|camera|camp|cancerresearch|canon|capetown|capital|capitalone|car|caravan|cards|care|career|careers|cars|cartier|casa|case|caseih|cash|casino|cat|catering|catholic|cba|cbn|cbre|cbs|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chintai|chloe|christmas|chrome|chrysler|church|ci|cipriani|circle|cisco|citadel|citi|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|comcast|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cookingchannel|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruise|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|data|date|dating|datsun|day|dclk|dds|de|deal|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|dhl|diamonds|diet|digital|direct|directory|discount|discover|dish|diy|dj|dk|dm|dnp|do|docs|doctor|dodge|dog|doha|domains|dot|download|drive|dtv|dubai|duck|dunlop|duns|dupont|durban|dvag|dvr|dz|earth|eat|ec|eco|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epost|epson|equipment|er|ericsson|erni|es|esq|estate|esurance|et|etisalat|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|extraspace|fage|fail|fairwinds|faith|family|fan|fans|farm|farmers|fashion|fast|fedex|feedback|ferrari|ferrero|fi|fiat|fidelity|fido|film|final|finance|financial|fire|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|flir|florist|flowers|fly|fm|fo|foo|food|foodnetwork|football|ford|forex|forsale|forum|foundation|fox|fr|free|fresenius|frl|frogans|frontdoor|frontier|ftr|fujitsu|fujixerox|fun|fund|furniture|futbol|fyi|ga|gal|gallery|gallo|gallup|game|games|gap|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|george|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glade|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|godaddy|gold|goldpoint|golf|goo|goodhands|goodyear|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|grocery|group|gs|gt|gu|guardian|gucci|guge|guide|guitars|guru|gw|gy|hair|hamburg|hangout|haus|hbo|hdfc|hdfcbank|health|healthcare|help|helsinki|here|hermes|hgtv|hiphop|hisamitsu|hitachi|hiv|hk|hkt|hm|hn|hockey|holdings|holiday|homedepot|homegoods|homes|homesense|honda|honeywell|horse|hospital|host|hosting|hot|hoteles|hotels|hotmail|house|how|hr|hsbc|ht|htc|hu|hughes|hyatt|hyundai|ibm|icbc|ice|icu|id|ie|ieee|ifm|ikano|il|im|imamat|imdb|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|intel|international|intuit|investments|io|ipiranga|iq|ir|irish|is|iselect|ismaili|ist|istanbul|it|itau|itv|iveco|iwc|jaguar|java|jcb|jcp|je|jeep|jetzt|jewelry|jio|jlc|jll|jm|jmp|jnj|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|juniper|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kindle|kitchen|kiwi|km|kn|koeln|komatsu|kosher|kp|kpmg|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|ladbrokes|lamborghini|lamer|lancaster|lancia|lancome|land|landrover|lanxess|lasalle|lat|latino|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|lefrak|legal|lego|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|lilly|limited|limo|lincoln|linde|link|lipsy|live|living|lixil|lk|loan|loans|locker|locus|loft|lol|london|lotte|lotto|love|lpl|lplfinancial|lr|ls|lt|ltd|ltda|lu|lundbeck|lupin|luxe|luxury|lv|ly|ma|macys|madrid|maif|maison|makeup|man|management|mango|map|market|marketing|markets|marriott|marshalls|maserati|mattel|mba|mc|mckinsey|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|merckmsd|metlife|mg|mh|miami|microsoft|mil|mini|mint|mit|mitsubishi|mk|ml|mlb|mls|mm|mma|mn|mo|mobi|mobile|mobily|moda|moe|moi|mom|monash|money|monster|mopar|mormon|mortgage|moscow|moto|motorcycles|mov|movie|movistar|mp|mq|mr|ms|msd|mt|mtn|mtr|mu|museum|mutual|mv|mw|mx|my|mz|na|nab|nadex|nagoya|name|nationwide|natura|navy|nba|nc|ne|nec|net|netbank|netflix|network|neustar|new|newholland|news|next|nextdirect|nexus|nf|nfl|ng|ngo|nhk|ni|nico|nike|nikon|ninja|nissan|nissay|nl|no|nokia|northwesternmutual|norton|now|nowruz|nowtv|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|observer|off|office|okinawa|olayan|olayangroup|oldnavy|ollo|om|omega|one|ong|onl|online|onyourside|ooo|open|oracle|orange|org|organic|origins|osaka|otsuka|ott|ovh|pa|page|panasonic|panerai|paris|pars|partners|parts|party|passagens|pay|pccw|pe|pet|pf|pfizer|pg|ph|pharmacy|phd|philips|phone|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pioneer|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pnc|pohl|poker|politie|porn|post|pr|pramerica|praxi|press|prime|pro|prod|productions|prof|progressive|promo|properties|property|protection|pru|prudential|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|qvc|racing|radio|raid|re|read|realestate|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|reliance|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|richardli|ricoh|rightathome|ril|rio|rip|rmit|ro|rocher|rocks|rodeo|rogers|room|rs|rsvp|ru|rugby|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsclub|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|save|saxo|sb|sbi|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scjohnson|scor|scot|sd|se|search|seat|secure|security|seek|select|sener|services|ses|seven|sew|sex|sexy|sfr|sg|sh|shangrila|sharp|shaw|shell|shia|shiksha|shoes|shop|shopping|shouji|show|showtime|shriram|si|silk|sina|singles|site|sj|sk|ski|skin|sky|skype|sl|sling|sm|smart|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|srt|st|stada|staples|star|starhub|statebank|statefarm|statoil|stc|stcgroup|stockholm|storage|store|stream|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiftcover|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|talk|taobao|target|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|tdk|team|tech|technology|tel|telecity|telefonica|temasek|tennis|teva|tf|tg|th|thd|theater|theatre|tiaa|tickets|tienda|tiffany|tips|tires|tirol|tj|tjmaxx|tjx|tk|tkmaxx|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tr|trade|trading|training|travel|travelchannel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubank|ubs|uconnect|ug|uk|unicom|university|uno|uol|ups|us|uy|uz|va|vacations|vana|vanguard|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|vig|viking|villas|vin|vip|virgin|visa|vision|vista|vistaprint|viva|vivo|vlaanderen|vn|vodka|volkswagen|volvo|vote|voting|voto|voyage|vu|vuelos|wales|walmart|walter|wang|wanggou|warman|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weibo|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|winners|wme|wolterskluwer|woodside|work|works|world|wow|ws|wtc|wtf|xbox|xerox|xfinity|xihuan|xin|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--3hcrj9c|xn--3oq18vl8pn36a|xn--3pxu8k|xn--42c2d9a|xn--45br5cyl|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--54b7fta0cc|xn--55qw42g|xn--55qx5d|xn--5su34j936bgsg|xn--5tzm5g|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80aqecdr1a|xn--80asehdb|xn--80aswg|xn--8y0a063a|xn--90a3ac|xn--90ae|xn--90ais|xn--9dbq2a|xn--9et52u|xn--9krt00a|xn--b4w605ferd|xn--bck1b9a5dre4c|xn--c1avg|xn--c2br7g|xn--cck2b3b|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--e1a4c|xn--eckvdtc9d|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fhbei|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--fzys8d69uvgm|xn--g2xx48c|xn--gckr3f0f|xn--gecrj9c|xn--gk3at1e|xn--h2breg3eve|xn--h2brj9c|xn--h2brj9c8c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1aef|xn--j1amh|xn--j6w193g|xn--jlq61u9w7b|xn--jvr189m|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a3ejt|xn--mgba3a4f16a|xn--mgba7c0bbn0a|xn--mgbaakc7dvf|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbai9azgqp6j|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgbca7dzdo|xn--mgberp4a5d4ar|xn--mgbgu82a|xn--mgbi4ecexp|xn--mgbpl2fh|xn--mgbt3dhd|xn--mgbtx2b|xn--mgbx4cd0ab|xn--mix891f|xn--mk1bu44c|xn--mxtq1m|xn--ngbc5azd|xn--ngbe9e0a|xn--ngbrx|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pbt977c|xn--pgbs0dh|xn--pssy2u|xn--q9jyb4c|xn--qcka1pmc|xn--qxam|xn--rhqv96g|xn--rovu88b|xn--rvc1e0am3e|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--tckwe|xn--tiq49xqyj|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--w4r85el8fhu5dnra|xn--w4rs40l|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|you|youtube|yt|yun|za|zappos|zara|zero|zip|zippo|zm|zone|zuerich|zw".split("|"),
- W = "0123456789".split(""), X = "0123456789abcdefghijklmnopqrstuvwxyz".split(""),
- Z = [" ", "\f", "\r", "\t", "\x0B", " ", " ", ""], F = [], J = function (n) {
- return new m(n)
- }, V = J(), $ = J(O), nn = J(x), en = J(), an = J(R);
- V.on("@", J(y)).on(".", J(k)).on("+", J(q)).on("#", J(N)).on("?", J(A)).on("/", J(L)).on("_", J(P)).on(":", J(v)).on("{", J(H)).on("[", J(B)).on("<", J(U)).on("(", J(M)).on("}", J(D)).on("]", J(I)).on(">", J(K)).on(")", J(_)).on("&", J(G)).on([",", ";", "!", '"', "'"], J(w)), V.on("\n", J(z)).on(Z, an), an.on(Z, an);
- for (var tn = 0; tn < Q.length; tn++) {
- var on = c(Q[tn], V, C, x);
- F.push.apply(F, on)
- }
- var rn = c("file", V, x, x), sn = c("ftp", V, x, x), cn = c("http", V, x, x), ln = c("mailto", V, x, x);
- F.push.apply(F, rn), F.push.apply(F, sn), F.push.apply(F, cn), F.push.apply(F, ln);
- var un = rn.pop(), gn = sn.pop(), hn = cn.pop(), bn = ln.pop(), pn = J(x), mn = J(S), fn = J(T);
- gn.on("s", pn).on(":", mn), hn.on("s", pn).on(":", mn), F.push(pn), un.on(":", mn), pn.on(":", mn), bn.on(":", fn);
- var dn = c("localhost", V, j, x);
- F.push.apply(F, dn), V.on(W, $), $.on("-", en).on(W, $).on(X, nn), nn.on("-", en).on(X, nn);
- for (var xn = 0; xn < F.length; xn++) F[xn].on("-", en).on(X, nn);
- en.on("-", en).on(W, nn).on(X, nn), V.defaultTransition = J(E);
- var yn = function (n) {
- for (var e = n.replace(/[A-Z]/g, function (n) {
- return n.toLowerCase()
- }), a = n.length, t = [], o = 0; o < a;) {
- for (var r = V, i = null, s = 0, c = null, l = -1; o < a && (i = r.next(e[o]));) r = i, r.accepts() ? (l = 0, c = r) : l >= 0 && l++, s++, o++;
- if (!(l < 0)) {
- o -= l, s -= l;
- var u = c.emit();
- t.push(new u(n.substr(o - s, s)))
- }
- }
- return t
- }, vn = V, kn = Object.freeze({State: m, TOKENS: Y, run: yn, start: vn}), wn = l();
- wn.prototype = {
- type: "token", isLink: !1, toString: function () {
- for (var n = [], e = 0; e < this.v.length; e++) n.push(this.v[e].toString());
- return n.join("")
- }, toHref: function () {
- return this.toString()
- }, toObject: function () {
- var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http";
- return {type: this.type, value: this.toString(), href: this.toHref(n)}
- }
- };
- var jn = a(wn, l(), {type: "email", isLink: !0}), zn = a(wn, l(), {
- type: "email", isLink: !0, toHref: function () {
- return "mailto:" + this.toString()
- }
- }), On = a(wn, l(), {type: "text"}), qn = a(wn, l(), {type: "nl"}), Nn = a(wn, l(), {
- type: "url", isLink: !0, toHref: function () {
- for (var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http", e = !1, a = !1, t = this.v, o = [], r = 0; t[r] instanceof S;) e = !0, o.push(t[r].toString().toLowerCase()), r++;
- for (; t[r] instanceof L;) a = !0, o.push(t[r].toString()), r++;
- for (; g(t[r]);) o.push(t[r].toString().toLowerCase()), r++;
- for (; r < t.length; r++) o.push(t[r].toString());
- return o = o.join(""), e || a || (o = n + "://" + o), o
- }, hasProtocol: function () {
- return this.v[0] instanceof S
- }
- }), Sn = Object.freeze({Base: wn, MAILTOEMAIL: jn, EMAIL: zn, NL: qn, TEXT: On, URL: Nn}), Tn = function (n) {
- return new f(n)
- }, An = Tn(), Ln = Tn(), Pn = Tn(), En = Tn(), Cn = Tn(), Rn = Tn(), Hn = Tn(), Bn = Tn(Nn), Un = Tn(),
- Mn = Tn(Nn), Dn = Tn(Nn), In = Tn(), Kn = Tn(), _n = Tn(), Gn = Tn(), Yn = Tn(), Qn = Tn(Nn), Wn = Tn(Nn),
- Xn = Tn(Nn), Zn = Tn(Nn), Fn = Tn(), Jn = Tn(), Vn = Tn(), $n = Tn(), ne = Tn(), ee = Tn(), ae = Tn(zn),
- te = Tn(), oe = Tn(zn), re = Tn(jn), ie = Tn(), se = Tn(), ce = Tn(), le = Tn(), ue = Tn(qn);
- An.on(z, ue).on(S, Ln).on(T, Pn).on(L, En), Ln.on(L, En), En.on(L, Cn), An.on(C, Rn).on(x, Rn).on(j, Bn).on(O, Rn), Cn.on(C, Dn).on(x, Dn).on(O, Dn).on(j, Dn), Rn.on(k, Hn), ne.on(k, ee), Hn.on(C, Bn).on(x, Rn).on(O, Rn).on(j, Rn), ee.on(C, ae).on(x, ne).on(O, ne).on(j, ne), Bn.on(k, Hn), ae.on(k, ee), Bn.on(v, Un).on(L, Dn), Un.on(O, Mn), Mn.on(L, Dn), ae.on(v, te), te.on(O, oe);
- var ge = [x, y, j, O, q, N, S, L, C, P, E, G], he = [v, k, A, w, D, I, K, _, H, B, U, M];
- Dn.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), In.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), Kn.on(D, Dn), _n.on(I, Dn), Gn.on(K, Dn), Yn.on(_, Dn), Qn.on(D, Dn), Wn.on(I, Dn), Xn.on(K, Dn), Zn.on(_, Dn), Fn.on(D, Dn), Jn.on(I, Dn), Vn.on(K, Dn), $n.on(_, Dn), Kn.on(ge, Qn), _n.on(ge, Wn), Gn.on(ge, Xn), Yn.on(ge, Zn), Kn.on(he, Fn), _n.on(he, Jn), Gn.on(he, Vn), Yn.on(he, $n), Qn.on(ge, Qn), Wn.on(ge, Wn), Xn.on(ge, Xn), Zn.on(ge, Zn), Qn.on(he, Qn), Wn.on(he, Wn), Xn.on(he, Xn), Zn.on(he, Zn), Fn.on(ge, Qn), Jn.on(ge, Wn), Vn.on(ge, Xn), $n.on(ge, Zn), Fn.on(he, Fn), Jn.on(he, Jn), Vn.on(he, Vn), $n.on(he, $n), Dn.on(ge, Dn), In.on(ge, Dn), Dn.on(he, In), In.on(he, In), Pn.on(C, re).on(x, re).on(O, re).on(j, re), re.on(ge, re).on(he, ie), ie.on(ge, re).on(he, ie);
- var be = [x, O, q, N, A, P, E, G, C];
- Rn.on(be, se).on(y, ce), Bn.on(be, se).on(y, ce), Hn.on(be, se), se.on(be, se).on(y, ce).on(k, le), le.on(be, se), ce.on(C, ne).on(x, ne).on(j, ae);
- var pe = function (n) {
- for (var e = n.length, a = 0, t = [], o = []; a < e;) {
- for (var r = An, i = null, s = null, c = 0, l = null, u = -1; a < e && !(i = r.next(n[a]));) o.push(n[a++]);
- for (; a < e && (s = i || r.next(n[a]));) i = null, r = s, r.accepts() ? (u = 0, l = r) : u >= 0 && u++, a++, c++;
- if (u < 0) for (var g = a - c; g < a; g++) o.push(n[g]); else {
- o.length > 0 && (t.push(new On(o)), o = []), a -= u, c -= u;
- var h = l.emit();
- t.push(new h(n.slice(a - c, a)))
- }
- }
- return o.length > 0 && t.push(new On(o)), t
- }, me = Object.freeze({State: f, TOKENS: Sn, run: pe, start: An});
- Array.isArray || (Array.isArray = function (n) {
- return "[object Array]" === Object.prototype.toString.call(n)
- });
- var fe = function (n) {
- return pe(yn(n))
- }, de = function (n) {
- for (var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n), t = [], o = 0; o < a.length; o++) {
- var r = a[o];
- !r.isLink || e && r.type !== e || t.push(r.toObject())
- }
- return t
- }, xe = function (n) {
- var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n);
- return 1 === a.length && a[0].isLink && (!e || a[0].type === e)
- };
- e.find = de, e.inherits = a, e.options = b, e.parser = me, e.scanner = kn, e.test = xe, e.tokenize = fe
- }(self.linkify = self.linkify || {})
-}();
-
-"use strict";
-!function (e, n, t) {
- var i = function (n) {
- function t(e, n, t) {
- var i = t[t.length - 1];
- e.replaceChild(i, n);
- for (var a = t.length - 2; a >= 0; a--) e.insertBefore(t[a], i), i = t[a]
- }
-
- function i(e, n, t) {
- for (var i = [], a = e, r = Array.isArray(a), o = 0, a = r ? a : a[Symbol.iterator](); ;) {
- var l;
- if (r) {
- if (o >= a.length) break;
- l = a[o++]
- } else {
- if (o = a.next(), o.done) break;
- l = o.value
- }
- var f = l;
- if ("nl" === f.type && n.nl2br) i.push(t.createElement("br")); else if (f.isLink && n.check(f)) {
- var s = n.resolve(f), c = s.formatted, u = s.formattedHref, y = s.tagName, d = s.className,
- m = s.target, k = s.events, h = s.attributes, v = t.createElement(y);
- if (v.setAttribute("href", u), d && v.setAttribute("class", d), m && v.setAttribute("target", m), h) for (var g in h) v.setAttribute(g, h[g]);
- if (k) for (var b in k) v.addEventListener ? v.addEventListener(b, k[b]) : v.attachEvent && v.attachEvent("on" + b, k[b]);
- v.appendChild(t.createTextNode(c)), i.push(v)
- } else i.push(t.createTextNode(f.toString()))
- }
- return i
- }
-
- function a(e, n, r) {
- if (!e || e.nodeType !== u) throw new Error("Cannot linkify " + e + " - Invalid DOM Node type");
- var o = n.ignoreTags;
- if ("A" === e.tagName || f.contains(o, e.tagName)) return e;
- for (var s = e.firstChild; s;) {
- var d = void 0, m = void 0, k = void 0;
- switch (s.nodeType) {
- case u:
- a(s, n, r);
- break;
- case y:
- if (d = s.nodeValue, m = l(d), 0 === m.length || 1 === m.length && m[0] instanceof c) break;
- k = i(m, n, r), t(e, s, k), s = k[k.length - 1]
- }
- s = s.nextSibling
- }
- return e
- }
-
- function r(n, t) {
- var i = arguments.length > 2 && void 0 !== arguments[2] && arguments[2];
- try {
- i = i || document || e && e.document || global && global.document
- } catch (r) {
- }
- if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");
- return t = new s(t), a(n, t, i)
- }
-
- function o(n) {
- function t(e) {
- return e = r.normalize(e), this.each(function () {
- r.helper(this, e, i)
- })
- }
-
- var i = arguments.length > 1 && void 0 !== arguments[1] && arguments[1];
- n.fn = n.fn || {};
- try {
- i = i || document || e && e.document || global && global.document
- } catch (a) {
- }
- if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");
- "function" != typeof n.fn.linkify && (n.fn.linkify = t, n(i).ready(function () {
- n("[data-linkify]").each(function () {
- var e = n(this), t = e.data(), i = t.linkify, a = t.linkifyNlbr,
- o = {nl2br: !!a && 0 !== a && "false" !== a};
- "linkifyAttributes" in t && (o.attributes = t.linkifyAttributes), "linkifyDefaultProtocol" in t && (o.defaultProtocol = t.linkifyDefaultProtocol), "linkifyEvents" in t && (o.events = t.linkifyEvents), "linkifyFormat" in t && (o.format = t.linkifyFormat), "linkifyFormatHref" in t && (o.formatHref = t.linkifyFormatHref), "linkifyTagname" in t && (o.tagName = t.linkifyTagname), "linkifyTarget" in t && (o.target = t.linkifyTarget), "linkifyValidate" in t && (o.validate = t.linkifyValidate), "linkifyIgnoreTags" in t && (o.ignoreTags = t.linkifyIgnoreTags), "linkifyClassName" in t ? o.className = t.linkifyClassName : "linkifyLinkclass" in t && (o.className = t.linkifyLinkclass), o = r.normalize(o);
- var l = "this" === i ? e : e.find(i);
- l.linkify(o)
- })
- }))
- }
-
- var l = n.tokenize, f = n.options, s = f.Options, c = n.parser.TOKENS.TEXT, u = 1, y = 3;
- r.helper = a, r.normalize = function (e) {
- return new s(e)
- };
- try {
- !(void 0).define && (e.linkifyElement = r)
- } catch (d) {
- }
- return o
- }(n);
- "function" != typeof t.fn.linkify && i(t)
+!function () {
+ "use strict";
+ var n = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (n) {
+ return typeof n
+ } : function (n) {
+ return n && "function" == typeof Symbol && n.constructor === Symbol && n !== Symbol.prototype ? "symbol" : typeof n
+ };
+ !function (e) {
+ function a(n, e) {
+ var a = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {}, t = Object.create(n.prototype);
+ for (var o in a) t[o] = a[o];
+ return t.constructor = e, e.prototype = t, e
+ }
+
+ function t(n) {
+ n = n || {}, this.defaultProtocol = n.hasOwnProperty("defaultProtocol") ? n.defaultProtocol : h.defaultProtocol, this.events = n.hasOwnProperty("events") ? n.events : h.events, this.format = n.hasOwnProperty("format") ? n.format : h.format, this.formatHref = n.hasOwnProperty("formatHref") ? n.formatHref : h.formatHref, this.nl2br = n.hasOwnProperty("nl2br") ? n.nl2br : h.nl2br, this.tagName = n.hasOwnProperty("tagName") ? n.tagName : h.tagName, this.target = n.hasOwnProperty("target") ? n.target : h.target, this.validate = n.hasOwnProperty("validate") ? n.validate : h.validate, this.ignoreTags = [], this.attributes = n.attributes || n.linkAttributes || h.attributes, this.className = n.hasOwnProperty("className") ? n.className : n.linkClass || h.className;
+ for (var e = n.hasOwnProperty("ignoreTags") ? n.ignoreTags : h.ignoreTags, a = 0; a < e.length; a++) this.ignoreTags.push(e[a].toUpperCase())
+ }
+
+ function o(n, e) {
+ for (var a = 0; a < n.length; a++) if (n[a] === e) return !0;
+ return !1
+ }
+
+ function r(n) {
+ return n
+ }
+
+ function i(n, e) {
+ return "url" === e ? "_blank" : null
+ }
+
+ function s() {
+ return function (n) {
+ this.j = [], this.T = n || null
+ }
+ }
+
+ function c(n, e, a, t) {
+ for (var o = 0, r = n.length, i = e, s = [], c = void 0; o < r && (c = i.next(n[o]));) i = c, o++;
+ if (o >= r) return [];
+ for (; o < r - 1;) c = new m(t), s.push(c), i.on(n[o], c), i = c, o++;
+ return c = new m(a), s.push(c), i.on(n[r - 1], c), s
+ }
+
+ function l() {
+ return function (n) {
+ n && (this.v = n)
+ }
+ }
+
+ function u(n) {
+ var e = n ? {v: n} : {};
+ return a(d, l(), e)
+ }
+
+ function g(n) {
+ return n instanceof x || n instanceof C
+ }
+
+ var h = {
+ defaultProtocol: "http",
+ events: null,
+ format: r,
+ formatHref: r,
+ nl2br: !1,
+ tagName: "a",
+ target: i,
+ validate: !0,
+ ignoreTags: [],
+ attributes: null,
+ className: "linkified"
+ };
+ t.prototype = {
+ resolve: function (n) {
+ var e = n.toHref(this.defaultProtocol);
+ return {
+ formatted: this.get("format", n.toString(), n),
+ formattedHref: this.get("formatHref", e, n),
+ tagName: this.get("tagName", e, n),
+ className: this.get("className", e, n),
+ target: this.get("target", e, n),
+ events: this.getObject("events", e, n),
+ attributes: this.getObject("attributes", e, n)
+ }
+ }, check: function (n) {
+ return this.get("validate", n.toString(), n)
+ }, get: function (e, a, t) {
+ var o = void 0, r = this[e];
+ if (!r) return r;
+ switch ("undefined" == typeof r ? "undefined" : n(r)) {
+ case"function":
+ return r(a, t.type);
+ case"object":
+ return o = r.hasOwnProperty(t.type) ? r[t.type] : h[e], "function" == typeof o ? o(a, t.type) : o
+ }
+ return r
+ }, getObject: function (n, e, a) {
+ var t = this[n];
+ return "function" == typeof t ? t(e, a.type) : t
+ }
+ };
+ var b = Object.freeze({defaults: h, Options: t, contains: o}), p = s();
+ p.prototype = {
+ defaultTransition: !1, on: function (n, e) {
+ if (n instanceof Array) {
+ for (var a = 0; a < n.length; a++) this.j.push([n[a], e]);
+ return this
+ }
+ return this.j.push([n, e]), this
+ }, next: function (n) {
+ for (var e = 0; e < this.j.length; e++) {
+ var a = this.j[e], t = a[0], o = a[1];
+ if (this.test(n, t)) return o
+ }
+ return this.defaultTransition
+ }, accepts: function () {
+ return !!this.T
+ }, test: function (n, e) {
+ return n === e
+ }, emit: function () {
+ return this.T
+ }
+ };
+ var m = a(p, s(), {
+ test: function (n, e) {
+ return n === e || e instanceof RegExp && e.test(n)
+ }
+ }), f = a(p, s(), {
+ jump: function (n) {
+ var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = this.next(new n(""));
+ return a === this.defaultTransition ? (a = new this.constructor(e), this.on(n, a)) : e && (a.T = e), a
+ }, test: function (n, e) {
+ return n instanceof e
+ }
+ }), d = l();
+ d.prototype = {
+ toString: function () {
+ return this.v + ""
+ }
+ };
+ var x = u(), y = u("@"), v = u(":"), k = u("."), w = u(), j = u(), z = u("\n"), O = u(), q = u("+"), N = u("#"),
+ S = u(), T = u("mailto:"), A = u("?"), L = u("/"), P = u("_"), E = u(), C = u(), R = u(), H = u("{"),
+ B = u("["), U = u("<"), M = u("("), D = u("}"), I = u("]"), K = u(">"), _ = u(")"), G = u("&"),
+ Y = Object.freeze({
+ Base: d,
+ DOMAIN: x,
+ AT: y,
+ COLON: v,
+ DOT: k,
+ PUNCTUATION: w,
+ LOCALHOST: j,
+ NL: z,
+ NUM: O,
+ PLUS: q,
+ POUND: N,
+ QUERY: A,
+ PROTOCOL: S,
+ MAILTO: T,
+ SLASH: L,
+ UNDERSCORE: P,
+ SYM: E,
+ TLD: C,
+ WS: R,
+ OPENBRACE: H,
+ OPENBRACKET: B,
+ OPENANGLEBRACKET: U,
+ OPENPAREN: M,
+ CLOSEBRACE: D,
+ CLOSEBRACKET: I,
+ CLOSEANGLEBRACKET: K,
+ CLOSEPAREN: _,
+ AMPERSAND: G
+ }),
+ Q = "aaa|aarp|abarth|abb|abbott|abbvie|abc|able|abogado|abudhabi|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|aetna|af|afamilycompany|afl|africa|ag|agakhan|agency|ai|aig|aigo|airbus|airforce|airtel|akdn|al|alfaromeo|alibaba|alipay|allfinanz|allstate|ally|alsace|alstom|am|americanexpress|americanfamily|amex|amfam|amica|amsterdam|analytics|android|anquan|anz|ao|aol|apartments|app|apple|aq|aquarelle|ar|arab|aramco|archi|army|arpa|art|arte|as|asda|asia|associates|at|athleta|attorney|au|auction|audi|audible|audio|auspost|author|auto|autos|avianca|aw|aws|ax|axa|az|azure|ba|baby|baidu|banamex|bananarepublic|band|bank|bar|barcelona|barclaycard|barclays|barefoot|bargains|baseball|basketball|bauhaus|bayern|bb|bbc|bbt|bbva|bcg|bcn|bd|be|beats|beauty|beer|bentley|berlin|best|bestbuy|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|blanco|blockbuster|blog|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bofa|bom|bond|boo|book|booking|boots|bosch|bostik|boston|bot|boutique|box|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|calvinklein|cam|camera|camp|cancerresearch|canon|capetown|capital|capitalone|car|caravan|cards|care|career|careers|cars|cartier|casa|case|caseih|cash|casino|cat|catering|catholic|cba|cbn|cbre|cbs|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chintai|chloe|christmas|chrome|chrysler|church|ci|cipriani|circle|cisco|citadel|citi|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|comcast|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cookingchannel|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruise|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|data|date|dating|datsun|day|dclk|dds|de|deal|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|dhl|diamonds|diet|digital|direct|directory|discount|discover|dish|diy|dj|dk|dm|dnp|do|docs|doctor|dodge|dog|doha|domains|dot|download|drive|dtv|dubai|duck|dunlop|duns|dupont|durban|dvag|dvr|dz|earth|eat|ec|eco|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epost|epson|equipment|er|ericsson|erni|es|esq|estate|esurance|et|etisalat|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|extraspace|fage|fail|fairwinds|faith|family|fan|fans|farm|farmers|fashion|fast|fedex|feedback|ferrari|ferrero|fi|fiat|fidelity|fido|film|final|finance|financial|fire|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|flir|florist|flowers|fly|fm|fo|foo|food|foodnetwork|football|ford|forex|forsale|forum|foundation|fox|fr|free|fresenius|frl|frogans|frontdoor|frontier|ftr|fujitsu|fujixerox|fun|fund|furniture|futbol|fyi|ga|gal|gallery|gallo|gallup|game|games|gap|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|george|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glade|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|godaddy|gold|goldpoint|golf|goo|goodhands|goodyear|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|grocery|group|gs|gt|gu|guardian|gucci|guge|guide|guitars|guru|gw|gy|hair|hamburg|hangout|haus|hbo|hdfc|hdfcbank|health|healthcare|help|helsinki|here|hermes|hgtv|hiphop|hisamitsu|hitachi|hiv|hk|hkt|hm|hn|hockey|holdings|holiday|homedepot|homegoods|homes|homesense|honda|honeywell|horse|hospital|host|hosting|hot|hoteles|hotels|hotmail|house|how|hr|hsbc|ht|htc|hu|hughes|hyatt|hyundai|ibm|icbc|ice|icu|id|ie|ieee|ifm|ikano|il|im|imamat|imdb|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|intel|international|intuit|investments|io|ipiranga|iq|ir|irish|is|iselect|ismaili|ist|istanbul|it|itau|itv|iveco|iwc|jaguar|java|jcb|jcp|je|jeep|jetzt|jewelry|jio|jlc|jll|jm|jmp|jnj|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|juniper|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kindle|kitchen|kiwi|km|kn|koeln|komatsu|kosher|kp|kpmg|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|ladbrokes|lamborghini|lamer|lancaster|lancia|lancome|land|landrover|lanxess|lasalle|lat|latino|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|lefrak|legal|lego|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|lilly|limited|limo|lincoln|linde|link|lipsy|live|living|lixil|lk|loan|loans|locker|locus|loft|lol|london|lotte|lotto|love|lpl|lplfinancial|lr|ls|lt|ltd|ltda|lu|lundbeck|lupin|luxe|luxury|lv|ly|ma|macys|madrid|maif|maison|makeup|man|management|mango|map|market|marketing|markets|marriott|marshalls|maserati|mattel|mba|mc|mckinsey|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|merckmsd|metlife|mg|mh|miami|microsoft|mil|mini|mint|mit|mitsubishi|mk|ml|mlb|mls|mm|mma|mn|mo|mobi|mobile|mobily|moda|moe|moi|mom|monash|money|monster|mopar|mormon|mortgage|moscow|moto|motorcycles|mov|movie|movistar|mp|mq|mr|ms|msd|mt|mtn|mtr|mu|museum|mutual|mv|mw|mx|my|mz|na|nab|nadex|nagoya|name|nationwide|natura|navy|nba|nc|ne|nec|net|netbank|netflix|network|neustar|new|newholland|news|next|nextdirect|nexus|nf|nfl|ng|ngo|nhk|ni|nico|nike|nikon|ninja|nissan|nissay|nl|no|nokia|northwesternmutual|norton|now|nowruz|nowtv|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|observer|off|office|okinawa|olayan|olayangroup|oldnavy|ollo|om|omega|one|ong|onl|online|onyourside|ooo|open|oracle|orange|org|organic|origins|osaka|otsuka|ott|ovh|pa|page|panasonic|panerai|paris|pars|partners|parts|party|passagens|pay|pccw|pe|pet|pf|pfizer|pg|ph|pharmacy|phd|philips|phone|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pioneer|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pnc|pohl|poker|politie|porn|post|pr|pramerica|praxi|press|prime|pro|prod|productions|prof|progressive|promo|properties|property|protection|pru|prudential|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|qvc|racing|radio|raid|re|read|realestate|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|reliance|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|richardli|ricoh|rightathome|ril|rio|rip|rmit|ro|rocher|rocks|rodeo|rogers|room|rs|rsvp|ru|rugby|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsclub|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|save|saxo|sb|sbi|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scjohnson|scor|scot|sd|se|search|seat|secure|security|seek|select|sener|services|ses|seven|sew|sex|sexy|sfr|sg|sh|shangrila|sharp|shaw|shell|shia|shiksha|shoes|shop|shopping|shouji|show|showtime|shriram|si|silk|sina|singles|site|sj|sk|ski|skin|sky|skype|sl|sling|sm|smart|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|srt|st|stada|staples|star|starhub|statebank|statefarm|statoil|stc|stcgroup|stockholm|storage|store|stream|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiftcover|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|talk|taobao|target|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|tdk|team|tech|technology|tel|telecity|telefonica|temasek|tennis|teva|tf|tg|th|thd|theater|theatre|tiaa|tickets|tienda|tiffany|tips|tires|tirol|tj|tjmaxx|tjx|tk|tkmaxx|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tr|trade|trading|training|travel|travelchannel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubank|ubs|uconnect|ug|uk|unicom|university|uno|uol|ups|us|uy|uz|va|vacations|vana|vanguard|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|vig|viking|villas|vin|vip|virgin|visa|vision|vista|vistaprint|viva|vivo|vlaanderen|vn|vodka|volkswagen|volvo|vote|voting|voto|voyage|vu|vuelos|wales|walmart|walter|wang|wanggou|warman|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weibo|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|winners|wme|wolterskluwer|woodside|work|works|world|wow|ws|wtc|wtf|xbox|xerox|xfinity|xihuan|xin|xn--11b4c3d|xn--1ck2e1b|xn--1qqw23a|xn--2scrj9c|xn--30rr7y|xn--3bst00m|xn--3ds443g|xn--3e0b707e|xn--3hcrj9c|xn--3oq18vl8pn36a|xn--3pxu8k|xn--42c2d9a|xn--45br5cyl|xn--45brj9c|xn--45q11c|xn--4gbrim|xn--54b7fta0cc|xn--55qw42g|xn--55qx5d|xn--5su34j936bgsg|xn--5tzm5g|xn--6frz82g|xn--6qq986b3xl|xn--80adxhks|xn--80ao21a|xn--80aqecdr1a|xn--80asehdb|xn--80aswg|xn--8y0a063a|xn--90a3ac|xn--90ae|xn--90ais|xn--9dbq2a|xn--9et52u|xn--9krt00a|xn--b4w605ferd|xn--bck1b9a5dre4c|xn--c1avg|xn--c2br7g|xn--cck2b3b|xn--cg4bki|xn--clchc0ea0b2g2a9gcd|xn--czr694b|xn--czrs0t|xn--czru2d|xn--d1acj3b|xn--d1alf|xn--e1a4c|xn--eckvdtc9d|xn--efvy88h|xn--estv75g|xn--fct429k|xn--fhbei|xn--fiq228c5hs|xn--fiq64b|xn--fiqs8s|xn--fiqz9s|xn--fjq720a|xn--flw351e|xn--fpcrj9c3d|xn--fzc2c9e2c|xn--fzys8d69uvgm|xn--g2xx48c|xn--gckr3f0f|xn--gecrj9c|xn--gk3at1e|xn--h2breg3eve|xn--h2brj9c|xn--h2brj9c8c|xn--hxt814e|xn--i1b6b1a6a2e|xn--imr513n|xn--io0a7i|xn--j1aef|xn--j1amh|xn--j6w193g|xn--jlq61u9w7b|xn--jvr189m|xn--kcrx77d1x4a|xn--kprw13d|xn--kpry57d|xn--kpu716f|xn--kput3i|xn--l1acc|xn--lgbbat1ad8j|xn--mgb9awbf|xn--mgba3a3ejt|xn--mgba3a4f16a|xn--mgba7c0bbn0a|xn--mgbaakc7dvf|xn--mgbaam7a8h|xn--mgbab2bd|xn--mgbai9azgqp6j|xn--mgbayh7gpa|xn--mgbb9fbpob|xn--mgbbh1a|xn--mgbbh1a71e|xn--mgbc0a9azcg|xn--mgbca7dzdo|xn--mgberp4a5d4ar|xn--mgbgu82a|xn--mgbi4ecexp|xn--mgbpl2fh|xn--mgbt3dhd|xn--mgbtx2b|xn--mgbx4cd0ab|xn--mix891f|xn--mk1bu44c|xn--mxtq1m|xn--ngbc5azd|xn--ngbe9e0a|xn--ngbrx|xn--node|xn--nqv7f|xn--nqv7fs00ema|xn--nyqy26a|xn--o3cw4h|xn--ogbpf8fl|xn--p1acf|xn--p1ai|xn--pbt977c|xn--pgbs0dh|xn--pssy2u|xn--q9jyb4c|xn--qcka1pmc|xn--qxam|xn--rhqv96g|xn--rovu88b|xn--rvc1e0am3e|xn--s9brj9c|xn--ses554g|xn--t60b56a|xn--tckwe|xn--tiq49xqyj|xn--unup4y|xn--vermgensberater-ctb|xn--vermgensberatung-pwb|xn--vhquv|xn--vuq861b|xn--w4r85el8fhu5dnra|xn--w4rs40l|xn--wgbh1c|xn--wgbl6a|xn--xhq521b|xn--xkc2al3hye2a|xn--xkc2dl3a5ee0h|xn--y9a3aq|xn--yfro4i67o|xn--ygbi2ammx|xn--zfr164b|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|you|youtube|yt|yun|za|zappos|zara|zero|zip|zippo|zm|zone|zuerich|zw".split("|"),
+ W = "0123456789".split(""), X = "0123456789abcdefghijklmnopqrstuvwxyz".split(""),
+ Z = [" ", "\f", "\r", "\t", "\x0B", " ", " ", ""], F = [], J = function (n) {
+ return new m(n)
+ }, V = J(), $ = J(O), nn = J(x), en = J(), an = J(R);
+ V.on("@", J(y)).on(".", J(k)).on("+", J(q)).on("#", J(N)).on("?", J(A)).on("/", J(L)).on("_", J(P)).on(":", J(v)).on("{", J(H)).on("[", J(B)).on("<", J(U)).on("(", J(M)).on("}", J(D)).on("]", J(I)).on(">", J(K)).on(")", J(_)).on("&", J(G)).on([",", ";", "!", '"', "'"], J(w)), V.on("\n", J(z)).on(Z, an), an.on(Z, an);
+ for (var tn = 0; tn < Q.length; tn++) {
+ var on = c(Q[tn], V, C, x);
+ F.push.apply(F, on)
+ }
+ var rn = c("file", V, x, x), sn = c("ftp", V, x, x), cn = c("http", V, x, x), ln = c("mailto", V, x, x);
+ F.push.apply(F, rn), F.push.apply(F, sn), F.push.apply(F, cn), F.push.apply(F, ln);
+ var un = rn.pop(), gn = sn.pop(), hn = cn.pop(), bn = ln.pop(), pn = J(x), mn = J(S), fn = J(T);
+ gn.on("s", pn).on(":", mn), hn.on("s", pn).on(":", mn), F.push(pn), un.on(":", mn), pn.on(":", mn), bn.on(":", fn);
+ var dn = c("localhost", V, j, x);
+ F.push.apply(F, dn), V.on(W, $), $.on("-", en).on(W, $).on(X, nn), nn.on("-", en).on(X, nn);
+ for (var xn = 0; xn < F.length; xn++) F[xn].on("-", en).on(X, nn);
+ en.on("-", en).on(W, nn).on(X, nn), V.defaultTransition = J(E);
+ var yn = function (n) {
+ for (var e = n.replace(/[A-Z]/g, function (n) {
+ return n.toLowerCase()
+ }), a = n.length, t = [], o = 0; o < a;) {
+ for (var r = V, i = null, s = 0, c = null, l = -1; o < a && (i = r.next(e[o]));) r = i, r.accepts() ? (l = 0, c = r) : l >= 0 && l++, s++, o++;
+ if (!(l < 0)) {
+ o -= l, s -= l;
+ var u = c.emit();
+ t.push(new u(n.substr(o - s, s)))
+ }
+ }
+ return t
+ }, vn = V, kn = Object.freeze({State: m, TOKENS: Y, run: yn, start: vn}), wn = l();
+ wn.prototype = {
+ type: "token", isLink: !1, toString: function () {
+ for (var n = [], e = 0; e < this.v.length; e++) n.push(this.v[e].toString());
+ return n.join("")
+ }, toHref: function () {
+ return this.toString()
+ }, toObject: function () {
+ var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http";
+ return {type: this.type, value: this.toString(), href: this.toHref(n)}
+ }
+ };
+ var jn = a(wn, l(), {type: "email", isLink: !0}), zn = a(wn, l(), {
+ type: "email", isLink: !0, toHref: function () {
+ return "mailto:" + this.toString()
+ }
+ }), On = a(wn, l(), {type: "text"}), qn = a(wn, l(), {type: "nl"}), Nn = a(wn, l(), {
+ type: "url", isLink: !0, toHref: function () {
+ for (var n = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "http", e = !1, a = !1, t = this.v, o = [], r = 0; t[r] instanceof S;) e = !0, o.push(t[r].toString().toLowerCase()), r++;
+ for (; t[r] instanceof L;) a = !0, o.push(t[r].toString()), r++;
+ for (; g(t[r]);) o.push(t[r].toString().toLowerCase()), r++;
+ for (; r < t.length; r++) o.push(t[r].toString());
+ return o = o.join(""), e || a || (o = n + "://" + o), o
+ }, hasProtocol: function () {
+ return this.v[0] instanceof S
+ }
+ }), Sn = Object.freeze({Base: wn, MAILTOEMAIL: jn, EMAIL: zn, NL: qn, TEXT: On, URL: Nn}), Tn = function (n) {
+ return new f(n)
+ }, An = Tn(), Ln = Tn(), Pn = Tn(), En = Tn(), Cn = Tn(), Rn = Tn(), Hn = Tn(), Bn = Tn(Nn), Un = Tn(),
+ Mn = Tn(Nn), Dn = Tn(Nn), In = Tn(), Kn = Tn(), _n = Tn(), Gn = Tn(), Yn = Tn(), Qn = Tn(Nn), Wn = Tn(Nn),
+ Xn = Tn(Nn), Zn = Tn(Nn), Fn = Tn(), Jn = Tn(), Vn = Tn(), $n = Tn(), ne = Tn(), ee = Tn(), ae = Tn(zn),
+ te = Tn(), oe = Tn(zn), re = Tn(jn), ie = Tn(), se = Tn(), ce = Tn(), le = Tn(), ue = Tn(qn);
+ An.on(z, ue).on(S, Ln).on(T, Pn).on(L, En), Ln.on(L, En), En.on(L, Cn), An.on(C, Rn).on(x, Rn).on(j, Bn).on(O, Rn), Cn.on(C, Dn).on(x, Dn).on(O, Dn).on(j, Dn), Rn.on(k, Hn), ne.on(k, ee), Hn.on(C, Bn).on(x, Rn).on(O, Rn).on(j, Rn), ee.on(C, ae).on(x, ne).on(O, ne).on(j, ne), Bn.on(k, Hn), ae.on(k, ee), Bn.on(v, Un).on(L, Dn), Un.on(O, Mn), Mn.on(L, Dn), ae.on(v, te), te.on(O, oe);
+ var ge = [x, y, j, O, q, N, S, L, C, P, E, G], he = [v, k, A, w, D, I, K, _, H, B, U, M];
+ Dn.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), In.on(H, Kn).on(B, _n).on(U, Gn).on(M, Yn), Kn.on(D, Dn), _n.on(I, Dn), Gn.on(K, Dn), Yn.on(_, Dn), Qn.on(D, Dn), Wn.on(I, Dn), Xn.on(K, Dn), Zn.on(_, Dn), Fn.on(D, Dn), Jn.on(I, Dn), Vn.on(K, Dn), $n.on(_, Dn), Kn.on(ge, Qn), _n.on(ge, Wn), Gn.on(ge, Xn), Yn.on(ge, Zn), Kn.on(he, Fn), _n.on(he, Jn), Gn.on(he, Vn), Yn.on(he, $n), Qn.on(ge, Qn), Wn.on(ge, Wn), Xn.on(ge, Xn), Zn.on(ge, Zn), Qn.on(he, Qn), Wn.on(he, Wn), Xn.on(he, Xn), Zn.on(he, Zn), Fn.on(ge, Qn), Jn.on(ge, Wn), Vn.on(ge, Xn), $n.on(ge, Zn), Fn.on(he, Fn), Jn.on(he, Jn), Vn.on(he, Vn), $n.on(he, $n), Dn.on(ge, Dn), In.on(ge, Dn), Dn.on(he, In), In.on(he, In), Pn.on(C, re).on(x, re).on(O, re).on(j, re), re.on(ge, re).on(he, ie), ie.on(ge, re).on(he, ie);
+ var be = [x, O, q, N, A, P, E, G, C];
+ Rn.on(be, se).on(y, ce), Bn.on(be, se).on(y, ce), Hn.on(be, se), se.on(be, se).on(y, ce).on(k, le), le.on(be, se), ce.on(C, ne).on(x, ne).on(j, ae);
+ var pe = function (n) {
+ for (var e = n.length, a = 0, t = [], o = []; a < e;) {
+ for (var r = An, i = null, s = null, c = 0, l = null, u = -1; a < e && !(i = r.next(n[a]));) o.push(n[a++]);
+ for (; a < e && (s = i || r.next(n[a]));) i = null, r = s, r.accepts() ? (u = 0, l = r) : u >= 0 && u++, a++, c++;
+ if (u < 0) for (var g = a - c; g < a; g++) o.push(n[g]); else {
+ o.length > 0 && (t.push(new On(o)), o = []), a -= u, c -= u;
+ var h = l.emit();
+ t.push(new h(n.slice(a - c, a)))
+ }
+ }
+ return o.length > 0 && t.push(new On(o)), t
+ }, me = Object.freeze({State: f, TOKENS: Sn, run: pe, start: An});
+ Array.isArray || (Array.isArray = function (n) {
+ return "[object Array]" === Object.prototype.toString.call(n)
+ });
+ var fe = function (n) {
+ return pe(yn(n))
+ }, de = function (n) {
+ for (var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n), t = [], o = 0; o < a.length; o++) {
+ var r = a[o];
+ !r.isLink || e && r.type !== e || t.push(r.toObject())
+ }
+ return t
+ }, xe = function (n) {
+ var e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null, a = fe(n);
+ return 1 === a.length && a[0].isLink && (!e || a[0].type === e)
+ };
+ e.find = de, e.inherits = a, e.options = b, e.parser = me, e.scanner = kn, e.test = xe, e.tokenize = fe
+ }(self.linkify = self.linkify || {})
+}();
+
+"use strict";
+!function (e, n, t) {
+ var i = function (n) {
+ function t(e, n, t) {
+ var i = t[t.length - 1];
+ e.replaceChild(i, n);
+ for (var a = t.length - 2; a >= 0; a--) e.insertBefore(t[a], i), i = t[a]
+ }
+
+ function i(e, n, t) {
+ for (var i = [], a = e, r = Array.isArray(a), o = 0, a = r ? a : a[Symbol.iterator](); ;) {
+ var l;
+ if (r) {
+ if (o >= a.length) break;
+ l = a[o++]
+ } else {
+ if (o = a.next(), o.done) break;
+ l = o.value
+ }
+ var f = l;
+ if ("nl" === f.type && n.nl2br) i.push(t.createElement("br")); else if (f.isLink && n.check(f)) {
+ var s = n.resolve(f), c = s.formatted, u = s.formattedHref, y = s.tagName, d = s.className,
+ m = s.target, k = s.events, h = s.attributes, v = t.createElement(y);
+ if (v.setAttribute("href", u), d && v.setAttribute("class", d), m && v.setAttribute("target", m), h) for (var g in h) v.setAttribute(g, h[g]);
+ if (k) for (var b in k) v.addEventListener ? v.addEventListener(b, k[b]) : v.attachEvent && v.attachEvent("on" + b, k[b]);
+ v.appendChild(t.createTextNode(c)), i.push(v)
+ } else i.push(t.createTextNode(f.toString()))
+ }
+ return i
+ }
+
+ function a(e, n, r) {
+ if (!e || e.nodeType !== u) throw new Error("Cannot linkify " + e + " - Invalid DOM Node type");
+ var o = n.ignoreTags;
+ if ("A" === e.tagName || f.contains(o, e.tagName)) return e;
+ for (var s = e.firstChild; s;) {
+ var d = void 0, m = void 0, k = void 0;
+ switch (s.nodeType) {
+ case u:
+ a(s, n, r);
+ break;
+ case y:
+ if (d = s.nodeValue, m = l(d), 0 === m.length || 1 === m.length && m[0] instanceof c) break;
+ k = i(m, n, r), t(e, s, k), s = k[k.length - 1]
+ }
+ s = s.nextSibling
+ }
+ return e
+ }
+
+ function r(n, t) {
+ var i = arguments.length > 2 && void 0 !== arguments[2] && arguments[2];
+ try {
+ i = i || document || e && e.document || global && global.document
+ } catch (r) {
+ }
+ if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");
+ return t = new s(t), a(n, t, i)
+ }
+
+ function o(n) {
+ function t(e) {
+ return e = r.normalize(e), this.each(function () {
+ r.helper(this, e, i)
+ })
+ }
+
+ var i = arguments.length > 1 && void 0 !== arguments[1] && arguments[1];
+ n.fn = n.fn || {};
+ try {
+ i = i || document || e && e.document || global && global.document
+ } catch (a) {
+ }
+ if (!i) throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");
+ "function" != typeof n.fn.linkify && (n.fn.linkify = t, n(i).ready(function () {
+ n("[data-linkify]").each(function () {
+ var e = n(this), t = e.data(), i = t.linkify, a = t.linkifyNlbr,
+ o = {nl2br: !!a && 0 !== a && "false" !== a};
+ "linkifyAttributes" in t && (o.attributes = t.linkifyAttributes), "linkifyDefaultProtocol" in t && (o.defaultProtocol = t.linkifyDefaultProtocol), "linkifyEvents" in t && (o.events = t.linkifyEvents), "linkifyFormat" in t && (o.format = t.linkifyFormat), "linkifyFormatHref" in t && (o.formatHref = t.linkifyFormatHref), "linkifyTagname" in t && (o.tagName = t.linkifyTagname), "linkifyTarget" in t && (o.target = t.linkifyTarget), "linkifyValidate" in t && (o.validate = t.linkifyValidate), "linkifyIgnoreTags" in t && (o.ignoreTags = t.linkifyIgnoreTags), "linkifyClassName" in t ? o.className = t.linkifyClassName : "linkifyLinkclass" in t && (o.className = t.linkifyLinkclass), o = r.normalize(o);
+ var l = "this" === i ? e : e.find(i);
+ l.linkify(o)
+ })
+ }))
+ }
+
+ var l = n.tokenize, f = n.options, s = f.Options, c = n.parser.TOKENS.TEXT, u = 1, y = 3;
+ r.helper = a, r.normalize = function (e) {
+ return new s(e)
+ };
+ try {
+ !(void 0).define && (e.linkifyElement = r)
+ } catch (d) {
+ }
+ return o
+ }(n);
+ "function" != typeof t.fn.linkify && i(t)
}(window, linkify, jQuery);
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/main.js b/main/app/sprinkles/core/assets/SiteAssets/js/main.js
index d2123f5..b359d2d 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/js/main.js
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/main.js
@@ -1,91 +1,91 @@
-var MainTabWindows = $(".MainTabWindows");
-var NavbarIconWrap = $(".NavbarIconWrap");
-var Navbar = $(".Navbar");
-var NavbarLine = $(".NavbarLine");
-
-
-/******
- NAVBAR
- *****/
-var $el, leftPos, newWidth;
-NavbarLine
- .css("left", $(".ActiveTab").position().left)
- .data("origLeft", NavbarLine.position().left)
- .data("origWidth", NavbarLine.width());
-NavbarIconWrap.on("click", function () {
- NavbarIconWrap.removeClass("ActiveTab");
- $(this).addClass("ActiveTab");
- var index = $(this).attr('id');
- MainTabWindows.slick('slickGoTo', index);
- //$('.MainTabWindows').flickity().flickity('select', index);
- $el = $(this);
- leftPos = $el.position().left;
- NavbarLine.stop().animate({
- left: leftPos,
- width: newWidth
- }, 300);
-});
-
-/********
- FLICKITY
- *******/
-MainTabWindows.slick({
- initialSlide: 2,
- mobileFirst: true,
- nextArrow: "",
- prevArrow: "",
- infinite: false,
- zIndex: 500
-});
-
-MainTabWindows.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
- //console.log(nextSlide);
- NavbarIconWrap.removeClass("ActiveTab");
- $el = $("#" + nextSlide);
- $el.addClass("ActiveTab");
- leftPos = $el.position().left;
- NavbarLine.stop().animate({
- left: leftPos,
- width: newWidth
- }, 300);
-});
-
-/*
-$('.MainTabWindows').flickity({
- cellAlign: 'left',
- prevNextButtons: false,
- pageDots: false,
- friction: 0.3,
- dragThreshold: ($("body").width() * 0.5),
- initialIndex: 2,
- wrapAround: true,
- maxSwipeWidth: 0,
- on: {
- change: function (index) {
- $(".NavbarIconWrap").removeClass("ActiveTab");
- $el = $("#" + index);
- $el.addClass("ActiveTab");
- leftPos = $el.position().left;
- $magicLine.stop().animate({
- left: leftPos,
- width: newWidth
- }, 300);
- },
- dragStart: function () {
- $(".ActiveTab").css({ transform: 'scale(1.05)' });
- },
- dragEnd: function () {
- $(".NavbarIconWrap").css({ transform: 'scale(1.0)' });
- }/*,
- scroll: function (event, progress) {
- var TotalWidth = $("body").width();
- console.log(progress / 10);
- leftPos = ((progress / 1000) * TotalWidth + 'px');
- $magicLine.stop().animate({
- left: leftPos,
- width: newWidth
- });
- }*
- }
-});
+var MainTabWindows = $(".MainTabWindows");
+var NavbarIconWrap = $(".NavbarIconWrap");
+var Navbar = $(".Navbar");
+var NavbarLine = $(".NavbarLine");
+
+
+/******
+ NAVBAR
+ *****/
+var $el, leftPos, newWidth;
+NavbarLine
+ .css("left", $(".ActiveTab").position().left)
+ .data("origLeft", NavbarLine.position().left)
+ .data("origWidth", NavbarLine.width());
+NavbarIconWrap.on("click", function () {
+ NavbarIconWrap.removeClass("ActiveTab");
+ $(this).addClass("ActiveTab");
+ var index = $(this).attr('id');
+ MainTabWindows.slick('slickGoTo', index);
+ //$('.MainTabWindows').flickity().flickity('select', index);
+ $el = $(this);
+ leftPos = $el.position().left;
+ NavbarLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+});
+
+/********
+ FLICKITY
+ *******/
+MainTabWindows.slick({
+ initialSlide: 2,
+ mobileFirst: true,
+ nextArrow: "",
+ prevArrow: "",
+ infinite: false,
+ zIndex: 500
+});
+
+MainTabWindows.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
+ //console.log(nextSlide);
+ NavbarIconWrap.removeClass("ActiveTab");
+ $el = $("#" + nextSlide);
+ $el.addClass("ActiveTab");
+ leftPos = $el.position().left;
+ NavbarLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+});
+
+/*
+$('.MainTabWindows').flickity({
+ cellAlign: 'left',
+ prevNextButtons: false,
+ pageDots: false,
+ friction: 0.3,
+ dragThreshold: ($("body").width() * 0.5),
+ initialIndex: 2,
+ wrapAround: true,
+ maxSwipeWidth: 0,
+ on: {
+ change: function (index) {
+ $(".NavbarIconWrap").removeClass("ActiveTab");
+ $el = $("#" + index);
+ $el.addClass("ActiveTab");
+ leftPos = $el.position().left;
+ $magicLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ }, 300);
+ },
+ dragStart: function () {
+ $(".ActiveTab").css({ transform: 'scale(1.05)' });
+ },
+ dragEnd: function () {
+ $(".NavbarIconWrap").css({ transform: 'scale(1.0)' });
+ }/*,
+ scroll: function (event, progress) {
+ var TotalWidth = $("body").width();
+ console.log(progress / 10);
+ leftPos = ((progress / 1000) * TotalWidth + 'px');
+ $magicLine.stop().animate({
+ left: leftPos,
+ width: newWidth
+ });
+ }*
+ }
+});
*/
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/js/slick.js b/main/app/sprinkles/core/assets/SiteAssets/js/slick.js
index c697993..5c668f2 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/js/slick.js
+++ b/main/app/sprinkles/core/assets/SiteAssets/js/slick.js
@@ -1,556 +1,556 @@
-!function (i) {
- "use strict";
- "function" == typeof define && define.amd ? define(["jquery"], i) : "undefined" != typeof exports ? module.exports = i(require("jquery")) : i(jQuery)
-}(function (i) {
- "use strict";
- var e = window.Slick || {};
- (e = function () {
- var e = 0;
- return function (t, o) {
- var s, n = this;
- n.defaults = {
- accessibility: !0,
- adaptiveHeight: !1,
- appendArrows: i(t),
- appendDots: i(t),
- arrows: !0,
- asNavFor: null,
- prevArrow: '
',
- nextArrow: '
',
- autoplay: !1,
- autoplaySpeed: 3e3,
- centerMode: !1,
- centerPadding: "50px",
- cssEase: "ease",
- customPaging: function (e, t) {
- return i('
').text(t + 1)
- },
- dots: !1,
- dotsClass: "slick-dots",
- draggable: !0,
- easing: "linear",
- edgeFriction: .35,
- fade: !1,
- focusOnSelect: !1,
- focusOnChange: !1,
- infinite: !0,
- initialSlide: 0,
- lazyLoad: "ondemand",
- mobileFirst: !1,
- pauseOnHover: !0,
- pauseOnFocus: !0,
- pauseOnDotsHover: !1,
- respondTo: "window",
- responsive: null,
- rows: 1,
- rtl: !1,
- slide: "",
- slidesPerRow: 1,
- slidesToShow: 1,
- slidesToScroll: 1,
- speed: 500,
- swipe: !0,
- swipeToSlide: !1,
- touchMove: !0,
- touchThreshold: 5,
- useCSS: !0,
- useTransform: !0,
- variableWidth: !1,
- vertical: !1,
- verticalSwiping: !1,
- waitForAnimate: !0,
- zIndex: 1e3
- }, n.initials = {
- animating: !1,
- dragging: !1,
- autoPlayTimer: null,
- currentDirection: 0,
- currentLeft: null,
- currentSlide: 0,
- direction: 1,
- $dots: null,
- listWidth: null,
- listHeight: null,
- loadIndex: 0,
- $nextArrow: null,
- $prevArrow: null,
- scrolling: !1,
- slideCount: null,
- slideWidth: null,
- $slideTrack: null,
- $slides: null,
- sliding: !1,
- slideOffset: 0,
- swipeLeft: null,
- swiping: !1,
- $list: null,
- touchObject: {},
- transformsEnabled: !1,
- unslicked: !1
- }, i.extend(n, n.initials), n.activeBreakpoint = null, n.animType = null, n.animProp = null, n.breakpoints = [], n.breakpointSettings = [], n.cssTransitions = !1, n.focussed = !1, n.interrupted = !1, n.hidden = "hidden", n.paused = !0, n.positionProp = null, n.respondTo = null, n.rowCount = 1, n.shouldClick = !0, n.$slider = i(t), n.$slidesCache = null, n.transformType = null, n.transitionType = null, n.visibilityChange = "visibilitychange", n.windowWidth = 0, n.windowTimer = null, s = i(t).data("slick") || {}, n.options = i.extend({}, n.defaults, o, s), n.currentSlide = n.options.initialSlide, n.originalSettings = n.options, void 0 !== document.mozHidden ? (n.hidden = "mozHidden", n.visibilityChange = "mozvisibilitychange") : void 0 !== document.webkitHidden && (n.hidden = "webkitHidden", n.visibilityChange = "webkitvisibilitychange"), n.autoPlay = i.proxy(n.autoPlay, n), n.autoPlayClear = i.proxy(n.autoPlayClear, n), n.autoPlayIterator = i.proxy(n.autoPlayIterator, n), n.changeSlide = i.proxy(n.changeSlide, n), n.clickHandler = i.proxy(n.clickHandler, n), n.selectHandler = i.proxy(n.selectHandler, n), n.setPosition = i.proxy(n.setPosition, n), n.swipeHandler = i.proxy(n.swipeHandler, n), n.dragHandler = i.proxy(n.dragHandler, n), n.keyHandler = i.proxy(n.keyHandler, n), n.instanceUid = e++, n.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/, n.registerBreakpoints(), n.init(!0)
- }
- }()).prototype.activateADA = function () {
- this.$slideTrack.find(".slick-active").attr({"aria-hidden": "false"}).find("a, input, button, select").attr({tabindex: "0"})
- }, e.prototype.addSlide = e.prototype.slickAdd = function (e, t, o) {
- var s = this;
- if ("boolean" == typeof t) o = t, t = null; else if (t < 0 || t >= s.slideCount) return !1;
- s.unload(), "number" == typeof t ? 0 === t && 0 === s.$slides.length ? i(e).appendTo(s.$slideTrack) : o ? i(e).insertBefore(s.$slides.eq(t)) : i(e).insertAfter(s.$slides.eq(t)) : !0 === o ? i(e).prependTo(s.$slideTrack) : i(e).appendTo(s.$slideTrack), s.$slides = s.$slideTrack.children(this.options.slide), s.$slideTrack.children(this.options.slide).detach(), s.$slideTrack.append(s.$slides), s.$slides.each(function (e, t) {
- i(t).attr("data-slick-index", e)
- }), s.$slidesCache = s.$slides, s.reinit()
- }, e.prototype.animateHeight = function () {
- var i = this;
- if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
- var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
- i.$list.animate({height: e}, i.options.speed)
- }
- }, e.prototype.animateSlide = function (e, t) {
- var o = {}, s = this;
- s.animateHeight(), !0 === s.options.rtl && !1 === s.options.vertical && (e = -e), !1 === s.transformsEnabled ? !1 === s.options.vertical ? s.$slideTrack.animate({left: e}, s.options.speed, s.options.easing, t) : s.$slideTrack.animate({top: e}, s.options.speed, s.options.easing, t) : !1 === s.cssTransitions ? (!0 === s.options.rtl && (s.currentLeft = -s.currentLeft), i({animStart: s.currentLeft}).animate({animStart: e}, {
- duration: s.options.speed,
- easing: s.options.easing,
- step: function (i) {
- i = Math.ceil(i), !1 === s.options.vertical ? (o[s.animType] = "translate(" + i + "px, 0px)", s.$slideTrack.css(o)) : (o[s.animType] = "translate(0px," + i + "px)", s.$slideTrack.css(o))
- },
- complete: function () {
- t && t.call()
- }
- })) : (s.applyTransition(), e = Math.ceil(e), !1 === s.options.vertical ? o[s.animType] = "translate3d(" + e + "px, 0px, 0px)" : o[s.animType] = "translate3d(0px," + e + "px, 0px)", s.$slideTrack.css(o), t && setTimeout(function () {
- s.disableTransition(), t.call()
- }, s.options.speed))
- }, e.prototype.getNavTarget = function () {
- var e = this, t = e.options.asNavFor;
- return t && null !== t && (t = i(t).not(e.$slider)), t
- }, e.prototype.asNavFor = function (e) {
- var t = this.getNavTarget();
- null !== t && "object" == typeof t && t.each(function () {
- var t = i(this).slick("getSlick");
- t.unslicked || t.slideHandler(e, !0)
- })
- }, e.prototype.applyTransition = function (i) {
- var e = this, t = {};
- !1 === e.options.fade ? t[e.transitionType] = e.transformType + " " + e.options.speed + "ms " + e.options.cssEase : t[e.transitionType] = "opacity " + e.options.speed + "ms " + e.options.cssEase, !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
- }, e.prototype.autoPlay = function () {
- var i = this;
- i.autoPlayClear(), i.slideCount > i.options.slidesToShow && (i.autoPlayTimer = setInterval(i.autoPlayIterator, i.options.autoplaySpeed))
- }, e.prototype.autoPlayClear = function () {
- var i = this;
- i.autoPlayTimer && clearInterval(i.autoPlayTimer)
- }, e.prototype.autoPlayIterator = function () {
- var i = this, e = i.currentSlide + i.options.slidesToScroll;
- i.paused || i.interrupted || i.focussed || (!1 === i.options.infinite && (1 === i.direction && i.currentSlide + 1 === i.slideCount - 1 ? i.direction = 0 : 0 === i.direction && (e = i.currentSlide - i.options.slidesToScroll, i.currentSlide - 1 == 0 && (i.direction = 1))), i.slideHandler(e))
- }, e.prototype.buildArrows = function () {
- var e = this;
- !0 === e.options.arrows && (e.$prevArrow = i(e.options.prevArrow).addClass("slick-arrow"), e.$nextArrow = i(e.options.nextArrow).addClass("slick-arrow"), e.slideCount > e.options.slidesToShow ? (e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.prependTo(e.options.appendArrows), e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.appendTo(e.options.appendArrows), !0 !== e.options.infinite && e.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true")) : e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({
- "aria-disabled": "true",
- tabindex: "-1"
- }))
- }, e.prototype.buildDots = function () {
- var e, t, o = this;
- if (!0 === o.options.dots) {
- for (o.$slider.addClass("slick-dotted"), t = i("
").addClass(o.options.dotsClass), e = 0; e <= o.getDotCount(); e += 1) t.append(i("
").append(o.options.customPaging.call(this, o, e)));
- o.$dots = t.appendTo(o.options.appendDots), o.$dots.find("li").first().addClass("slick-active")
- }
- }, e.prototype.buildOut = function () {
- var e = this;
- e.$slides = e.$slider.children(e.options.slide + ":not(.slick-cloned)").addClass("slick-slide"), e.slideCount = e.$slides.length, e.$slides.each(function (e, t) {
- i(t).attr("data-slick-index", e).data("originalStyling", i(t).attr("style") || "")
- }), e.$slider.addClass("slick-slider"), e.$slideTrack = 0 === e.slideCount ? i('
').appendTo(e.$slider) : e.$slides.wrapAll('
').parent(), e.$list = e.$slideTrack.wrap('
').parent(), e.$slideTrack.css("opacity", 0), !0 !== e.options.centerMode && !0 !== e.options.swipeToSlide || (e.options.slidesToScroll = 1), i("img[data-lazy]", e.$slider).not("[src]").addClass("slick-loading"), e.setupInfinite(), e.buildArrows(), e.buildDots(), e.updateDots(), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), !0 === e.options.draggable && e.$list.addClass("draggable")
- }, e.prototype.buildRows = function () {
- var i, e, t, o, s, n, r, l = this;
- if (o = document.createDocumentFragment(), n = l.$slider.children(), l.options.rows > 1) {
- for (r = l.options.slidesPerRow * l.options.rows, s = Math.ceil(n.length / r), i = 0; i < s; i++) {
- var d = document.createElement("div");
- for (e = 0; e < l.options.rows; e++) {
- var a = document.createElement("div");
- for (t = 0; t < l.options.slidesPerRow; t++) {
- var c = i * r + (e * l.options.slidesPerRow + t);
- n.get(c) && a.appendChild(n.get(c))
- }
- d.appendChild(a)
- }
- o.appendChild(d)
- }
- l.$slider.empty().append(o), l.$slider.children().children().children().css({
- width: 100 / l.options.slidesPerRow + "%",
- display: "inline-block"
- })
- }
- }, e.prototype.checkResponsive = function (e, t) {
- var o, s, n, r = this, l = !1, d = r.$slider.width(), a = window.innerWidth || i(window).width();
- if ("window" === r.respondTo ? n = a : "slider" === r.respondTo ? n = d : "min" === r.respondTo && (n = Math.min(a, d)), r.options.responsive && r.options.responsive.length && null !== r.options.responsive) {
- s = null;
- for (o in r.breakpoints) r.breakpoints.hasOwnProperty(o) && (!1 === r.originalSettings.mobileFirst ? n < r.breakpoints[o] && (s = r.breakpoints[o]) : n > r.breakpoints[o] && (s = r.breakpoints[o]));
- null !== s ? null !== r.activeBreakpoint ? (s !== r.activeBreakpoint || t) && (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : null !== r.activeBreakpoint && (r.activeBreakpoint = null, r.options = r.originalSettings, !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e), l = s), e || !1 === l || r.$slider.trigger("breakpoint", [r, l])
- }
- }, e.prototype.changeSlide = function (e, t) {
- var o, s, n, r = this, l = i(e.currentTarget);
- switch (l.is("a") && e.preventDefault(), l.is("li") || (l = l.closest("li")), n = r.slideCount % r.options.slidesToScroll != 0, o = n ? 0 : (r.slideCount - r.currentSlide) % r.options.slidesToScroll, e.data.message) {
- case"previous":
- s = 0 === o ? r.options.slidesToScroll : r.options.slidesToShow - o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide - s, !1, t);
- break;
- case"next":
- s = 0 === o ? r.options.slidesToScroll : o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide + s, !1, t);
- break;
- case"index":
- var d = 0 === e.data.index ? 0 : e.data.index || l.index() * r.options.slidesToScroll;
- r.slideHandler(r.checkNavigable(d), !1, t), l.children().trigger("focus");
- break;
- default:
- return
- }
- }, e.prototype.checkNavigable = function (i) {
- var e, t;
- if (e = this.getNavigableIndexes(), t = 0, i > e[e.length - 1]) i = e[e.length - 1]; else for (var o in e) {
- if (i < e[o]) {
- i = t;
- break
- }
- t = e[o]
- }
- return i
- }, e.prototype.cleanUpEvents = function () {
- var e = this;
- e.options.dots && null !== e.$dots && (i("li", e.$dots).off("click.slick", e.changeSlide).off("mouseenter.slick", i.proxy(e.interrupt, e, !0)).off("mouseleave.slick", i.proxy(e.interrupt, e, !1)), !0 === e.options.accessibility && e.$dots.off("keydown.slick", e.keyHandler)), e.$slider.off("focus.slick blur.slick"), !0 === e.options.arrows && e.slideCount > e.options.slidesToShow && (e.$prevArrow && e.$prevArrow.off("click.slick", e.changeSlide), e.$nextArrow && e.$nextArrow.off("click.slick", e.changeSlide), !0 === e.options.accessibility && (e.$prevArrow && e.$prevArrow.off("keydown.slick", e.keyHandler), e.$nextArrow && e.$nextArrow.off("keydown.slick", e.keyHandler))), e.$list.off("touchstart.slick mousedown.slick", e.swipeHandler), e.$list.off("touchmove.slick mousemove.slick", e.swipeHandler), e.$list.off("touchend.slick mouseup.slick", e.swipeHandler), e.$list.off("touchcancel.slick mouseleave.slick", e.swipeHandler), e.$list.off("click.slick", e.clickHandler), i(document).off(e.visibilityChange, e.visibility), e.cleanUpSlideEvents(), !0 === e.options.accessibility && e.$list.off("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().off("click.slick", e.selectHandler), i(window).off("orientationchange.slick.slick-" + e.instanceUid, e.orientationChange), i(window).off("resize.slick.slick-" + e.instanceUid, e.resize), i("[draggable!=true]", e.$slideTrack).off("dragstart", e.preventDefault), i(window).off("load.slick.slick-" + e.instanceUid, e.setPosition)
- }, e.prototype.cleanUpSlideEvents = function () {
- var e = this;
- e.$list.off("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.off("mouseleave.slick", i.proxy(e.interrupt, e, !1))
- }, e.prototype.cleanUpRows = function () {
- var i, e = this;
- e.options.rows > 1 && ((i = e.$slides.children().children()).removeAttr("style"), e.$slider.empty().append(i))
- }, e.prototype.clickHandler = function (i) {
- !1 === this.shouldClick && (i.stopImmediatePropagation(), i.stopPropagation(), i.preventDefault())
- }, e.prototype.destroy = function (e) {
- var t = this;
- t.autoPlayClear(), t.touchObject = {}, t.cleanUpEvents(), i(".slick-cloned", t.$slider).detach(), t.$dots && t.$dots.remove(), t.$prevArrow && t.$prevArrow.length && (t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.prevArrow) && t.$prevArrow.remove()), t.$nextArrow && t.$nextArrow.length && (t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.nextArrow) && t.$nextArrow.remove()), t.$slides && (t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function () {
- i(this).attr("style", i(this).data("originalStyling"))
- }), t.$slideTrack.children(this.options.slide).detach(), t.$slideTrack.detach(), t.$list.detach(), t.$slider.append(t.$slides)), t.cleanUpRows(), t.$slider.removeClass("slick-slider"), t.$slider.removeClass("slick-initialized"), t.$slider.removeClass("slick-dotted"), t.unslicked = !0, e || t.$slider.trigger("destroy", [t])
- }, e.prototype.disableTransition = function (i) {
- var e = this, t = {};
- t[e.transitionType] = "", !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
- }, e.prototype.fadeSlide = function (i, e) {
- var t = this;
- !1 === t.cssTransitions ? (t.$slides.eq(i).css({zIndex: t.options.zIndex}), t.$slides.eq(i).animate({opacity: 1}, t.options.speed, t.options.easing, e)) : (t.applyTransition(i), t.$slides.eq(i).css({
- opacity: 1,
- zIndex: t.options.zIndex
- }), e && setTimeout(function () {
- t.disableTransition(i), e.call()
- }, t.options.speed))
- }, e.prototype.fadeSlideOut = function (i) {
- var e = this;
- !1 === e.cssTransitions ? e.$slides.eq(i).animate({
- opacity: 0,
- zIndex: e.options.zIndex - 2
- }, e.options.speed, e.options.easing) : (e.applyTransition(i), e.$slides.eq(i).css({
- opacity: 0,
- zIndex: e.options.zIndex - 2
- }))
- }, e.prototype.filterSlides = e.prototype.slickFilter = function (i) {
- var e = this;
- null !== i && (e.$slidesCache = e.$slides, e.unload(), e.$slideTrack.children(this.options.slide).detach(), e.$slidesCache.filter(i).appendTo(e.$slideTrack), e.reinit())
- }, e.prototype.focusHandler = function () {
- var e = this;
- e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick", "*", function (t) {
- t.stopImmediatePropagation();
- var o = i(this);
- setTimeout(function () {
- e.options.pauseOnFocus && (e.focussed = o.is(":focus"), e.autoPlay())
- }, 0)
- })
- }, e.prototype.getCurrent = e.prototype.slickCurrentSlide = function () {
- return this.currentSlide
- }, e.prototype.getDotCount = function () {
- var i = this, e = 0, t = 0, o = 0;
- if (!0 === i.options.infinite) if (i.slideCount <= i.options.slidesToShow) ++o; else for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else if (!0 === i.options.centerMode) o = i.slideCount; else if (i.options.asNavFor) for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else o = 1 + Math.ceil((i.slideCount - i.options.slidesToShow) / i.options.slidesToScroll);
- return o - 1
- }, e.prototype.getLeft = function (i) {
- var e, t, o, s, n = this, r = 0;
- return n.slideOffset = 0, t = n.$slides.first().outerHeight(!0), !0 === n.options.infinite ? (n.slideCount > n.options.slidesToShow && (n.slideOffset = n.slideWidth * n.options.slidesToShow * -1, s = -1, !0 === n.options.vertical && !0 === n.options.centerMode && (2 === n.options.slidesToShow ? s = -1.5 : 1 === n.options.slidesToShow && (s = -2)), r = t * n.options.slidesToShow * s), n.slideCount % n.options.slidesToScroll != 0 && i + n.options.slidesToScroll > n.slideCount && n.slideCount > n.options.slidesToShow && (i > n.slideCount ? (n.slideOffset = (n.options.slidesToShow - (i - n.slideCount)) * n.slideWidth * -1, r = (n.options.slidesToShow - (i - n.slideCount)) * t * -1) : (n.slideOffset = n.slideCount % n.options.slidesToScroll * n.slideWidth * -1, r = n.slideCount % n.options.slidesToScroll * t * -1))) : i + n.options.slidesToShow > n.slideCount && (n.slideOffset = (i + n.options.slidesToShow - n.slideCount) * n.slideWidth, r = (i + n.options.slidesToShow - n.slideCount) * t), n.slideCount <= n.options.slidesToShow && (n.slideOffset = 0, r = 0), !0 === n.options.centerMode && n.slideCount <= n.options.slidesToShow ? n.slideOffset = n.slideWidth * Math.floor(n.options.slidesToShow) / 2 - n.slideWidth * n.slideCount / 2 : !0 === n.options.centerMode && !0 === n.options.infinite ? n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2) - n.slideWidth : !0 === n.options.centerMode && (n.slideOffset = 0, n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2)), e = !1 === n.options.vertical ? i * n.slideWidth * -1 + n.slideOffset : i * t * -1 + r, !0 === n.options.variableWidth && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, !0 === n.options.centerMode && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow + 1), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, e += (n.$list.width() - o.outerWidth()) / 2)), e
- }, e.prototype.getOption = e.prototype.slickGetOption = function (i) {
- return this.options[i]
- }, e.prototype.getNavigableIndexes = function () {
- var i, e = this, t = 0, o = 0, s = [];
- for (!1 === e.options.infinite ? i = e.slideCount : (t = -1 * e.options.slidesToScroll, o = -1 * e.options.slidesToScroll, i = 2 * e.slideCount); t < i;) s.push(t), t = o + e.options.slidesToScroll, o += e.options.slidesToScroll <= e.options.slidesToShow ? e.options.slidesToScroll : e.options.slidesToShow;
- return s
- }, e.prototype.getSlick = function () {
- return this
- }, e.prototype.getSlideCount = function () {
- var e, t, o = this;
- return t = !0 === o.options.centerMode ? o.slideWidth * Math.floor(o.options.slidesToShow / 2) : 0, !0 === o.options.swipeToSlide ? (o.$slideTrack.find(".slick-slide").each(function (s, n) {
- if (n.offsetLeft - t + i(n).outerWidth() / 2 > -1 * o.swipeLeft) return e = n, !1
- }), Math.abs(i(e).attr("data-slick-index") - o.currentSlide) || 1) : o.options.slidesToScroll
- }, e.prototype.goTo = e.prototype.slickGoTo = function (i, e) {
- this.changeSlide({data: {message: "index", index: parseInt(i)}}, e)
- }, e.prototype.init = function (e) {
- var t = this;
- i(t.$slider).hasClass("slick-initialized") || (i(t.$slider).addClass("slick-initialized"), t.buildRows(), t.buildOut(), t.setProps(), t.startLoad(), t.loadSlider(), t.initializeEvents(), t.updateArrows(), t.updateDots(), t.checkResponsive(!0), t.focusHandler()), e && t.$slider.trigger("init", [t]), !0 === t.options.accessibility && t.initADA(), t.options.autoplay && (t.paused = !1, t.autoPlay())
- }, e.prototype.initADA = function () {
- var e = this, t = Math.ceil(e.slideCount / e.options.slidesToShow),
- o = e.getNavigableIndexes().filter(function (i) {
- return i >= 0 && i < e.slideCount
- });
- e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({
- "aria-hidden": "true",
- tabindex: "-1"
- }).find("a, input, button, select").attr({tabindex: "-1"}), null !== e.$dots && (e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function (t) {
- var s = o.indexOf(t);
- i(this).attr({
- role: "tabpanel",
- id: "slick-slide" + e.instanceUid + t,
- tabindex: -1
- }), -1 !== s && i(this).attr({"aria-describedby": "slick-slide-control" + e.instanceUid + s})
- }), e.$dots.attr("role", "tablist").find("li").each(function (s) {
- var n = o[s];
- i(this).attr({role: "presentation"}), i(this).find("button").first().attr({
- role: "tab",
- id: "slick-slide-control" + e.instanceUid + s,
- "aria-controls": "slick-slide" + e.instanceUid + n,
- "aria-label": s + 1 + " of " + t,
- "aria-selected": null,
- tabindex: "-1"
- })
- }).eq(e.currentSlide).find("button").attr({"aria-selected": "true", tabindex: "0"}).end());
- for (var s = e.currentSlide, n = s + e.options.slidesToShow; s < n; s++) e.$slides.eq(s).attr("tabindex", 0);
- e.activateADA()
- }, e.prototype.initArrowEvents = function () {
- var i = this;
- !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.off("click.slick").on("click.slick", {message: "previous"}, i.changeSlide), i.$nextArrow.off("click.slick").on("click.slick", {message: "next"}, i.changeSlide), !0 === i.options.accessibility && (i.$prevArrow.on("keydown.slick", i.keyHandler), i.$nextArrow.on("keydown.slick", i.keyHandler)))
- }, e.prototype.initDotEvents = function () {
- var e = this;
- !0 === e.options.dots && (i("li", e.$dots).on("click.slick", {message: "index"}, e.changeSlide), !0 === e.options.accessibility && e.$dots.on("keydown.slick", e.keyHandler)), !0 === e.options.dots && !0 === e.options.pauseOnDotsHover && i("li", e.$dots).on("mouseenter.slick", i.proxy(e.interrupt, e, !0)).on("mouseleave.slick", i.proxy(e.interrupt, e, !1))
- }, e.prototype.initSlideEvents = function () {
- var e = this;
- e.options.pauseOnHover && (e.$list.on("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.on("mouseleave.slick", i.proxy(e.interrupt, e, !1)))
- }, e.prototype.initializeEvents = function () {
- var e = this;
- e.initArrowEvents(), e.initDotEvents(), e.initSlideEvents(), e.$list.on("touchstart.slick mousedown.slick", {action: "start"}, e.swipeHandler), e.$list.on("touchmove.slick mousemove.slick", {action: "move"}, e.swipeHandler), e.$list.on("touchend.slick mouseup.slick", {action: "end"}, e.swipeHandler), e.$list.on("touchcancel.slick mouseleave.slick", {action: "end"}, e.swipeHandler), e.$list.on("click.slick", e.clickHandler), i(document).on(e.visibilityChange, i.proxy(e.visibility, e)), !0 === e.options.accessibility && e.$list.on("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), i(window).on("orientationchange.slick.slick-" + e.instanceUid, i.proxy(e.orientationChange, e)), i(window).on("resize.slick.slick-" + e.instanceUid, i.proxy(e.resize, e)), i("[draggable!=true]", e.$slideTrack).on("dragstart", e.preventDefault), i(window).on("load.slick.slick-" + e.instanceUid, e.setPosition), i(e.setPosition)
- }, e.prototype.initUI = function () {
- var i = this;
- !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.show(), i.$nextArrow.show()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.show()
- }, e.prototype.keyHandler = function (i) {
- var e = this;
- i.target.tagName.match("TEXTAREA|INPUT|SELECT") || (37 === i.keyCode && !0 === e.options.accessibility ? e.changeSlide({data: {message: !0 === e.options.rtl ? "next" : "previous"}}) : 39 === i.keyCode && !0 === e.options.accessibility && e.changeSlide({data: {message: !0 === e.options.rtl ? "previous" : "next"}}))
- }, e.prototype.lazyLoad = function () {
- function e(e) {
- i("img[data-lazy]", e).each(function () {
- var e = i(this), t = i(this).attr("data-lazy"), o = i(this).attr("data-srcset"),
- s = i(this).attr("data-sizes") || n.$slider.attr("data-sizes"), r = document.createElement("img");
- r.onload = function () {
- e.animate({opacity: 0}, 100, function () {
- o && (e.attr("srcset", o), s && e.attr("sizes", s)), e.attr("src", t).animate({opacity: 1}, 200, function () {
- e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")
- }), n.$slider.trigger("lazyLoaded", [n, e, t])
- })
- }, r.onerror = function () {
- e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), n.$slider.trigger("lazyLoadError", [n, e, t])
- }, r.src = t
- })
- }
-
- var t, o, s, n = this;
- if (!0 === n.options.centerMode ? !0 === n.options.infinite ? s = (o = n.currentSlide + (n.options.slidesToShow / 2 + 1)) + n.options.slidesToShow + 2 : (o = Math.max(0, n.currentSlide - (n.options.slidesToShow / 2 + 1)), s = n.options.slidesToShow / 2 + 1 + 2 + n.currentSlide) : (o = n.options.infinite ? n.options.slidesToShow + n.currentSlide : n.currentSlide, s = Math.ceil(o + n.options.slidesToShow), !0 === n.options.fade && (o > 0 && o--, s <= n.slideCount && s++)), t = n.$slider.find(".slick-slide").slice(o, s), "anticipated" === n.options.lazyLoad) for (var r = o - 1, l = s, d = n.$slider.find(".slick-slide"), a = 0; a < n.options.slidesToScroll; a++) r < 0 && (r = n.slideCount - 1), t = (t = t.add(d.eq(r))).add(d.eq(l)), r--, l++;
- e(t), n.slideCount <= n.options.slidesToShow ? e(n.$slider.find(".slick-slide")) : n.currentSlide >= n.slideCount - n.options.slidesToShow ? e(n.$slider.find(".slick-cloned").slice(0, n.options.slidesToShow)) : 0 === n.currentSlide && e(n.$slider.find(".slick-cloned").slice(-1 * n.options.slidesToShow))
- }, e.prototype.loadSlider = function () {
- var i = this;
- i.setPosition(), i.$slideTrack.css({opacity: 1}), i.$slider.removeClass("slick-loading"), i.initUI(), "progressive" === i.options.lazyLoad && i.progressiveLazyLoad()
- }, e.prototype.next = e.prototype.slickNext = function () {
- this.changeSlide({data: {message: "next"}})
- }, e.prototype.orientationChange = function () {
- var i = this;
- i.checkResponsive(), i.setPosition()
- }, e.prototype.pause = e.prototype.slickPause = function () {
- var i = this;
- i.autoPlayClear(), i.paused = !0
- }, e.prototype.play = e.prototype.slickPlay = function () {
- var i = this;
- i.autoPlay(), i.options.autoplay = !0, i.paused = !1, i.focussed = !1, i.interrupted = !1
- }, e.prototype.postSlide = function (e) {
- var t = this;
- t.unslicked || (t.$slider.trigger("afterChange", [t, e]), t.animating = !1, t.slideCount > t.options.slidesToShow && t.setPosition(), t.swipeLeft = null, t.options.autoplay && t.autoPlay(), !0 === t.options.accessibility && (t.initADA(), t.options.focusOnChange && i(t.$slides.get(t.currentSlide)).attr("tabindex", 0).focus()))
- }, e.prototype.prev = e.prototype.slickPrev = function () {
- this.changeSlide({data: {message: "previous"}})
- }, e.prototype.preventDefault = function (i) {
- i.preventDefault()
- }, e.prototype.progressiveLazyLoad = function (e) {
- e = e || 1;
- var t, o, s, n, r, l = this, d = i("img[data-lazy]", l.$slider);
- d.length ? (t = d.first(), o = t.attr("data-lazy"), s = t.attr("data-srcset"), n = t.attr("data-sizes") || l.$slider.attr("data-sizes"), (r = document.createElement("img")).onload = function () {
- s && (t.attr("srcset", s), n && t.attr("sizes", n)), t.attr("src", o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"), !0 === l.options.adaptiveHeight && l.setPosition(), l.$slider.trigger("lazyLoaded", [l, t, o]), l.progressiveLazyLoad()
- }, r.onerror = function () {
- e < 3 ? setTimeout(function () {
- l.progressiveLazyLoad(e + 1)
- }, 500) : (t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), l.$slider.trigger("lazyLoadError", [l, t, o]), l.progressiveLazyLoad())
- }, r.src = o) : l.$slider.trigger("allImagesLoaded", [l])
- }, e.prototype.refresh = function (e) {
- var t, o, s = this;
- o = s.slideCount - s.options.slidesToShow, !s.options.infinite && s.currentSlide > o && (s.currentSlide = o), s.slideCount <= s.options.slidesToShow && (s.currentSlide = 0), t = s.currentSlide, s.destroy(!0), i.extend(s, s.initials, {currentSlide: t}), s.init(), e || s.changeSlide({
- data: {
- message: "index",
- index: t
- }
- }, !1)
- }, e.prototype.registerBreakpoints = function () {
- var e, t, o, s = this, n = s.options.responsive || null;
- if ("array" === i.type(n) && n.length) {
- s.respondTo = s.options.respondTo || "window";
- for (e in n) if (o = s.breakpoints.length - 1, n.hasOwnProperty(e)) {
- for (t = n[e].breakpoint; o >= 0;) s.breakpoints[o] && s.breakpoints[o] === t && s.breakpoints.splice(o, 1), o--;
- s.breakpoints.push(t), s.breakpointSettings[t] = n[e].settings
- }
- s.breakpoints.sort(function (i, e) {
- return s.options.mobileFirst ? i - e : e - i
- })
- }
- }, e.prototype.reinit = function () {
- var e = this;
- e.$slides = e.$slideTrack.children(e.options.slide).addClass("slick-slide"), e.slideCount = e.$slides.length, e.currentSlide >= e.slideCount && 0 !== e.currentSlide && (e.currentSlide = e.currentSlide - e.options.slidesToScroll), e.slideCount <= e.options.slidesToShow && (e.currentSlide = 0), e.registerBreakpoints(), e.setProps(), e.setupInfinite(), e.buildArrows(), e.updateArrows(), e.initArrowEvents(), e.buildDots(), e.updateDots(), e.initDotEvents(), e.cleanUpSlideEvents(), e.initSlideEvents(), e.checkResponsive(!1, !0), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), e.setPosition(), e.focusHandler(), e.paused = !e.options.autoplay, e.autoPlay(), e.$slider.trigger("reInit", [e])
- }, e.prototype.resize = function () {
- var e = this;
- i(window).width() !== e.windowWidth && (clearTimeout(e.windowDelay), e.windowDelay = window.setTimeout(function () {
- e.windowWidth = i(window).width(), e.checkResponsive(), e.unslicked || e.setPosition()
- }, 50))
- }, e.prototype.removeSlide = e.prototype.slickRemove = function (i, e, t) {
- var o = this;
- if (i = "boolean" == typeof i ? !0 === (e = i) ? 0 : o.slideCount - 1 : !0 === e ? --i : i, o.slideCount < 1 || i < 0 || i > o.slideCount - 1) return !1;
- o.unload(), !0 === t ? o.$slideTrack.children().remove() : o.$slideTrack.children(this.options.slide).eq(i).remove(), o.$slides = o.$slideTrack.children(this.options.slide), o.$slideTrack.children(this.options.slide).detach(), o.$slideTrack.append(o.$slides), o.$slidesCache = o.$slides, o.reinit()
- }, e.prototype.setCSS = function (i) {
- var e, t, o = this, s = {};
- !0 === o.options.rtl && (i = -i), e = "left" == o.positionProp ? Math.ceil(i) + "px" : "0px", t = "top" == o.positionProp ? Math.ceil(i) + "px" : "0px", s[o.positionProp] = i, !1 === o.transformsEnabled ? o.$slideTrack.css(s) : (s = {}, !1 === o.cssTransitions ? (s[o.animType] = "translate(" + e + ", " + t + ")", o.$slideTrack.css(s)) : (s[o.animType] = "translate3d(" + e + ", " + t + ", 0px)", o.$slideTrack.css(s)))
- }, e.prototype.setDimensions = function () {
- var i = this;
- !1 === i.options.vertical ? !0 === i.options.centerMode && i.$list.css({padding: "0px " + i.options.centerPadding}) : (i.$list.height(i.$slides.first().outerHeight(!0) * i.options.slidesToShow), !0 === i.options.centerMode && i.$list.css({padding: i.options.centerPadding + " 0px"})), i.listWidth = i.$list.width(), i.listHeight = i.$list.height(), !1 === i.options.vertical && !1 === i.options.variableWidth ? (i.slideWidth = Math.ceil(i.listWidth / i.options.slidesToShow), i.$slideTrack.width(Math.ceil(i.slideWidth * i.$slideTrack.children(".slick-slide").length))) : !0 === i.options.variableWidth ? i.$slideTrack.width(5e3 * i.slideCount) : (i.slideWidth = Math.ceil(i.listWidth), i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0) * i.$slideTrack.children(".slick-slide").length)));
- var e = i.$slides.first().outerWidth(!0) - i.$slides.first().width();
- !1 === i.options.variableWidth && i.$slideTrack.children(".slick-slide").width(i.slideWidth - e)
- }, e.prototype.setFade = function () {
- var e, t = this;
- t.$slides.each(function (o, s) {
- e = t.slideWidth * o * -1, !0 === t.options.rtl ? i(s).css({
- position: "relative",
- right: e,
- top: 0,
- zIndex: t.options.zIndex - 2,
- opacity: 0
- }) : i(s).css({position: "relative", left: e, top: 0, zIndex: t.options.zIndex - 2, opacity: 0})
- }), t.$slides.eq(t.currentSlide).css({zIndex: t.options.zIndex - 1, opacity: 1})
- }, e.prototype.setHeight = function () {
- var i = this;
- if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
- var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
- i.$list.css("height", e)
- }
- }, e.prototype.setOption = e.prototype.slickSetOption = function () {
- var e, t, o, s, n, r = this, l = !1;
- if ("object" === i.type(arguments[0]) ? (o = arguments[0], l = arguments[1], n = "multiple") : "string" === i.type(arguments[0]) && (o = arguments[0], s = arguments[1], l = arguments[2], "responsive" === arguments[0] && "array" === i.type(arguments[1]) ? n = "responsive" : void 0 !== arguments[1] && (n = "single")), "single" === n) r.options[o] = s; else if ("multiple" === n) i.each(o, function (i, e) {
- r.options[i] = e
- }); else if ("responsive" === n) for (t in s) if ("array" !== i.type(r.options.responsive)) r.options.responsive = [s[t]]; else {
- for (e = r.options.responsive.length - 1; e >= 0;) r.options.responsive[e].breakpoint === s[t].breakpoint && r.options.responsive.splice(e, 1), e--;
- r.options.responsive.push(s[t])
- }
- l && (r.unload(), r.reinit())
- }, e.prototype.setPosition = function () {
- var i = this;
- i.setDimensions(), i.setHeight(), !1 === i.options.fade ? i.setCSS(i.getLeft(i.currentSlide)) : i.setFade(), i.$slider.trigger("setPosition", [i])
- }, e.prototype.setProps = function () {
- var i = this, e = document.body.style;
- i.positionProp = !0 === i.options.vertical ? "top" : "left", "top" === i.positionProp ? i.$slider.addClass("slick-vertical") : i.$slider.removeClass("slick-vertical"), void 0 === e.WebkitTransition && void 0 === e.MozTransition && void 0 === e.msTransition || !0 === i.options.useCSS && (i.cssTransitions = !0), i.options.fade && ("number" == typeof i.options.zIndex ? i.options.zIndex < 3 && (i.options.zIndex = 3) : i.options.zIndex = i.defaults.zIndex), void 0 !== e.OTransform && (i.animType = "OTransform", i.transformType = "-o-transform", i.transitionType = "OTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.MozTransform && (i.animType = "MozTransform", i.transformType = "-moz-transform", i.transitionType = "MozTransition", void 0 === e.perspectiveProperty && void 0 === e.MozPerspective && (i.animType = !1)), void 0 !== e.webkitTransform && (i.animType = "webkitTransform", i.transformType = "-webkit-transform", i.transitionType = "webkitTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.msTransform && (i.animType = "msTransform", i.transformType = "-ms-transform", i.transitionType = "msTransition", void 0 === e.msTransform && (i.animType = !1)), void 0 !== e.transform && !1 !== i.animType && (i.animType = "transform", i.transformType = "transform", i.transitionType = "transition"), i.transformsEnabled = i.options.useTransform && null !== i.animType && !1 !== i.animType
- }, e.prototype.setSlideClasses = function (i) {
- var e, t, o, s, n = this;
- if (t = n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden", "true"), n.$slides.eq(i).addClass("slick-current"), !0 === n.options.centerMode) {
- var r = n.options.slidesToShow % 2 == 0 ? 1 : 0;
- e = Math.floor(n.options.slidesToShow / 2), !0 === n.options.infinite && (i >= e && i <= n.slideCount - 1 - e ? n.$slides.slice(i - e + r, i + e + 1).addClass("slick-active").attr("aria-hidden", "false") : (o = n.options.slidesToShow + i, t.slice(o - e + 1 + r, o + e + 2).addClass("slick-active").attr("aria-hidden", "false")), 0 === i ? t.eq(t.length - 1 - n.options.slidesToShow).addClass("slick-center") : i === n.slideCount - 1 && t.eq(n.options.slidesToShow).addClass("slick-center")), n.$slides.eq(i).addClass("slick-center")
- } else i >= 0 && i <= n.slideCount - n.options.slidesToShow ? n.$slides.slice(i, i + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false") : t.length <= n.options.slidesToShow ? t.addClass("slick-active").attr("aria-hidden", "false") : (s = n.slideCount % n.options.slidesToShow, o = !0 === n.options.infinite ? n.options.slidesToShow + i : i, n.options.slidesToShow == n.options.slidesToScroll && n.slideCount - i < n.options.slidesToShow ? t.slice(o - (n.options.slidesToShow - s), o + s).addClass("slick-active").attr("aria-hidden", "false") : t.slice(o, o + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false"));
- "ondemand" !== n.options.lazyLoad && "anticipated" !== n.options.lazyLoad || n.lazyLoad()
- }, e.prototype.setupInfinite = function () {
- var e, t, o, s = this;
- if (!0 === s.options.fade && (s.options.centerMode = !1), !0 === s.options.infinite && !1 === s.options.fade && (t = null, s.slideCount > s.options.slidesToShow)) {
- for (o = !0 === s.options.centerMode ? s.options.slidesToShow + 1 : s.options.slidesToShow, e = s.slideCount; e > s.slideCount - o; e -= 1) t = e - 1, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t - s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");
- for (e = 0; e < o + s.slideCount; e += 1) t = e, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t + s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");
- s.$slideTrack.find(".slick-cloned").find("[id]").each(function () {
- i(this).attr("id", "")
- })
- }
- }, e.prototype.interrupt = function (i) {
- var e = this;
- i || e.autoPlay(), e.interrupted = i
- }, e.prototype.selectHandler = function (e) {
- var t = this, o = i(e.target).is(".slick-slide") ? i(e.target) : i(e.target).parents(".slick-slide"),
- s = parseInt(o.attr("data-slick-index"));
- s || (s = 0), t.slideCount <= t.options.slidesToShow ? t.slideHandler(s, !1, !0) : t.slideHandler(s)
- }, e.prototype.slideHandler = function (i, e, t) {
- var o, s, n, r, l, d = null, a = this;
- if (e = e || !1, !(!0 === a.animating && !0 === a.options.waitForAnimate || !0 === a.options.fade && a.currentSlide === i)) if (!1 === e && a.asNavFor(i), o = i, d = a.getLeft(o), r = a.getLeft(a.currentSlide), a.currentLeft = null === a.swipeLeft ? r : a.swipeLeft, !1 === a.options.infinite && !1 === a.options.centerMode && (i < 0 || i > a.getDotCount() * a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
- a.postSlide(o)
- }) : a.postSlide(o)); else if (!1 === a.options.infinite && !0 === a.options.centerMode && (i < 0 || i > a.slideCount - a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
- a.postSlide(o)
- }) : a.postSlide(o)); else {
- if (a.options.autoplay && clearInterval(a.autoPlayTimer), s = o < 0 ? a.slideCount % a.options.slidesToScroll != 0 ? a.slideCount - a.slideCount % a.options.slidesToScroll : a.slideCount + o : o >= a.slideCount ? a.slideCount % a.options.slidesToScroll != 0 ? 0 : o - a.slideCount : o, a.animating = !0, a.$slider.trigger("beforeChange", [a, a.currentSlide, s]), n = a.currentSlide, a.currentSlide = s, a.setSlideClasses(a.currentSlide), a.options.asNavFor && (l = (l = a.getNavTarget()).slick("getSlick")).slideCount <= l.options.slidesToShow && l.setSlideClasses(a.currentSlide), a.updateDots(), a.updateArrows(), !0 === a.options.fade) return !0 !== t ? (a.fadeSlideOut(n), a.fadeSlide(s, function () {
- a.postSlide(s)
- })) : a.postSlide(s), void a.animateHeight();
- !0 !== t ? a.animateSlide(d, function () {
- a.postSlide(s)
- }) : a.postSlide(s)
- }
- }, e.prototype.startLoad = function () {
- var i = this;
- !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.hide(), i.$nextArrow.hide()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.hide(), i.$slider.addClass("slick-loading")
- }, e.prototype.swipeDirection = function () {
- var i, e, t, o, s = this;
- return i = s.touchObject.startX - s.touchObject.curX, e = s.touchObject.startY - s.touchObject.curY, t = Math.atan2(e, i), (o = Math.round(180 * t / Math.PI)) < 0 && (o = 360 - Math.abs(o)), o <= 45 && o >= 0 ? !1 === s.options.rtl ? "left" : "right" : o <= 360 && o >= 315 ? !1 === s.options.rtl ? "left" : "right" : o >= 135 && o <= 225 ? !1 === s.options.rtl ? "right" : "left" : !0 === s.options.verticalSwiping ? o >= 35 && o <= 135 ? "down" : "up" : "vertical"
- }, e.prototype.swipeEnd = function (i) {
- var e, t, o = this;
- if (o.dragging = !1, o.swiping = !1, o.scrolling) return o.scrolling = !1, !1;
- if (o.interrupted = !1, o.shouldClick = !(o.touchObject.swipeLength > 10), void 0 === o.touchObject.curX) return !1;
- if (!0 === o.touchObject.edgeHit && o.$slider.trigger("edge", [o, o.swipeDirection()]), o.touchObject.swipeLength >= o.touchObject.minSwipe) {
- switch (t = o.swipeDirection()) {
- case"left":
- case"down":
- e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide + o.getSlideCount()) : o.currentSlide + o.getSlideCount(), o.currentDirection = 0;
- break;
- case"right":
- case"up":
- e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide - o.getSlideCount()) : o.currentSlide - o.getSlideCount(), o.currentDirection = 1
- }
- "vertical" != t && (o.slideHandler(e), o.touchObject = {}, o.$slider.trigger("swipe", [o, t]))
- } else o.touchObject.startX !== o.touchObject.curX && (o.slideHandler(o.currentSlide), o.touchObject = {})
- }, e.prototype.swipeHandler = function (i) {
- var e = this;
- if (!(!1 === e.options.swipe || "ontouchend" in document && !1 === e.options.swipe || !1 === e.options.draggable && -1 !== i.type.indexOf("mouse"))) switch (e.touchObject.fingerCount = i.originalEvent && void 0 !== i.originalEvent.touches ? i.originalEvent.touches.length : 1, e.touchObject.minSwipe = e.listWidth / e.options.touchThreshold, !0 === e.options.verticalSwiping && (e.touchObject.minSwipe = e.listHeight / e.options.touchThreshold), i.data.action) {
- case"start":
- e.swipeStart(i);
- break;
- case"move":
- e.swipeMove(i);
- break;
- case"end":
- e.swipeEnd(i)
- }
- }, e.prototype.swipeMove = function (i) {
- var e, t, o, s, n, r, l = this;
- return n = void 0 !== i.originalEvent ? i.originalEvent.touches : null, !(!l.dragging || l.scrolling || n && 1 !== n.length) && (e = l.getLeft(l.currentSlide), l.touchObject.curX = void 0 !== n ? n[0].pageX : i.clientX, l.touchObject.curY = void 0 !== n ? n[0].pageY : i.clientY, l.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(l.touchObject.curX - l.touchObject.startX, 2))), r = Math.round(Math.sqrt(Math.pow(l.touchObject.curY - l.touchObject.startY, 2))), !l.options.verticalSwiping && !l.swiping && r > 4 ? (l.scrolling = !0, !1) : (!0 === l.options.verticalSwiping && (l.touchObject.swipeLength = r), t = l.swipeDirection(), void 0 !== i.originalEvent && l.touchObject.swipeLength > 4 && (l.swiping = !0, i.preventDefault()), s = (!1 === l.options.rtl ? 1 : -1) * (l.touchObject.curX > l.touchObject.startX ? 1 : -1), !0 === l.options.verticalSwiping && (s = l.touchObject.curY > l.touchObject.startY ? 1 : -1), o = l.touchObject.swipeLength, l.touchObject.edgeHit = !1, !1 === l.options.infinite && (0 === l.currentSlide && "right" === t || l.currentSlide >= l.getDotCount() && "left" === t) && (o = l.touchObject.swipeLength * l.options.edgeFriction, l.touchObject.edgeHit = !0), !1 === l.options.vertical ? l.swipeLeft = e + o * s : l.swipeLeft = e + o * (l.$list.height() / l.listWidth) * s, !0 === l.options.verticalSwiping && (l.swipeLeft = e + o * s), !0 !== l.options.fade && !1 !== l.options.touchMove && (!0 === l.animating ? (l.swipeLeft = null, !1) : void l.setCSS(l.swipeLeft))))
- }, e.prototype.swipeStart = function (i) {
- var e, t = this;
- if (t.interrupted = !0, 1 !== t.touchObject.fingerCount || t.slideCount <= t.options.slidesToShow) return t.touchObject = {}, !1;
- void 0 !== i.originalEvent && void 0 !== i.originalEvent.touches && (e = i.originalEvent.touches[0]), t.touchObject.startX = t.touchObject.curX = void 0 !== e ? e.pageX : i.clientX, t.touchObject.startY = t.touchObject.curY = void 0 !== e ? e.pageY : i.clientY, t.dragging = !0
- }, e.prototype.unfilterSlides = e.prototype.slickUnfilter = function () {
- var i = this;
- null !== i.$slidesCache && (i.unload(), i.$slideTrack.children(this.options.slide).detach(), i.$slidesCache.appendTo(i.$slideTrack), i.reinit())
- }, e.prototype.unload = function () {
- var e = this;
- i(".slick-cloned", e.$slider).remove(), e.$dots && e.$dots.remove(), e.$prevArrow && e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.remove(), e.$nextArrow && e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.remove(), e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden", "true").css("width", "")
- }, e.prototype.unslick = function (i) {
- var e = this;
- e.$slider.trigger("unslick", [e, i]), e.destroy()
- }, e.prototype.updateArrows = function () {
- var i = this;
- Math.floor(i.options.slidesToShow / 2), !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && !i.options.infinite && (i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), 0 === i.currentSlide ? (i.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - i.options.slidesToShow && !1 === i.options.centerMode ? (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - 1 && !0 === i.options.centerMode && (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")))
- }, e.prototype.updateDots = function () {
- var i = this;
- null !== i.$dots && (i.$dots.find("li").removeClass("slick-active").end(), i.$dots.find("li").eq(Math.floor(i.currentSlide / i.options.slidesToScroll)).addClass("slick-active"))
- }, e.prototype.visibility = function () {
- var i = this;
- i.options.autoplay && (document[i.hidden] ? i.interrupted = !0 : i.interrupted = !1)
- }, i.fn.slick = function () {
- var i, t, o = this, s = arguments[0], n = Array.prototype.slice.call(arguments, 1), r = o.length;
- for (i = 0; i < r; i++) if ("object" == typeof s || void 0 === s ? o[i].slick = new e(o[i], s) : t = o[i].slick[s].apply(o[i].slick, n), void 0 !== t) return t;
- return o
- }
+!function (i) {
+ "use strict";
+ "function" == typeof define && define.amd ? define(["jquery"], i) : "undefined" != typeof exports ? module.exports = i(require("jquery")) : i(jQuery)
+}(function (i) {
+ "use strict";
+ var e = window.Slick || {};
+ (e = function () {
+ var e = 0;
+ return function (t, o) {
+ var s, n = this;
+ n.defaults = {
+ accessibility: !0,
+ adaptiveHeight: !1,
+ appendArrows: i(t),
+ appendDots: i(t),
+ arrows: !0,
+ asNavFor: null,
+ prevArrow: '
',
+ nextArrow: '
',
+ autoplay: !1,
+ autoplaySpeed: 3e3,
+ centerMode: !1,
+ centerPadding: "50px",
+ cssEase: "ease",
+ customPaging: function (e, t) {
+ return i('
').text(t + 1)
+ },
+ dots: !1,
+ dotsClass: "slick-dots",
+ draggable: !0,
+ easing: "linear",
+ edgeFriction: .35,
+ fade: !1,
+ focusOnSelect: !1,
+ focusOnChange: !1,
+ infinite: !0,
+ initialSlide: 0,
+ lazyLoad: "ondemand",
+ mobileFirst: !1,
+ pauseOnHover: !0,
+ pauseOnFocus: !0,
+ pauseOnDotsHover: !1,
+ respondTo: "window",
+ responsive: null,
+ rows: 1,
+ rtl: !1,
+ slide: "",
+ slidesPerRow: 1,
+ slidesToShow: 1,
+ slidesToScroll: 1,
+ speed: 500,
+ swipe: !0,
+ swipeToSlide: !1,
+ touchMove: !0,
+ touchThreshold: 5,
+ useCSS: !0,
+ useTransform: !0,
+ variableWidth: !1,
+ vertical: !1,
+ verticalSwiping: !1,
+ waitForAnimate: !0,
+ zIndex: 1e3
+ }, n.initials = {
+ animating: !1,
+ dragging: !1,
+ autoPlayTimer: null,
+ currentDirection: 0,
+ currentLeft: null,
+ currentSlide: 0,
+ direction: 1,
+ $dots: null,
+ listWidth: null,
+ listHeight: null,
+ loadIndex: 0,
+ $nextArrow: null,
+ $prevArrow: null,
+ scrolling: !1,
+ slideCount: null,
+ slideWidth: null,
+ $slideTrack: null,
+ $slides: null,
+ sliding: !1,
+ slideOffset: 0,
+ swipeLeft: null,
+ swiping: !1,
+ $list: null,
+ touchObject: {},
+ transformsEnabled: !1,
+ unslicked: !1
+ }, i.extend(n, n.initials), n.activeBreakpoint = null, n.animType = null, n.animProp = null, n.breakpoints = [], n.breakpointSettings = [], n.cssTransitions = !1, n.focussed = !1, n.interrupted = !1, n.hidden = "hidden", n.paused = !0, n.positionProp = null, n.respondTo = null, n.rowCount = 1, n.shouldClick = !0, n.$slider = i(t), n.$slidesCache = null, n.transformType = null, n.transitionType = null, n.visibilityChange = "visibilitychange", n.windowWidth = 0, n.windowTimer = null, s = i(t).data("slick") || {}, n.options = i.extend({}, n.defaults, o, s), n.currentSlide = n.options.initialSlide, n.originalSettings = n.options, void 0 !== document.mozHidden ? (n.hidden = "mozHidden", n.visibilityChange = "mozvisibilitychange") : void 0 !== document.webkitHidden && (n.hidden = "webkitHidden", n.visibilityChange = "webkitvisibilitychange"), n.autoPlay = i.proxy(n.autoPlay, n), n.autoPlayClear = i.proxy(n.autoPlayClear, n), n.autoPlayIterator = i.proxy(n.autoPlayIterator, n), n.changeSlide = i.proxy(n.changeSlide, n), n.clickHandler = i.proxy(n.clickHandler, n), n.selectHandler = i.proxy(n.selectHandler, n), n.setPosition = i.proxy(n.setPosition, n), n.swipeHandler = i.proxy(n.swipeHandler, n), n.dragHandler = i.proxy(n.dragHandler, n), n.keyHandler = i.proxy(n.keyHandler, n), n.instanceUid = e++, n.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/, n.registerBreakpoints(), n.init(!0)
+ }
+ }()).prototype.activateADA = function () {
+ this.$slideTrack.find(".slick-active").attr({"aria-hidden": "false"}).find("a, input, button, select").attr({tabindex: "0"})
+ }, e.prototype.addSlide = e.prototype.slickAdd = function (e, t, o) {
+ var s = this;
+ if ("boolean" == typeof t) o = t, t = null; else if (t < 0 || t >= s.slideCount) return !1;
+ s.unload(), "number" == typeof t ? 0 === t && 0 === s.$slides.length ? i(e).appendTo(s.$slideTrack) : o ? i(e).insertBefore(s.$slides.eq(t)) : i(e).insertAfter(s.$slides.eq(t)) : !0 === o ? i(e).prependTo(s.$slideTrack) : i(e).appendTo(s.$slideTrack), s.$slides = s.$slideTrack.children(this.options.slide), s.$slideTrack.children(this.options.slide).detach(), s.$slideTrack.append(s.$slides), s.$slides.each(function (e, t) {
+ i(t).attr("data-slick-index", e)
+ }), s.$slidesCache = s.$slides, s.reinit()
+ }, e.prototype.animateHeight = function () {
+ var i = this;
+ if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
+ var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
+ i.$list.animate({height: e}, i.options.speed)
+ }
+ }, e.prototype.animateSlide = function (e, t) {
+ var o = {}, s = this;
+ s.animateHeight(), !0 === s.options.rtl && !1 === s.options.vertical && (e = -e), !1 === s.transformsEnabled ? !1 === s.options.vertical ? s.$slideTrack.animate({left: e}, s.options.speed, s.options.easing, t) : s.$slideTrack.animate({top: e}, s.options.speed, s.options.easing, t) : !1 === s.cssTransitions ? (!0 === s.options.rtl && (s.currentLeft = -s.currentLeft), i({animStart: s.currentLeft}).animate({animStart: e}, {
+ duration: s.options.speed,
+ easing: s.options.easing,
+ step: function (i) {
+ i = Math.ceil(i), !1 === s.options.vertical ? (o[s.animType] = "translate(" + i + "px, 0px)", s.$slideTrack.css(o)) : (o[s.animType] = "translate(0px," + i + "px)", s.$slideTrack.css(o))
+ },
+ complete: function () {
+ t && t.call()
+ }
+ })) : (s.applyTransition(), e = Math.ceil(e), !1 === s.options.vertical ? o[s.animType] = "translate3d(" + e + "px, 0px, 0px)" : o[s.animType] = "translate3d(0px," + e + "px, 0px)", s.$slideTrack.css(o), t && setTimeout(function () {
+ s.disableTransition(), t.call()
+ }, s.options.speed))
+ }, e.prototype.getNavTarget = function () {
+ var e = this, t = e.options.asNavFor;
+ return t && null !== t && (t = i(t).not(e.$slider)), t
+ }, e.prototype.asNavFor = function (e) {
+ var t = this.getNavTarget();
+ null !== t && "object" == typeof t && t.each(function () {
+ var t = i(this).slick("getSlick");
+ t.unslicked || t.slideHandler(e, !0)
+ })
+ }, e.prototype.applyTransition = function (i) {
+ var e = this, t = {};
+ !1 === e.options.fade ? t[e.transitionType] = e.transformType + " " + e.options.speed + "ms " + e.options.cssEase : t[e.transitionType] = "opacity " + e.options.speed + "ms " + e.options.cssEase, !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
+ }, e.prototype.autoPlay = function () {
+ var i = this;
+ i.autoPlayClear(), i.slideCount > i.options.slidesToShow && (i.autoPlayTimer = setInterval(i.autoPlayIterator, i.options.autoplaySpeed))
+ }, e.prototype.autoPlayClear = function () {
+ var i = this;
+ i.autoPlayTimer && clearInterval(i.autoPlayTimer)
+ }, e.prototype.autoPlayIterator = function () {
+ var i = this, e = i.currentSlide + i.options.slidesToScroll;
+ i.paused || i.interrupted || i.focussed || (!1 === i.options.infinite && (1 === i.direction && i.currentSlide + 1 === i.slideCount - 1 ? i.direction = 0 : 0 === i.direction && (e = i.currentSlide - i.options.slidesToScroll, i.currentSlide - 1 == 0 && (i.direction = 1))), i.slideHandler(e))
+ }, e.prototype.buildArrows = function () {
+ var e = this;
+ !0 === e.options.arrows && (e.$prevArrow = i(e.options.prevArrow).addClass("slick-arrow"), e.$nextArrow = i(e.options.nextArrow).addClass("slick-arrow"), e.slideCount > e.options.slidesToShow ? (e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"), e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.prependTo(e.options.appendArrows), e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.appendTo(e.options.appendArrows), !0 !== e.options.infinite && e.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true")) : e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({
+ "aria-disabled": "true",
+ tabindex: "-1"
+ }))
+ }, e.prototype.buildDots = function () {
+ var e, t, o = this;
+ if (!0 === o.options.dots) {
+ for (o.$slider.addClass("slick-dotted"), t = i("
").addClass(o.options.dotsClass), e = 0; e <= o.getDotCount(); e += 1) t.append(i("
").append(o.options.customPaging.call(this, o, e)));
+ o.$dots = t.appendTo(o.options.appendDots), o.$dots.find("li").first().addClass("slick-active")
+ }
+ }, e.prototype.buildOut = function () {
+ var e = this;
+ e.$slides = e.$slider.children(e.options.slide + ":not(.slick-cloned)").addClass("slick-slide"), e.slideCount = e.$slides.length, e.$slides.each(function (e, t) {
+ i(t).attr("data-slick-index", e).data("originalStyling", i(t).attr("style") || "")
+ }), e.$slider.addClass("slick-slider"), e.$slideTrack = 0 === e.slideCount ? i('
').appendTo(e.$slider) : e.$slides.wrapAll('
').parent(), e.$list = e.$slideTrack.wrap('
').parent(), e.$slideTrack.css("opacity", 0), !0 !== e.options.centerMode && !0 !== e.options.swipeToSlide || (e.options.slidesToScroll = 1), i("img[data-lazy]", e.$slider).not("[src]").addClass("slick-loading"), e.setupInfinite(), e.buildArrows(), e.buildDots(), e.updateDots(), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), !0 === e.options.draggable && e.$list.addClass("draggable")
+ }, e.prototype.buildRows = function () {
+ var i, e, t, o, s, n, r, l = this;
+ if (o = document.createDocumentFragment(), n = l.$slider.children(), l.options.rows > 1) {
+ for (r = l.options.slidesPerRow * l.options.rows, s = Math.ceil(n.length / r), i = 0; i < s; i++) {
+ var d = document.createElement("div");
+ for (e = 0; e < l.options.rows; e++) {
+ var a = document.createElement("div");
+ for (t = 0; t < l.options.slidesPerRow; t++) {
+ var c = i * r + (e * l.options.slidesPerRow + t);
+ n.get(c) && a.appendChild(n.get(c))
+ }
+ d.appendChild(a)
+ }
+ o.appendChild(d)
+ }
+ l.$slider.empty().append(o), l.$slider.children().children().children().css({
+ width: 100 / l.options.slidesPerRow + "%",
+ display: "inline-block"
+ })
+ }
+ }, e.prototype.checkResponsive = function (e, t) {
+ var o, s, n, r = this, l = !1, d = r.$slider.width(), a = window.innerWidth || i(window).width();
+ if ("window" === r.respondTo ? n = a : "slider" === r.respondTo ? n = d : "min" === r.respondTo && (n = Math.min(a, d)), r.options.responsive && r.options.responsive.length && null !== r.options.responsive) {
+ s = null;
+ for (o in r.breakpoints) r.breakpoints.hasOwnProperty(o) && (!1 === r.originalSettings.mobileFirst ? n < r.breakpoints[o] && (s = r.breakpoints[o]) : n > r.breakpoints[o] && (s = r.breakpoints[o]));
+ null !== s ? null !== r.activeBreakpoint ? (s !== r.activeBreakpoint || t) && (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : (r.activeBreakpoint = s, "unslick" === r.breakpointSettings[s] ? r.unslick(s) : (r.options = i.extend({}, r.originalSettings, r.breakpointSettings[s]), !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e)), l = s) : null !== r.activeBreakpoint && (r.activeBreakpoint = null, r.options = r.originalSettings, !0 === e && (r.currentSlide = r.options.initialSlide), r.refresh(e), l = s), e || !1 === l || r.$slider.trigger("breakpoint", [r, l])
+ }
+ }, e.prototype.changeSlide = function (e, t) {
+ var o, s, n, r = this, l = i(e.currentTarget);
+ switch (l.is("a") && e.preventDefault(), l.is("li") || (l = l.closest("li")), n = r.slideCount % r.options.slidesToScroll != 0, o = n ? 0 : (r.slideCount - r.currentSlide) % r.options.slidesToScroll, e.data.message) {
+ case"previous":
+ s = 0 === o ? r.options.slidesToScroll : r.options.slidesToShow - o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide - s, !1, t);
+ break;
+ case"next":
+ s = 0 === o ? r.options.slidesToScroll : o, r.slideCount > r.options.slidesToShow && r.slideHandler(r.currentSlide + s, !1, t);
+ break;
+ case"index":
+ var d = 0 === e.data.index ? 0 : e.data.index || l.index() * r.options.slidesToScroll;
+ r.slideHandler(r.checkNavigable(d), !1, t), l.children().trigger("focus");
+ break;
+ default:
+ return
+ }
+ }, e.prototype.checkNavigable = function (i) {
+ var e, t;
+ if (e = this.getNavigableIndexes(), t = 0, i > e[e.length - 1]) i = e[e.length - 1]; else for (var o in e) {
+ if (i < e[o]) {
+ i = t;
+ break
+ }
+ t = e[o]
+ }
+ return i
+ }, e.prototype.cleanUpEvents = function () {
+ var e = this;
+ e.options.dots && null !== e.$dots && (i("li", e.$dots).off("click.slick", e.changeSlide).off("mouseenter.slick", i.proxy(e.interrupt, e, !0)).off("mouseleave.slick", i.proxy(e.interrupt, e, !1)), !0 === e.options.accessibility && e.$dots.off("keydown.slick", e.keyHandler)), e.$slider.off("focus.slick blur.slick"), !0 === e.options.arrows && e.slideCount > e.options.slidesToShow && (e.$prevArrow && e.$prevArrow.off("click.slick", e.changeSlide), e.$nextArrow && e.$nextArrow.off("click.slick", e.changeSlide), !0 === e.options.accessibility && (e.$prevArrow && e.$prevArrow.off("keydown.slick", e.keyHandler), e.$nextArrow && e.$nextArrow.off("keydown.slick", e.keyHandler))), e.$list.off("touchstart.slick mousedown.slick", e.swipeHandler), e.$list.off("touchmove.slick mousemove.slick", e.swipeHandler), e.$list.off("touchend.slick mouseup.slick", e.swipeHandler), e.$list.off("touchcancel.slick mouseleave.slick", e.swipeHandler), e.$list.off("click.slick", e.clickHandler), i(document).off(e.visibilityChange, e.visibility), e.cleanUpSlideEvents(), !0 === e.options.accessibility && e.$list.off("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().off("click.slick", e.selectHandler), i(window).off("orientationchange.slick.slick-" + e.instanceUid, e.orientationChange), i(window).off("resize.slick.slick-" + e.instanceUid, e.resize), i("[draggable!=true]", e.$slideTrack).off("dragstart", e.preventDefault), i(window).off("load.slick.slick-" + e.instanceUid, e.setPosition)
+ }, e.prototype.cleanUpSlideEvents = function () {
+ var e = this;
+ e.$list.off("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.off("mouseleave.slick", i.proxy(e.interrupt, e, !1))
+ }, e.prototype.cleanUpRows = function () {
+ var i, e = this;
+ e.options.rows > 1 && ((i = e.$slides.children().children()).removeAttr("style"), e.$slider.empty().append(i))
+ }, e.prototype.clickHandler = function (i) {
+ !1 === this.shouldClick && (i.stopImmediatePropagation(), i.stopPropagation(), i.preventDefault())
+ }, e.prototype.destroy = function (e) {
+ var t = this;
+ t.autoPlayClear(), t.touchObject = {}, t.cleanUpEvents(), i(".slick-cloned", t.$slider).detach(), t.$dots && t.$dots.remove(), t.$prevArrow && t.$prevArrow.length && (t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.prevArrow) && t.$prevArrow.remove()), t.$nextArrow && t.$nextArrow.length && (t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display", ""), t.htmlExpr.test(t.options.nextArrow) && t.$nextArrow.remove()), t.$slides && (t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function () {
+ i(this).attr("style", i(this).data("originalStyling"))
+ }), t.$slideTrack.children(this.options.slide).detach(), t.$slideTrack.detach(), t.$list.detach(), t.$slider.append(t.$slides)), t.cleanUpRows(), t.$slider.removeClass("slick-slider"), t.$slider.removeClass("slick-initialized"), t.$slider.removeClass("slick-dotted"), t.unslicked = !0, e || t.$slider.trigger("destroy", [t])
+ }, e.prototype.disableTransition = function (i) {
+ var e = this, t = {};
+ t[e.transitionType] = "", !1 === e.options.fade ? e.$slideTrack.css(t) : e.$slides.eq(i).css(t)
+ }, e.prototype.fadeSlide = function (i, e) {
+ var t = this;
+ !1 === t.cssTransitions ? (t.$slides.eq(i).css({zIndex: t.options.zIndex}), t.$slides.eq(i).animate({opacity: 1}, t.options.speed, t.options.easing, e)) : (t.applyTransition(i), t.$slides.eq(i).css({
+ opacity: 1,
+ zIndex: t.options.zIndex
+ }), e && setTimeout(function () {
+ t.disableTransition(i), e.call()
+ }, t.options.speed))
+ }, e.prototype.fadeSlideOut = function (i) {
+ var e = this;
+ !1 === e.cssTransitions ? e.$slides.eq(i).animate({
+ opacity: 0,
+ zIndex: e.options.zIndex - 2
+ }, e.options.speed, e.options.easing) : (e.applyTransition(i), e.$slides.eq(i).css({
+ opacity: 0,
+ zIndex: e.options.zIndex - 2
+ }))
+ }, e.prototype.filterSlides = e.prototype.slickFilter = function (i) {
+ var e = this;
+ null !== i && (e.$slidesCache = e.$slides, e.unload(), e.$slideTrack.children(this.options.slide).detach(), e.$slidesCache.filter(i).appendTo(e.$slideTrack), e.reinit())
+ }, e.prototype.focusHandler = function () {
+ var e = this;
+ e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick", "*", function (t) {
+ t.stopImmediatePropagation();
+ var o = i(this);
+ setTimeout(function () {
+ e.options.pauseOnFocus && (e.focussed = o.is(":focus"), e.autoPlay())
+ }, 0)
+ })
+ }, e.prototype.getCurrent = e.prototype.slickCurrentSlide = function () {
+ return this.currentSlide
+ }, e.prototype.getDotCount = function () {
+ var i = this, e = 0, t = 0, o = 0;
+ if (!0 === i.options.infinite) if (i.slideCount <= i.options.slidesToShow) ++o; else for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else if (!0 === i.options.centerMode) o = i.slideCount; else if (i.options.asNavFor) for (; e < i.slideCount;) ++o, e = t + i.options.slidesToScroll, t += i.options.slidesToScroll <= i.options.slidesToShow ? i.options.slidesToScroll : i.options.slidesToShow; else o = 1 + Math.ceil((i.slideCount - i.options.slidesToShow) / i.options.slidesToScroll);
+ return o - 1
+ }, e.prototype.getLeft = function (i) {
+ var e, t, o, s, n = this, r = 0;
+ return n.slideOffset = 0, t = n.$slides.first().outerHeight(!0), !0 === n.options.infinite ? (n.slideCount > n.options.slidesToShow && (n.slideOffset = n.slideWidth * n.options.slidesToShow * -1, s = -1, !0 === n.options.vertical && !0 === n.options.centerMode && (2 === n.options.slidesToShow ? s = -1.5 : 1 === n.options.slidesToShow && (s = -2)), r = t * n.options.slidesToShow * s), n.slideCount % n.options.slidesToScroll != 0 && i + n.options.slidesToScroll > n.slideCount && n.slideCount > n.options.slidesToShow && (i > n.slideCount ? (n.slideOffset = (n.options.slidesToShow - (i - n.slideCount)) * n.slideWidth * -1, r = (n.options.slidesToShow - (i - n.slideCount)) * t * -1) : (n.slideOffset = n.slideCount % n.options.slidesToScroll * n.slideWidth * -1, r = n.slideCount % n.options.slidesToScroll * t * -1))) : i + n.options.slidesToShow > n.slideCount && (n.slideOffset = (i + n.options.slidesToShow - n.slideCount) * n.slideWidth, r = (i + n.options.slidesToShow - n.slideCount) * t), n.slideCount <= n.options.slidesToShow && (n.slideOffset = 0, r = 0), !0 === n.options.centerMode && n.slideCount <= n.options.slidesToShow ? n.slideOffset = n.slideWidth * Math.floor(n.options.slidesToShow) / 2 - n.slideWidth * n.slideCount / 2 : !0 === n.options.centerMode && !0 === n.options.infinite ? n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2) - n.slideWidth : !0 === n.options.centerMode && (n.slideOffset = 0, n.slideOffset += n.slideWidth * Math.floor(n.options.slidesToShow / 2)), e = !1 === n.options.vertical ? i * n.slideWidth * -1 + n.slideOffset : i * t * -1 + r, !0 === n.options.variableWidth && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, !0 === n.options.centerMode && (o = n.slideCount <= n.options.slidesToShow || !1 === n.options.infinite ? n.$slideTrack.children(".slick-slide").eq(i) : n.$slideTrack.children(".slick-slide").eq(i + n.options.slidesToShow + 1), e = !0 === n.options.rtl ? o[0] ? -1 * (n.$slideTrack.width() - o[0].offsetLeft - o.width()) : 0 : o[0] ? -1 * o[0].offsetLeft : 0, e += (n.$list.width() - o.outerWidth()) / 2)), e
+ }, e.prototype.getOption = e.prototype.slickGetOption = function (i) {
+ return this.options[i]
+ }, e.prototype.getNavigableIndexes = function () {
+ var i, e = this, t = 0, o = 0, s = [];
+ for (!1 === e.options.infinite ? i = e.slideCount : (t = -1 * e.options.slidesToScroll, o = -1 * e.options.slidesToScroll, i = 2 * e.slideCount); t < i;) s.push(t), t = o + e.options.slidesToScroll, o += e.options.slidesToScroll <= e.options.slidesToShow ? e.options.slidesToScroll : e.options.slidesToShow;
+ return s
+ }, e.prototype.getSlick = function () {
+ return this
+ }, e.prototype.getSlideCount = function () {
+ var e, t, o = this;
+ return t = !0 === o.options.centerMode ? o.slideWidth * Math.floor(o.options.slidesToShow / 2) : 0, !0 === o.options.swipeToSlide ? (o.$slideTrack.find(".slick-slide").each(function (s, n) {
+ if (n.offsetLeft - t + i(n).outerWidth() / 2 > -1 * o.swipeLeft) return e = n, !1
+ }), Math.abs(i(e).attr("data-slick-index") - o.currentSlide) || 1) : o.options.slidesToScroll
+ }, e.prototype.goTo = e.prototype.slickGoTo = function (i, e) {
+ this.changeSlide({data: {message: "index", index: parseInt(i)}}, e)
+ }, e.prototype.init = function (e) {
+ var t = this;
+ i(t.$slider).hasClass("slick-initialized") || (i(t.$slider).addClass("slick-initialized"), t.buildRows(), t.buildOut(), t.setProps(), t.startLoad(), t.loadSlider(), t.initializeEvents(), t.updateArrows(), t.updateDots(), t.checkResponsive(!0), t.focusHandler()), e && t.$slider.trigger("init", [t]), !0 === t.options.accessibility && t.initADA(), t.options.autoplay && (t.paused = !1, t.autoPlay())
+ }, e.prototype.initADA = function () {
+ var e = this, t = Math.ceil(e.slideCount / e.options.slidesToShow),
+ o = e.getNavigableIndexes().filter(function (i) {
+ return i >= 0 && i < e.slideCount
+ });
+ e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({
+ "aria-hidden": "true",
+ tabindex: "-1"
+ }).find("a, input, button, select").attr({tabindex: "-1"}), null !== e.$dots && (e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function (t) {
+ var s = o.indexOf(t);
+ i(this).attr({
+ role: "tabpanel",
+ id: "slick-slide" + e.instanceUid + t,
+ tabindex: -1
+ }), -1 !== s && i(this).attr({"aria-describedby": "slick-slide-control" + e.instanceUid + s})
+ }), e.$dots.attr("role", "tablist").find("li").each(function (s) {
+ var n = o[s];
+ i(this).attr({role: "presentation"}), i(this).find("button").first().attr({
+ role: "tab",
+ id: "slick-slide-control" + e.instanceUid + s,
+ "aria-controls": "slick-slide" + e.instanceUid + n,
+ "aria-label": s + 1 + " of " + t,
+ "aria-selected": null,
+ tabindex: "-1"
+ })
+ }).eq(e.currentSlide).find("button").attr({"aria-selected": "true", tabindex: "0"}).end());
+ for (var s = e.currentSlide, n = s + e.options.slidesToShow; s < n; s++) e.$slides.eq(s).attr("tabindex", 0);
+ e.activateADA()
+ }, e.prototype.initArrowEvents = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.off("click.slick").on("click.slick", {message: "previous"}, i.changeSlide), i.$nextArrow.off("click.slick").on("click.slick", {message: "next"}, i.changeSlide), !0 === i.options.accessibility && (i.$prevArrow.on("keydown.slick", i.keyHandler), i.$nextArrow.on("keydown.slick", i.keyHandler)))
+ }, e.prototype.initDotEvents = function () {
+ var e = this;
+ !0 === e.options.dots && (i("li", e.$dots).on("click.slick", {message: "index"}, e.changeSlide), !0 === e.options.accessibility && e.$dots.on("keydown.slick", e.keyHandler)), !0 === e.options.dots && !0 === e.options.pauseOnDotsHover && i("li", e.$dots).on("mouseenter.slick", i.proxy(e.interrupt, e, !0)).on("mouseleave.slick", i.proxy(e.interrupt, e, !1))
+ }, e.prototype.initSlideEvents = function () {
+ var e = this;
+ e.options.pauseOnHover && (e.$list.on("mouseenter.slick", i.proxy(e.interrupt, e, !0)), e.$list.on("mouseleave.slick", i.proxy(e.interrupt, e, !1)))
+ }, e.prototype.initializeEvents = function () {
+ var e = this;
+ e.initArrowEvents(), e.initDotEvents(), e.initSlideEvents(), e.$list.on("touchstart.slick mousedown.slick", {action: "start"}, e.swipeHandler), e.$list.on("touchmove.slick mousemove.slick", {action: "move"}, e.swipeHandler), e.$list.on("touchend.slick mouseup.slick", {action: "end"}, e.swipeHandler), e.$list.on("touchcancel.slick mouseleave.slick", {action: "end"}, e.swipeHandler), e.$list.on("click.slick", e.clickHandler), i(document).on(e.visibilityChange, i.proxy(e.visibility, e)), !0 === e.options.accessibility && e.$list.on("keydown.slick", e.keyHandler), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), i(window).on("orientationchange.slick.slick-" + e.instanceUid, i.proxy(e.orientationChange, e)), i(window).on("resize.slick.slick-" + e.instanceUid, i.proxy(e.resize, e)), i("[draggable!=true]", e.$slideTrack).on("dragstart", e.preventDefault), i(window).on("load.slick.slick-" + e.instanceUid, e.setPosition), i(e.setPosition)
+ }, e.prototype.initUI = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.show(), i.$nextArrow.show()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.show()
+ }, e.prototype.keyHandler = function (i) {
+ var e = this;
+ i.target.tagName.match("TEXTAREA|INPUT|SELECT") || (37 === i.keyCode && !0 === e.options.accessibility ? e.changeSlide({data: {message: !0 === e.options.rtl ? "next" : "previous"}}) : 39 === i.keyCode && !0 === e.options.accessibility && e.changeSlide({data: {message: !0 === e.options.rtl ? "previous" : "next"}}))
+ }, e.prototype.lazyLoad = function () {
+ function e(e) {
+ i("img[data-lazy]", e).each(function () {
+ var e = i(this), t = i(this).attr("data-lazy"), o = i(this).attr("data-srcset"),
+ s = i(this).attr("data-sizes") || n.$slider.attr("data-sizes"), r = document.createElement("img");
+ r.onload = function () {
+ e.animate({opacity: 0}, 100, function () {
+ o && (e.attr("srcset", o), s && e.attr("sizes", s)), e.attr("src", t).animate({opacity: 1}, 200, function () {
+ e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")
+ }), n.$slider.trigger("lazyLoaded", [n, e, t])
+ })
+ }, r.onerror = function () {
+ e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), n.$slider.trigger("lazyLoadError", [n, e, t])
+ }, r.src = t
+ })
+ }
+
+ var t, o, s, n = this;
+ if (!0 === n.options.centerMode ? !0 === n.options.infinite ? s = (o = n.currentSlide + (n.options.slidesToShow / 2 + 1)) + n.options.slidesToShow + 2 : (o = Math.max(0, n.currentSlide - (n.options.slidesToShow / 2 + 1)), s = n.options.slidesToShow / 2 + 1 + 2 + n.currentSlide) : (o = n.options.infinite ? n.options.slidesToShow + n.currentSlide : n.currentSlide, s = Math.ceil(o + n.options.slidesToShow), !0 === n.options.fade && (o > 0 && o--, s <= n.slideCount && s++)), t = n.$slider.find(".slick-slide").slice(o, s), "anticipated" === n.options.lazyLoad) for (var r = o - 1, l = s, d = n.$slider.find(".slick-slide"), a = 0; a < n.options.slidesToScroll; a++) r < 0 && (r = n.slideCount - 1), t = (t = t.add(d.eq(r))).add(d.eq(l)), r--, l++;
+ e(t), n.slideCount <= n.options.slidesToShow ? e(n.$slider.find(".slick-slide")) : n.currentSlide >= n.slideCount - n.options.slidesToShow ? e(n.$slider.find(".slick-cloned").slice(0, n.options.slidesToShow)) : 0 === n.currentSlide && e(n.$slider.find(".slick-cloned").slice(-1 * n.options.slidesToShow))
+ }, e.prototype.loadSlider = function () {
+ var i = this;
+ i.setPosition(), i.$slideTrack.css({opacity: 1}), i.$slider.removeClass("slick-loading"), i.initUI(), "progressive" === i.options.lazyLoad && i.progressiveLazyLoad()
+ }, e.prototype.next = e.prototype.slickNext = function () {
+ this.changeSlide({data: {message: "next"}})
+ }, e.prototype.orientationChange = function () {
+ var i = this;
+ i.checkResponsive(), i.setPosition()
+ }, e.prototype.pause = e.prototype.slickPause = function () {
+ var i = this;
+ i.autoPlayClear(), i.paused = !0
+ }, e.prototype.play = e.prototype.slickPlay = function () {
+ var i = this;
+ i.autoPlay(), i.options.autoplay = !0, i.paused = !1, i.focussed = !1, i.interrupted = !1
+ }, e.prototype.postSlide = function (e) {
+ var t = this;
+ t.unslicked || (t.$slider.trigger("afterChange", [t, e]), t.animating = !1, t.slideCount > t.options.slidesToShow && t.setPosition(), t.swipeLeft = null, t.options.autoplay && t.autoPlay(), !0 === t.options.accessibility && (t.initADA(), t.options.focusOnChange && i(t.$slides.get(t.currentSlide)).attr("tabindex", 0).focus()))
+ }, e.prototype.prev = e.prototype.slickPrev = function () {
+ this.changeSlide({data: {message: "previous"}})
+ }, e.prototype.preventDefault = function (i) {
+ i.preventDefault()
+ }, e.prototype.progressiveLazyLoad = function (e) {
+ e = e || 1;
+ var t, o, s, n, r, l = this, d = i("img[data-lazy]", l.$slider);
+ d.length ? (t = d.first(), o = t.attr("data-lazy"), s = t.attr("data-srcset"), n = t.attr("data-sizes") || l.$slider.attr("data-sizes"), (r = document.createElement("img")).onload = function () {
+ s && (t.attr("srcset", s), n && t.attr("sizes", n)), t.attr("src", o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"), !0 === l.options.adaptiveHeight && l.setPosition(), l.$slider.trigger("lazyLoaded", [l, t, o]), l.progressiveLazyLoad()
+ }, r.onerror = function () {
+ e < 3 ? setTimeout(function () {
+ l.progressiveLazyLoad(e + 1)
+ }, 500) : (t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"), l.$slider.trigger("lazyLoadError", [l, t, o]), l.progressiveLazyLoad())
+ }, r.src = o) : l.$slider.trigger("allImagesLoaded", [l])
+ }, e.prototype.refresh = function (e) {
+ var t, o, s = this;
+ o = s.slideCount - s.options.slidesToShow, !s.options.infinite && s.currentSlide > o && (s.currentSlide = o), s.slideCount <= s.options.slidesToShow && (s.currentSlide = 0), t = s.currentSlide, s.destroy(!0), i.extend(s, s.initials, {currentSlide: t}), s.init(), e || s.changeSlide({
+ data: {
+ message: "index",
+ index: t
+ }
+ }, !1)
+ }, e.prototype.registerBreakpoints = function () {
+ var e, t, o, s = this, n = s.options.responsive || null;
+ if ("array" === i.type(n) && n.length) {
+ s.respondTo = s.options.respondTo || "window";
+ for (e in n) if (o = s.breakpoints.length - 1, n.hasOwnProperty(e)) {
+ for (t = n[e].breakpoint; o >= 0;) s.breakpoints[o] && s.breakpoints[o] === t && s.breakpoints.splice(o, 1), o--;
+ s.breakpoints.push(t), s.breakpointSettings[t] = n[e].settings
+ }
+ s.breakpoints.sort(function (i, e) {
+ return s.options.mobileFirst ? i - e : e - i
+ })
+ }
+ }, e.prototype.reinit = function () {
+ var e = this;
+ e.$slides = e.$slideTrack.children(e.options.slide).addClass("slick-slide"), e.slideCount = e.$slides.length, e.currentSlide >= e.slideCount && 0 !== e.currentSlide && (e.currentSlide = e.currentSlide - e.options.slidesToScroll), e.slideCount <= e.options.slidesToShow && (e.currentSlide = 0), e.registerBreakpoints(), e.setProps(), e.setupInfinite(), e.buildArrows(), e.updateArrows(), e.initArrowEvents(), e.buildDots(), e.updateDots(), e.initDotEvents(), e.cleanUpSlideEvents(), e.initSlideEvents(), e.checkResponsive(!1, !0), !0 === e.options.focusOnSelect && i(e.$slideTrack).children().on("click.slick", e.selectHandler), e.setSlideClasses("number" == typeof e.currentSlide ? e.currentSlide : 0), e.setPosition(), e.focusHandler(), e.paused = !e.options.autoplay, e.autoPlay(), e.$slider.trigger("reInit", [e])
+ }, e.prototype.resize = function () {
+ var e = this;
+ i(window).width() !== e.windowWidth && (clearTimeout(e.windowDelay), e.windowDelay = window.setTimeout(function () {
+ e.windowWidth = i(window).width(), e.checkResponsive(), e.unslicked || e.setPosition()
+ }, 50))
+ }, e.prototype.removeSlide = e.prototype.slickRemove = function (i, e, t) {
+ var o = this;
+ if (i = "boolean" == typeof i ? !0 === (e = i) ? 0 : o.slideCount - 1 : !0 === e ? --i : i, o.slideCount < 1 || i < 0 || i > o.slideCount - 1) return !1;
+ o.unload(), !0 === t ? o.$slideTrack.children().remove() : o.$slideTrack.children(this.options.slide).eq(i).remove(), o.$slides = o.$slideTrack.children(this.options.slide), o.$slideTrack.children(this.options.slide).detach(), o.$slideTrack.append(o.$slides), o.$slidesCache = o.$slides, o.reinit()
+ }, e.prototype.setCSS = function (i) {
+ var e, t, o = this, s = {};
+ !0 === o.options.rtl && (i = -i), e = "left" == o.positionProp ? Math.ceil(i) + "px" : "0px", t = "top" == o.positionProp ? Math.ceil(i) + "px" : "0px", s[o.positionProp] = i, !1 === o.transformsEnabled ? o.$slideTrack.css(s) : (s = {}, !1 === o.cssTransitions ? (s[o.animType] = "translate(" + e + ", " + t + ")", o.$slideTrack.css(s)) : (s[o.animType] = "translate3d(" + e + ", " + t + ", 0px)", o.$slideTrack.css(s)))
+ }, e.prototype.setDimensions = function () {
+ var i = this;
+ !1 === i.options.vertical ? !0 === i.options.centerMode && i.$list.css({padding: "0px " + i.options.centerPadding}) : (i.$list.height(i.$slides.first().outerHeight(!0) * i.options.slidesToShow), !0 === i.options.centerMode && i.$list.css({padding: i.options.centerPadding + " 0px"})), i.listWidth = i.$list.width(), i.listHeight = i.$list.height(), !1 === i.options.vertical && !1 === i.options.variableWidth ? (i.slideWidth = Math.ceil(i.listWidth / i.options.slidesToShow), i.$slideTrack.width(Math.ceil(i.slideWidth * i.$slideTrack.children(".slick-slide").length))) : !0 === i.options.variableWidth ? i.$slideTrack.width(5e3 * i.slideCount) : (i.slideWidth = Math.ceil(i.listWidth), i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0) * i.$slideTrack.children(".slick-slide").length)));
+ var e = i.$slides.first().outerWidth(!0) - i.$slides.first().width();
+ !1 === i.options.variableWidth && i.$slideTrack.children(".slick-slide").width(i.slideWidth - e)
+ }, e.prototype.setFade = function () {
+ var e, t = this;
+ t.$slides.each(function (o, s) {
+ e = t.slideWidth * o * -1, !0 === t.options.rtl ? i(s).css({
+ position: "relative",
+ right: e,
+ top: 0,
+ zIndex: t.options.zIndex - 2,
+ opacity: 0
+ }) : i(s).css({position: "relative", left: e, top: 0, zIndex: t.options.zIndex - 2, opacity: 0})
+ }), t.$slides.eq(t.currentSlide).css({zIndex: t.options.zIndex - 1, opacity: 1})
+ }, e.prototype.setHeight = function () {
+ var i = this;
+ if (1 === i.options.slidesToShow && !0 === i.options.adaptiveHeight && !1 === i.options.vertical) {
+ var e = i.$slides.eq(i.currentSlide).outerHeight(!0);
+ i.$list.css("height", e)
+ }
+ }, e.prototype.setOption = e.prototype.slickSetOption = function () {
+ var e, t, o, s, n, r = this, l = !1;
+ if ("object" === i.type(arguments[0]) ? (o = arguments[0], l = arguments[1], n = "multiple") : "string" === i.type(arguments[0]) && (o = arguments[0], s = arguments[1], l = arguments[2], "responsive" === arguments[0] && "array" === i.type(arguments[1]) ? n = "responsive" : void 0 !== arguments[1] && (n = "single")), "single" === n) r.options[o] = s; else if ("multiple" === n) i.each(o, function (i, e) {
+ r.options[i] = e
+ }); else if ("responsive" === n) for (t in s) if ("array" !== i.type(r.options.responsive)) r.options.responsive = [s[t]]; else {
+ for (e = r.options.responsive.length - 1; e >= 0;) r.options.responsive[e].breakpoint === s[t].breakpoint && r.options.responsive.splice(e, 1), e--;
+ r.options.responsive.push(s[t])
+ }
+ l && (r.unload(), r.reinit())
+ }, e.prototype.setPosition = function () {
+ var i = this;
+ i.setDimensions(), i.setHeight(), !1 === i.options.fade ? i.setCSS(i.getLeft(i.currentSlide)) : i.setFade(), i.$slider.trigger("setPosition", [i])
+ }, e.prototype.setProps = function () {
+ var i = this, e = document.body.style;
+ i.positionProp = !0 === i.options.vertical ? "top" : "left", "top" === i.positionProp ? i.$slider.addClass("slick-vertical") : i.$slider.removeClass("slick-vertical"), void 0 === e.WebkitTransition && void 0 === e.MozTransition && void 0 === e.msTransition || !0 === i.options.useCSS && (i.cssTransitions = !0), i.options.fade && ("number" == typeof i.options.zIndex ? i.options.zIndex < 3 && (i.options.zIndex = 3) : i.options.zIndex = i.defaults.zIndex), void 0 !== e.OTransform && (i.animType = "OTransform", i.transformType = "-o-transform", i.transitionType = "OTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.MozTransform && (i.animType = "MozTransform", i.transformType = "-moz-transform", i.transitionType = "MozTransition", void 0 === e.perspectiveProperty && void 0 === e.MozPerspective && (i.animType = !1)), void 0 !== e.webkitTransform && (i.animType = "webkitTransform", i.transformType = "-webkit-transform", i.transitionType = "webkitTransition", void 0 === e.perspectiveProperty && void 0 === e.webkitPerspective && (i.animType = !1)), void 0 !== e.msTransform && (i.animType = "msTransform", i.transformType = "-ms-transform", i.transitionType = "msTransition", void 0 === e.msTransform && (i.animType = !1)), void 0 !== e.transform && !1 !== i.animType && (i.animType = "transform", i.transformType = "transform", i.transitionType = "transition"), i.transformsEnabled = i.options.useTransform && null !== i.animType && !1 !== i.animType
+ }, e.prototype.setSlideClasses = function (i) {
+ var e, t, o, s, n = this;
+ if (t = n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden", "true"), n.$slides.eq(i).addClass("slick-current"), !0 === n.options.centerMode) {
+ var r = n.options.slidesToShow % 2 == 0 ? 1 : 0;
+ e = Math.floor(n.options.slidesToShow / 2), !0 === n.options.infinite && (i >= e && i <= n.slideCount - 1 - e ? n.$slides.slice(i - e + r, i + e + 1).addClass("slick-active").attr("aria-hidden", "false") : (o = n.options.slidesToShow + i, t.slice(o - e + 1 + r, o + e + 2).addClass("slick-active").attr("aria-hidden", "false")), 0 === i ? t.eq(t.length - 1 - n.options.slidesToShow).addClass("slick-center") : i === n.slideCount - 1 && t.eq(n.options.slidesToShow).addClass("slick-center")), n.$slides.eq(i).addClass("slick-center")
+ } else i >= 0 && i <= n.slideCount - n.options.slidesToShow ? n.$slides.slice(i, i + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false") : t.length <= n.options.slidesToShow ? t.addClass("slick-active").attr("aria-hidden", "false") : (s = n.slideCount % n.options.slidesToShow, o = !0 === n.options.infinite ? n.options.slidesToShow + i : i, n.options.slidesToShow == n.options.slidesToScroll && n.slideCount - i < n.options.slidesToShow ? t.slice(o - (n.options.slidesToShow - s), o + s).addClass("slick-active").attr("aria-hidden", "false") : t.slice(o, o + n.options.slidesToShow).addClass("slick-active").attr("aria-hidden", "false"));
+ "ondemand" !== n.options.lazyLoad && "anticipated" !== n.options.lazyLoad || n.lazyLoad()
+ }, e.prototype.setupInfinite = function () {
+ var e, t, o, s = this;
+ if (!0 === s.options.fade && (s.options.centerMode = !1), !0 === s.options.infinite && !1 === s.options.fade && (t = null, s.slideCount > s.options.slidesToShow)) {
+ for (o = !0 === s.options.centerMode ? s.options.slidesToShow + 1 : s.options.slidesToShow, e = s.slideCount; e > s.slideCount - o; e -= 1) t = e - 1, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t - s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");
+ for (e = 0; e < o + s.slideCount; e += 1) t = e, i(s.$slides[t]).clone(!0).attr("id", "").attr("data-slick-index", t + s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");
+ s.$slideTrack.find(".slick-cloned").find("[id]").each(function () {
+ i(this).attr("id", "")
+ })
+ }
+ }, e.prototype.interrupt = function (i) {
+ var e = this;
+ i || e.autoPlay(), e.interrupted = i
+ }, e.prototype.selectHandler = function (e) {
+ var t = this, o = i(e.target).is(".slick-slide") ? i(e.target) : i(e.target).parents(".slick-slide"),
+ s = parseInt(o.attr("data-slick-index"));
+ s || (s = 0), t.slideCount <= t.options.slidesToShow ? t.slideHandler(s, !1, !0) : t.slideHandler(s)
+ }, e.prototype.slideHandler = function (i, e, t) {
+ var o, s, n, r, l, d = null, a = this;
+ if (e = e || !1, !(!0 === a.animating && !0 === a.options.waitForAnimate || !0 === a.options.fade && a.currentSlide === i)) if (!1 === e && a.asNavFor(i), o = i, d = a.getLeft(o), r = a.getLeft(a.currentSlide), a.currentLeft = null === a.swipeLeft ? r : a.swipeLeft, !1 === a.options.infinite && !1 === a.options.centerMode && (i < 0 || i > a.getDotCount() * a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
+ a.postSlide(o)
+ }) : a.postSlide(o)); else if (!1 === a.options.infinite && !0 === a.options.centerMode && (i < 0 || i > a.slideCount - a.options.slidesToScroll)) !1 === a.options.fade && (o = a.currentSlide, !0 !== t ? a.animateSlide(r, function () {
+ a.postSlide(o)
+ }) : a.postSlide(o)); else {
+ if (a.options.autoplay && clearInterval(a.autoPlayTimer), s = o < 0 ? a.slideCount % a.options.slidesToScroll != 0 ? a.slideCount - a.slideCount % a.options.slidesToScroll : a.slideCount + o : o >= a.slideCount ? a.slideCount % a.options.slidesToScroll != 0 ? 0 : o - a.slideCount : o, a.animating = !0, a.$slider.trigger("beforeChange", [a, a.currentSlide, s]), n = a.currentSlide, a.currentSlide = s, a.setSlideClasses(a.currentSlide), a.options.asNavFor && (l = (l = a.getNavTarget()).slick("getSlick")).slideCount <= l.options.slidesToShow && l.setSlideClasses(a.currentSlide), a.updateDots(), a.updateArrows(), !0 === a.options.fade) return !0 !== t ? (a.fadeSlideOut(n), a.fadeSlide(s, function () {
+ a.postSlide(s)
+ })) : a.postSlide(s), void a.animateHeight();
+ !0 !== t ? a.animateSlide(d, function () {
+ a.postSlide(s)
+ }) : a.postSlide(s)
+ }
+ }, e.prototype.startLoad = function () {
+ var i = this;
+ !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && (i.$prevArrow.hide(), i.$nextArrow.hide()), !0 === i.options.dots && i.slideCount > i.options.slidesToShow && i.$dots.hide(), i.$slider.addClass("slick-loading")
+ }, e.prototype.swipeDirection = function () {
+ var i, e, t, o, s = this;
+ return i = s.touchObject.startX - s.touchObject.curX, e = s.touchObject.startY - s.touchObject.curY, t = Math.atan2(e, i), (o = Math.round(180 * t / Math.PI)) < 0 && (o = 360 - Math.abs(o)), o <= 45 && o >= 0 ? !1 === s.options.rtl ? "left" : "right" : o <= 360 && o >= 315 ? !1 === s.options.rtl ? "left" : "right" : o >= 135 && o <= 225 ? !1 === s.options.rtl ? "right" : "left" : !0 === s.options.verticalSwiping ? o >= 35 && o <= 135 ? "down" : "up" : "vertical"
+ }, e.prototype.swipeEnd = function (i) {
+ var e, t, o = this;
+ if (o.dragging = !1, o.swiping = !1, o.scrolling) return o.scrolling = !1, !1;
+ if (o.interrupted = !1, o.shouldClick = !(o.touchObject.swipeLength > 10), void 0 === o.touchObject.curX) return !1;
+ if (!0 === o.touchObject.edgeHit && o.$slider.trigger("edge", [o, o.swipeDirection()]), o.touchObject.swipeLength >= o.touchObject.minSwipe) {
+ switch (t = o.swipeDirection()) {
+ case"left":
+ case"down":
+ e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide + o.getSlideCount()) : o.currentSlide + o.getSlideCount(), o.currentDirection = 0;
+ break;
+ case"right":
+ case"up":
+ e = o.options.swipeToSlide ? o.checkNavigable(o.currentSlide - o.getSlideCount()) : o.currentSlide - o.getSlideCount(), o.currentDirection = 1
+ }
+ "vertical" != t && (o.slideHandler(e), o.touchObject = {}, o.$slider.trigger("swipe", [o, t]))
+ } else o.touchObject.startX !== o.touchObject.curX && (o.slideHandler(o.currentSlide), o.touchObject = {})
+ }, e.prototype.swipeHandler = function (i) {
+ var e = this;
+ if (!(!1 === e.options.swipe || "ontouchend" in document && !1 === e.options.swipe || !1 === e.options.draggable && -1 !== i.type.indexOf("mouse"))) switch (e.touchObject.fingerCount = i.originalEvent && void 0 !== i.originalEvent.touches ? i.originalEvent.touches.length : 1, e.touchObject.minSwipe = e.listWidth / e.options.touchThreshold, !0 === e.options.verticalSwiping && (e.touchObject.minSwipe = e.listHeight / e.options.touchThreshold), i.data.action) {
+ case"start":
+ e.swipeStart(i);
+ break;
+ case"move":
+ e.swipeMove(i);
+ break;
+ case"end":
+ e.swipeEnd(i)
+ }
+ }, e.prototype.swipeMove = function (i) {
+ var e, t, o, s, n, r, l = this;
+ return n = void 0 !== i.originalEvent ? i.originalEvent.touches : null, !(!l.dragging || l.scrolling || n && 1 !== n.length) && (e = l.getLeft(l.currentSlide), l.touchObject.curX = void 0 !== n ? n[0].pageX : i.clientX, l.touchObject.curY = void 0 !== n ? n[0].pageY : i.clientY, l.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(l.touchObject.curX - l.touchObject.startX, 2))), r = Math.round(Math.sqrt(Math.pow(l.touchObject.curY - l.touchObject.startY, 2))), !l.options.verticalSwiping && !l.swiping && r > 4 ? (l.scrolling = !0, !1) : (!0 === l.options.verticalSwiping && (l.touchObject.swipeLength = r), t = l.swipeDirection(), void 0 !== i.originalEvent && l.touchObject.swipeLength > 4 && (l.swiping = !0, i.preventDefault()), s = (!1 === l.options.rtl ? 1 : -1) * (l.touchObject.curX > l.touchObject.startX ? 1 : -1), !0 === l.options.verticalSwiping && (s = l.touchObject.curY > l.touchObject.startY ? 1 : -1), o = l.touchObject.swipeLength, l.touchObject.edgeHit = !1, !1 === l.options.infinite && (0 === l.currentSlide && "right" === t || l.currentSlide >= l.getDotCount() && "left" === t) && (o = l.touchObject.swipeLength * l.options.edgeFriction, l.touchObject.edgeHit = !0), !1 === l.options.vertical ? l.swipeLeft = e + o * s : l.swipeLeft = e + o * (l.$list.height() / l.listWidth) * s, !0 === l.options.verticalSwiping && (l.swipeLeft = e + o * s), !0 !== l.options.fade && !1 !== l.options.touchMove && (!0 === l.animating ? (l.swipeLeft = null, !1) : void l.setCSS(l.swipeLeft))))
+ }, e.prototype.swipeStart = function (i) {
+ var e, t = this;
+ if (t.interrupted = !0, 1 !== t.touchObject.fingerCount || t.slideCount <= t.options.slidesToShow) return t.touchObject = {}, !1;
+ void 0 !== i.originalEvent && void 0 !== i.originalEvent.touches && (e = i.originalEvent.touches[0]), t.touchObject.startX = t.touchObject.curX = void 0 !== e ? e.pageX : i.clientX, t.touchObject.startY = t.touchObject.curY = void 0 !== e ? e.pageY : i.clientY, t.dragging = !0
+ }, e.prototype.unfilterSlides = e.prototype.slickUnfilter = function () {
+ var i = this;
+ null !== i.$slidesCache && (i.unload(), i.$slideTrack.children(this.options.slide).detach(), i.$slidesCache.appendTo(i.$slideTrack), i.reinit())
+ }, e.prototype.unload = function () {
+ var e = this;
+ i(".slick-cloned", e.$slider).remove(), e.$dots && e.$dots.remove(), e.$prevArrow && e.htmlExpr.test(e.options.prevArrow) && e.$prevArrow.remove(), e.$nextArrow && e.htmlExpr.test(e.options.nextArrow) && e.$nextArrow.remove(), e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden", "true").css("width", "")
+ }, e.prototype.unslick = function (i) {
+ var e = this;
+ e.$slider.trigger("unslick", [e, i]), e.destroy()
+ }, e.prototype.updateArrows = function () {
+ var i = this;
+ Math.floor(i.options.slidesToShow / 2), !0 === i.options.arrows && i.slideCount > i.options.slidesToShow && !i.options.infinite && (i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false"), 0 === i.currentSlide ? (i.$prevArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - i.options.slidesToShow && !1 === i.options.centerMode ? (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")) : i.currentSlide >= i.slideCount - 1 && !0 === i.options.centerMode && (i.$nextArrow.addClass("slick-disabled").attr("aria-disabled", "true"), i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled", "false")))
+ }, e.prototype.updateDots = function () {
+ var i = this;
+ null !== i.$dots && (i.$dots.find("li").removeClass("slick-active").end(), i.$dots.find("li").eq(Math.floor(i.currentSlide / i.options.slidesToScroll)).addClass("slick-active"))
+ }, e.prototype.visibility = function () {
+ var i = this;
+ i.options.autoplay && (document[i.hidden] ? i.interrupted = !0 : i.interrupted = !1)
+ }, i.fn.slick = function () {
+ var i, t, o = this, s = arguments[0], n = Array.prototype.slice.call(arguments, 1), r = o.length;
+ for (i = 0; i < r; i++) if ("object" == typeof s || void 0 === s ? o[i].slick = new e(o[i], s) : t = o[i].slick[s].apply(o[i].slick, n), void 0 !== t) return t;
+ return o
+ }
});
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php
index 15f573b..7b9ad17 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/bin/WebChatServer.php
@@ -1,18 +1,18 @@
-run();
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php
index da78c9b..603bc01 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/Chatserver/src/ChatProcessor.php
@@ -1,118 +1,118 @@
-clients = new \SplObjectStorage;
- $this->subscriptions = [];
- $this->users = [];
- $this->connectedUsersNames = [];
- }
-
- public function onOpen(ConnectionInterface $conn) {
- $generator = new Alliteration();
- $this->clients->attach($conn);
- $this->users[$conn->resourceId] = $conn;
- $this->connectedUsersNames[$conn->resourceId] = $generator->getName();
- }
-
- /*public function onMessage(ConnectionInterface $from, $msg) {
- $numRecv = count($this->clients) - 1;
- echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
- , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
-
- foreach ($this->clients as $client) {
- if ($from === $client) {
- $client->send("
You - " . $msg);
- } else {
- $client->send("
" . $from->resourceId . " - " . $msg);
- }
- }
- }
- */
-
- public function onMessage(ConnectionInterface $conn, MessageInterface $msg) {
- $data = json_decode($msg);
- switch ($data->ClientMessageType) {
- case "Subscribe":
- $this->subscriptions[$conn->resourceId] = $data->Channel;
- foreach ($this->subscriptions as $id => $channel) {
- if ($this->subscriptions[$conn->resourceId] == $channel) {
- $MessageObject = new \stdClass();
- $MessageObject->ServerMessage = true;
- $MessageObject->ServerMessageType = "GroupJoin";
- $MessageObject->GroupName = $channel;
- $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
- if ($id === $conn->resourceId) {
- $MessageObject->WasHimself = true;
- } else {
- $MessageObject->WasHimself = false;
- }
- $MessageJson = json_encode($MessageObject, true);
- $this->users[$id]->send($MessageJson);
- }
- }
- break;
- case "Message":
- if (isset($this->subscriptions[$conn->resourceId])) {
- $target = $this->subscriptions[$conn->resourceId];
- foreach ($this->subscriptions as $id => $channel) {
- if ($channel == $target) {
- $MessageObject = new \stdClass();
- $MessageObject->ServerMessage = false;
- $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
- $MessageObject->Message = htmlspecialchars($data->Message);
- if ($id === $conn->resourceId) {
- $MessageObject->WasHimself = true;
- } else {
- $MessageObject->WasHimself = false;
- }
- $MessageJson = json_encode($MessageObject, true);
- $this->users[$id]->send($MessageJson);
- }
- }
- }
- }
- }
-
- public function onClose(ConnectionInterface $conn) {
- $this->clients->detach($conn);
- foreach ($this->clients as $client) {
- if (isset($this->subscriptions[$conn->resourceId])) {
- $target = $this->subscriptions[$conn->resourceId];
- foreach ($this->subscriptions as $id => $channel) {
- if ($channel == $target) {
- $MessageObject = new \stdClass();
- $MessageObject->ServerMessage = true;
- $MessageObject->ServerMessageType = "UserDisconnect";
- $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
- $MessageJson = json_encode($MessageObject, true);
- $this->users[$id]->send($MessageJson);
- }
- }
- }
- }
- unset($this->users[$conn->resourceId]);
- unset($this->subscriptions[$conn->resourceId]);
- unset($this->connectedUsersNames[$conn->resourceId]);
- }
-
- public function onError(ConnectionInterface $conn, \Exception $e) {
- echo "An error has occurred: {$e->getMessage()}\n";
-
- $conn->close();
- }
+clients = new \SplObjectStorage;
+ $this->subscriptions = [];
+ $this->users = [];
+ $this->connectedUsersNames = [];
+ }
+
+ public function onOpen(ConnectionInterface $conn) {
+ $generator = new Alliteration();
+ $this->clients->attach($conn);
+ $this->users[$conn->resourceId] = $conn;
+ $this->connectedUsersNames[$conn->resourceId] = $generator->getName();
+ }
+
+ /*public function onMessage(ConnectionInterface $from, $msg) {
+ $numRecv = count($this->clients) - 1;
+ echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
+ , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
+
+ foreach ($this->clients as $client) {
+ if ($from === $client) {
+ $client->send("
You - " . $msg);
+ } else {
+ $client->send("
" . $from->resourceId . " - " . $msg);
+ }
+ }
+ }
+ */
+
+ public function onMessage(ConnectionInterface $conn, MessageInterface $msg) {
+ $data = json_decode($msg);
+ switch ($data->ClientMessageType) {
+ case "Subscribe":
+ $this->subscriptions[$conn->resourceId] = $data->Channel;
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($this->subscriptions[$conn->resourceId] == $channel) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = true;
+ $MessageObject->ServerMessageType = "GroupJoin";
+ $MessageObject->GroupName = $channel;
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ if ($id === $conn->resourceId) {
+ $MessageObject->WasHimself = true;
+ } else {
+ $MessageObject->WasHimself = false;
+ }
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ break;
+ case "Message":
+ if (isset($this->subscriptions[$conn->resourceId])) {
+ $target = $this->subscriptions[$conn->resourceId];
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($channel == $target) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = false;
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ $MessageObject->Message = htmlspecialchars($data->Message);
+ if ($id === $conn->resourceId) {
+ $MessageObject->WasHimself = true;
+ } else {
+ $MessageObject->WasHimself = false;
+ }
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ }
+ }
+ }
+
+ public function onClose(ConnectionInterface $conn) {
+ $this->clients->detach($conn);
+ foreach ($this->clients as $client) {
+ if (isset($this->subscriptions[$conn->resourceId])) {
+ $target = $this->subscriptions[$conn->resourceId];
+ foreach ($this->subscriptions as $id => $channel) {
+ if ($channel == $target) {
+ $MessageObject = new \stdClass();
+ $MessageObject->ServerMessage = true;
+ $MessageObject->ServerMessageType = "UserDisconnect";
+ $MessageObject->Username = $this->connectedUsersNames[$conn->resourceId];
+ $MessageJson = json_encode($MessageObject, true);
+ $this->users[$id]->send($MessageJson);
+ }
+ }
+ }
+ }
+ unset($this->users[$conn->resourceId]);
+ unset($this->subscriptions[$conn->resourceId]);
+ unset($this->connectedUsersNames[$conn->resourceId]);
+ }
+
+ public function onError(ConnectionInterface $conn, \Exception $e) {
+ echo "An error has occurred: {$e->getMessage()}\n";
+
+ $conn->close();
+ }
}
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php b/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php
index 725a005..97f1311 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/SavePublicKey.php
@@ -1,17 +1,17 @@
-prepare("SELECT count(*) FROM `PublicKeys` WHERE UserID = :UserID");
- $CheckIfAlreadySetStmt->bindValue(':UserID', $_POST['UserID']);
- $CheckIfAlreadySetStmt->execute();
- $CheckIfAlreadySetRes = $CheckIfAlreadySetStmt->fetchColumn();
- if ($CheckIfAlreadySetRes == 1) {
- $UpdatePublicKeyStmt = $conn->prepare("UPDATE `PublicKeys` SET PublicKeyString = :PublicKeyString WHERE UserID = :UserID");
- $UpdatePublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
- } else if ($CheckIfAlreadySetRes == 0) {
- $InsertPublicKeyStmt = $conn->prepare("INSERT INTO `PublicKeys` (UserID, PublicKeyString) VALUES (:UserID, :PublicKeyString)");
- $InsertPublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
- }
-} else {
- http_response_code(400);
+prepare("SELECT count(*) FROM `PublicKeys` WHERE UserID = :UserID");
+ $CheckIfAlreadySetStmt->bindValue(':UserID', $_POST['UserID']);
+ $CheckIfAlreadySetStmt->execute();
+ $CheckIfAlreadySetRes = $CheckIfAlreadySetStmt->fetchColumn();
+ if ($CheckIfAlreadySetRes == 1) {
+ $UpdatePublicKeyStmt = $conn->prepare("UPDATE `PublicKeys` SET PublicKeyString = :PublicKeyString WHERE UserID = :UserID");
+ $UpdatePublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
+ } else if ($CheckIfAlreadySetRes == 0) {
+ $InsertPublicKeyStmt = $conn->prepare("INSERT INTO `PublicKeys` (UserID, PublicKeyString) VALUES (:UserID, :PublicKeyString)");
+ $InsertPublicKeyStmt->execute(array('PublicKeyString' => $_POST["PublicKeyString"], 'UserID' => $_POST["UserID"]));
+ }
+} else {
+ http_response_code(400);
}
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock b/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock
deleted file mode 100644
index a852b73..0000000
--- a/main/app/sprinkles/core/assets/SiteAssets/php/composer.lock
+++ /dev/null
@@ -1,943 +0,0 @@
-{
- "_readme": [
- "This file locks the dependencies of your project to a known state",
- "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
- "This file is @generated automatically"
- ],
- "content-hash": "7db98e9dbf466f436f9127ff8289eac0",
- "packages": [
- {
- "name": "cboden/ratchet",
- "version": "v0.4.1",
- "source": {
- "type": "git",
- "url": "https://github.com/ratchetphp/Ratchet.git",
- "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/0d31f3a8ad4795fd48397712709e55cd07f51360",
- "reference": "0d31f3a8ad4795fd48397712709e55cd07f51360",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/psr7": "^1.0",
- "php": ">=5.4.2",
- "ratchet/rfc6455": "^0.2",
- "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5",
- "symfony/http-foundation": "^2.6|^3.0|^4.0",
- "symfony/routing": "^2.6|^3.0|^4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.8"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Ratchet\\": "src/Ratchet"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Chris Boden",
- "email": "cboden@gmail.com",
- "role": "Developer"
- }
- ],
- "description": "PHP WebSocket library",
- "homepage": "http://socketo.me",
- "keywords": [
- "Ratchet",
- "WebSockets",
- "server",
- "sockets",
- "websocket"
- ],
- "time": "2017-12-12T00:49:31+00:00"
- },
- {
- "name": "evenement/evenement",
- "version": "v3.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/igorw/evenement.git",
- "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
- "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7",
- "shasum": ""
- },
- "require": {
- "php": ">=7.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.0"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "Evenement": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Igor Wiedler",
- "email": "igor@wiedler.ch"
- }
- ],
- "description": "Événement is a very simple event dispatching library for PHP",
- "keywords": [
- "event-dispatcher",
- "event-emitter"
- ],
- "time": "2017-07-23T21:35:13+00:00"
- },
- {
- "name": "guzzlehttp/psr7",
- "version": "1.4.2",
- "source": {
- "type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
- "reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0",
- "psr/http-message": "~1.0"
- },
- "provide": {
- "psr/http-message-implementation": "1.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
- },
- {
- "name": "Tobias Schultze",
- "homepage": "https://github.com/Tobion"
- }
- ],
- "description": "PSR-7 message implementation that also provides common utility methods",
- "keywords": [
- "http",
- "message",
- "request",
- "response",
- "stream",
- "uri",
- "url"
- ],
- "time": "2017-03-20T17:10:46+00:00"
- },
- {
- "name": "nubs/random-name-generator",
- "version": "v2.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/nubs/random-name-generator.git",
- "reference": "7004eb1724e1c4a154553e44312b7045fe412b77"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nubs/random-name-generator/zipball/7004eb1724e1c4a154553e44312b7045fe412b77",
- "reference": "7004eb1724e1c4a154553e44312b7045fe412b77",
- "shasum": ""
- },
- "require": {
- "php": "~5.6 || ~7.0"
- },
- "require-dev": {
- "cinam/randomizer": ">=1.1.1,<2.0",
- "phpunit/phpunit": "~5.0",
- "satooshi/php-coveralls": "~1.0",
- "squizlabs/php_codesniffer": "~2.3"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Nubs\\RandomNameGenerator\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Spencer Rinehart",
- "email": "anubis@overthemonkey.com",
- "role": "Developer"
- }
- ],
- "description": "A library to create interesting, sometimes entertaining, random names.",
- "keywords": [
- "alliteration",
- "generator",
- "random",
- "video game"
- ],
- "time": "2016-12-04T01:57:19+00:00"
- },
- {
- "name": "paragonie/random_compat",
- "version": "v2.0.12",
- "source": {
- "type": "git",
- "url": "https://github.com/paragonie/random_compat.git",
- "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
- "reference": "258c89a6b97de7dfaf5b8c7607d0478e236b04fb",
- "shasum": ""
- },
- "require": {
- "php": ">=5.2.0"
- },
- "require-dev": {
- "phpunit/phpunit": "4.*|5.*"
- },
- "suggest": {
- "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
- },
- "type": "library",
- "autoload": {
- "files": [
- "lib/random.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com"
- }
- ],
- "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
- "keywords": [
- "csprng",
- "pseudorandom",
- "random"
- ],
- "time": "2018-04-04T21:24:14+00:00"
- },
- {
- "name": "psr/http-message",
- "version": "1.0.1",
- "source": {
- "type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Psr\\Http\\Message\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
- }
- ],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
- "keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
- ],
- "time": "2016-08-06T14:39:51+00:00"
- },
- {
- "name": "ratchet/rfc6455",
- "version": "v0.2.3",
- "source": {
- "type": "git",
- "url": "https://github.com/ratchetphp/RFC6455.git",
- "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/cc8a1a46a703ce01de10fdb5fab387381b66edc8",
- "reference": "cc8a1a46a703ce01de10fdb5fab387381b66edc8",
- "shasum": ""
- },
- "require": {
- "guzzlehttp/psr7": "^1.0",
- "php": ">=5.4.2"
- },
- "require-dev": {
- "phpunit/phpunit": "4.8.*",
- "react/http": "^0.4.1",
- "react/socket-client": "^0.4.3"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Ratchet\\RFC6455\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Chris Boden",
- "email": "cboden@gmail.com",
- "role": "Developer"
- }
- ],
- "description": "RFC6455 WebSocket protocol handler",
- "homepage": "http://socketo.me",
- "keywords": [
- "WebSockets",
- "rfc6455",
- "websocket"
- ],
- "time": "2017-09-13T13:49:42+00:00"
- },
- {
- "name": "react/cache",
- "version": "v0.4.2",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/cache.git",
- "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/cache/zipball/75494f26b4ef089db9bf8c90b63c296246e099e8",
- "reference": "75494f26b4ef089db9bf8c90b63c296246e099e8",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0",
- "react/promise": "~2.0|~1.1"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Cache\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Async, Promise-based cache interface for ReactPHP",
- "keywords": [
- "cache",
- "caching",
- "promise",
- "reactphp"
- ],
- "time": "2017-12-20T16:47:13+00:00"
- },
- {
- "name": "react/dns",
- "version": "v0.4.13",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/dns.git",
- "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/dns/zipball/7d1e08c300fd7de600810883386ee5e2a64898f4",
- "reference": "7d1e08c300fd7de600810883386ee5e2a64898f4",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0",
- "react/cache": "~0.4.0|~0.3.0",
- "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
- "react/promise": "^2.1 || ^1.2.1",
- "react/promise-timer": "^1.2",
- "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.5"
- },
- "require-dev": {
- "clue/block-react": "^1.2",
- "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Dns\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Async DNS resolver for ReactPHP",
- "keywords": [
- "async",
- "dns",
- "dns-resolver",
- "reactphp"
- ],
- "time": "2018-02-27T12:51:22+00:00"
- },
- {
- "name": "react/event-loop",
- "version": "v0.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/event-loop.git",
- "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/event-loop/zipball/e1e0647a5c6e2c86013a24e9c8252113df86105a",
- "reference": "e1e0647a5c6e2c86013a24e9c8252113df86105a",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.8.35 || ^5.7 || ^6.4"
- },
- "suggest": {
- "ext-event": "~1.0 for ExtEventLoop",
- "ext-pcntl": "For signal handling support when using the StreamSelectLoop"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\EventLoop\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.",
- "keywords": [
- "asynchronous",
- "event-loop"
- ],
- "time": "2018-04-09T11:59:21+00:00"
- },
- {
- "name": "react/promise",
- "version": "v2.5.1",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/promise.git",
- "reference": "62785ae604c8d69725d693eb370e1d67e94c4053"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise/zipball/62785ae604c8d69725d693eb370e1d67e94c4053",
- "reference": "62785ae604c8d69725d693eb370e1d67e94c4053",
- "shasum": ""
- },
- "require": {
- "php": ">=5.4.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.8"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Promise\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jan Sorgalla",
- "email": "jsorgalla@gmail.com"
- }
- ],
- "description": "A lightweight implementation of CommonJS Promises/A for PHP",
- "keywords": [
- "promise",
- "promises"
- ],
- "time": "2017-03-25T12:08:31+00:00"
- },
- {
- "name": "react/promise-timer",
- "version": "v1.2.1",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/promise-timer.git",
- "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
- "reference": "9b4cd9cbe7457e0d87fe8aa7ccceab8a2c830fbd",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3",
- "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
- "react/promise": "~2.1|~1.2"
- },
- "require-dev": {
- "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Promise\\Timer\\": "src/"
- },
- "files": [
- "src/functions.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Christian Lück",
- "email": "christian@lueck.tv"
- }
- ],
- "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.",
- "homepage": "https://github.com/react/promise-timer",
- "keywords": [
- "async",
- "event-loop",
- "promise",
- "reactphp",
- "timeout",
- "timer"
- ],
- "time": "2017-12-22T15:41:41+00:00"
- },
- {
- "name": "react/socket",
- "version": "v0.8.10",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/socket.git",
- "reference": "d3957313c92b539537fccc80170c05a27ec25796"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/socket/zipball/d3957313c92b539537fccc80170c05a27ec25796",
- "reference": "d3957313c92b539537fccc80170c05a27ec25796",
- "shasum": ""
- },
- "require": {
- "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
- "php": ">=5.3.0",
- "react/dns": "^0.4.13",
- "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5",
- "react/promise": "^2.1 || ^1.2",
- "react/promise-timer": "~1.0",
- "react/stream": "^1.0 || ^0.7.1"
- },
- "require-dev": {
- "clue/block-react": "^1.2",
- "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Socket\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
- "keywords": [
- "Connection",
- "Socket",
- "async",
- "reactphp",
- "stream"
- ],
- "time": "2018-02-28T09:32:38+00:00"
- },
- {
- "name": "react/stream",
- "version": "v0.7.7",
- "source": {
- "type": "git",
- "url": "https://github.com/reactphp/stream.git",
- "reference": "10100896018fd847a257cd81143b8e1b7be08e40"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/reactphp/stream/zipball/10100896018fd847a257cd81143b8e1b7be08e40",
- "reference": "10100896018fd847a257cd81143b8e1b7be08e40",
- "shasum": ""
- },
- "require": {
- "evenement/evenement": "^3.0 || ^2.0 || ^1.0",
- "php": ">=5.3.8",
- "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5"
- },
- "require-dev": {
- "clue/stream-filter": "~1.2",
- "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "React\\Stream\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP",
- "keywords": [
- "event-driven",
- "io",
- "non-blocking",
- "pipe",
- "reactphp",
- "readable",
- "stream",
- "writable"
- ],
- "time": "2018-01-19T15:04:38+00:00"
- },
- {
- "name": "symfony/http-foundation",
- "version": "v3.4.8",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/http-foundation.git",
- "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
- "reference": "b11e6d165ff4cbf5685d185ab19a90f2f3bb7d1e",
- "shasum": ""
- },
- "require": {
- "php": "^5.5.9|>=7.0.8",
- "symfony/polyfill-mbstring": "~1.1",
- "symfony/polyfill-php70": "~1.6"
- },
- "require-dev": {
- "symfony/expression-language": "~2.8|~3.0|~4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\HttpFoundation\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony HttpFoundation Component",
- "homepage": "https://symfony.com",
- "time": "2018-04-03T05:22:50+00:00"
- },
- {
- "name": "symfony/polyfill-mbstring",
- "version": "v1.7.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
- "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.3"
- },
- "suggest": {
- "ext-mbstring": "For best performance"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.7-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2018-01-30T19:27:44+00:00"
- },
- {
- "name": "symfony/polyfill-php70",
- "version": "v1.7.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php70.git",
- "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3532bfcd8f933a7816f3a0a59682fc404776600f",
- "reference": "3532bfcd8f933a7816f3a0a59682fc404776600f",
- "shasum": ""
- },
- "require": {
- "paragonie/random_compat": "~1.0|~2.0",
- "php": ">=5.3.3"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.7-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php70\\": ""
- },
- "files": [
- "bootstrap.php"
- ],
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2018-01-30T19:27:44+00:00"
- },
- {
- "name": "symfony/routing",
- "version": "v3.4.8",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/routing.git",
- "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/50f333b707bef9f6972ad04e6df3ec8875c9a67c",
- "reference": "50f333b707bef9f6972ad04e6df3ec8875c9a67c",
- "shasum": ""
- },
- "require": {
- "php": "^5.5.9|>=7.0.8"
- },
- "conflict": {
- "symfony/config": "<3.3.1",
- "symfony/dependency-injection": "<3.3",
- "symfony/yaml": "<3.4"
- },
- "require-dev": {
- "doctrine/annotations": "~1.0",
- "doctrine/common": "~2.2",
- "psr/log": "~1.0",
- "symfony/config": "^3.3.1|~4.0",
- "symfony/dependency-injection": "~3.3|~4.0",
- "symfony/expression-language": "~2.8|~3.0|~4.0",
- "symfony/http-foundation": "~2.8|~3.0|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "doctrine/annotations": "For using the annotation loader",
- "symfony/config": "For using the all-in-one router or any loader",
- "symfony/dependency-injection": "For loading routes from a service",
- "symfony/expression-language": "For using expression matching",
- "symfony/http-foundation": "For using a Symfony Request object",
- "symfony/yaml": "For using the YAML loader"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.4-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Routing\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony Routing Component",
- "homepage": "https://symfony.com",
- "keywords": [
- "router",
- "routing",
- "uri",
- "url"
- ],
- "time": "2018-04-04T13:22:16+00:00"
- }
- ],
- "packages-dev": [],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": [],
- "platform-dev": []
-}
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php b/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php
index c2a8dbc..178940b 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/scripts.php
@@ -1,12 +1,12 @@
-add('assets/js/fontawesome.js');
-$minifier->add('assets/js/modernizr.js');
-$minifier->add('assets/js/language.js');
-$minifier->add('assets/js/encryption.js');
-$minifier->add('assets/js/chat.js');
-$minifier->add('assets/js/slick.js');
-$minifier->add('assets/js/main.js');
+add('assets/js/fontawesome.js');
+$minifier->add('assets/js/modernizr.js');
+$minifier->add('assets/js/language.js');
+$minifier->add('assets/js/encryption.js');
+$minifier->add('assets/js/chat.js');
+$minifier->add('assets/js/slick.js');
+$minifier->add('assets/js/main.js');
echo $minifier->minify();
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php b/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php
index 66dbc50..69a2636 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/stylesheet.php
@@ -1,6 +1,6 @@
-add('assets/css/main.css');
+add('assets/css/main.css');
echo $minifier->minify();
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore
index 793ef58..b9d0923 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/cboden/ratchet/.gitignore
@@ -1,5 +1,5 @@
-phpunit.xml
-reports
-sandbox
-vendor
+phpunit.xml
+reports
+sandbox
+vendor
composer.lock
\ No newline at end of file
diff --git a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php
index 835b27a..f356ea5 100644
--- a/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php
+++ b/main/app/sprinkles/core/assets/SiteAssets/php/vendor/natxet/CssMin/src/CssMin.php
@@ -1,5155 +1,5155 @@
-
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- * --
- *
- * @package CssMin
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-/**
- * Abstract definition of a CSS token class.
- *
- * Every token has to extend this class.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssToken
-{
- /**
- * Returns the token as string.
- *
- * @return string
- */
- abstract public function __toString();
-}
-
-/**
- * Abstract definition of a for a ruleset start token.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssRulesetStartToken extends aCssToken
-{
-
-}
-
-/**
- * Abstract definition of a for ruleset end token.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssRulesetEndToken extends aCssToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "}";
- }
-}
-
-/**
- * Abstract definition of a parser plugin.
- *
- * Every parser plugin have to extend this class. A parser plugin contains the logic to parse one or aspects of a
- * stylesheet.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssParserPlugin
-{
- /**
- * Plugin configuration.
- *
- * @var array
- */
- protected $configuration = array();
- /**
- * The CssParser of the plugin.
- *
- * @var CssParser
- */
- protected $parser = null;
- /**
- * Plugin buffer.
- *
- * @var string
- */
- protected $buffer = "";
- /**
- * Constructor.
- *
- * @param CssParser $parser The CssParser object of this plugin.
- * @param array $configuration Plugin configuration [optional]
- * @return void
- */
- public function __construct(CssParser $parser, array $configuration = null)
- {
- $this->configuration = $configuration;
- $this->parser = $parser;
- }
- /**
- * Returns the array of chars triggering the parser plugin.
- *
- * @return array
- */
- abstract public function getTriggerChars();
- /**
- * Returns the array of states triggering the parser plugin or FALSE if every state will trigger the parser plugin.
- *
- * @return array
- */
- abstract public function getTriggerStates();
- /**
- * Parser routine of the plugin.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- abstract public function parse($index, $char, $previousChar, $state);
-}
-
-/**
- * Abstract definition of a minifier plugin class.
- *
- * Minifier plugin process the parsed tokens one by one to apply changes to the token. Every minifier plugin has to
- * extend this class.
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssMinifierPlugin
-{
- /**
- * Plugin configuration.
- *
- * @var array
- */
- protected $configuration = array();
- /**
- * The CssMinifier of the plugin.
- *
- * @var CssMinifier
- */
- protected $minifier = null;
- /**
- * Constructor.
- *
- * @param CssMinifier $minifier The CssMinifier object of this plugin.
- * @param array $configuration Plugin configuration [optional]
- * @return void
- */
- public function __construct(CssMinifier $minifier, array $configuration = array())
- {
- $this->configuration = $configuration;
- $this->minifier = $minifier;
- }
- /**
- * Apply the plugin to the token.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- abstract public function apply(aCssToken &$token);
- /**
- * --
- *
- * @return array
- */
- abstract public function getTriggerTokens();
-}
-
-/**
- * Abstract definition of a minifier filter class.
- *
- * Minifier filters allows a pre-processing of the parsed token to add, edit or delete tokens. Every minifier filter
- * has to extend this class.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssMinifierFilter
-{
- /**
- * Filter configuration.
- *
- * @var array
- */
- protected $configuration = array();
- /**
- * The CssMinifier of the filter.
- *
- * @var CssMinifier
- */
- protected $minifier = null;
- /**
- * Constructor.
- *
- * @param CssMinifier $minifier The CssMinifier object of this plugin.
- * @param array $configuration Filter configuration [optional]
- * @return void
- */
- public function __construct(CssMinifier $minifier, array $configuration = array())
- {
- $this->configuration = $configuration;
- $this->minifier = $minifier;
- }
- /**
- * Filter the tokens.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- abstract public function apply(array &$tokens);
-}
-
-/**
- * Abstract formatter definition.
- *
- * Every formatter have to extend this class.
- *
- * @package CssMin/Formatter
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssFormatter
-{
- /**
- * Indent string.
- *
- * @var string
- */
- protected $indent = " ";
- /**
- * Declaration padding.
- *
- * @var integer
- */
- protected $padding = 0;
- /**
- * Tokens.
- *
- * @var array
- */
- protected $tokens = array();
- /**
- * Constructor.
- *
- * @param array $tokens Array of CssToken
- * @param string $indent Indent string [optional]
- * @param integer $padding Declaration value padding [optional]
- */
- public function __construct(array $tokens, $indent = null, $padding = null)
- {
- $this->tokens = $tokens;
- $this->indent = !is_null($indent) ? $indent : $this->indent;
- $this->padding = !is_null($padding) ? $padding : $this->padding;
- }
- /**
- * Returns the array of aCssToken as formatted string.
- *
- * @return string
- */
- abstract public function __toString();
-}
-
-/**
- * Abstract definition of a ruleset declaration token.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssDeclarationToken extends aCssToken
-{
- /**
- * Is the declaration flagged as important?
- *
- * @var boolean
- */
- public $IsImportant = false;
- /**
- * Is the declaration flagged as last one of the ruleset?
- *
- * @var boolean
- */
- public $IsLast = false;
- /**
- * Property name of the declaration.
- *
- * @var string
- */
- public $Property = "";
- /**
- * Value of the declaration.
- *
- * @var string
- */
- public $Value = "";
- /**
- * Set the properties of the @font-face declaration.
- *
- * @param string $property Property of the declaration
- * @param string $value Value of the declaration
- * @param boolean $isImportant Is the !important flag is set?
- * @param boolean $IsLast Is the declaration the last one of the block?
- * @return void
- */
- public function __construct($property, $value, $isImportant = false, $isLast = false)
- {
- $this->Property = $property;
- $this->Value = $value;
- $this->IsImportant = $isImportant;
- $this->IsLast = $isLast;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return $this->Property . ":" . $this->Value . ($this->IsImportant ? " !important" : "") . ($this->IsLast ? "" : ";");
- }
-}
-
-/**
- * Abstract definition of a for at-rule block start token.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssAtBlockStartToken extends aCssToken
-{
-
-}
-
-/**
- * Abstract definition of a for at-rule block end token.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-abstract class aCssAtBlockEndToken extends aCssToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "}";
- }
-}
-
-/**
- * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/etzLs Whitesmiths indent style}.
- *
- * @package CssMin/Formatter
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssWhitesmithsFormatter extends aCssFormatter
-{
- /**
- * Implements {@link aCssFormatter::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- $r = array();
- $level = 0;
- for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
- {
- $token = $this->tokens[$i];
- $class = get_class($token);
- $indent = str_repeat($this->indent, $level);
- if ($class === "CssCommentToken")
- {
- $lines = array_map("trim", explode("\n", $token->Comment));
- for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
- {
- $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
- }
- }
- elseif ($class === "CssAtCharsetToken")
- {
- $r[] = $indent . "@charset " . $token->Charset . ";";
- }
- elseif ($class === "CssAtFontFaceStartToken")
- {
- $r[] = $indent . "@font-face";
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssAtImportToken")
- {
- $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
- }
- elseif ($class === "CssAtKeyframesStartToken")
- {
- $r[] = $indent . "@keyframes " . $token->Name;
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssAtMediaStartToken")
- {
- $r[] = $indent . "@media " . implode(", ", $token->MediaTypes);
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssAtPageStartToken")
- {
- $r[] = $indent . "@page";
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssAtVariablesStartToken")
- {
- $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes);
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
- {
- $r[] = $indent . implode(", ", $token->Selectors);
- $r[] = $this->indent . $indent . "{";
- $level++;
- }
- elseif ($class === "CssAtFontFaceDeclarationToken"
- || $class === "CssAtKeyframesRulesetDeclarationToken"
- || $class === "CssAtPageDeclarationToken"
- || $class === "CssAtVariablesDeclarationToken"
- || $class === "CssRulesetDeclarationToken"
- )
- {
- $declaration = $indent . $token->Property . ": ";
- if ($this->padding)
- {
- $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
- }
- $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
- }
- elseif ($class === "CssAtFontFaceEndToken"
- || $class === "CssAtMediaEndToken"
- || $class === "CssAtKeyframesEndToken"
- || $class === "CssAtKeyframesRulesetEndToken"
- || $class === "CssAtPageEndToken"
- || $class === "CssAtVariablesEndToken"
- || $class === "CssRulesetEndToken"
- )
- {
- $r[] = $indent . "}";
- $level--;
- }
- }
- return implode("\n", $r);
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will process var-statement and sets the declaration value to the variable value.
- *
- * This plugin only apply the variable values. The variable values itself will get parsed by the
- * {@link CssVariablesMinifierFilter}.
- *
- * Example:
- *
- * @variables
- * {
- * defaultColor: black;
- * }
- * color: var(defaultColor);
- *
- *
- * Will get converted to:
- *
- * color:black;
- *
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssVariablesMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Regular expression matching a value.
- *
- * @var string
- */
- private $reMatch = "/var\((.+)\)/iSU";
- /**
- * Parsed variables.
- *
- * @var array
- */
- private $variables = null;
- /**
- * Returns the variables.
- *
- * @return array
- */
- public function getVariables()
- {
- return $this->variables;
- }
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (stripos($token->Value, "var") !== false && preg_match_all($this->reMatch, $token->Value, $m))
- {
- $mediaTypes = $token->MediaTypes;
- if (!in_array("all", $mediaTypes))
- {
- $mediaTypes[] = "all";
- }
- for ($i = 0, $l = count($m[0]); $i < $l; $i++)
- {
- $variable = trim($m[1][$i]);
- foreach ($mediaTypes as $mediaType)
- {
- if (isset($this->variables[$mediaType], $this->variables[$mediaType][$variable]))
- {
- // Variable value found => set the declaration value to the variable value and return
- $token->Value = str_replace($m[0][$i], $this->variables[$mediaType][$variable], $token->Value);
- continue 2;
- }
- }
- // If no value was found trigger an error and replace the token with a CssNullToken
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": No value found for variable " . $variable . "
in media types " . implode(", ", $mediaTypes) . "
", (string) $token));
- $token = new CssNullToken();
- return true;
- }
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
- /**
- * Sets the variables.
- *
- * @param array $variables Variables to set
- * @return void
- */
- public function setVariables(array $variables)
- {
- $this->variables = $variables;
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} will parse the variable declarations out of @variables at-rule
- * blocks. The variables will get store in the {@link CssVariablesMinifierPlugin} that will apply the variables to
- * declaration.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssVariablesMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $variables = array();
- $defaultMediaTypes = array("all");
- $mediaTypes = array();
- $remove = array();
- for($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- // @variables at-rule block found
- if (get_class($tokens[$i]) === "CssAtVariablesStartToken")
- {
- $remove[] = $i;
- $mediaTypes = (count($tokens[$i]->MediaTypes) == 0 ? $defaultMediaTypes : $tokens[$i]->MediaTypes);
- foreach ($mediaTypes as $mediaType)
- {
- if (!isset($variables[$mediaType]))
- {
- $variables[$mediaType] = array();
- }
- }
- // Read the variable declaration tokens
- for($i = $i; $i < $l; $i++)
- {
- // Found a variable declaration => read the variable values
- if (get_class($tokens[$i]) === "CssAtVariablesDeclarationToken")
- {
- foreach ($mediaTypes as $mediaType)
- {
- $variables[$mediaType][$tokens[$i]->Property] = $tokens[$i]->Value;
- }
- $remove[] = $i;
- }
- // Found the variables end token => break;
- elseif (get_class($tokens[$i]) === "CssAtVariablesEndToken")
- {
- $remove[] = $i;
- break;
- }
- }
- }
- }
- // Variables in @variables at-rule blocks
- foreach($variables as $mediaType => $null)
- {
- foreach($variables[$mediaType] as $variable => $value)
- {
- // If a var() statement in a variable value found...
- if (stripos($value, "var") !== false && preg_match_all("/var\((.+)\)/iSU", $value, $m))
- {
- // ... then replace the var() statement with the variable values.
- for ($i = 0, $l = count($m[0]); $i < $l; $i++)
- {
- $variables[$mediaType][$variable] = str_replace($m[0][$i], (isset($variables[$mediaType][$m[1][$i]]) ? $variables[$mediaType][$m[1][$i]] : ""), $variables[$mediaType][$variable]);
- }
- }
- }
- }
- // Remove the complete @variables at-rule block
- foreach ($remove as $i)
- {
- $tokens[$i] = null;
- }
- if (!($plugin = $this->minifier->getPlugin("CssVariablesMinifierPlugin")))
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin CssVariablesMinifierPlugin
was not found but is required for " . __CLASS__ . "
"));
- }
- else
- {
- $plugin->setVariables($variables);
- }
- return count($remove);
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for preserve parsing url() values.
- *
- * This plugin return no {@link aCssToken CssToken} but ensures that url() values will get parsed properly.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssUrlParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("(", ")");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return false;
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of string
- if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 3, 4)) === "url(" && $state !== "T_URL")
- {
- $this->parser->pushState("T_URL");
- $this->parser->setExclusive(__CLASS__);
- }
- // Escaped LF in url => remove escape backslash and LF
- elseif ($char === "\n" && $previousChar === "\\" && $state === "T_URL")
- {
- $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
- }
- // Parse error: Unescaped LF in string literal
- elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_URL")
- {
- $line = $this->parser->getBuffer();
- $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . ")"); // Replace the LF with the url string delimiter
- $this->parser->popState();
- $this->parser->unsetExclusive();
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
- }
- // End of string
- elseif ($char === ")" && $state === "T_URL")
- {
- $this->parser->popState();
- $this->parser->unsetExclusive();
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for preserve parsing string values.
- *
- * This plugin return no {@link aCssToken CssToken} but ensures that string values will get parsed properly.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssStringParserPlugin extends aCssParserPlugin
-{
- /**
- * Current string delimiter char.
- *
- * @var string
- */
- private $delimiterChar = null;
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("\"", "'", "\n");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return false;
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of string
- if (($char === "\"" || $char === "'") && $state !== "T_STRING")
- {
- $this->delimiterChar = $char;
- $this->parser->pushState("T_STRING");
- $this->parser->setExclusive(__CLASS__);
- }
- // Escaped LF in string => remove escape backslash and LF
- elseif ($char === "\n" && $previousChar === "\\" && $state === "T_STRING")
- {
- $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
- }
- // Parse error: Unescaped LF in string literal
- elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_STRING")
- {
- $line = $this->parser->getBuffer();
- $this->parser->popState();
- $this->parser->unsetExclusive();
- $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . $this->delimiterChar); // Replace the LF with the current string char
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
- $this->delimiterChar = null;
- }
- // End of string
- elseif ($char === $this->delimiterChar && $state === "T_STRING")
- {
- // If the Previous char is a escape char count the amount of the previous escape chars. If the amount of
- // escape chars is uneven do not end the string
- if ($previousChar == "\\")
- {
- $source = $this->parser->getSource();
- $c = 1;
- $i = $index - 2;
- while (substr($source, $i, 1) === "\\")
- {
- $c++; $i--;
- }
- if ($c % 2)
- {
- return false;
- }
- }
- $this->parser->popState();
- $this->parser->unsetExclusive();
- $this->delimiterChar = null;
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} sorts the ruleset declarations of a ruleset by name.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Rowan Beentje
- * @copyright Rowan Beentje
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssSortRulesetPropertiesMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- // Only look for ruleset start rules
- if (get_class($tokens[$i]) !== "CssRulesetStartToken") { continue; }
- // Look for the corresponding ruleset end
- $endIndex = false;
- for ($ii = $i + 1; $ii < $l; $ii++)
- {
- if (get_class($tokens[$ii]) !== "CssRulesetEndToken") { continue; }
- $endIndex = $ii;
- break;
- }
- if (!$endIndex) { break; }
- $startIndex = $i;
- $i = $endIndex;
- // Skip if there's only one token in this ruleset
- if ($endIndex - $startIndex <= 2) { continue; }
- // Ensure that everything between the start and end is a declaration token, for safety
- for ($ii = $startIndex + 1; $ii < $endIndex; $ii++)
- {
- if (get_class($tokens[$ii]) !== "CssRulesetDeclarationToken") { continue(2); }
- }
- $declarations = array_slice($tokens, $startIndex + 1, $endIndex - $startIndex - 1);
- // Check whether a sort is required
- $sortRequired = $lastPropertyName = false;
- foreach ($declarations as $declaration)
- {
- if ($lastPropertyName)
- {
- if (strcmp($lastPropertyName, $declaration->Property) > 0)
- {
- $sortRequired = true;
- break;
- }
- }
- $lastPropertyName = $declaration->Property;
- }
- if (!$sortRequired) { continue; }
- // Arrange the declarations alphabetically by name
- usort($declarations, array(__CLASS__, "userDefinedSort1"));
- // Update "IsLast" property
- for ($ii = 0, $ll = count($declarations) - 1; $ii <= $ll; $ii++)
- {
- if ($ii == $ll)
- {
- $declarations[$ii]->IsLast = true;
- }
- else
- {
- $declarations[$ii]->IsLast = false;
- }
- }
- // Splice back into the array.
- array_splice($tokens, $startIndex + 1, $endIndex - $startIndex - 1, $declarations);
- $r += $endIndex - $startIndex - 1;
- }
- return $r;
- }
- /**
- * User defined sort function.
- *
- * @return integer
- */
- public static function userDefinedSort1($a, $b)
- {
- return strcmp($a->Property, $b->Property);
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a ruleset.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRulesetStartToken extends aCssRulesetStartToken
-{
- /**
- * Array of selectors.
- *
- * @var array
- */
- public $Selectors = array();
- /**
- * Set the properties of a ruleset token.
- *
- * @param array $selectors Selectors of the ruleset
- * @return void
- */
- public function __construct(array $selectors = array())
- {
- $this->Selectors = $selectors;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return implode(",", $this->Selectors) . "{";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing ruleset block with including declarations.
- *
- * Found rulesets will add a {@link CssRulesetStartToken} and {@link CssRulesetEndToken} to the
- * parser; including declarations as {@link CssRulesetDeclarationToken}.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRulesetParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array(",", "{", "}", ":", ";");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_MEDIA", "T_RULESET::SELECTORS", "T_RULESET", "T_RULESET_DECLARATION");
- }
- /**
- * Selectors.
- *
- * @var array
- */
- private $selectors = array();
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of Ruleset and selectors
- if ($char === "," && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
- {
- if ($state !== "T_RULESET::SELECTORS")
- {
- $this->parser->pushState("T_RULESET::SELECTORS");
- }
- $this->selectors[] = $this->parser->getAndClearBuffer(",{");
- }
- // End of selectors and start of declarations
- elseif ($char === "{" && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
- {
- if ($this->parser->getBuffer() !== "")
- {
- $this->selectors[] = $this->parser->getAndClearBuffer(",{");
- if ($state == "T_RULESET::SELECTORS")
- {
- $this->parser->popState();
- }
- $this->parser->pushState("T_RULESET");
- $this->parser->appendToken(new CssRulesetStartToken($this->selectors));
- $this->selectors = array();
- }
- }
- // Start of declaration
- elseif ($char === ":" && $state === "T_RULESET")
- {
- $this->parser->pushState("T_RULESET_DECLARATION");
- $this->buffer = $this->parser->getAndClearBuffer(":;", true);
- }
- // Unterminated ruleset declaration
- elseif ($char === ":" && $state === "T_RULESET_DECLARATION")
- {
- // Ignore Internet Explorer filter declarations
- if ($this->buffer === "filter")
- {
- return false;
- }
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
- }
- // End of declaration
- elseif (($char === ";" || $char === "}") && $state === "T_RULESET_DECLARATION")
- {
- $value = $this->parser->getAndClearBuffer(";}");
- if (strtolower(substr($value, -10, 10)) === "!important")
- {
- $value = trim(substr($value, 0, -10));
- $isImportant = true;
- }
- else
- {
- $isImportant = false;
- }
- $this->parser->popState();
- $this->parser->appendToken(new CssRulesetDeclarationToken($this->buffer, $value, $this->parser->getMediaTypes(), $isImportant));
- // Declaration ends with a right curly brace; so we have to end the ruleset
- if ($char === "}")
- {
- $this->parser->appendToken(new CssRulesetEndToken());
- $this->parser->popState();
- }
- $this->buffer = "";
- }
- // End of ruleset
- elseif ($char === "}" && $state === "T_RULESET")
- {
- $this->parser->popState();
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssRulesetEndToken());
- $this->buffer = "";
- $this->selectors = array();
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a ruleset.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRulesetEndToken extends aCssRulesetEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a ruleset declaration.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRulesetDeclarationToken extends aCssDeclarationToken
-{
- /**
- * Media types of the declaration.
- *
- * @var array
- */
- public $MediaTypes = array("all");
- /**
- * Set the properties of a ddocument- or at-rule @media level declaration.
- *
- * @param string $property Property of the declaration
- * @param string $value Value of the declaration
- * @param mixed $mediaTypes Media types of the declaration
- * @param boolean $isImportant Is the !important flag is set
- * @param boolean $isLast Is the declaration the last one of the ruleset
- * @return void
- */
- public function __construct($property, $value, $mediaTypes = null, $isImportant = false, $isLast = false)
- {
- parent::__construct($property, $value, $isImportant, $isLast);
- $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} sets the IsLast property of any last declaration in a ruleset,
- * @font-face at-rule or @page at-rule block. If the property IsLast is TRUE the decrations will get stringified
- * without tailing semicolon.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRemoveLastDelarationSemiColonMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- $current = get_class($tokens[$i]);
- $next = isset($tokens[$i+1]) ? get_class($tokens[$i+1]) : false;
- if (($current === "CssRulesetDeclarationToken" && $next === "CssRulesetEndToken") ||
- ($current === "CssAtFontFaceDeclarationToken" && $next === "CssAtFontFaceEndToken") ||
- ($current === "CssAtPageDeclarationToken" && $next === "CssAtPageEndToken"))
- {
- $tokens[$i]->IsLast = true;
- }
- }
- return 0;
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} will remove any empty rulesets (including @keyframes at-rule block
- * rulesets).
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRemoveEmptyRulesetsMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- $current = get_class($tokens[$i]);
- $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
- if (($current === "CssRulesetStartToken" && $next === "CssRulesetEndToken") ||
- ($current === "CssAtKeyframesRulesetStartToken" && $next === "CssAtKeyframesRulesetEndToken" && !array_intersect(array("from", "0%", "to", "100%"), array_map("strtolower", $tokens[$i]->Selectors)))
- )
- {
- $tokens[$i] = null;
- $tokens[$i + 1] = null;
- $i++;
- $r = $r + 2;
- }
- }
- return $r;
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} will remove any empty @font-face, @keyframes, @media and @page
- * at-rule blocks.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRemoveEmptyAtBlocksMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- $current = get_class($tokens[$i]);
- $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
- if (($current === "CssAtFontFaceStartToken" && $next === "CssAtFontFaceEndToken") ||
- ($current === "CssAtKeyframesStartToken" && $next === "CssAtKeyframesEndToken") ||
- ($current === "CssAtPageStartToken" && $next === "CssAtPageEndToken") ||
- ($current === "CssAtMediaStartToken" && $next === "CssAtMediaEndToken"))
- {
- $tokens[$i] = null;
- $tokens[$i + 1] = null;
- $i++;
- $r = $r + 2;
- }
- }
- return $r;
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} will remove any comments from the array of parsed tokens.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssRemoveCommentsMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Regular expression whitelisting any important comments to preserve.
- *
- * @var string
- */
- private $whitelistPattern = '/(^\/\*!|@preserve|copyright|license|author|https?:|www\.)/i';
-
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- if (get_class($tokens[$i]) === "CssCommentToken")
- {
- if (!preg_match($this->whitelistPattern, $tokens[$i]->Comment))
- {
- $tokens[$i] = null;
- $r++;
- }
- }
- }
- return $r;
- }
-}
-
-/**
- * CSS Parser.
- *
- * @package CssMin/Parser
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssParser
-{
- /**
- * Parse buffer.
- *
- * @var string
- */
- private $buffer = "";
- /**
- * {@link aCssParserPlugin Plugins}.
- *
- * @var array
- */
- private $plugins = array();
- /**
- * Source to parse.
- *
- * @var string
- */
- private $source = "";
- /**
- * Current state.
- *
- * @var integer
- */
- private $state = "T_DOCUMENT";
- /**
- * Exclusive state.
- *
- * @var string
- */
- private $stateExclusive = false;
- /**
- * Media types state.
- *
- * @var mixed
- */
- private $stateMediaTypes = false;
- /**
- * State stack.
- *
- * @var array
- */
- private $states = array("T_DOCUMENT");
- /**
- * Parsed tokens.
- *
- * @var array
- */
- private $tokens = array();
- /**
- * Constructer.
- *
- * Create instances of the used {@link aCssParserPlugin plugins}.
- *
- * @param string $source CSS source [optional]
- * @param array $plugins Plugin configuration [optional]
- * @return void
- */
- public function __construct($source = null, array $plugins = null)
- {
- $plugins = array_merge(array
- (
- "Comment" => true,
- "String" => true,
- "Url" => true,
- "Expression" => true,
- "Ruleset" => true,
- "AtCharset" => true,
- "AtFontFace" => true,
- "AtImport" => true,
- "AtKeyframes" => true,
- "AtMedia" => true,
- "AtPage" => true,
- "AtVariables" => true
- ), is_array($plugins) ? $plugins : array());
- // Create plugin instances
- foreach ($plugins as $name => $config)
- {
- if ($config !== false)
- {
- $class = "Css" . $name . "ParserPlugin";
- $config = is_array($config) ? $config : array();
- if (class_exists($class))
- {
- $this->plugins[] = new $class($this, $config);
- }
- else
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . "
with the class name " . $class . "
was not found"));
- }
- }
- }
- if (!is_null($source))
- {
- $this->parse($source);
- }
- }
- /**
- * Append a token to the array of tokens.
- *
- * @param aCssToken $token Token to append
- * @return void
- */
- public function appendToken(aCssToken $token)
- {
- $this->tokens[] = $token;
- }
- /**
- * Clears the current buffer.
- *
- * @return void
- */
- public function clearBuffer()
- {
- $this->buffer = "";
- }
- /**
- * Returns and clear the current buffer.
- *
- * @param string $trim Chars to use to trim the returned buffer
- * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
- * @return string
- */
- public function getAndClearBuffer($trim = "", $tolower = false)
- {
- $r = $this->getBuffer($trim, $tolower);
- $this->buffer = "";
- return $r;
- }
- /**
- * Returns the current buffer.
- *
- * @param string $trim Chars to use to trim the returned buffer
- * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
- * @return string
- */
- public function getBuffer($trim = "", $tolower = false)
- {
- $r = $this->buffer;
- if ($trim)
- {
- $r = trim($r, " \t\n\r\0\x0B" . $trim);
- }
- if ($tolower)
- {
- $r = strtolower($r);
- }
- return $r;
- }
- /**
- * Returns the current media types state.
- *
- * @return array
- */
- public function getMediaTypes()
- {
- return $this->stateMediaTypes;
- }
- /**
- * Returns the CSS source.
- *
- * @return string
- */
- public function getSource()
- {
- return $this->source;
- }
- /**
- * Returns the current state.
- *
- * @return integer The current state
- */
- public function getState()
- {
- return $this->state;
- }
- /**
- * Returns a plugin by class name.
- *
- * @param string $name Class name of the plugin
- * @return aCssParserPlugin
- */
- public function getPlugin($class)
- {
- static $index = null;
- if (is_null($index))
- {
- $index = array();
- for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
- {
- $index[get_class($this->plugins[$i])] = $i;
- }
- }
- return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
- }
- /**
- * Returns the parsed tokens.
- *
- * @return array
- */
- public function getTokens()
- {
- return $this->tokens;
- }
- /**
- * Returns if the current state equals the passed state.
- *
- * @param integer $state State to compare with the current state
- * @return boolean TRUE is the state equals to the passed state; FALSE if not
- */
- public function isState($state)
- {
- return ($this->state == $state);
- }
- /**
- * Parse the CSS source and return a array with parsed tokens.
- *
- * @param string $source CSS source
- * @return array Array with tokens
- */
- public function parse($source)
- {
- // Reset
- $this->source = "";
- $this->tokens = array();
- // Create a global and plugin lookup table for trigger chars; set array of plugins as local variable and create
- // several helper variables for plugin handling
- $globalTriggerChars = "";
- $plugins = $this->plugins;
- $pluginCount = count($plugins);
- $pluginIndex = array();
- $pluginTriggerStates = array();
- $pluginTriggerChars = array();
- for ($i = 0, $l = count($plugins); $i < $l; $i++)
- {
- $tPluginClassName = get_class($plugins[$i]);
- $pluginTriggerChars[$i] = implode("", $plugins[$i]->getTriggerChars());
- $tPluginTriggerStates = $plugins[$i]->getTriggerStates();
- $pluginTriggerStates[$i] = $tPluginTriggerStates === false ? false : "|" . implode("|", $tPluginTriggerStates) . "|";
- $pluginIndex[$tPluginClassName] = $i;
- for ($ii = 0, $ll = strlen($pluginTriggerChars[$i]); $ii < $ll; $ii++)
- {
- $c = substr($pluginTriggerChars[$i], $ii, 1);
- if (strpos($globalTriggerChars, $c) === false)
- {
- $globalTriggerChars .= $c;
- }
- }
- }
- // Normalise line endings
- $source = str_replace("\r\n", "\n", $source); // Windows to Unix line endings
- $source = str_replace("\r", "\n", $source); // Mac to Unix line endings
- $this->source = $source;
- // Variables
- $buffer = &$this->buffer;
- $exclusive = &$this->stateExclusive;
- $state = &$this->state;
- $c = $p = null;
- // --
- for ($i = 0, $l = strlen($source); $i < $l; $i++)
- {
- // Set the current Char
- $c = $source[$i]; // Is faster than: $c = substr($source, $i, 1);
- // Normalize and filter double whitespace characters
- if ($exclusive === false)
- {
- if ($c === "\n" || $c === "\t")
- {
- $c = " ";
- }
- if ($c === " " && $p === " ")
- {
- continue;
- }
- }
- $buffer .= $c;
-
- // Fix case when value of url() contains parentheses, for example: url("data: ... ()")
- if ($this->getState() == 'T_URL' && $c == ')') {
- $trimmedBuffer = trim($buffer);
- if (preg_match('@url\((\s+)?".+@', $trimmedBuffer)
- && !preg_match('@url\((\s+)?".+"\)@', $trimmedBuffer)
- || preg_match('@url\((\s+)?\'.+@', $trimmedBuffer)
- && !preg_match('@url\((\s+)?\'.+\'\)@', $trimmedBuffer)
- ) {
- $p = $c; // Set the parent char
- continue;
- }
- }
-
- // Extended processing only if the current char is a global trigger char
- if (strpos($globalTriggerChars, $c) !== false)
- {
- // Exclusive state is set; process with the exclusive plugin
- if ($exclusive)
- {
- $tPluginIndex = $pluginIndex[$exclusive];
- if (strpos($pluginTriggerChars[$tPluginIndex], $c) !== false && ($pluginTriggerStates[$tPluginIndex] === false || strpos($pluginTriggerStates[$tPluginIndex], $state) !== false))
- {
- $r = $plugins[$tPluginIndex]->parse($i, $c, $p, $state);
- // Return value is TRUE => continue with next char
- if ($r === true)
- {
- continue;
- }
- // Return value is numeric => set new index and continue with next char
- elseif ($r !== false && $r != $i)
- {
- $i = $r;
- continue;
- }
- }
- }
- // Else iterate through the plugins
- else
- {
- $triggerState = "|" . $state . "|";
- for ($ii = 0, $ll = $pluginCount; $ii < $ll; $ii++)
- {
- // Only process if the current char is one of the plugin trigger chars
- if (strpos($pluginTriggerChars[$ii], $c) !== false && ($pluginTriggerStates[$ii] === false || strpos($pluginTriggerStates[$ii], $triggerState) !== false))
- {
- // Process with the plugin
- $r = $plugins[$ii]->parse($i, $c, $p, $state);
- // Return value is TRUE => break the plugin loop and and continue with next char
- if ($r === true)
- {
- break;
- }
- // Return value is numeric => set new index, break the plugin loop and and continue with next char
- elseif ($r !== false && $r != $i)
- {
- $i = $r;
- break;
- }
- }
- }
- }
- }
- $p = $c; // Set the parent char
- }
- return $this->tokens;
- }
- /**
- * Remove the last state of the state stack and return the removed stack value.
- *
- * @return integer Removed state value
- */
- public function popState()
- {
- $r = array_pop($this->states);
- $this->state = $this->states[count($this->states) - 1];
- return $r;
- }
- /**
- * Adds a new state onto the state stack.
- *
- * @param integer $state State to add onto the state stack.
- * @return integer The index of the added state in the state stacks
- */
- public function pushState($state)
- {
- $r = array_push($this->states, $state);
- $this->state = $this->states[count($this->states) - 1];
- return $r;
- }
- /**
- * Sets/restores the buffer.
- *
- * @param string $buffer Buffer to set
- * @return void
- */
- public function setBuffer($buffer)
- {
- $this->buffer = $buffer;
- }
- /**
- * Set the exclusive state.
- *
- * @param string $exclusive Exclusive state
- * @return void
- */
- public function setExclusive($exclusive)
- {
- $this->stateExclusive = $exclusive;
- }
- /**
- * Set the media types state.
- *
- * @param array $mediaTypes Media types state
- * @return void
- */
- public function setMediaTypes(array $mediaTypes)
- {
- $this->stateMediaTypes = $mediaTypes;
- }
- /**
- * Sets the current state in the state stack; equals to {@link CssParser::popState()} + {@link CssParser::pushState()}.
- *
- * @param integer $state State to set
- * @return integer
- */
- public function setState($state)
- {
- $r = array_pop($this->states);
- array_push($this->states, $state);
- $this->state = $this->states[count($this->states) - 1];
- return $r;
- }
- /**
- * Removes the exclusive state.
- *
- * @return void
- */
- public function unsetExclusive()
- {
- $this->stateExclusive = false;
- }
- /**
- * Removes the media types state.
- *
- * @return void
- */
- public function unsetMediaTypes()
- {
- $this->stateMediaTypes = false;
- }
-}
-
-/**
- * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/j4XdU OTBS indent style} (The One True Brace Style).
- *
- * @package CssMin/Formatter
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssOtbsFormatter extends aCssFormatter
-{
- /**
- * Implements {@link aCssFormatter::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- $r = array();
- $level = 0;
- for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
- {
- $token = $this->tokens[$i];
- $class = get_class($token);
- $indent = str_repeat($this->indent, $level);
- if ($class === "CssCommentToken")
- {
- $lines = array_map("trim", explode("\n", $token->Comment));
- for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
- {
- $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
- }
- }
- elseif ($class === "CssAtCharsetToken")
- {
- $r[] = $indent . "@charset " . $token->Charset . ";";
- }
- elseif ($class === "CssAtFontFaceStartToken")
- {
- $r[] = $indent . "@font-face {";
- $level++;
- }
- elseif ($class === "CssAtImportToken")
- {
- $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
- }
- elseif ($class === "CssAtKeyframesStartToken")
- {
- $r[] = $indent . "@keyframes " . $token->Name . " {";
- $level++;
- }
- elseif ($class === "CssAtMediaStartToken")
- {
- $r[] = $indent . "@media " . implode(", ", $token->MediaTypes) . " {";
- $level++;
- }
- elseif ($class === "CssAtPageStartToken")
- {
- $r[] = $indent . "@page {";
- $level++;
- }
- elseif ($class === "CssAtVariablesStartToken")
- {
- $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes) . " {";
- $level++;
- }
- elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
- {
- $r[] = $indent . implode(", ", $token->Selectors) . " {";
- $level++;
- }
- elseif ($class === "CssAtFontFaceDeclarationToken"
- || $class === "CssAtKeyframesRulesetDeclarationToken"
- || $class === "CssAtPageDeclarationToken"
- || $class === "CssAtVariablesDeclarationToken"
- || $class === "CssRulesetDeclarationToken"
- )
- {
- $declaration = $indent . $token->Property . ": ";
- if ($this->padding)
- {
- $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
- }
- $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
- }
- elseif ($class === "CssAtFontFaceEndToken"
- || $class === "CssAtMediaEndToken"
- || $class === "CssAtKeyframesEndToken"
- || $class === "CssAtKeyframesRulesetEndToken"
- || $class === "CssAtPageEndToken"
- || $class === "CssAtVariablesEndToken"
- || $class === "CssRulesetEndToken"
- )
- {
- $level--;
- $r[] = str_repeat($indent, $level) . "}";
- }
- }
- return implode("\n", $r);
- }
-}
-
-/**
- * This {@link aCssToken CSS token} is a utility token that extends {@link aNullToken} and returns only a empty string.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssNullToken extends aCssToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "";
- }
-}
-
-/**
- * CSS Minifier.
- *
- * @package CssMin/Minifier
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssMinifier
-{
- /**
- * {@link aCssMinifierFilter Filters}.
- *
- * @var array
- */
- private $filters = array();
- /**
- * {@link aCssMinifierPlugin Plugins}.
- *
- * @var array
- */
- private $plugins = array();
- /**
- * Minified source.
- *
- * @var string
- */
- private $minified = "";
- /**
- * Constructer.
- *
- * Creates instances of {@link aCssMinifierFilter filters} and {@link aCssMinifierPlugin plugins}.
- *
- * @param string $source CSS source [optional]
- * @param array $filters Filter configuration [optional]
- * @param array $plugins Plugin configuration [optional]
- * @return void
- */
- public function __construct($source = null, array $filters = null, array $plugins = null)
- {
- $filters = array_merge(array
- (
- "ImportImports" => false,
- "RemoveComments" => true,
- "RemoveEmptyRulesets" => true,
- "RemoveEmptyAtBlocks" => true,
- "ConvertLevel3Properties" => false,
- "ConvertLevel3AtKeyframes" => false,
- "Variables" => true,
- "RemoveLastDelarationSemiColon" => true
- ), is_array($filters) ? $filters : array());
- $plugins = array_merge(array
- (
- "Variables" => true,
- "ConvertFontWeight" => false,
- "ConvertHslColors" => false,
- "ConvertRgbColors" => false,
- "ConvertNamedColors" => false,
- "CompressColorValues" => false,
- "CompressUnitValues" => false,
- "CompressExpressionValues" => false
- ), is_array($plugins) ? $plugins : array());
- // Filters
- foreach ($filters as $name => $config)
- {
- if ($config !== false)
- {
- $class = "Css" . $name . "MinifierFilter";
- $config = is_array($config) ? $config : array();
- if (class_exists($class))
- {
- $this->filters[] = new $class($this, $config);
- }
- else
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The filter " . $name . "
with the class name " . $class . "
was not found"));
- }
- }
- }
- // Plugins
- foreach ($plugins as $name => $config)
- {
- if ($config !== false)
- {
- $class = "Css" . $name . "MinifierPlugin";
- $config = is_array($config) ? $config : array();
- if (class_exists($class))
- {
- $this->plugins[] = new $class($this, $config);
- }
- else
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . "
with the class name " . $class . "
was not found"));
- }
- }
- }
- // --
- if (!is_null($source))
- {
- $this->minify($source);
- }
- }
- /**
- * Returns the minified Source.
- *
- * @return string
- */
- public function getMinified()
- {
- return $this->minified;
- }
- /**
- * Returns a plugin by class name.
- *
- * @param string $name Class name of the plugin
- * @return aCssMinifierPlugin
- */
- public function getPlugin($class)
- {
- static $index = null;
- if (is_null($index))
- {
- $index = array();
- for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
- {
- $index[get_class($this->plugins[$i])] = $i;
- }
- }
- return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
- }
- /**
- * Minifies the CSS source.
- *
- * @param string $source CSS source
- * @return string
- */
- public function minify($source)
- {
- // Variables
- $r = "";
- $parser = new CssParser($source);
- $tokens = $parser->getTokens();
- $filters = $this->filters;
- $filterCount = count($this->filters);
- $plugins = $this->plugins;
- $pluginCount = count($plugins);
- $pluginIndex = array();
- $pluginTriggerTokens = array();
- $globalTriggerTokens = array();
- for ($i = 0, $l = count($plugins); $i < $l; $i++)
- {
- $tPluginClassName = get_class($plugins[$i]);
- $pluginTriggerTokens[$i] = $plugins[$i]->getTriggerTokens();
- foreach ($pluginTriggerTokens[$i] as $v)
- {
- if (!in_array($v, $globalTriggerTokens))
- {
- $globalTriggerTokens[] = $v;
- }
- }
- $pluginTriggerTokens[$i] = "|" . implode("|", $pluginTriggerTokens[$i]) . "|";
- $pluginIndex[$tPluginClassName] = $i;
- }
- $globalTriggerTokens = "|" . implode("|", $globalTriggerTokens) . "|";
- /*
- * Apply filters
- */
- for($i = 0; $i < $filterCount; $i++)
- {
- // Apply the filter; if the return value is larger than 0...
- if ($filters[$i]->apply($tokens) > 0)
- {
- // ...then filter null values and rebuild the token array
- $tokens = array_values(array_filter($tokens));
- }
- }
- $tokenCount = count($tokens);
- /*
- * Apply plugins
- */
- for($i = 0; $i < $tokenCount; $i++)
- {
- $triggerToken = "|" . get_class($tokens[$i]) . "|";
- if (strpos($globalTriggerTokens, $triggerToken) !== false)
- {
- for($ii = 0; $ii < $pluginCount; $ii++)
- {
- if (strpos($pluginTriggerTokens[$ii], $triggerToken) !== false || $pluginTriggerTokens[$ii] === false)
- {
- // Apply the plugin; if the return value is TRUE continue to the next token
- if ($plugins[$ii]->apply($tokens[$i]) === true)
- {
- continue 2;
- }
- }
- }
- }
- }
- // Stringify the tokens
- for($i = 0; $i < $tokenCount; $i++)
- {
- $r .= (string) $tokens[$i];
- }
- $this->minified = $r;
- return $r;
- }
-}
-
-/**
- * CssMin - A (simple) css minifier with benefits
- *
- * --
- * Copyright (c) 2011 Joe Scylla
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- * --
- *
- * @package CssMin
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssMin
-{
- /**
- * Index of classes
- *
- * @var array
- */
- private static $classIndex = array();
- /**
- * Parse/minify errors
- *
- * @var array
- */
- private static $errors = array();
- /**
- * Verbose output.
- *
- * @var boolean
- */
- private static $isVerbose = false;
- /**
- * {@link http://goo.gl/JrW54 Autoload} function of CssMin.
- *
- * @param string $class Name of the class
- * @return void
- */
- public static function autoload($class)
- {
- if (isset(self::$classIndex[$class]))
- {
- require(self::$classIndex[$class]);
- }
- }
- /**
- * Return errors
- *
- * @return array of {CssError}.
- */
- public static function getErrors()
- {
- return self::$errors;
- }
- /**
- * Returns if there were errors.
- *
- * @return boolean
- */
- public static function hasErrors()
- {
- return count(self::$errors) > 0;
- }
- /**
- * Initialises CssMin.
- *
- * @return void
- */
- public static function initialise()
- {
- // Create the class index for autoloading or including
- $paths = array(dirname(__FILE__));
- for ($i = 0; $i < count($paths); $i++)
- {
- $path = $paths[$i];
- $subDirectorys = glob($path . "*", GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
- if (is_array($subDirectorys))
- {
- foreach ($subDirectorys as $subDirectory)
- {
- $paths[] = $subDirectory;
- }
- }
- $files = glob($path . "*.php", 0);
- if (is_array($files))
- {
- foreach ($files as $file)
- {
- $class = substr(basename($file), 0, -4);
- self::$classIndex[$class] = $file;
- }
- }
- }
- krsort(self::$classIndex);
- // Only use autoloading if spl_autoload_register() is available and no __autoload() is defined (because
- // __autoload() breaks if spl_autoload_register() is used.
- if (function_exists("spl_autoload_register") && !is_callable("__autoload"))
- {
- spl_autoload_register(array(__CLASS__, "autoload"));
- }
- // Otherwise include all class files
- else
- {
- foreach (self::$classIndex as $class => $file)
- {
- if (!class_exists($class))
- {
- require_once($file);
- }
- }
- }
- }
- /**
- * Minifies CSS source.
- *
- * @param string $source CSS source
- * @param array $filters Filter configuration [optional]
- * @param array $plugins Plugin configuration [optional]
- * @return string Minified CSS
- */
- public static function minify($source, array $filters = null, array $plugins = null)
- {
- self::$errors = array();
- $minifier = new CssMinifier($source, $filters, $plugins);
- return $minifier->getMinified();
- }
- /**
- * Parse the CSS source.
- *
- * @param string $source CSS source
- * @param array $plugins Plugin configuration [optional]
- * @return array Array of aCssToken
- */
- public static function parse($source, array $plugins = null)
- {
- self::$errors = array();
- $parser = new CssParser($source, $plugins);
- return $parser->getTokens();
- }
- /**
- * --
- *
- * @param boolean $to
- * @return boolean
- */
- public static function setVerbose($to)
- {
- self::$isVerbose = (boolean) $to;
- return self::$isVerbose;
- }
- /**
- * --
- *
- * @param CssError $error
- * @return void
- */
- public static function triggerError(CssError $error)
- {
- self::$errors[] = $error;
- if (self::$isVerbose)
- {
- trigger_error((string) $error, E_USER_WARNING);
- }
- }
-}
-// Initialises CssMin
-CssMin::initialise();
-
-/**
- * This {@link aCssMinifierFilter minifier filter} import external css files defined with the @import at-rule into the
- * current stylesheet.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssImportImportsMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Array with already imported external stylesheets.
- *
- * @var array
- */
- private $imported = array();
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- if (!isset($this->configuration["BasePath"]) || !is_dir($this->configuration["BasePath"]))
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Base path " . ($this->configuration["BasePath"] ? $this->configuration["BasePath"] : "null"). "
is not a directory"));
- return 0;
- }
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- if (get_class($tokens[$i]) === "CssAtImportToken")
- {
- $import = $this->configuration["BasePath"] . "/" . $tokens[$i]->Import;
- // Import file was not found/is not a file
- if (!is_file($import))
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. "
was not found.", (string) $tokens[$i]));
- }
- // Import file already imported; remove this @import at-rule to prevent recursions
- elseif (in_array($import, $this->imported))
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. "
was already imported.", (string) $tokens[$i]));
- $tokens[$i] = null;
- }
- else
- {
- $this->imported[] = $import;
- $parser = new CssParser(file_get_contents($import));
- $import = $parser->getTokens();
- // The @import at-rule has media types defined requiring special handling
- if (count($tokens[$i]->MediaTypes) > 0 && !(count($tokens[$i]->MediaTypes) == 1 && $tokens[$i]->MediaTypes[0] == "all"))
- {
- $blocks = array();
- /*
- * Filter or set media types of @import at-rule or remove the @import at-rule if no media type is matching the parent @import at-rule
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- if (get_class($import[$ii]) === "CssAtImportToken")
- {
- // @import at-rule defines no media type or only the "all" media type; set the media types to the one defined in the parent @import at-rule
- if (count($import[$ii]->MediaTypes) == 0 || (count($import[$ii]->MediaTypes) == 1 && $import[$ii]->MediaTypes[0] == "all"))
- {
- $import[$ii]->MediaTypes = $tokens[$i]->MediaTypes;
- }
- // @import at-rule defineds one or more media types; filter out media types not matching with the parent @import at-rule
- elseif (count($import[$ii]->MediaTypes) > 0)
- {
- foreach ($import[$ii]->MediaTypes as $index => $mediaType)
- {
- if (!in_array($mediaType, $tokens[$i]->MediaTypes))
- {
- unset($import[$ii]->MediaTypes[$index]);
- }
- }
- $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
- // If there are no media types left in the @import at-rule remove the @import at-rule
- if (count($import[$ii]->MediaTypes) == 0)
- {
- $import[$ii] = null;
- }
- }
- }
- }
- /*
- * Remove media types of @media at-rule block not defined in the @import at-rule
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- if (get_class($import[$ii]) === "CssAtMediaStartToken")
- {
- foreach ($import[$ii]->MediaTypes as $index => $mediaType)
- {
- if (!in_array($mediaType, $tokens[$i]->MediaTypes))
- {
- unset($import[$ii]->MediaTypes[$index]);
- }
- $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
- }
- }
- }
- /*
- * If no media types left of the @media at-rule block remove the complete block
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- if (get_class($import[$ii]) === "CssAtMediaStartToken")
- {
- if (count($import[$ii]->MediaTypes) === 0)
- {
- for ($iii = $ii; $iii < $ll; $iii++)
- {
- if (get_class($import[$iii]) === "CssAtMediaEndToken")
- {
- break;
- }
- }
- if (get_class($import[$iii]) === "CssAtMediaEndToken")
- {
- array_splice($import, $ii, $iii - $ii + 1, array());
- $ll = count($import);
- }
- }
- }
- }
- /*
- * If the media types of the @media at-rule equals the media types defined in the @import
- * at-rule remove the CssAtMediaStartToken and CssAtMediaEndToken token
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- if (get_class($import[$ii]) === "CssAtMediaStartToken" && count(array_diff($tokens[$i]->MediaTypes, $import[$ii]->MediaTypes)) === 0)
- {
- for ($iii = $ii; $iii < $ll; $iii++)
- {
- if (get_class($import[$iii]) == "CssAtMediaEndToken")
- {
- break;
- }
- }
- if (get_class($import[$iii]) == "CssAtMediaEndToken")
- {
- unset($import[$ii]);
- unset($import[$iii]);
- $import = array_values($import);
- $ll = count($import);
- }
- }
- }
- /**
- * Extract CssAtImportToken and CssAtCharsetToken tokens
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- $class = get_class($import[$ii]);
- if ($class === "CssAtImportToken" || $class === "CssAtCharsetToken")
- {
- $blocks = array_merge($blocks, array_splice($import, $ii, 1, array()));
- $ll = count($import);
- }
- }
- /*
- * Extract the @font-face, @media and @page at-rule block
- */
- for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
- {
- $class = get_class($import[$ii]);
- if ($class === "CssAtFontFaceStartToken" || $class === "CssAtMediaStartToken" || $class === "CssAtPageStartToken" || $class === "CssAtVariablesStartToken")
- {
- for ($iii = $ii; $iii < $ll; $iii++)
- {
- $class = get_class($import[$iii]);
- if ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken")
- {
- break;
- }
- }
- $class = get_class($import[$iii]);
- if (isset($import[$iii]) && ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken"))
- {
- $blocks = array_merge($blocks, array_splice($import, $ii, $iii - $ii + 1, array()));
- $ll = count($import);
- }
- }
- }
- // Create the import array with extracted tokens and the rulesets wrapped into a @media at-rule block
- $import = array_merge($blocks, array(new CssAtMediaStartToken($tokens[$i]->MediaTypes)), $import, array(new CssAtMediaEndToken()));
- }
- // Insert the imported tokens
- array_splice($tokens, $i, 1, $import);
- // Modify parameters of the for-loop
- $i--;
- $l = count($tokens);
- }
- }
- }
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for preserve parsing expression() declaration values.
- *
- * This plugin return no {@link aCssToken CssToken} but ensures that expression() declaration values will get parsed
- * properly.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssExpressionParserPlugin extends aCssParserPlugin
-{
- /**
- * Count of left braces.
- *
- * @var integer
- */
- private $leftBraces = 0;
- /**
- * Count of right braces.
- *
- * @var integer
- */
- private $rightBraces = 0;
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("(", ")", ";", "}");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return false;
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of expression
- if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 10, 11)) === "expression(" && $state !== "T_EXPRESSION")
- {
- $this->parser->pushState("T_EXPRESSION");
- $this->leftBraces++;
- }
- // Count left braces
- elseif ($char === "(" && $state === "T_EXPRESSION")
- {
- $this->leftBraces++;
- }
- // Count right braces
- elseif ($char === ")" && $state === "T_EXPRESSION")
- {
- $this->rightBraces++;
- }
- // Possible end of expression; if left and right braces are equal the expressen ends
- elseif (($char === ";" || $char === "}") && $state === "T_EXPRESSION" && $this->leftBraces === $this->rightBraces)
- {
- $this->leftBraces = $this->rightBraces = 0;
- $this->parser->popState();
- return $index - 1;
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * CSS Error.
- *
- * @package CssMin
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssError
-{
- /**
- * File.
- *
- * @var string
- */
- public $File = "";
- /**
- * Line.
- *
- * @var integer
- */
- public $Line = 0;
- /**
- * Error message.
- *
- * @var string
- */
- public $Message = "";
- /**
- * Source.
- *
- * @var string
- */
- public $Source = "";
- /**
- * Constructor triggering the error.
- *
- * @param string $message Error message
- * @param string $source Corresponding line [optional]
- * @return void
- */
- public function __construct($file, $line, $message, $source = "")
- {
- $this->File = $file;
- $this->Line = $line;
- $this->Message = $message;
- $this->Source = $source;
- }
- /**
- * Returns the error as formatted string.
- *
- * @return string
- */
- public function __toString()
- {
- return $this->Message . ($this->Source ? ":
" . $this->Source . "
": "") . "
in file " . $this->File . " at line " . $this->Line;
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will convert a color value in rgb notation to hexadecimal notation.
- *
- * Example:
- *
- * color: rgb(200,60%,5);
- *
- *
- * Will get converted to:
- *
- * color:#c89905;
- *
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertRgbColorsMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Regular expression matching the value.
- *
- * @var string
- */
- private $reMatch = "/rgb\s*\(\s*([0-9%]+)\s*,\s*([0-9%]+)\s*,\s*([0-9%]+)\s*\)/iS";
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (stripos($token->Value, "rgb") !== false && preg_match($this->reMatch, $token->Value, $m))
- {
- for ($i = 1, $l = count($m); $i < $l; $i++)
- {
- if (strpos("%", $m[$i]) !== false)
- {
- $m[$i] = substr($m[$i], 0, -1);
- $m[$i] = (int) (256 * ($m[$i] / 100));
- }
- $m[$i] = str_pad(dechex($m[$i]), 2, "0", STR_PAD_LEFT);
- }
- $token->Value = str_replace($m[0], "#" . $m[1] . $m[2] . $m[3], $token->Value);
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will convert named color values to hexadecimal notation.
- *
- * Example:
- *
- * color: black;
- * border: 1px solid indigo;
- *
- *
- * Will get converted to:
- *
- * color:#000;
- * border:1px solid #4b0082;
- *
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertNamedColorsMinifierPlugin extends aCssMinifierPlugin
-{
-
- /**
- * Regular expression matching the value.
- *
- * @var string
- */
- private $reMatch = null;
- /**
- * Transformation table used by the {@link CssConvertNamedColorsMinifierPlugin::reReplace() replacement method}.
- *
- * @var array
- */
- private $transformation = array
- (
- "aliceblue" => "#f0f8ff",
- "antiquewhite" => "#faebd7",
- "aqua" => "#0ff",
- "aquamarine" => "#7fffd4",
- "azure" => "#f0ffff",
- "beige" => "#f5f5dc",
- "black" => "#000",
- "blue" => "#00f",
- "blueviolet" => "#8a2be2",
- "brown" => "#a52a2a",
- "burlywood" => "#deb887",
- "cadetblue" => "#5f9ea0",
- "chartreuse" => "#7fff00",
- "chocolate" => "#d2691e",
- "coral" => "#ff7f50",
- "cornflowerblue" => "#6495ed",
- "cornsilk" => "#fff8dc",
- "crimson" => "#dc143c",
- "darkblue" => "#00008b",
- "darkcyan" => "#008b8b",
- "darkgoldenrod" => "#b8860b",
- "darkgray" => "#a9a9a9",
- "darkgreen" => "#006400",
- "darkkhaki" => "#bdb76b",
- "darkmagenta" => "#8b008b",
- "darkolivegreen" => "#556b2f",
- "darkorange" => "#ff8c00",
- "darkorchid" => "#9932cc",
- "darkred" => "#8b0000",
- "darksalmon" => "#e9967a",
- "darkseagreen" => "#8fbc8f",
- "darkslateblue" => "#483d8b",
- "darkslategray" => "#2f4f4f",
- "darkturquoise" => "#00ced1",
- "darkviolet" => "#9400d3",
- "deeppink" => "#ff1493",
- "deepskyblue" => "#00bfff",
- "dimgray" => "#696969",
- "dodgerblue" => "#1e90ff",
- "firebrick" => "#b22222",
- "floralwhite" => "#fffaf0",
- "forestgreen" => "#228b22",
- "fuchsia" => "#f0f",
- "gainsboro" => "#dcdcdc",
- "ghostwhite" => "#f8f8ff",
- "gold" => "#ffd700",
- "goldenrod" => "#daa520",
- "gray" => "#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",
- "lightgreen" => "#90ee90",
- "lightgrey" => "#d3d3d3",
- "lightpink" => "#ffb6c1",
- "lightsalmon" => "#ffa07a",
- "lightseagreen" => "#20b2aa",
- "lightskyblue" => "#87cefa",
- "lightslategray" => "#789",
- "lightsteelblue" => "#b0c4de",
- "lightyellow" => "#ffffe0",
- "lime" => "#0f0",
- "limegreen" => "#32cd32",
- "linen" => "#faf0e6",
- "maroon" => "#800000",
- "mediumaquamarine" => "#66cdaa",
- "mediumblue" => "#0000cd",
- "mediumorchid" => "#ba55d3",
- "mediumpurple" => "#9370db",
- "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" => "#db7093",
- "papayawhip" => "#ffefd5",
- "peachpuff" => "#ffdab9",
- "peru" => "#cd853f",
- "pink" => "#ffc0cb",
- "plum" => "#dda0dd",
- "powderblue" => "#b0e0e6",
- "purple" => "#800080",
- "red" => "#f00",
- "rosybrown" => "#bc8f8f",
- "royalblue" => "#4169e1",
- "saddlebrown" => "#8b4513",
- "salmon" => "#fa8072",
- "sandybrown" => "#f4a460",
- "seagreen" => "#2e8b57",
- "seashell" => "#fff5ee",
- "sienna" => "#a0522d",
- "silver" => "#c0c0c0",
- "skyblue" => "#87ceeb",
- "slateblue" => "#6a5acd",
- "slategray" => "#708090",
- "snow" => "#fffafa",
- "springgreen" => "#00ff7f",
- "steelblue" => "#4682b4",
- "tan" => "#d2b48c",
- "teal" => "#008080",
- "thistle" => "#d8bfd8",
- "tomato" => "#ff6347",
- "turquoise" => "#40e0d0",
- "violet" => "#ee82ee",
- "wheat" => "#f5deb3",
- "white" => "#fff",
- "whitesmoke" => "#f5f5f5",
- "yellow" => "#ff0",
- "yellowgreen" => "#9acd32"
- );
- /**
- * Overwrites {@link aCssMinifierPlugin::__construct()}.
- *
- * The constructor will create the {@link CssConvertNamedColorsMinifierPlugin::$reMatch replace regular expression}
- * based on the {@link CssConvertNamedColorsMinifierPlugin::$transformation transformation table}.
- *
- * @param CssMinifier $minifier The CssMinifier object of this plugin.
- * @param array $configuration Plugin configuration [optional]
- * @return void
- */
- public function __construct(CssMinifier $minifier, array $configuration = array())
- {
- $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)) . ")(\s|$)+/iS";
- parent::__construct($minifier, $configuration);
- }
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- $lcValue = strtolower($token->Value);
- // Declaration value equals a value in the transformation table => simple replace
- if (isset($this->transformation[$lcValue]))
- {
- $token->Value = $this->transformation[$lcValue];
- }
- // Declaration value contains a value in the transformation table => regular expression replace
- elseif (preg_match($this->reMatch, $token->Value))
- {
- $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
- }
- return false;
- }
- /**
- * Callback for replacement value.
- *
- * @param array $match
- * @return string
- */
- private function reReplace($match)
- {
- return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} triggers on CSS Level 3 properties and will add declaration tokens
- * with browser-specific properties.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertLevel3PropertiesMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Css property transformations table. Used to convert CSS3 and proprietary properties to the browser-specific
- * counterparts.
- *
- * @var array
- */
- private $transformations = array
- (
- // Property Array(Mozilla, Webkit, Opera, Internet Explorer); NULL values are placeholders and will get ignored
- "animation" => array(null, "-webkit-animation", null, null),
- "animation-delay" => array(null, "-webkit-animation-delay", null, null),
- "animation-direction" => array(null, "-webkit-animation-direction", null, null),
- "animation-duration" => array(null, "-webkit-animation-duration", null, null),
- "animation-fill-mode" => array(null, "-webkit-animation-fill-mode", null, null),
- "animation-iteration-count" => array(null, "-webkit-animation-iteration-count", null, null),
- "animation-name" => array(null, "-webkit-animation-name", null, null),
- "animation-play-state" => array(null, "-webkit-animation-play-state", null, null),
- "animation-timing-function" => array(null, "-webkit-animation-timing-function", null, null),
- "appearance" => array("-moz-appearance", "-webkit-appearance", null, null),
- "backface-visibility" => array(null, "-webkit-backface-visibility", null, null),
- "background-clip" => array(null, "-webkit-background-clip", null, null),
- "background-composite" => array(null, "-webkit-background-composite", null, null),
- "background-inline-policy" => array("-moz-background-inline-policy", null, null, null),
- "background-origin" => array(null, "-webkit-background-origin", null, null),
- "background-position-x" => array(null, null, null, "-ms-background-position-x"),
- "background-position-y" => array(null, null, null, "-ms-background-position-y"),
- "background-size" => array(null, "-webkit-background-size", null, null),
- "behavior" => array(null, null, null, "-ms-behavior"),
- "binding" => array("-moz-binding", null, null, null),
- "border-after" => array(null, "-webkit-border-after", null, null),
- "border-after-color" => array(null, "-webkit-border-after-color", null, null),
- "border-after-style" => array(null, "-webkit-border-after-style", null, null),
- "border-after-width" => array(null, "-webkit-border-after-width", null, null),
- "border-before" => array(null, "-webkit-border-before", null, null),
- "border-before-color" => array(null, "-webkit-border-before-color", null, null),
- "border-before-style" => array(null, "-webkit-border-before-style", null, null),
- "border-before-width" => array(null, "-webkit-border-before-width", null, null),
- "border-border-bottom-colors" => array("-moz-border-bottom-colors", null, null, null),
- "border-bottom-left-radius" => array("-moz-border-radius-bottomleft", "-webkit-border-bottom-left-radius", null, null),
- "border-bottom-right-radius" => array("-moz-border-radius-bottomright", "-webkit-border-bottom-right-radius", null, null),
- "border-end" => array("-moz-border-end", "-webkit-border-end", null, null),
- "border-end-color" => array("-moz-border-end-color", "-webkit-border-end-color", null, null),
- "border-end-style" => array("-moz-border-end-style", "-webkit-border-end-style", null, null),
- "border-end-width" => array("-moz-border-end-width", "-webkit-border-end-width", null, null),
- "border-fit" => array(null, "-webkit-border-fit", null, null),
- "border-horizontal-spacing" => array(null, "-webkit-border-horizontal-spacing", null, null),
- "border-image" => array("-moz-border-image", "-webkit-border-image", null, null),
- "border-left-colors" => array("-moz-border-left-colors", null, null, null),
- "border-radius" => array("-moz-border-radius", "-webkit-border-radius", null, null),
- "border-border-right-colors" => array("-moz-border-right-colors", null, null, null),
- "border-start" => array("-moz-border-start", "-webkit-border-start", null, null),
- "border-start-color" => array("-moz-border-start-color", "-webkit-border-start-color", null, null),
- "border-start-style" => array("-moz-border-start-style", "-webkit-border-start-style", null, null),
- "border-start-width" => array("-moz-border-start-width", "-webkit-border-start-width", null, null),
- "border-top-colors" => array("-moz-border-top-colors", null, null, null),
- "border-top-left-radius" => array("-moz-border-radius-topleft", "-webkit-border-top-left-radius", null, null),
- "border-top-right-radius" => array("-moz-border-radius-topright", "-webkit-border-top-right-radius", null, null),
- "border-vertical-spacing" => array(null, "-webkit-border-vertical-spacing", null, null),
- "box-align" => array("-moz-box-align", "-webkit-box-align", null, null),
- "box-direction" => array("-moz-box-direction", "-webkit-box-direction", null, null),
- "box-flex" => array("-moz-box-flex", "-webkit-box-flex", null, null),
- "box-flex-group" => array(null, "-webkit-box-flex-group", null, null),
- "box-flex-lines" => array(null, "-webkit-box-flex-lines", null, null),
- "box-ordinal-group" => array("-moz-box-ordinal-group", "-webkit-box-ordinal-group", null, null),
- "box-orient" => array("-moz-box-orient", "-webkit-box-orient", null, null),
- "box-pack" => array("-moz-box-pack", "-webkit-box-pack", null, null),
- "box-reflect" => array(null, "-webkit-box-reflect", null, null),
- "box-shadow" => array("-moz-box-shadow", "-webkit-box-shadow", null, null),
- "box-sizing" => array("-moz-box-sizing", null, null, null),
- "color-correction" => array(null, "-webkit-color-correction", null, null),
- "column-break-after" => array(null, "-webkit-column-break-after", null, null),
- "column-break-before" => array(null, "-webkit-column-break-before", null, null),
- "column-break-inside" => array(null, "-webkit-column-break-inside", null, null),
- "column-count" => array("-moz-column-count", "-webkit-column-count", null, null),
- "column-gap" => array("-moz-column-gap", "-webkit-column-gap", null, null),
- "column-rule" => array("-moz-column-rule", "-webkit-column-rule", null, null),
- "column-rule-color" => array("-moz-column-rule-color", "-webkit-column-rule-color", null, null),
- "column-rule-style" => array("-moz-column-rule-style", "-webkit-column-rule-style", null, null),
- "column-rule-width" => array("-moz-column-rule-width", "-webkit-column-rule-width", null, null),
- "column-span" => array(null, "-webkit-column-span", null, null),
- "column-width" => array("-moz-column-width", "-webkit-column-width", null, null),
- "columns" => array(null, "-webkit-columns", null, null),
- "filter" => array(__CLASS__, "filter"),
- "float-edge" => array("-moz-float-edge", null, null, null),
- "font-feature-settings" => array("-moz-font-feature-settings", null, null, null),
- "font-language-override" => array("-moz-font-language-override", null, null, null),
- "font-size-delta" => array(null, "-webkit-font-size-delta", null, null),
- "font-smoothing" => array(null, "-webkit-font-smoothing", null, null),
- "force-broken-image-icon" => array("-moz-force-broken-image-icon", null, null, null),
- "highlight" => array(null, "-webkit-highlight", null, null),
- "hyphenate-character" => array(null, "-webkit-hyphenate-character", null, null),
- "hyphenate-locale" => array(null, "-webkit-hyphenate-locale", null, null),
- "hyphens" => array(null, "-webkit-hyphens", null, null),
- "force-broken-image-icon" => array("-moz-image-region", null, null, null),
- "ime-mode" => array(null, null, null, "-ms-ime-mode"),
- "interpolation-mode" => array(null, null, null, "-ms-interpolation-mode"),
- "layout-flow" => array(null, null, null, "-ms-layout-flow"),
- "layout-grid" => array(null, null, null, "-ms-layout-grid"),
- "layout-grid-char" => array(null, null, null, "-ms-layout-grid-char"),
- "layout-grid-line" => array(null, null, null, "-ms-layout-grid-line"),
- "layout-grid-mode" => array(null, null, null, "-ms-layout-grid-mode"),
- "layout-grid-type" => array(null, null, null, "-ms-layout-grid-type"),
- "line-break" => array(null, "-webkit-line-break", null, "-ms-line-break"),
- "line-clamp" => array(null, "-webkit-line-clamp", null, null),
- "line-grid-mode" => array(null, null, null, "-ms-line-grid-mode"),
- "logical-height" => array(null, "-webkit-logical-height", null, null),
- "logical-width" => array(null, "-webkit-logical-width", null, null),
- "margin-after" => array(null, "-webkit-margin-after", null, null),
- "margin-after-collapse" => array(null, "-webkit-margin-after-collapse", null, null),
- "margin-before" => array(null, "-webkit-margin-before", null, null),
- "margin-before-collapse" => array(null, "-webkit-margin-before-collapse", null, null),
- "margin-bottom-collapse" => array(null, "-webkit-margin-bottom-collapse", null, null),
- "margin-collapse" => array(null, "-webkit-margin-collapse", null, null),
- "margin-end" => array("-moz-margin-end", "-webkit-margin-end", null, null),
- "margin-start" => array("-moz-margin-start", "-webkit-margin-start", null, null),
- "margin-top-collapse" => array(null, "-webkit-margin-top-collapse", null, null),
- "marquee " => array(null, "-webkit-marquee", null, null),
- "marquee-direction" => array(null, "-webkit-marquee-direction", null, null),
- "marquee-increment" => array(null, "-webkit-marquee-increment", null, null),
- "marquee-repetition" => array(null, "-webkit-marquee-repetition", null, null),
- "marquee-speed" => array(null, "-webkit-marquee-speed", null, null),
- "marquee-style" => array(null, "-webkit-marquee-style", null, null),
- "mask" => array(null, "-webkit-mask", null, null),
- "mask-attachment" => array(null, "-webkit-mask-attachment", null, null),
- "mask-box-image" => array(null, "-webkit-mask-box-image", null, null),
- "mask-clip" => array(null, "-webkit-mask-clip", null, null),
- "mask-composite" => array(null, "-webkit-mask-composite", null, null),
- "mask-image" => array(null, "-webkit-mask-image", null, null),
- "mask-origin" => array(null, "-webkit-mask-origin", null, null),
- "mask-position" => array(null, "-webkit-mask-position", null, null),
- "mask-position-x" => array(null, "-webkit-mask-position-x", null, null),
- "mask-position-y" => array(null, "-webkit-mask-position-y", null, null),
- "mask-repeat" => array(null, "-webkit-mask-repeat", null, null),
- "mask-repeat-x" => array(null, "-webkit-mask-repeat-x", null, null),
- "mask-repeat-y" => array(null, "-webkit-mask-repeat-y", null, null),
- "mask-size" => array(null, "-webkit-mask-size", null, null),
- "match-nearest-mail-blockquote-color" => array(null, "-webkit-match-nearest-mail-blockquote-color", null, null),
- "max-logical-height" => array(null, "-webkit-max-logical-height", null, null),
- "max-logical-width" => array(null, "-webkit-max-logical-width", null, null),
- "min-logical-height" => array(null, "-webkit-min-logical-height", null, null),
- "min-logical-width" => array(null, "-webkit-min-logical-width", null, null),
- "object-fit" => array(null, null, "-o-object-fit", null),
- "object-position" => array(null, null, "-o-object-position", null),
- "opacity" => array(__CLASS__, "opacity"),
- "outline-radius" => array("-moz-outline-radius", null, null, null),
- "outline-bottom-left-radius" => array("-moz-outline-radius-bottomleft", null, null, null),
- "outline-bottom-right-radius" => array("-moz-outline-radius-bottomright", null, null, null),
- "outline-top-left-radius" => array("-moz-outline-radius-topleft", null, null, null),
- "outline-top-right-radius" => array("-moz-outline-radius-topright", null, null, null),
- "padding-after" => array(null, "-webkit-padding-after", null, null),
- "padding-before" => array(null, "-webkit-padding-before", null, null),
- "padding-end" => array("-moz-padding-end", "-webkit-padding-end", null, null),
- "padding-start" => array("-moz-padding-start", "-webkit-padding-start", null, null),
- "perspective" => array(null, "-webkit-perspective", null, null),
- "perspective-origin" => array(null, "-webkit-perspective-origin", null, null),
- "perspective-origin-x" => array(null, "-webkit-perspective-origin-x", null, null),
- "perspective-origin-y" => array(null, "-webkit-perspective-origin-y", null, null),
- "rtl-ordering" => array(null, "-webkit-rtl-ordering", null, null),
- "scrollbar-3dlight-color" => array(null, null, null, "-ms-scrollbar-3dlight-color"),
- "scrollbar-arrow-color" => array(null, null, null, "-ms-scrollbar-arrow-color"),
- "scrollbar-base-color" => array(null, null, null, "-ms-scrollbar-base-color"),
- "scrollbar-darkshadow-color" => array(null, null, null, "-ms-scrollbar-darkshadow-color"),
- "scrollbar-face-color" => array(null, null, null, "-ms-scrollbar-face-color"),
- "scrollbar-highlight-color" => array(null, null, null, "-ms-scrollbar-highlight-color"),
- "scrollbar-shadow-color" => array(null, null, null, "-ms-scrollbar-shadow-color"),
- "scrollbar-track-color" => array(null, null, null, "-ms-scrollbar-track-color"),
- "stack-sizing" => array("-moz-stack-sizing", null, null, null),
- "svg-shadow" => array(null, "-webkit-svg-shadow", null, null),
- "tab-size" => array("-moz-tab-size", null, "-o-tab-size", null),
- "table-baseline" => array(null, null, "-o-table-baseline", null),
- "text-align-last" => array(null, null, null, "-ms-text-align-last"),
- "text-autospace" => array(null, null, null, "-ms-text-autospace"),
- "text-combine" => array(null, "-webkit-text-combine", null, null),
- "text-decorations-in-effect" => array(null, "-webkit-text-decorations-in-effect", null, null),
- "text-emphasis" => array(null, "-webkit-text-emphasis", null, null),
- "text-emphasis-color" => array(null, "-webkit-text-emphasis-color", null, null),
- "text-emphasis-position" => array(null, "-webkit-text-emphasis-position", null, null),
- "text-emphasis-style" => array(null, "-webkit-text-emphasis-style", null, null),
- "text-fill-color" => array(null, "-webkit-text-fill-color", null, null),
- "text-justify" => array(null, null, null, "-ms-text-justify"),
- "text-kashida-space" => array(null, null, null, "-ms-text-kashida-space"),
- "text-overflow" => array(null, null, "-o-text-overflow", "-ms-text-overflow"),
- "text-security" => array(null, "-webkit-text-security", null, null),
- "text-size-adjust" => array(null, "-webkit-text-size-adjust", null, "-ms-text-size-adjust"),
- "text-stroke" => array(null, "-webkit-text-stroke", null, null),
- "text-stroke-color" => array(null, "-webkit-text-stroke-color", null, null),
- "text-stroke-width" => array(null, "-webkit-text-stroke-width", null, null),
- "text-underline-position" => array(null, null, null, "-ms-text-underline-position"),
- "transform" => array("-moz-transform", "-webkit-transform", "-o-transform", null),
- "transform-origin" => array("-moz-transform-origin", "-webkit-transform-origin", "-o-transform-origin", null),
- "transform-origin-x" => array(null, "-webkit-transform-origin-x", null, null),
- "transform-origin-y" => array(null, "-webkit-transform-origin-y", null, null),
- "transform-origin-z" => array(null, "-webkit-transform-origin-z", null, null),
- "transform-style" => array(null, "-webkit-transform-style", null, null),
- "transition" => array("-moz-transition", "-webkit-transition", "-o-transition", null),
- "transition-delay" => array("-moz-transition-delay", "-webkit-transition-delay", "-o-transition-delay", null),
- "transition-duration" => array("-moz-transition-duration", "-webkit-transition-duration", "-o-transition-duration", null),
- "transition-property" => array("-moz-transition-property", "-webkit-transition-property", "-o-transition-property", null),
- "transition-timing-function" => array("-moz-transition-timing-function", "-webkit-transition-timing-function", "-o-transition-timing-function", null),
- "user-drag" => array(null, "-webkit-user-drag", null, null),
- "user-focus" => array("-moz-user-focus", null, null, null),
- "user-input" => array("-moz-user-input", null, null, null),
- "user-modify" => array("-moz-user-modify", "-webkit-user-modify", null, null),
- "user-select" => array("-moz-user-select", "-webkit-user-select", null, null),
- "white-space" => array(__CLASS__, "whiteSpace"),
- "window-shadow" => array("-moz-window-shadow", null, null, null),
- "word-break" => array(null, null, null, "-ms-word-break"),
- "word-wrap" => array(null, null, null, "-ms-word-wrap"),
- "writing-mode" => array(null, "-webkit-writing-mode", null, "-ms-writing-mode"),
- "zoom" => array(null, null, null, "-ms-zoom")
- );
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- $transformations = &$this->transformations;
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- if (get_class($tokens[$i]) === "CssRulesetDeclarationToken")
- {
- $tProperty = $tokens[$i]->Property;
- if (isset($transformations[$tProperty]))
- {
- $result = array();
- if (is_callable($transformations[$tProperty]))
- {
- $result = call_user_func_array($transformations[$tProperty], array($tokens[$i]));
- if (!is_array($result) && is_object($result))
- {
- $result = array($result);
- }
- }
- else
- {
- $tValue = $tokens[$i]->Value;
- $tMediaTypes = $tokens[$i]->MediaTypes;
- foreach ($transformations[$tProperty] as $property)
- {
- if ($property !== null)
- {
- $result[] = new CssRulesetDeclarationToken($property, $tValue, $tMediaTypes);
- }
- }
- }
- if (count($result) > 0)
- {
- array_splice($tokens, $i + 1, 0, $result);
- $i += count($result);
- $l += count($result);
- }
- }
- }
- }
- return $r;
- }
- /**
- * Transforms the Internet Explorer specific declaration property "filter" to Internet Explorer 8+ compatible
- * declaratiopn property "-ms-filter".
- *
- * @param aCssToken $token
- * @return array
- */
- private static function filter($token)
- {
- $r = array
- (
- new CssRulesetDeclarationToken("-ms-filter", "\"" . $token->Value . "\"", $token->MediaTypes),
- );
- return $r;
- }
- /**
- * Transforms "opacity: {value}" into browser specific counterparts.
- *
- * @param aCssToken $token
- * @return array
- */
- private static function opacity($token)
- {
- // Calculate the value for Internet Explorer filter statement
- $ieValue = (int) ((float) $token->Value * 100);
- $r = array
- (
- // Internet Explorer >= 8
- new CssRulesetDeclarationToken("-ms-filter", "\"alpha(opacity=" . $ieValue . ")\"", $token->MediaTypes),
- // Internet Explorer >= 4 <= 7
- new CssRulesetDeclarationToken("filter", "alpha(opacity=" . $ieValue . ")", $token->MediaTypes),
- new CssRulesetDeclarationToken("zoom", "1", $token->MediaTypes)
- );
- return $r;
- }
- /**
- * Transforms "white-space: pre-wrap" into browser specific counterparts.
- *
- * @param aCssToken $token
- * @return array
- */
- private static function whiteSpace($token)
- {
- if (strtolower($token->Value) === "pre-wrap")
- {
- $r = array
- (
- // Firefox < 3
- new CssRulesetDeclarationToken("white-space", "-moz-pre-wrap", $token->MediaTypes),
- // Webkit
- new CssRulesetDeclarationToken("white-space", "-webkit-pre-wrap", $token->MediaTypes),
- // Opera >= 4 <= 6
- new CssRulesetDeclarationToken("white-space", "-pre-wrap", $token->MediaTypes),
- // Opera >= 7
- new CssRulesetDeclarationToken("white-space", "-o-pre-wrap", $token->MediaTypes),
- // Internet Explorer >= 5.5
- new CssRulesetDeclarationToken("word-wrap", "break-word", $token->MediaTypes)
- );
- return $r;
- }
- else
- {
- return array();
- }
- }
-}
-
-/**
- * This {@link aCssMinifierFilter minifier filter} will convert @keyframes at-rule block to browser specific counterparts.
- *
- * @package CssMin/Minifier/Filters
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertLevel3AtKeyframesMinifierFilter extends aCssMinifierFilter
-{
- /**
- * Implements {@link aCssMinifierFilter::filter()}.
- *
- * @param array $tokens Array of objects of type aCssToken
- * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
- */
- public function apply(array &$tokens)
- {
- $r = 0;
- $transformations = array("-moz-keyframes", "-webkit-keyframes");
- for ($i = 0, $l = count($tokens); $i < $l; $i++)
- {
- if (get_class($tokens[$i]) === "CssAtKeyframesStartToken")
- {
- for ($ii = $i; $ii < $l; $ii++)
- {
- if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
- {
- break;
- }
- }
- if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
- {
- $add = array();
- $source = array();
- for ($iii = $i; $iii <= $ii; $iii++)
- {
- $source[] = clone($tokens[$iii]);
- }
- foreach ($transformations as $transformation)
- {
- $t = array();
- foreach ($source as $token)
- {
- $t[] = clone($token);
- }
- $t[0]->AtRuleName = $transformation;
- $add = array_merge($add, $t);
- }
- if (isset($this->configuration["RemoveSource"]) && $this->configuration["RemoveSource"] === true)
- {
- array_splice($tokens, $i, $ii - $i + 1, $add);
- }
- else
- {
- array_splice($tokens, $ii + 1, 0, $add);
- }
- $l = count($tokens);
- $i = $ii + count($add);
- $r += count($add);
- }
- }
- }
- return $r;
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will convert a color value in hsl notation to hexadecimal notation.
- *
- * Example:
- *
- * color: hsl(232,36%,48%);
- *
- *
- * Will get converted to:
- *
- * color:#4e5aa7;
- *
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertHslColorsMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Regular expression matching the value.
- *
- * @var string
- */
- private $reMatch = "/^hsl\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*%\s*,\s*([0-9]+)\s*%\s*\)/iS";
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (stripos($token->Value, "hsl") !== false && preg_match($this->reMatch, $token->Value, $m))
- {
- $token->Value = str_replace($m[0], $this->hsl2hex($m[1], $m[2], $m[3]), $token->Value);
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
- /**
- * Convert a HSL value to hexadecimal notation.
- *
- * Based on: {@link http://www.easyrgb.com/index.php?X=MATH&H=19#text19}.
- *
- * @param integer $hue Hue
- * @param integer $saturation Saturation
- * @param integer $lightness Lightnesss
- * @return string
- */
- private function hsl2hex($hue, $saturation, $lightness)
- {
- $hue = $hue / 360;
- $saturation = $saturation / 100;
- $lightness = $lightness / 100;
- if ($saturation == 0)
- {
- $red = $lightness * 255;
- $green = $lightness * 255;
- $blue = $lightness * 255;
- }
- else
- {
- if ($lightness < 0.5 )
- {
- $v2 = $lightness * (1 + $saturation);
- }
- else
- {
- $v2 = ($lightness + $saturation) - ($saturation * $lightness);
- }
- $v1 = 2 * $lightness - $v2;
- $red = 255 * self::hue2rgb($v1, $v2, $hue + (1 / 3));
- $green = 255 * self::hue2rgb($v1, $v2, $hue);
- $blue = 255 * self::hue2rgb($v1, $v2, $hue - (1 / 3));
- }
- return "#" . str_pad(dechex(round($red)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($green)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($blue)), 2, "0", STR_PAD_LEFT);
- }
- /**
- * Apply hue to a rgb color value.
- *
- * @param integer $v1 Value 1
- * @param integer $v2 Value 2
- * @param integer $hue Hue
- * @return integer
- */
- private function hue2rgb($v1, $v2, $hue)
- {
- if ($hue < 0)
- {
- $hue += 1;
- }
- if ($hue > 1)
- {
- $hue -= 1;
- }
- if ((6 * $hue) < 1)
- {
- return ($v1 + ($v2 - $v1) * 6 * $hue);
- }
- if ((2 * $hue) < 1)
- {
- return ($v2);
- }
- if ((3 * $hue) < 2)
- {
- return ($v1 + ($v2 - $v1) * (( 2 / 3) - $hue) * 6);
- }
- return $v1;
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will convert the font-weight values normal and bold to their numeric notation.
- *
- * Example:
- *
- * font-weight: normal;
- * font: bold 11px monospace;
- *
- *
- * Will get converted to:
- *
- * font-weight:400;
- * font:700 11px monospace;
- *
- *
- * @package CssMin/Minifier/Pluginsn
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssConvertFontWeightMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Array of included declaration properties this plugin will process; others declaration properties will get
- * ignored.
- *
- * @var array
- */
- private $include = array
- (
- "font",
- "font-weight"
- );
- /**
- * Regular expression matching the value.
- *
- * @var string
- */
- private $reMatch = null;
- /**
- * Transformation table used by the {@link CssConvertFontWeightMinifierPlugin::reReplace() replacement method}.
- *
- * @var array
- */
- private $transformation = array
- (
- "normal" => "400",
- "bold" => "700"
- );
- /**
- * Overwrites {@link aCssMinifierPlugin::__construct()}.
- *
- * The constructor will create the {@link CssConvertFontWeightMinifierPlugin::$reMatch replace regular expression}
- * based on the {@link CssConvertFontWeightMinifierPlugin::$transformation transformation table}.
- *
- * @param CssMinifier $minifier The CssMinifier object of this plugin.
- * @return void
- */
- public function __construct(CssMinifier $minifier)
- {
- $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)). ")(\s|$)+/iS";
- parent::__construct($minifier);
- }
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (in_array($token->Property, $this->include) && preg_match($this->reMatch, $token->Value, $m))
- {
- $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
- }
- return false;
- }
- /**
- * Callback for replacement value.
- *
- * @param array $match
- * @return string
- */
- private function reReplace($match)
- {
- return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will compress several unit values to their short notations. Examples:
- *
- *
- * padding: 0.5em;
- * border: 0px;
- * margin: 0 0 0 0;
- *
- *
- * Will get compressed to:
- *
- *
- * padding:.5px;
- * border:0;
- * margin:0;
- *
- *
- * --
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssCompressUnitValuesMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Regular expression used for matching and replacing unit values.
- *
- * @var array
- */
- private $re = array
- (
- "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}.\${2}\${4}",
- "/(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}0",
- );
- /**
- * Regular expression used for matching and replacing unit values only for non-blacklisted declarations.
- *
- * @var array
- */
- private $reBlacklisted = array(
- "/(^0\s0\s0\s0)|(^0\s0\s0$)|(^0\s0$)/iS" => "0",
- );
- /**
- * Blacklisted properties for the above regular expression.
- *
- * @var array
- */
- private $propertiesBlacklist = array('background-position');
- /**
- * Regular expression matching the value.
- *
- * @var string
- */
- private $reMatch = "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)|(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)|(^0\s0\s0\s0$)|(^0\s0\s0$)|(^0\s0$)/iS";
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (preg_match($this->reMatch, $token->Value))
- {
- foreach ($this->re as $reMatch => $reReplace)
- {
- $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
- }
- if (!in_array($token->Property, $this->propertiesBlacklist))
- {
- foreach ($this->reBlacklisted as $reMatch => $reReplace)
- {
- $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
- }
- }
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} compress the content of expresssion() declaration values.
- *
- * For compression of expressions {@link https://github.com/rgrove/jsmin-php/ JSMin} will get used. JSMin have to be
- * already included or loadable via {@link http://goo.gl/JrW54 PHP autoloading}.
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssCompressExpressionValuesMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (class_exists("JSMin") && stripos($token->Value, "expression(") !== false)
- {
- $value = $token->Value;
- $value = substr($token->Value, stripos($token->Value, "expression(") + 10);
- $value = trim(JSMin::minify($value));
- $token->Value = "expression(" . $value . ")";
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssMinifierPlugin} will convert hexadecimal color value with 6 chars to their 3 char hexadecimal
- * notation (if possible).
- *
- * Example:
- *
- * color: #aabbcc;
- *
- *
- * Will get converted to:
- *
- * color:#abc;
- *
- *
- * @package CssMin/Minifier/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssCompressColorValuesMinifierPlugin extends aCssMinifierPlugin
-{
- /**
- * Regular expression matching 6 char hexadecimal color values.
- *
- * @var string
- */
- private $reMatch = "/\#([0-9a-f]{6})/iS";
- /**
- * Implements {@link aCssMinifierPlugin::minify()}.
- *
- * @param aCssToken $token Token to process
- * @return boolean Return TRUE to break the processing of this token; FALSE to continue
- */
- public function apply(aCssToken &$token)
- {
- if (strpos($token->Value, "#") !== false && preg_match($this->reMatch, $token->Value, $m))
- {
- $value = strtolower($m[1]);
- if ($value[0] == $value[1] && $value[2] == $value[3] && $value[4] == $value[5])
- {
- $token->Value = str_replace($m[0], "#" . $value[0] . $value[2] . $value[4], $token->Value);
- }
- }
- return false;
- }
- /**
- * Implements {@link aMinifierPlugin::getTriggerTokens()}
- *
- * @return array
- */
- public function getTriggerTokens()
- {
- return array
- (
- "CssAtFontFaceDeclarationToken",
- "CssAtPageDeclarationToken",
- "CssRulesetDeclarationToken"
- );
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents a CSS comment.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssCommentToken extends aCssToken
-{
- /**
- * Comment as Text.
- *
- * @var string
- */
- public $Comment = "";
- /**
- * Set the properties of a comment token.
- *
- * @param string $comment Comment including comment delimiters
- * @return void
- */
- public function __construct($comment)
- {
- $this->Comment = $comment;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return $this->Comment;
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing comments.
- *
- * Adds a {@link CssCommentToken} to the parser if a comment was found.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssCommentParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("*", "/");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return false;
- }
- /**
- * Stored buffer for restore.
- *
- * @var string
- */
- private $restoreBuffer = "";
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- if ($char === "*" && $previousChar === "/" && $state !== "T_COMMENT")
- {
- $this->parser->pushState("T_COMMENT");
- $this->parser->setExclusive(__CLASS__);
- $this->restoreBuffer = substr($this->parser->getAndClearBuffer(), 0, -2);
- }
- elseif ($char === "/" && $previousChar === "*" && $state === "T_COMMENT")
- {
- $this->parser->popState();
- $this->parser->unsetExclusive();
- $this->parser->appendToken(new CssCommentToken("/*" . $this->parser->getAndClearBuffer()));
- $this->parser->setBuffer($this->restoreBuffer);
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a @variables at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtVariablesStartToken extends aCssAtBlockStartToken
-{
- /**
- * Media types of the @variables at-rule block.
- *
- * @var array
- */
- public $MediaTypes = array();
- /**
- * Set the properties of a @variables at-rule token.
- *
- * @param array $mediaTypes Media types
- * @return void
- */
- public function __construct($mediaTypes = null)
- {
- $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @variables at-rule block with including declarations.
- *
- * Found @variables at-rule blocks will add a {@link CssAtVariablesStartToken} and {@link CssAtVariablesEndToken} to the
- * parser; including declarations as {@link CssAtVariablesDeclarationToken}.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtVariablesParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", "{", "}", ":", ";");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_VARIABLES::PREPARE", "T_AT_VARIABLES", "T_AT_VARIABLES_DECLARATION");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of @variables at-rule block
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@variables")
- {
- $this->parser->pushState("T_AT_VARIABLES::PREPARE");
- $this->parser->clearBuffer();
- return $index + 10;
- }
- // Start of @variables declarations
- elseif ($char === "{" && $state === "T_AT_VARIABLES::PREPARE")
- {
- $this->parser->setState("T_AT_VARIABLES");
- $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{"))));
- $this->parser->appendToken(new CssAtVariablesStartToken($mediaTypes));
- }
- // Start of @variables declaration
- if ($char === ":" && $state === "T_AT_VARIABLES")
- {
- $this->buffer = $this->parser->getAndClearBuffer(":");
- $this->parser->pushState("T_AT_VARIABLES_DECLARATION");
- }
- // Unterminated @variables declaration
- elseif ($char === ":" && $state === "T_AT_VARIABLES_DECLARATION")
- {
- // Ignore Internet Explorer filter declarations
- if ($this->buffer === "filter")
- {
- return false;
- }
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @variables declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
- }
- // End of @variables declaration
- elseif (($char === ";" || $char === "}") && $state === "T_AT_VARIABLES_DECLARATION")
- {
- $value = $this->parser->getAndClearBuffer(";}");
- if (strtolower(substr($value, -10, 10)) === "!important")
- {
- $value = trim(substr($value, 0, -10));
- $isImportant = true;
- }
- else
- {
- $isImportant = false;
- }
- $this->parser->popState();
- $this->parser->appendToken(new CssAtVariablesDeclarationToken($this->buffer, $value, $isImportant));
- $this->buffer = "";
- }
- // End of @variables at-rule block
- elseif ($char === "}" && $state === "T_AT_VARIABLES")
- {
- $this->parser->popState();
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssAtVariablesEndToken());
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a @variables at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtVariablesEndToken extends aCssAtBlockEndToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "";
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents a declaration of a @variables at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtVariablesDeclarationToken extends aCssDeclarationToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "";
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a @page at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtPageStartToken extends aCssAtBlockStartToken
-{
- /**
- * Selector.
- *
- * @var string
- */
- public $Selector = "";
- /**
- * Sets the properties of the @page at-rule.
- *
- * @param string $selector Selector
- * @return void
- */
- public function __construct($selector = "")
- {
- $this->Selector = $selector;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "@page" . ($this->Selector ? " " . $this->Selector : "") . "{";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @page at-rule block with including declarations.
- *
- * Found @page at-rule blocks will add a {@link CssAtPageStartToken} and {@link CssAtPageEndToken} to the
- * parser; including declarations as {@link CssAtPageDeclarationToken}.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtPageParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", "{", "}", ":", ";");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_PAGE::SELECTOR", "T_AT_PAGE", "T_AT_PAGE_DECLARATION");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of @page at-rule block
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 5)) === "@page")
- {
- $this->parser->pushState("T_AT_PAGE::SELECTOR");
- $this->parser->clearBuffer();
- return $index + 5;
- }
- // Start of @page declarations
- elseif ($char === "{" && $state === "T_AT_PAGE::SELECTOR")
- {
- $selector = $this->parser->getAndClearBuffer("{");
- $this->parser->setState("T_AT_PAGE");
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssAtPageStartToken($selector));
- }
- // Start of @page declaration
- elseif ($char === ":" && $state === "T_AT_PAGE")
- {
- $this->parser->pushState("T_AT_PAGE_DECLARATION");
- $this->buffer = $this->parser->getAndClearBuffer(":", true);
- }
- // Unterminated @font-face declaration
- elseif ($char === ":" && $state === "T_AT_PAGE_DECLARATION")
- {
- // Ignore Internet Explorer filter declarations
- if ($this->buffer === "filter")
- {
- return false;
- }
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @page declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
- }
- // End of @page declaration
- elseif (($char === ";" || $char === "}") && $state == "T_AT_PAGE_DECLARATION")
- {
- $value = $this->parser->getAndClearBuffer(";}");
- if (strtolower(substr($value, -10, 10)) == "!important")
- {
- $value = trim(substr($value, 0, -10));
- $isImportant = true;
- }
- else
- {
- $isImportant = false;
- }
- $this->parser->popState();
- $this->parser->appendToken(new CssAtPageDeclarationToken($this->buffer, $value, $isImportant));
- // --
- if ($char === "}")
- {
- $this->parser->popState();
- $this->parser->appendToken(new CssAtPageEndToken());
- }
- $this->buffer = "";
- }
- // End of @page at-rule block
- elseif ($char === "}" && $state === "T_AT_PAGE")
- {
- $this->parser->popState();
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssAtPageEndToken());
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a @page at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtPageEndToken extends aCssAtBlockEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a declaration of a @page at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtPageDeclarationToken extends aCssDeclarationToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a @media at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtMediaStartToken extends aCssAtBlockStartToken
-{
- /**
- * Sets the properties of the @media at-rule.
- *
- * @param array $mediaTypes Media types
- * @return void
- */
- public function __construct(array $mediaTypes = array())
- {
- $this->MediaTypes = $mediaTypes;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "@media " . implode(",", $this->MediaTypes) . "{";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @media at-rule block.
- *
- * Found @media at-rule blocks will add a {@link CssAtMediaStartToken} and {@link CssAtMediaEndToken} to the parser.
- * This plugin will also set the the current media types using {@link CssParser::setMediaTypes()} and
- * {@link CssParser::unsetMediaTypes()}.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtMediaParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", "{", "}");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_MEDIA::PREPARE", "T_AT_MEDIA");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 6)) === "@media")
- {
- $this->parser->pushState("T_AT_MEDIA::PREPARE");
- $this->parser->clearBuffer();
- return $index + 6;
- }
- elseif ($char === "{" && $state === "T_AT_MEDIA::PREPARE")
- {
- $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{"))));
- $this->parser->setMediaTypes($mediaTypes);
- $this->parser->setState("T_AT_MEDIA");
- $this->parser->appendToken(new CssAtMediaStartToken($mediaTypes));
- }
- elseif ($char === "}" && $state === "T_AT_MEDIA")
- {
- $this->parser->appendToken(new CssAtMediaEndToken());
- $this->parser->clearBuffer();
- $this->parser->unsetMediaTypes();
- $this->parser->popState();
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a @media at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtMediaEndToken extends aCssAtBlockEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a @keyframes at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesStartToken extends aCssAtBlockStartToken
-{
- /**
- * Name of the at-rule.
- *
- * @var string
- */
- public $AtRuleName = "keyframes";
- /**
- * Name
- *
- * @var string
- */
- public $Name = "";
- /**
- * Sets the properties of the @page at-rule.
- *
- * @param string $selector Selector
- * @return void
- */
- public function __construct($name, $atRuleName = null)
- {
- $this->Name = $name;
- if (!is_null($atRuleName))
- {
- $this->AtRuleName = $atRuleName;
- }
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- if ($this->AtRuleName === "-moz-keyframes")
- {
- return "@-moz-keyframes " . $this->Name . " {";
- }
- return "@" . $this->AtRuleName . " " . $this->Name . "{";
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a ruleset of a @keyframes at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesRulesetStartToken extends aCssRulesetStartToken
-{
- /**
- * Array of selectors.
- *
- * @var array
- */
- public $Selectors = array();
- /**
- * Set the properties of a ruleset token.
- *
- * @param array $selectors Selectors of the ruleset
- * @return void
- */
- public function __construct(array $selectors = array())
- {
- $this->Selectors = $selectors;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return implode(",", $this->Selectors) . "{";
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a ruleset of a @keyframes at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesRulesetEndToken extends aCssRulesetEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a ruleset declaration of a @keyframes at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesRulesetDeclarationToken extends aCssDeclarationToken
-{
-
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @keyframes at-rule blocks, rulesets and declarations.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesParserPlugin extends aCssParserPlugin
-{
- /**
- * @var string Keyword
- */
- private $atRuleName = "";
- /**
- * Selectors.
- *
- * @var array
- */
- private $selectors = array();
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", "{", "}", ":", ",", ";");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_KEYFRAMES::NAME", "T_AT_KEYFRAMES", "T_AT_KEYFRAMES_RULESETS", "T_AT_KEYFRAMES_RULESET", "T_AT_KEYFRAMES_RULESET_DECLARATION");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of @keyframes at-rule block
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@keyframes")
- {
- $this->atRuleName = "keyframes";
- $this->parser->pushState("T_AT_KEYFRAMES::NAME");
- $this->parser->clearBuffer();
- return $index + 10;
- }
- // Start of @keyframes at-rule block (@-moz-keyframes)
- elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 15)) === "@-moz-keyframes")
- {
- $this->atRuleName = "-moz-keyframes";
- $this->parser->pushState("T_AT_KEYFRAMES::NAME");
- $this->parser->clearBuffer();
- return $index + 15;
- }
- // Start of @keyframes at-rule block (@-webkit-keyframes)
- elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 18)) === "@-webkit-keyframes")
- {
- $this->atRuleName = "-webkit-keyframes";
- $this->parser->pushState("T_AT_KEYFRAMES::NAME");
- $this->parser->clearBuffer();
- return $index + 18;
- }
- // Start of @keyframes at-rule block (@-o-keyframes)
- elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 13)) === "@-o-keyframes")
- {
- $this->atRuleName = "-o-keyframes";
- $this->parser->pushState("T_AT_KEYFRAMES::NAME");
- $this->parser->clearBuffer();
- return $index + 13;
- }
- // Start of @keyframes at-rule block (@-ms-keyframes)
- elseif ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 14)) === "@-ms-keyframes")
- {
- $this->atRuleName = "-ms-keyframes";
- $this->parser->pushState("T_AT_KEYFRAMES::NAME");
- $this->parser->clearBuffer();
- return $index + 14;
- }
- // Start of @keyframes rulesets
- elseif ($char === "{" && $state === "T_AT_KEYFRAMES::NAME")
- {
- $name = $this->parser->getAndClearBuffer("{\"'");
- $this->parser->setState("T_AT_KEYFRAMES_RULESETS");
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssAtKeyframesStartToken($name, $this->atRuleName));
- }
- // Start of @keyframe ruleset and selectors
- if ($char === "," && $state === "T_AT_KEYFRAMES_RULESETS")
- {
- $this->selectors[] = $this->parser->getAndClearBuffer(",{");
- }
- // Start of a @keyframes ruleset
- elseif ($char === "{" && $state === "T_AT_KEYFRAMES_RULESETS")
- {
- if ($this->parser->getBuffer() !== "")
- {
- $this->selectors[] = $this->parser->getAndClearBuffer(",{");
- $this->parser->pushState("T_AT_KEYFRAMES_RULESET");
- $this->parser->appendToken(new CssAtKeyframesRulesetStartToken($this->selectors));
- $this->selectors = array();
- }
- }
- // Start of @keyframes ruleset declaration
- elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET")
- {
- $this->parser->pushState("T_AT_KEYFRAMES_RULESET_DECLARATION");
- $this->buffer = $this->parser->getAndClearBuffer(":;", true);
- }
- // Unterminated @keyframes ruleset declaration
- elseif ($char === ":" && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION")
- {
- // Ignore Internet Explorer filter declarations
- if ($this->buffer === "filter")
- {
- return false;
- }
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @keyframes ruleset declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
- }
- // End of declaration
- elseif (($char === ";" || $char === "}") && $state === "T_AT_KEYFRAMES_RULESET_DECLARATION")
- {
- $value = $this->parser->getAndClearBuffer(";}");
- if (strtolower(substr($value, -10, 10)) === "!important")
- {
- $value = trim(substr($value, 0, -10));
- $isImportant = true;
- }
- else
- {
- $isImportant = false;
- }
- $this->parser->popState();
- $this->parser->appendToken(new CssAtKeyframesRulesetDeclarationToken($this->buffer, $value, $isImportant));
- // Declaration ends with a right curly brace; so we have to end the ruleset
- if ($char === "}")
- {
- $this->parser->appendToken(new CssAtKeyframesRulesetEndToken());
- $this->parser->popState();
- }
- $this->buffer = "";
- }
- // End of @keyframes ruleset
- elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESET")
- {
- $this->parser->clearBuffer();
-
- $this->parser->popState();
- $this->parser->appendToken(new CssAtKeyframesRulesetEndToken());
- }
- // End of @keyframes rulesets
- elseif ($char === "}" && $state === "T_AT_KEYFRAMES_RULESETS")
- {
- $this->parser->clearBuffer();
- $this->parser->popState();
- $this->parser->appendToken(new CssAtKeyframesEndToken());
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a @keyframes at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtKeyframesEndToken extends aCssAtBlockEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a @import at-rule.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1.b1 (2001-02-22)
- */
-class CssAtImportToken extends aCssToken
-{
- /**
- * Import path of the @import at-rule.
- *
- * @var string
- */
- public $Import = "";
- /**
- * Media types of the @import at-rule.
- *
- * @var array
- */
- public $MediaTypes = array();
- /**
- * Set the properties of a @import at-rule token.
- *
- * @param string $import Import path
- * @param array $mediaTypes Media types
- * @return void
- */
- public function __construct($import, $mediaTypes)
- {
- $this->Import = $import;
- $this->MediaTypes = $mediaTypes ? $mediaTypes : array();
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "@import \"" . $this->Import . "\"" . (count($this->MediaTypes) > 0 ? " " . implode(",", $this->MediaTypes) : ""). ";";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @import at-rule.
- *
- * If a @import at-rule was found this plugin will add a {@link CssAtImportToken} to the parser.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtImportParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", ";", ",", "\n");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_IMPORT");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 7)) === "@import")
- {
- $this->parser->pushState("T_AT_IMPORT");
- $this->parser->clearBuffer();
- return $index + 7;
- }
- elseif (($char === ";" || $char === "\n") && $state === "T_AT_IMPORT")
- {
- $this->buffer = $this->parser->getAndClearBuffer(";");
- $pos = false;
- foreach (array(")", "\"", "'") as $needle)
- {
- if (($pos = strrpos($this->buffer, $needle)) !== false)
- {
- break;
- }
- }
- $import = substr($this->buffer, 0, $pos + 1);
- if (stripos($import, "url(") === 0)
- {
- $import = substr($import, 4, -1);
- }
- $import = trim($import, " \t\n\r\0\x0B'\"");
- $mediaTypes = array_filter(array_map("trim", explode(",", trim(substr($this->buffer, $pos + 1), " \t\n\r\0\x0B{"))));
- if ($pos)
- {
- $this->parser->appendToken(new CssAtImportToken($import, $mediaTypes));
- }
- else
- {
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Invalid @import at-rule syntax", $this->buffer));
- }
- $this->parser->popState();
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the start of a @font-face at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtFontFaceStartToken extends aCssAtBlockStartToken
-{
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "@font-face{";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @font-face at-rule block with including declarations.
- *
- * Found @font-face at-rule blocks will add a {@link CssAtFontFaceStartToken} and {@link CssAtFontFaceEndToken} to the
- * parser; including declarations as {@link CssAtFontFaceDeclarationToken}.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtFontFaceParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", "{", "}", ":", ";");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_FONT_FACE::PREPARE", "T_AT_FONT_FACE", "T_AT_FONT_FACE_DECLARATION");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- // Start of @font-face at-rule block
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@font-face")
- {
- $this->parser->pushState("T_AT_FONT_FACE::PREPARE");
- $this->parser->clearBuffer();
- return $index + 10 - 1;
- }
- // Start of @font-face declarations
- elseif ($char === "{" && $state === "T_AT_FONT_FACE::PREPARE")
- {
- $this->parser->setState("T_AT_FONT_FACE");
- $this->parser->clearBuffer();
- $this->parser->appendToken(new CssAtFontFaceStartToken());
- }
- // Start of @font-face declaration
- elseif ($char === ":" && $state === "T_AT_FONT_FACE")
- {
- $this->parser->pushState("T_AT_FONT_FACE_DECLARATION");
- $this->buffer = $this->parser->getAndClearBuffer(":", true);
- }
- // Unterminated @font-face declaration
- elseif ($char === ":" && $state === "T_AT_FONT_FACE_DECLARATION")
- {
- // Ignore Internet Explorer filter declarations
- if ($this->buffer === "filter")
- {
- return false;
- }
- CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @font-face declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
- }
- // End of @font-face declaration
- elseif (($char === ";" || $char === "}") && $state === "T_AT_FONT_FACE_DECLARATION")
- {
- $value = $this->parser->getAndClearBuffer(";}");
- if (strtolower(substr($value, -10, 10)) === "!important")
- {
- $value = trim(substr($value, 0, -10));
- $isImportant = true;
- }
- else
- {
- $isImportant = false;
- }
- $this->parser->popState();
- $this->parser->appendToken(new CssAtFontFaceDeclarationToken($this->buffer, $value, $isImportant));
- $this->buffer = "";
- // --
- if ($char === "}")
- {
- $this->parser->appendToken(new CssAtFontFaceEndToken());
- $this->parser->popState();
- }
- }
- // End of @font-face at-rule block
- elseif ($char === "}" && $state === "T_AT_FONT_FACE")
- {
- $this->parser->appendToken(new CssAtFontFaceEndToken());
- $this->parser->clearBuffer();
- $this->parser->popState();
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-/**
- * This {@link aCssToken CSS token} represents the end of a @font-face at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtFontFaceEndToken extends aCssAtBlockEndToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a declaration of a @font-face at-rule block.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtFontFaceDeclarationToken extends aCssDeclarationToken
-{
-
-}
-
-/**
- * This {@link aCssToken CSS token} represents a @charset at-rule.
- *
- * @package CssMin/Tokens
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtCharsetToken extends aCssToken
-{
- /**
- * Charset of the @charset at-rule.
- *
- * @var string
- */
- public $Charset = "";
- /**
- * Set the properties of @charset at-rule token.
- *
- * @param string $charset Charset of the @charset at-rule token
- * @return void
- */
- public function __construct($charset)
- {
- $this->Charset = $charset;
- }
- /**
- * Implements {@link aCssToken::__toString()}.
- *
- * @return string
- */
- public function __toString()
- {
- return "@charset " . $this->Charset . ";";
- }
-}
-
-/**
- * {@link aCssParserPlugin Parser plugin} for parsing @charset at-rule.
- *
- * If a @charset at-rule was found this plugin will add a {@link CssAtCharsetToken} to the parser.
- *
- * @package CssMin/Parser/Plugins
- * @link http://code.google.com/p/cssmin/
- * @author Joe Scylla
- * @copyright 2008 - 2011 Joe Scylla
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 3.0.1
- */
-class CssAtCharsetParserPlugin extends aCssParserPlugin
-{
- /**
- * Implements {@link aCssParserPlugin::getTriggerChars()}.
- *
- * @return array
- */
- public function getTriggerChars()
- {
- return array("@", ";", "\n");
- }
- /**
- * Implements {@link aCssParserPlugin::getTriggerStates()}.
- *
- * @return array
- */
- public function getTriggerStates()
- {
- return array("T_DOCUMENT", "T_AT_CHARSET");
- }
- /**
- * Implements {@link aCssParserPlugin::parse()}.
- *
- * @param integer $index Current index
- * @param string $char Current char
- * @param string $previousChar Previous char
- * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
- */
- public function parse($index, $char, $previousChar, $state)
- {
- if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 8)) === "@charset")
- {
- $this->parser->pushState("T_AT_CHARSET");
- $this->parser->clearBuffer();
- return $index + 8;
- }
- elseif (($char === ";" || $char === "\n") && $state === "T_AT_CHARSET")
- {
- $charset = $this->parser->getAndClearBuffer(";");
- $this->parser->popState();
- $this->parser->appendToken(new CssAtCharsetToken($charset));
- }
- else
- {
- return false;
- }
- return true;
- }
-}
-
-?>
+
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * --
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+/**
+ * Abstract definition of a CSS token class.
+ *
+ * Every token has to extend this class.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssToken
+{
+ /**
+ * Returns the token as string.
+ *
+ * @return string
+ */
+ abstract public function __toString();
+}
+
+/**
+ * Abstract definition of a for a ruleset start token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssRulesetStartToken extends aCssToken
+{
+
+}
+
+/**
+ * Abstract definition of a for ruleset end token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssRulesetEndToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "}";
+ }
+}
+
+/**
+ * Abstract definition of a parser plugin.
+ *
+ * Every parser plugin have to extend this class. A parser plugin contains the logic to parse one or aspects of a
+ * stylesheet.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssParserPlugin
+{
+ /**
+ * Plugin configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssParser of the plugin.
+ *
+ * @var CssParser
+ */
+ protected $parser = null;
+ /**
+ * Plugin buffer.
+ *
+ * @var string
+ */
+ protected $buffer = "";
+ /**
+ * Constructor.
+ *
+ * @param CssParser $parser The CssParser object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssParser $parser, array $configuration = null)
+ {
+ $this->configuration = $configuration;
+ $this->parser = $parser;
+ }
+ /**
+ * Returns the array of chars triggering the parser plugin.
+ *
+ * @return array
+ */
+ abstract public function getTriggerChars();
+ /**
+ * Returns the array of states triggering the parser plugin or FALSE if every state will trigger the parser plugin.
+ *
+ * @return array
+ */
+ abstract public function getTriggerStates();
+ /**
+ * Parser routine of the plugin.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ abstract public function parse($index, $char, $previousChar, $state);
+}
+
+/**
+ * Abstract definition of a minifier plugin class.
+ *
+ * Minifier plugin process the parsed tokens one by one to apply changes to the token. Every minifier plugin has to
+ * extend this class.
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssMinifierPlugin
+{
+ /**
+ * Plugin configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssMinifier of the plugin.
+ *
+ * @var CssMinifier
+ */
+ protected $minifier = null;
+ /**
+ * Constructor.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->configuration = $configuration;
+ $this->minifier = $minifier;
+ }
+ /**
+ * Apply the plugin to the token.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ abstract public function apply(aCssToken &$token);
+ /**
+ * --
+ *
+ * @return array
+ */
+ abstract public function getTriggerTokens();
+}
+
+/**
+ * Abstract definition of a minifier filter class.
+ *
+ * Minifier filters allows a pre-processing of the parsed token to add, edit or delete tokens. Every minifier filter
+ * has to extend this class.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssMinifierFilter
+{
+ /**
+ * Filter configuration.
+ *
+ * @var array
+ */
+ protected $configuration = array();
+ /**
+ * The CssMinifier of the filter.
+ *
+ * @var CssMinifier
+ */
+ protected $minifier = null;
+ /**
+ * Constructor.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Filter configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->configuration = $configuration;
+ $this->minifier = $minifier;
+ }
+ /**
+ * Filter the tokens.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ abstract public function apply(array &$tokens);
+}
+
+/**
+ * Abstract formatter definition.
+ *
+ * Every formatter have to extend this class.
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssFormatter
+{
+ /**
+ * Indent string.
+ *
+ * @var string
+ */
+ protected $indent = " ";
+ /**
+ * Declaration padding.
+ *
+ * @var integer
+ */
+ protected $padding = 0;
+ /**
+ * Tokens.
+ *
+ * @var array
+ */
+ protected $tokens = array();
+ /**
+ * Constructor.
+ *
+ * @param array $tokens Array of CssToken
+ * @param string $indent Indent string [optional]
+ * @param integer $padding Declaration value padding [optional]
+ */
+ public function __construct(array $tokens, $indent = null, $padding = null)
+ {
+ $this->tokens = $tokens;
+ $this->indent = !is_null($indent) ? $indent : $this->indent;
+ $this->padding = !is_null($padding) ? $padding : $this->padding;
+ }
+ /**
+ * Returns the array of aCssToken as formatted string.
+ *
+ * @return string
+ */
+ abstract public function __toString();
+}
+
+/**
+ * Abstract definition of a ruleset declaration token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssDeclarationToken extends aCssToken
+{
+ /**
+ * Is the declaration flagged as important?
+ *
+ * @var boolean
+ */
+ public $IsImportant = false;
+ /**
+ * Is the declaration flagged as last one of the ruleset?
+ *
+ * @var boolean
+ */
+ public $IsLast = false;
+ /**
+ * Property name of the declaration.
+ *
+ * @var string
+ */
+ public $Property = "";
+ /**
+ * Value of the declaration.
+ *
+ * @var string
+ */
+ public $Value = "";
+ /**
+ * Set the properties of the @font-face declaration.
+ *
+ * @param string $property Property of the declaration
+ * @param string $value Value of the declaration
+ * @param boolean $isImportant Is the !important flag is set?
+ * @param boolean $IsLast Is the declaration the last one of the block?
+ * @return void
+ */
+ public function __construct($property, $value, $isImportant = false, $isLast = false)
+ {
+ $this->Property = $property;
+ $this->Value = $value;
+ $this->IsImportant = $isImportant;
+ $this->IsLast = $isLast;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Property . ":" . $this->Value . ($this->IsImportant ? " !important" : "") . ($this->IsLast ? "" : ";");
+ }
+}
+
+/**
+ * Abstract definition of a for at-rule block start token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssAtBlockStartToken extends aCssToken
+{
+
+}
+
+/**
+ * Abstract definition of a for at-rule block end token.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+abstract class aCssAtBlockEndToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "}";
+ }
+}
+
+/**
+ * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/etzLs Whitesmiths indent style}.
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssWhitesmithsFormatter extends aCssFormatter
+{
+ /**
+ * Implements {@link aCssFormatter::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $r = array();
+ $level = 0;
+ for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
+ {
+ $token = $this->tokens[$i];
+ $class = get_class($token);
+ $indent = str_repeat($this->indent, $level);
+ if ($class === "CssCommentToken")
+ {
+ $lines = array_map("trim", explode("\n", $token->Comment));
+ for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
+ {
+ $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
+ }
+ }
+ elseif ($class === "CssAtCharsetToken")
+ {
+ $r[] = $indent . "@charset " . $token->Charset . ";";
+ }
+ elseif ($class === "CssAtFontFaceStartToken")
+ {
+ $r[] = $indent . "@font-face";
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtImportToken")
+ {
+ $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
+ }
+ elseif ($class === "CssAtKeyframesStartToken")
+ {
+ $r[] = $indent . "@keyframes " . $token->Name;
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtMediaStartToken")
+ {
+ $r[] = $indent . "@media " . implode(", ", $token->MediaTypes);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtPageStartToken")
+ {
+ $r[] = $indent . "@page";
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtVariablesStartToken")
+ {
+ $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
+ {
+ $r[] = $indent . implode(", ", $token->Selectors);
+ $r[] = $this->indent . $indent . "{";
+ $level++;
+ }
+ elseif ($class === "CssAtFontFaceDeclarationToken"
+ || $class === "CssAtKeyframesRulesetDeclarationToken"
+ || $class === "CssAtPageDeclarationToken"
+ || $class === "CssAtVariablesDeclarationToken"
+ || $class === "CssRulesetDeclarationToken"
+ )
+ {
+ $declaration = $indent . $token->Property . ": ";
+ if ($this->padding)
+ {
+ $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
+ }
+ $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
+ }
+ elseif ($class === "CssAtFontFaceEndToken"
+ || $class === "CssAtMediaEndToken"
+ || $class === "CssAtKeyframesEndToken"
+ || $class === "CssAtKeyframesRulesetEndToken"
+ || $class === "CssAtPageEndToken"
+ || $class === "CssAtVariablesEndToken"
+ || $class === "CssRulesetEndToken"
+ )
+ {
+ $r[] = $indent . "}";
+ $level--;
+ }
+ }
+ return implode("\n", $r);
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will process var-statement and sets the declaration value to the variable value.
+ *
+ * This plugin only apply the variable values. The variable values itself will get parsed by the
+ * {@link CssVariablesMinifierFilter}.
+ *
+ * Example:
+ *
+ * @variables
+ * {
+ * defaultColor: black;
+ * }
+ * color: var(defaultColor);
+ *
+ *
+ * Will get converted to:
+ *
+ * color:black;
+ *
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssVariablesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching a value.
+ *
+ * @var string
+ */
+ private $reMatch = "/var\((.+)\)/iSU";
+ /**
+ * Parsed variables.
+ *
+ * @var array
+ */
+ private $variables = null;
+ /**
+ * Returns the variables.
+ *
+ * @return array
+ */
+ public function getVariables()
+ {
+ return $this->variables;
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "var") !== false && preg_match_all($this->reMatch, $token->Value, $m))
+ {
+ $mediaTypes = $token->MediaTypes;
+ if (!in_array("all", $mediaTypes))
+ {
+ $mediaTypes[] = "all";
+ }
+ for ($i = 0, $l = count($m[0]); $i < $l; $i++)
+ {
+ $variable = trim($m[1][$i]);
+ foreach ($mediaTypes as $mediaType)
+ {
+ if (isset($this->variables[$mediaType], $this->variables[$mediaType][$variable]))
+ {
+ // Variable value found => set the declaration value to the variable value and return
+ $token->Value = str_replace($m[0][$i], $this->variables[$mediaType][$variable], $token->Value);
+ continue 2;
+ }
+ }
+ // If no value was found trigger an error and replace the token with a CssNullToken
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": No value found for variable " . $variable . "
in media types " . implode(", ", $mediaTypes) . "
", (string) $token));
+ $token = new CssNullToken();
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+ /**
+ * Sets the variables.
+ *
+ * @param array $variables Variables to set
+ * @return void
+ */
+ public function setVariables(array $variables)
+ {
+ $this->variables = $variables;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will parse the variable declarations out of @variables at-rule
+ * blocks. The variables will get store in the {@link CssVariablesMinifierPlugin} that will apply the variables to
+ * declaration.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssVariablesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $variables = array();
+ $defaultMediaTypes = array("all");
+ $mediaTypes = array();
+ $remove = array();
+ for($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ // @variables at-rule block found
+ if (get_class($tokens[$i]) === "CssAtVariablesStartToken")
+ {
+ $remove[] = $i;
+ $mediaTypes = (count($tokens[$i]->MediaTypes) == 0 ? $defaultMediaTypes : $tokens[$i]->MediaTypes);
+ foreach ($mediaTypes as $mediaType)
+ {
+ if (!isset($variables[$mediaType]))
+ {
+ $variables[$mediaType] = array();
+ }
+ }
+ // Read the variable declaration tokens
+ for($i = $i; $i < $l; $i++)
+ {
+ // Found a variable declaration => read the variable values
+ if (get_class($tokens[$i]) === "CssAtVariablesDeclarationToken")
+ {
+ foreach ($mediaTypes as $mediaType)
+ {
+ $variables[$mediaType][$tokens[$i]->Property] = $tokens[$i]->Value;
+ }
+ $remove[] = $i;
+ }
+ // Found the variables end token => break;
+ elseif (get_class($tokens[$i]) === "CssAtVariablesEndToken")
+ {
+ $remove[] = $i;
+ break;
+ }
+ }
+ }
+ }
+ // Variables in @variables at-rule blocks
+ foreach($variables as $mediaType => $null)
+ {
+ foreach($variables[$mediaType] as $variable => $value)
+ {
+ // If a var() statement in a variable value found...
+ if (stripos($value, "var") !== false && preg_match_all("/var\((.+)\)/iSU", $value, $m))
+ {
+ // ... then replace the var() statement with the variable values.
+ for ($i = 0, $l = count($m[0]); $i < $l; $i++)
+ {
+ $variables[$mediaType][$variable] = str_replace($m[0][$i], (isset($variables[$mediaType][$m[1][$i]]) ? $variables[$mediaType][$m[1][$i]] : ""), $variables[$mediaType][$variable]);
+ }
+ }
+ }
+ }
+ // Remove the complete @variables at-rule block
+ foreach ($remove as $i)
+ {
+ $tokens[$i] = null;
+ }
+ if (!($plugin = $this->minifier->getPlugin("CssVariablesMinifierPlugin")))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin CssVariablesMinifierPlugin
was not found but is required for " . __CLASS__ . "
"));
+ }
+ else
+ {
+ $plugin->setVariables($variables);
+ }
+ return count($remove);
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing url() values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that url() values will get parsed properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssUrlParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("(", ")");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of string
+ if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 3, 4)) === "url(" && $state !== "T_URL")
+ {
+ $this->parser->pushState("T_URL");
+ $this->parser->setExclusive(__CLASS__);
+ }
+ // Escaped LF in url => remove escape backslash and LF
+ elseif ($char === "\n" && $previousChar === "\\" && $state === "T_URL")
+ {
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
+ }
+ // Parse error: Unescaped LF in string literal
+ elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_URL")
+ {
+ $line = $this->parser->getBuffer();
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . ")"); // Replace the LF with the url string delimiter
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
+ }
+ // End of string
+ elseif ($char === ")" && $state === "T_URL")
+ {
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing string values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that string values will get parsed properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssStringParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Current string delimiter char.
+ *
+ * @var string
+ */
+ private $delimiterChar = null;
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("\"", "'", "\n");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of string
+ if (($char === "\"" || $char === "'") && $state !== "T_STRING")
+ {
+ $this->delimiterChar = $char;
+ $this->parser->pushState("T_STRING");
+ $this->parser->setExclusive(__CLASS__);
+ }
+ // Escaped LF in string => remove escape backslash and LF
+ elseif ($char === "\n" && $previousChar === "\\" && $state === "T_STRING")
+ {
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -2));
+ }
+ // Parse error: Unescaped LF in string literal
+ elseif ($char === "\n" && $previousChar !== "\\" && $state === "T_STRING")
+ {
+ $line = $this->parser->getBuffer();
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->parser->setBuffer(substr($this->parser->getBuffer(), 0, -1) . $this->delimiterChar); // Replace the LF with the current string char
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated string literal", $line . "_"));
+ $this->delimiterChar = null;
+ }
+ // End of string
+ elseif ($char === $this->delimiterChar && $state === "T_STRING")
+ {
+ // If the Previous char is a escape char count the amount of the previous escape chars. If the amount of
+ // escape chars is uneven do not end the string
+ if ($previousChar == "\\")
+ {
+ $source = $this->parser->getSource();
+ $c = 1;
+ $i = $index - 2;
+ while (substr($source, $i, 1) === "\\")
+ {
+ $c++; $i--;
+ }
+ if ($c % 2)
+ {
+ return false;
+ }
+ }
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->delimiterChar = null;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} sorts the ruleset declarations of a ruleset by name.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Rowan Beentje
+ * @copyright Rowan Beentje
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssSortRulesetPropertiesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ // Only look for ruleset start rules
+ if (get_class($tokens[$i]) !== "CssRulesetStartToken") { continue; }
+ // Look for the corresponding ruleset end
+ $endIndex = false;
+ for ($ii = $i + 1; $ii < $l; $ii++)
+ {
+ if (get_class($tokens[$ii]) !== "CssRulesetEndToken") { continue; }
+ $endIndex = $ii;
+ break;
+ }
+ if (!$endIndex) { break; }
+ $startIndex = $i;
+ $i = $endIndex;
+ // Skip if there's only one token in this ruleset
+ if ($endIndex - $startIndex <= 2) { continue; }
+ // Ensure that everything between the start and end is a declaration token, for safety
+ for ($ii = $startIndex + 1; $ii < $endIndex; $ii++)
+ {
+ if (get_class($tokens[$ii]) !== "CssRulesetDeclarationToken") { continue(2); }
+ }
+ $declarations = array_slice($tokens, $startIndex + 1, $endIndex - $startIndex - 1);
+ // Check whether a sort is required
+ $sortRequired = $lastPropertyName = false;
+ foreach ($declarations as $declaration)
+ {
+ if ($lastPropertyName)
+ {
+ if (strcmp($lastPropertyName, $declaration->Property) > 0)
+ {
+ $sortRequired = true;
+ break;
+ }
+ }
+ $lastPropertyName = $declaration->Property;
+ }
+ if (!$sortRequired) { continue; }
+ // Arrange the declarations alphabetically by name
+ usort($declarations, array(__CLASS__, "userDefinedSort1"));
+ // Update "IsLast" property
+ for ($ii = 0, $ll = count($declarations) - 1; $ii <= $ll; $ii++)
+ {
+ if ($ii == $ll)
+ {
+ $declarations[$ii]->IsLast = true;
+ }
+ else
+ {
+ $declarations[$ii]->IsLast = false;
+ }
+ }
+ // Splice back into the array.
+ array_splice($tokens, $startIndex + 1, $endIndex - $startIndex - 1, $declarations);
+ $r += $endIndex - $startIndex - 1;
+ }
+ return $r;
+ }
+ /**
+ * User defined sort function.
+ *
+ * @return integer
+ */
+ public static function userDefinedSort1($a, $b)
+ {
+ return strcmp($a->Property, $b->Property);
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a ruleset.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetStartToken extends aCssRulesetStartToken
+{
+ /**
+ * Array of selectors.
+ *
+ * @var array
+ */
+ public $Selectors = array();
+ /**
+ * Set the properties of a ruleset token.
+ *
+ * @param array $selectors Selectors of the ruleset
+ * @return void
+ */
+ public function __construct(array $selectors = array())
+ {
+ $this->Selectors = $selectors;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return implode(",", $this->Selectors) . "{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing ruleset block with including declarations.
+ *
+ * Found rulesets will add a {@link CssRulesetStartToken} and {@link CssRulesetEndToken} to the
+ * parser; including declarations as {@link CssRulesetDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array(",", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_MEDIA", "T_RULESET::SELECTORS", "T_RULESET", "T_RULESET_DECLARATION");
+ }
+ /**
+ * Selectors.
+ *
+ * @var array
+ */
+ private $selectors = array();
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of Ruleset and selectors
+ if ($char === "," && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
+ {
+ if ($state !== "T_RULESET::SELECTORS")
+ {
+ $this->parser->pushState("T_RULESET::SELECTORS");
+ }
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ }
+ // End of selectors and start of declarations
+ elseif ($char === "{" && ($state === "T_DOCUMENT" || $state === "T_AT_MEDIA" || $state === "T_RULESET::SELECTORS"))
+ {
+ if ($this->parser->getBuffer() !== "")
+ {
+ $this->selectors[] = $this->parser->getAndClearBuffer(",{");
+ if ($state == "T_RULESET::SELECTORS")
+ {
+ $this->parser->popState();
+ }
+ $this->parser->pushState("T_RULESET");
+ $this->parser->appendToken(new CssRulesetStartToken($this->selectors));
+ $this->selectors = array();
+ }
+ }
+ // Start of declaration
+ elseif ($char === ":" && $state === "T_RULESET")
+ {
+ $this->parser->pushState("T_RULESET_DECLARATION");
+ $this->buffer = $this->parser->getAndClearBuffer(":;", true);
+ }
+ // Unterminated ruleset declaration
+ elseif ($char === ":" && $state === "T_RULESET_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_RULESET_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssRulesetDeclarationToken($this->buffer, $value, $this->parser->getMediaTypes(), $isImportant));
+ // Declaration ends with a right curly brace; so we have to end the ruleset
+ if ($char === "}")
+ {
+ $this->parser->appendToken(new CssRulesetEndToken());
+ $this->parser->popState();
+ }
+ $this->buffer = "";
+ }
+ // End of ruleset
+ elseif ($char === "}" && $state === "T_RULESET")
+ {
+ $this->parser->popState();
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssRulesetEndToken());
+ $this->buffer = "";
+ $this->selectors = array();
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a ruleset.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetEndToken extends aCssRulesetEndToken
+{
+
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a ruleset declaration.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRulesetDeclarationToken extends aCssDeclarationToken
+{
+ /**
+ * Media types of the declaration.
+ *
+ * @var array
+ */
+ public $MediaTypes = array("all");
+ /**
+ * Set the properties of a ddocument- or at-rule @media level declaration.
+ *
+ * @param string $property Property of the declaration
+ * @param string $value Value of the declaration
+ * @param mixed $mediaTypes Media types of the declaration
+ * @param boolean $isImportant Is the !important flag is set
+ * @param boolean $isLast Is the declaration the last one of the ruleset
+ * @return void
+ */
+ public function __construct($property, $value, $mediaTypes = null, $isImportant = false, $isLast = false)
+ {
+ parent::__construct($property, $value, $isImportant, $isLast);
+ $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} sets the IsLast property of any last declaration in a ruleset,
+ * @font-face at-rule or @page at-rule block. If the property IsLast is TRUE the decrations will get stringified
+ * without tailing semicolon.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveLastDelarationSemiColonMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i+1]) ? get_class($tokens[$i+1]) : false;
+ if (($current === "CssRulesetDeclarationToken" && $next === "CssRulesetEndToken") ||
+ ($current === "CssAtFontFaceDeclarationToken" && $next === "CssAtFontFaceEndToken") ||
+ ($current === "CssAtPageDeclarationToken" && $next === "CssAtPageEndToken"))
+ {
+ $tokens[$i]->IsLast = true;
+ }
+ }
+ return 0;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any empty rulesets (including @keyframes at-rule block
+ * rulesets).
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveEmptyRulesetsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
+ if (($current === "CssRulesetStartToken" && $next === "CssRulesetEndToken") ||
+ ($current === "CssAtKeyframesRulesetStartToken" && $next === "CssAtKeyframesRulesetEndToken" && !array_intersect(array("from", "0%", "to", "100%"), array_map("strtolower", $tokens[$i]->Selectors)))
+ )
+ {
+ $tokens[$i] = null;
+ $tokens[$i + 1] = null;
+ $i++;
+ $r = $r + 2;
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any empty @font-face, @keyframes, @media and @page
+ * at-rule blocks.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveEmptyAtBlocksMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ $current = get_class($tokens[$i]);
+ $next = isset($tokens[$i + 1]) ? get_class($tokens[$i + 1]) : false;
+ if (($current === "CssAtFontFaceStartToken" && $next === "CssAtFontFaceEndToken") ||
+ ($current === "CssAtKeyframesStartToken" && $next === "CssAtKeyframesEndToken") ||
+ ($current === "CssAtPageStartToken" && $next === "CssAtPageEndToken") ||
+ ($current === "CssAtMediaStartToken" && $next === "CssAtMediaEndToken"))
+ {
+ $tokens[$i] = null;
+ $tokens[$i + 1] = null;
+ $i++;
+ $r = $r + 2;
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will remove any comments from the array of parsed tokens.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssRemoveCommentsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Regular expression whitelisting any important comments to preserve.
+ *
+ * @var string
+ */
+ private $whitelistPattern = '/(^\/\*!|@preserve|copyright|license|author|https?:|www\.)/i';
+
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssCommentToken")
+ {
+ if (!preg_match($this->whitelistPattern, $tokens[$i]->Comment))
+ {
+ $tokens[$i] = null;
+ $r++;
+ }
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * CSS Parser.
+ *
+ * @package CssMin/Parser
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssParser
+{
+ /**
+ * Parse buffer.
+ *
+ * @var string
+ */
+ private $buffer = "";
+ /**
+ * {@link aCssParserPlugin Plugins}.
+ *
+ * @var array
+ */
+ private $plugins = array();
+ /**
+ * Source to parse.
+ *
+ * @var string
+ */
+ private $source = "";
+ /**
+ * Current state.
+ *
+ * @var integer
+ */
+ private $state = "T_DOCUMENT";
+ /**
+ * Exclusive state.
+ *
+ * @var string
+ */
+ private $stateExclusive = false;
+ /**
+ * Media types state.
+ *
+ * @var mixed
+ */
+ private $stateMediaTypes = false;
+ /**
+ * State stack.
+ *
+ * @var array
+ */
+ private $states = array("T_DOCUMENT");
+ /**
+ * Parsed tokens.
+ *
+ * @var array
+ */
+ private $tokens = array();
+ /**
+ * Constructer.
+ *
+ * Create instances of the used {@link aCssParserPlugin plugins}.
+ *
+ * @param string $source CSS source [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct($source = null, array $plugins = null)
+ {
+ $plugins = array_merge(array
+ (
+ "Comment" => true,
+ "String" => true,
+ "Url" => true,
+ "Expression" => true,
+ "Ruleset" => true,
+ "AtCharset" => true,
+ "AtFontFace" => true,
+ "AtImport" => true,
+ "AtKeyframes" => true,
+ "AtMedia" => true,
+ "AtPage" => true,
+ "AtVariables" => true
+ ), is_array($plugins) ? $plugins : array());
+ // Create plugin instances
+ foreach ($plugins as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "ParserPlugin";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->plugins[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . "
with the class name " . $class . "
was not found"));
+ }
+ }
+ }
+ if (!is_null($source))
+ {
+ $this->parse($source);
+ }
+ }
+ /**
+ * Append a token to the array of tokens.
+ *
+ * @param aCssToken $token Token to append
+ * @return void
+ */
+ public function appendToken(aCssToken $token)
+ {
+ $this->tokens[] = $token;
+ }
+ /**
+ * Clears the current buffer.
+ *
+ * @return void
+ */
+ public function clearBuffer()
+ {
+ $this->buffer = "";
+ }
+ /**
+ * Returns and clear the current buffer.
+ *
+ * @param string $trim Chars to use to trim the returned buffer
+ * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
+ * @return string
+ */
+ public function getAndClearBuffer($trim = "", $tolower = false)
+ {
+ $r = $this->getBuffer($trim, $tolower);
+ $this->buffer = "";
+ return $r;
+ }
+ /**
+ * Returns the current buffer.
+ *
+ * @param string $trim Chars to use to trim the returned buffer
+ * @param boolean $tolower if TRUE the returned buffer will get converted to lower case
+ * @return string
+ */
+ public function getBuffer($trim = "", $tolower = false)
+ {
+ $r = $this->buffer;
+ if ($trim)
+ {
+ $r = trim($r, " \t\n\r\0\x0B" . $trim);
+ }
+ if ($tolower)
+ {
+ $r = strtolower($r);
+ }
+ return $r;
+ }
+ /**
+ * Returns the current media types state.
+ *
+ * @return array
+ */
+ public function getMediaTypes()
+ {
+ return $this->stateMediaTypes;
+ }
+ /**
+ * Returns the CSS source.
+ *
+ * @return string
+ */
+ public function getSource()
+ {
+ return $this->source;
+ }
+ /**
+ * Returns the current state.
+ *
+ * @return integer The current state
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+ /**
+ * Returns a plugin by class name.
+ *
+ * @param string $name Class name of the plugin
+ * @return aCssParserPlugin
+ */
+ public function getPlugin($class)
+ {
+ static $index = null;
+ if (is_null($index))
+ {
+ $index = array();
+ for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
+ {
+ $index[get_class($this->plugins[$i])] = $i;
+ }
+ }
+ return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
+ }
+ /**
+ * Returns the parsed tokens.
+ *
+ * @return array
+ */
+ public function getTokens()
+ {
+ return $this->tokens;
+ }
+ /**
+ * Returns if the current state equals the passed state.
+ *
+ * @param integer $state State to compare with the current state
+ * @return boolean TRUE is the state equals to the passed state; FALSE if not
+ */
+ public function isState($state)
+ {
+ return ($this->state == $state);
+ }
+ /**
+ * Parse the CSS source and return a array with parsed tokens.
+ *
+ * @param string $source CSS source
+ * @return array Array with tokens
+ */
+ public function parse($source)
+ {
+ // Reset
+ $this->source = "";
+ $this->tokens = array();
+ // Create a global and plugin lookup table for trigger chars; set array of plugins as local variable and create
+ // several helper variables for plugin handling
+ $globalTriggerChars = "";
+ $plugins = $this->plugins;
+ $pluginCount = count($plugins);
+ $pluginIndex = array();
+ $pluginTriggerStates = array();
+ $pluginTriggerChars = array();
+ for ($i = 0, $l = count($plugins); $i < $l; $i++)
+ {
+ $tPluginClassName = get_class($plugins[$i]);
+ $pluginTriggerChars[$i] = implode("", $plugins[$i]->getTriggerChars());
+ $tPluginTriggerStates = $plugins[$i]->getTriggerStates();
+ $pluginTriggerStates[$i] = $tPluginTriggerStates === false ? false : "|" . implode("|", $tPluginTriggerStates) . "|";
+ $pluginIndex[$tPluginClassName] = $i;
+ for ($ii = 0, $ll = strlen($pluginTriggerChars[$i]); $ii < $ll; $ii++)
+ {
+ $c = substr($pluginTriggerChars[$i], $ii, 1);
+ if (strpos($globalTriggerChars, $c) === false)
+ {
+ $globalTriggerChars .= $c;
+ }
+ }
+ }
+ // Normalise line endings
+ $source = str_replace("\r\n", "\n", $source); // Windows to Unix line endings
+ $source = str_replace("\r", "\n", $source); // Mac to Unix line endings
+ $this->source = $source;
+ // Variables
+ $buffer = &$this->buffer;
+ $exclusive = &$this->stateExclusive;
+ $state = &$this->state;
+ $c = $p = null;
+ // --
+ for ($i = 0, $l = strlen($source); $i < $l; $i++)
+ {
+ // Set the current Char
+ $c = $source[$i]; // Is faster than: $c = substr($source, $i, 1);
+ // Normalize and filter double whitespace characters
+ if ($exclusive === false)
+ {
+ if ($c === "\n" || $c === "\t")
+ {
+ $c = " ";
+ }
+ if ($c === " " && $p === " ")
+ {
+ continue;
+ }
+ }
+ $buffer .= $c;
+
+ // Fix case when value of url() contains parentheses, for example: url("data: ... ()")
+ if ($this->getState() == 'T_URL' && $c == ')') {
+ $trimmedBuffer = trim($buffer);
+ if (preg_match('@url\((\s+)?".+@', $trimmedBuffer)
+ && !preg_match('@url\((\s+)?".+"\)@', $trimmedBuffer)
+ || preg_match('@url\((\s+)?\'.+@', $trimmedBuffer)
+ && !preg_match('@url\((\s+)?\'.+\'\)@', $trimmedBuffer)
+ ) {
+ $p = $c; // Set the parent char
+ continue;
+ }
+ }
+
+ // Extended processing only if the current char is a global trigger char
+ if (strpos($globalTriggerChars, $c) !== false)
+ {
+ // Exclusive state is set; process with the exclusive plugin
+ if ($exclusive)
+ {
+ $tPluginIndex = $pluginIndex[$exclusive];
+ if (strpos($pluginTriggerChars[$tPluginIndex], $c) !== false && ($pluginTriggerStates[$tPluginIndex] === false || strpos($pluginTriggerStates[$tPluginIndex], $state) !== false))
+ {
+ $r = $plugins[$tPluginIndex]->parse($i, $c, $p, $state);
+ // Return value is TRUE => continue with next char
+ if ($r === true)
+ {
+ continue;
+ }
+ // Return value is numeric => set new index and continue with next char
+ elseif ($r !== false && $r != $i)
+ {
+ $i = $r;
+ continue;
+ }
+ }
+ }
+ // Else iterate through the plugins
+ else
+ {
+ $triggerState = "|" . $state . "|";
+ for ($ii = 0, $ll = $pluginCount; $ii < $ll; $ii++)
+ {
+ // Only process if the current char is one of the plugin trigger chars
+ if (strpos($pluginTriggerChars[$ii], $c) !== false && ($pluginTriggerStates[$ii] === false || strpos($pluginTriggerStates[$ii], $triggerState) !== false))
+ {
+ // Process with the plugin
+ $r = $plugins[$ii]->parse($i, $c, $p, $state);
+ // Return value is TRUE => break the plugin loop and and continue with next char
+ if ($r === true)
+ {
+ break;
+ }
+ // Return value is numeric => set new index, break the plugin loop and and continue with next char
+ elseif ($r !== false && $r != $i)
+ {
+ $i = $r;
+ break;
+ }
+ }
+ }
+ }
+ }
+ $p = $c; // Set the parent char
+ }
+ return $this->tokens;
+ }
+ /**
+ * Remove the last state of the state stack and return the removed stack value.
+ *
+ * @return integer Removed state value
+ */
+ public function popState()
+ {
+ $r = array_pop($this->states);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Adds a new state onto the state stack.
+ *
+ * @param integer $state State to add onto the state stack.
+ * @return integer The index of the added state in the state stacks
+ */
+ public function pushState($state)
+ {
+ $r = array_push($this->states, $state);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Sets/restores the buffer.
+ *
+ * @param string $buffer Buffer to set
+ * @return void
+ */
+ public function setBuffer($buffer)
+ {
+ $this->buffer = $buffer;
+ }
+ /**
+ * Set the exclusive state.
+ *
+ * @param string $exclusive Exclusive state
+ * @return void
+ */
+ public function setExclusive($exclusive)
+ {
+ $this->stateExclusive = $exclusive;
+ }
+ /**
+ * Set the media types state.
+ *
+ * @param array $mediaTypes Media types state
+ * @return void
+ */
+ public function setMediaTypes(array $mediaTypes)
+ {
+ $this->stateMediaTypes = $mediaTypes;
+ }
+ /**
+ * Sets the current state in the state stack; equals to {@link CssParser::popState()} + {@link CssParser::pushState()}.
+ *
+ * @param integer $state State to set
+ * @return integer
+ */
+ public function setState($state)
+ {
+ $r = array_pop($this->states);
+ array_push($this->states, $state);
+ $this->state = $this->states[count($this->states) - 1];
+ return $r;
+ }
+ /**
+ * Removes the exclusive state.
+ *
+ * @return void
+ */
+ public function unsetExclusive()
+ {
+ $this->stateExclusive = false;
+ }
+ /**
+ * Removes the media types state.
+ *
+ * @return void
+ */
+ public function unsetMediaTypes()
+ {
+ $this->stateMediaTypes = false;
+ }
+}
+
+/**
+ * {@link aCssFromatter Formatter} returning the CSS source in {@link http://goo.gl/j4XdU OTBS indent style} (The One True Brace Style).
+ *
+ * @package CssMin/Formatter
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssOtbsFormatter extends aCssFormatter
+{
+ /**
+ * Implements {@link aCssFormatter::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ $r = array();
+ $level = 0;
+ for ($i = 0, $l = count($this->tokens); $i < $l; $i++)
+ {
+ $token = $this->tokens[$i];
+ $class = get_class($token);
+ $indent = str_repeat($this->indent, $level);
+ if ($class === "CssCommentToken")
+ {
+ $lines = array_map("trim", explode("\n", $token->Comment));
+ for ($ii = 0, $ll = count($lines); $ii < $ll; $ii++)
+ {
+ $r[] = $indent . (substr($lines[$ii], 0, 1) == "*" ? " " : "") . $lines[$ii];
+ }
+ }
+ elseif ($class === "CssAtCharsetToken")
+ {
+ $r[] = $indent . "@charset " . $token->Charset . ";";
+ }
+ elseif ($class === "CssAtFontFaceStartToken")
+ {
+ $r[] = $indent . "@font-face {";
+ $level++;
+ }
+ elseif ($class === "CssAtImportToken")
+ {
+ $r[] = $indent . "@import " . $token->Import . " " . implode(", ", $token->MediaTypes) . ";";
+ }
+ elseif ($class === "CssAtKeyframesStartToken")
+ {
+ $r[] = $indent . "@keyframes " . $token->Name . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtMediaStartToken")
+ {
+ $r[] = $indent . "@media " . implode(", ", $token->MediaTypes) . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtPageStartToken")
+ {
+ $r[] = $indent . "@page {";
+ $level++;
+ }
+ elseif ($class === "CssAtVariablesStartToken")
+ {
+ $r[] = $indent . "@variables " . implode(", ", $token->MediaTypes) . " {";
+ $level++;
+ }
+ elseif ($class === "CssRulesetStartToken" || $class === "CssAtKeyframesRulesetStartToken")
+ {
+ $r[] = $indent . implode(", ", $token->Selectors) . " {";
+ $level++;
+ }
+ elseif ($class === "CssAtFontFaceDeclarationToken"
+ || $class === "CssAtKeyframesRulesetDeclarationToken"
+ || $class === "CssAtPageDeclarationToken"
+ || $class === "CssAtVariablesDeclarationToken"
+ || $class === "CssRulesetDeclarationToken"
+ )
+ {
+ $declaration = $indent . $token->Property . ": ";
+ if ($this->padding)
+ {
+ $declaration = str_pad($declaration, $this->padding, " ", STR_PAD_RIGHT);
+ }
+ $r[] = $declaration . $token->Value . ($token->IsImportant ? " !important" : "") . ";";
+ }
+ elseif ($class === "CssAtFontFaceEndToken"
+ || $class === "CssAtMediaEndToken"
+ || $class === "CssAtKeyframesEndToken"
+ || $class === "CssAtKeyframesRulesetEndToken"
+ || $class === "CssAtPageEndToken"
+ || $class === "CssAtVariablesEndToken"
+ || $class === "CssRulesetEndToken"
+ )
+ {
+ $level--;
+ $r[] = str_repeat($indent, $level) . "}";
+ }
+ }
+ return implode("\n", $r);
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} is a utility token that extends {@link aNullToken} and returns only a empty string.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssNullToken extends aCssToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * CSS Minifier.
+ *
+ * @package CssMin/Minifier
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssMinifier
+{
+ /**
+ * {@link aCssMinifierFilter Filters}.
+ *
+ * @var array
+ */
+ private $filters = array();
+ /**
+ * {@link aCssMinifierPlugin Plugins}.
+ *
+ * @var array
+ */
+ private $plugins = array();
+ /**
+ * Minified source.
+ *
+ * @var string
+ */
+ private $minified = "";
+ /**
+ * Constructer.
+ *
+ * Creates instances of {@link aCssMinifierFilter filters} and {@link aCssMinifierPlugin plugins}.
+ *
+ * @param string $source CSS source [optional]
+ * @param array $filters Filter configuration [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct($source = null, array $filters = null, array $plugins = null)
+ {
+ $filters = array_merge(array
+ (
+ "ImportImports" => false,
+ "RemoveComments" => true,
+ "RemoveEmptyRulesets" => true,
+ "RemoveEmptyAtBlocks" => true,
+ "ConvertLevel3Properties" => false,
+ "ConvertLevel3AtKeyframes" => false,
+ "Variables" => true,
+ "RemoveLastDelarationSemiColon" => true
+ ), is_array($filters) ? $filters : array());
+ $plugins = array_merge(array
+ (
+ "Variables" => true,
+ "ConvertFontWeight" => false,
+ "ConvertHslColors" => false,
+ "ConvertRgbColors" => false,
+ "ConvertNamedColors" => false,
+ "CompressColorValues" => false,
+ "CompressUnitValues" => false,
+ "CompressExpressionValues" => false
+ ), is_array($plugins) ? $plugins : array());
+ // Filters
+ foreach ($filters as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "MinifierFilter";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->filters[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The filter " . $name . "
with the class name " . $class . "
was not found"));
+ }
+ }
+ }
+ // Plugins
+ foreach ($plugins as $name => $config)
+ {
+ if ($config !== false)
+ {
+ $class = "Css" . $name . "MinifierPlugin";
+ $config = is_array($config) ? $config : array();
+ if (class_exists($class))
+ {
+ $this->plugins[] = new $class($this, $config);
+ }
+ else
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": The plugin " . $name . "
with the class name " . $class . "
was not found"));
+ }
+ }
+ }
+ // --
+ if (!is_null($source))
+ {
+ $this->minify($source);
+ }
+ }
+ /**
+ * Returns the minified Source.
+ *
+ * @return string
+ */
+ public function getMinified()
+ {
+ return $this->minified;
+ }
+ /**
+ * Returns a plugin by class name.
+ *
+ * @param string $name Class name of the plugin
+ * @return aCssMinifierPlugin
+ */
+ public function getPlugin($class)
+ {
+ static $index = null;
+ if (is_null($index))
+ {
+ $index = array();
+ for ($i = 0, $l = count($this->plugins); $i < $l; $i++)
+ {
+ $index[get_class($this->plugins[$i])] = $i;
+ }
+ }
+ return isset($index[$class]) ? $this->plugins[$index[$class]] : false;
+ }
+ /**
+ * Minifies the CSS source.
+ *
+ * @param string $source CSS source
+ * @return string
+ */
+ public function minify($source)
+ {
+ // Variables
+ $r = "";
+ $parser = new CssParser($source);
+ $tokens = $parser->getTokens();
+ $filters = $this->filters;
+ $filterCount = count($this->filters);
+ $plugins = $this->plugins;
+ $pluginCount = count($plugins);
+ $pluginIndex = array();
+ $pluginTriggerTokens = array();
+ $globalTriggerTokens = array();
+ for ($i = 0, $l = count($plugins); $i < $l; $i++)
+ {
+ $tPluginClassName = get_class($plugins[$i]);
+ $pluginTriggerTokens[$i] = $plugins[$i]->getTriggerTokens();
+ foreach ($pluginTriggerTokens[$i] as $v)
+ {
+ if (!in_array($v, $globalTriggerTokens))
+ {
+ $globalTriggerTokens[] = $v;
+ }
+ }
+ $pluginTriggerTokens[$i] = "|" . implode("|", $pluginTriggerTokens[$i]) . "|";
+ $pluginIndex[$tPluginClassName] = $i;
+ }
+ $globalTriggerTokens = "|" . implode("|", $globalTriggerTokens) . "|";
+ /*
+ * Apply filters
+ */
+ for($i = 0; $i < $filterCount; $i++)
+ {
+ // Apply the filter; if the return value is larger than 0...
+ if ($filters[$i]->apply($tokens) > 0)
+ {
+ // ...then filter null values and rebuild the token array
+ $tokens = array_values(array_filter($tokens));
+ }
+ }
+ $tokenCount = count($tokens);
+ /*
+ * Apply plugins
+ */
+ for($i = 0; $i < $tokenCount; $i++)
+ {
+ $triggerToken = "|" . get_class($tokens[$i]) . "|";
+ if (strpos($globalTriggerTokens, $triggerToken) !== false)
+ {
+ for($ii = 0; $ii < $pluginCount; $ii++)
+ {
+ if (strpos($pluginTriggerTokens[$ii], $triggerToken) !== false || $pluginTriggerTokens[$ii] === false)
+ {
+ // Apply the plugin; if the return value is TRUE continue to the next token
+ if ($plugins[$ii]->apply($tokens[$i]) === true)
+ {
+ continue 2;
+ }
+ }
+ }
+ }
+ }
+ // Stringify the tokens
+ for($i = 0; $i < $tokenCount; $i++)
+ {
+ $r .= (string) $tokens[$i];
+ }
+ $this->minified = $r;
+ return $r;
+ }
+}
+
+/**
+ * CssMin - A (simple) css minifier with benefits
+ *
+ * --
+ * Copyright (c) 2011 Joe Scylla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ * --
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssMin
+{
+ /**
+ * Index of classes
+ *
+ * @var array
+ */
+ private static $classIndex = array();
+ /**
+ * Parse/minify errors
+ *
+ * @var array
+ */
+ private static $errors = array();
+ /**
+ * Verbose output.
+ *
+ * @var boolean
+ */
+ private static $isVerbose = false;
+ /**
+ * {@link http://goo.gl/JrW54 Autoload} function of CssMin.
+ *
+ * @param string $class Name of the class
+ * @return void
+ */
+ public static function autoload($class)
+ {
+ if (isset(self::$classIndex[$class]))
+ {
+ require(self::$classIndex[$class]);
+ }
+ }
+ /**
+ * Return errors
+ *
+ * @return array of {CssError}.
+ */
+ public static function getErrors()
+ {
+ return self::$errors;
+ }
+ /**
+ * Returns if there were errors.
+ *
+ * @return boolean
+ */
+ public static function hasErrors()
+ {
+ return count(self::$errors) > 0;
+ }
+ /**
+ * Initialises CssMin.
+ *
+ * @return void
+ */
+ public static function initialise()
+ {
+ // Create the class index for autoloading or including
+ $paths = array(dirname(__FILE__));
+ for ($i = 0; $i < count($paths); $i++)
+ {
+ $path = $paths[$i];
+ $subDirectorys = glob($path . "*", GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
+ if (is_array($subDirectorys))
+ {
+ foreach ($subDirectorys as $subDirectory)
+ {
+ $paths[] = $subDirectory;
+ }
+ }
+ $files = glob($path . "*.php", 0);
+ if (is_array($files))
+ {
+ foreach ($files as $file)
+ {
+ $class = substr(basename($file), 0, -4);
+ self::$classIndex[$class] = $file;
+ }
+ }
+ }
+ krsort(self::$classIndex);
+ // Only use autoloading if spl_autoload_register() is available and no __autoload() is defined (because
+ // __autoload() breaks if spl_autoload_register() is used.
+ if (function_exists("spl_autoload_register") && !is_callable("__autoload"))
+ {
+ spl_autoload_register(array(__CLASS__, "autoload"));
+ }
+ // Otherwise include all class files
+ else
+ {
+ foreach (self::$classIndex as $class => $file)
+ {
+ if (!class_exists($class))
+ {
+ require_once($file);
+ }
+ }
+ }
+ }
+ /**
+ * Minifies CSS source.
+ *
+ * @param string $source CSS source
+ * @param array $filters Filter configuration [optional]
+ * @param array $plugins Plugin configuration [optional]
+ * @return string Minified CSS
+ */
+ public static function minify($source, array $filters = null, array $plugins = null)
+ {
+ self::$errors = array();
+ $minifier = new CssMinifier($source, $filters, $plugins);
+ return $minifier->getMinified();
+ }
+ /**
+ * Parse the CSS source.
+ *
+ * @param string $source CSS source
+ * @param array $plugins Plugin configuration [optional]
+ * @return array Array of aCssToken
+ */
+ public static function parse($source, array $plugins = null)
+ {
+ self::$errors = array();
+ $parser = new CssParser($source, $plugins);
+ return $parser->getTokens();
+ }
+ /**
+ * --
+ *
+ * @param boolean $to
+ * @return boolean
+ */
+ public static function setVerbose($to)
+ {
+ self::$isVerbose = (boolean) $to;
+ return self::$isVerbose;
+ }
+ /**
+ * --
+ *
+ * @param CssError $error
+ * @return void
+ */
+ public static function triggerError(CssError $error)
+ {
+ self::$errors[] = $error;
+ if (self::$isVerbose)
+ {
+ trigger_error((string) $error, E_USER_WARNING);
+ }
+ }
+}
+// Initialises CssMin
+CssMin::initialise();
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} import external css files defined with the @import at-rule into the
+ * current stylesheet.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssImportImportsMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Array with already imported external stylesheets.
+ *
+ * @var array
+ */
+ private $imported = array();
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ if (!isset($this->configuration["BasePath"]) || !is_dir($this->configuration["BasePath"]))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Base path " . ($this->configuration["BasePath"] ? $this->configuration["BasePath"] : "null"). "
is not a directory"));
+ return 0;
+ }
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssAtImportToken")
+ {
+ $import = $this->configuration["BasePath"] . "/" . $tokens[$i]->Import;
+ // Import file was not found/is not a file
+ if (!is_file($import))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. "
was not found.", (string) $tokens[$i]));
+ }
+ // Import file already imported; remove this @import at-rule to prevent recursions
+ elseif (in_array($import, $this->imported))
+ {
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Import file " . $import. "
was already imported.", (string) $tokens[$i]));
+ $tokens[$i] = null;
+ }
+ else
+ {
+ $this->imported[] = $import;
+ $parser = new CssParser(file_get_contents($import));
+ $import = $parser->getTokens();
+ // The @import at-rule has media types defined requiring special handling
+ if (count($tokens[$i]->MediaTypes) > 0 && !(count($tokens[$i]->MediaTypes) == 1 && $tokens[$i]->MediaTypes[0] == "all"))
+ {
+ $blocks = array();
+ /*
+ * Filter or set media types of @import at-rule or remove the @import at-rule if no media type is matching the parent @import at-rule
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtImportToken")
+ {
+ // @import at-rule defines no media type or only the "all" media type; set the media types to the one defined in the parent @import at-rule
+ if (count($import[$ii]->MediaTypes) == 0 || (count($import[$ii]->MediaTypes) == 1 && $import[$ii]->MediaTypes[0] == "all"))
+ {
+ $import[$ii]->MediaTypes = $tokens[$i]->MediaTypes;
+ }
+ // @import at-rule defineds one or more media types; filter out media types not matching with the parent @import at-rule
+ elseif (count($import[$ii]->MediaTypes) > 0)
+ {
+ foreach ($import[$ii]->MediaTypes as $index => $mediaType)
+ {
+ if (!in_array($mediaType, $tokens[$i]->MediaTypes))
+ {
+ unset($import[$ii]->MediaTypes[$index]);
+ }
+ }
+ $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
+ // If there are no media types left in the @import at-rule remove the @import at-rule
+ if (count($import[$ii]->MediaTypes) == 0)
+ {
+ $import[$ii] = null;
+ }
+ }
+ }
+ }
+ /*
+ * Remove media types of @media at-rule block not defined in the @import at-rule
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken")
+ {
+ foreach ($import[$ii]->MediaTypes as $index => $mediaType)
+ {
+ if (!in_array($mediaType, $tokens[$i]->MediaTypes))
+ {
+ unset($import[$ii]->MediaTypes[$index]);
+ }
+ $import[$ii]->MediaTypes = array_values($import[$ii]->MediaTypes);
+ }
+ }
+ }
+ /*
+ * If no media types left of the @media at-rule block remove the complete block
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken")
+ {
+ if (count($import[$ii]->MediaTypes) === 0)
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ if (get_class($import[$iii]) === "CssAtMediaEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($import[$iii]) === "CssAtMediaEndToken")
+ {
+ array_splice($import, $ii, $iii - $ii + 1, array());
+ $ll = count($import);
+ }
+ }
+ }
+ }
+ /*
+ * If the media types of the @media at-rule equals the media types defined in the @import
+ * at-rule remove the CssAtMediaStartToken and CssAtMediaEndToken token
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ if (get_class($import[$ii]) === "CssAtMediaStartToken" && count(array_diff($tokens[$i]->MediaTypes, $import[$ii]->MediaTypes)) === 0)
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ if (get_class($import[$iii]) == "CssAtMediaEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($import[$iii]) == "CssAtMediaEndToken")
+ {
+ unset($import[$ii]);
+ unset($import[$iii]);
+ $import = array_values($import);
+ $ll = count($import);
+ }
+ }
+ }
+ /**
+ * Extract CssAtImportToken and CssAtCharsetToken tokens
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ $class = get_class($import[$ii]);
+ if ($class === "CssAtImportToken" || $class === "CssAtCharsetToken")
+ {
+ $blocks = array_merge($blocks, array_splice($import, $ii, 1, array()));
+ $ll = count($import);
+ }
+ }
+ /*
+ * Extract the @font-face, @media and @page at-rule block
+ */
+ for($ii = 0, $ll = count($import); $ii < $ll; $ii++)
+ {
+ $class = get_class($import[$ii]);
+ if ($class === "CssAtFontFaceStartToken" || $class === "CssAtMediaStartToken" || $class === "CssAtPageStartToken" || $class === "CssAtVariablesStartToken")
+ {
+ for ($iii = $ii; $iii < $ll; $iii++)
+ {
+ $class = get_class($import[$iii]);
+ if ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken")
+ {
+ break;
+ }
+ }
+ $class = get_class($import[$iii]);
+ if (isset($import[$iii]) && ($class === "CssAtFontFaceEndToken" || $class === "CssAtMediaEndToken" || $class === "CssAtPageEndToken" || $class === "CssAtVariablesEndToken"))
+ {
+ $blocks = array_merge($blocks, array_splice($import, $ii, $iii - $ii + 1, array()));
+ $ll = count($import);
+ }
+ }
+ }
+ // Create the import array with extracted tokens and the rulesets wrapped into a @media at-rule block
+ $import = array_merge($blocks, array(new CssAtMediaStartToken($tokens[$i]->MediaTypes)), $import, array(new CssAtMediaEndToken()));
+ }
+ // Insert the imported tokens
+ array_splice($tokens, $i, 1, $import);
+ // Modify parameters of the for-loop
+ $i--;
+ $l = count($tokens);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for preserve parsing expression() declaration values.
+ *
+ * This plugin return no {@link aCssToken CssToken} but ensures that expression() declaration values will get parsed
+ * properly.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssExpressionParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Count of left braces.
+ *
+ * @var integer
+ */
+ private $leftBraces = 0;
+ /**
+ * Count of right braces.
+ *
+ * @var integer
+ */
+ private $rightBraces = 0;
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("(", ")", ";", "}");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of expression
+ if ($char === "(" && strtolower(substr($this->parser->getSource(), $index - 10, 11)) === "expression(" && $state !== "T_EXPRESSION")
+ {
+ $this->parser->pushState("T_EXPRESSION");
+ $this->leftBraces++;
+ }
+ // Count left braces
+ elseif ($char === "(" && $state === "T_EXPRESSION")
+ {
+ $this->leftBraces++;
+ }
+ // Count right braces
+ elseif ($char === ")" && $state === "T_EXPRESSION")
+ {
+ $this->rightBraces++;
+ }
+ // Possible end of expression; if left and right braces are equal the expressen ends
+ elseif (($char === ";" || $char === "}") && $state === "T_EXPRESSION" && $this->leftBraces === $this->rightBraces)
+ {
+ $this->leftBraces = $this->rightBraces = 0;
+ $this->parser->popState();
+ return $index - 1;
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * CSS Error.
+ *
+ * @package CssMin
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssError
+{
+ /**
+ * File.
+ *
+ * @var string
+ */
+ public $File = "";
+ /**
+ * Line.
+ *
+ * @var integer
+ */
+ public $Line = 0;
+ /**
+ * Error message.
+ *
+ * @var string
+ */
+ public $Message = "";
+ /**
+ * Source.
+ *
+ * @var string
+ */
+ public $Source = "";
+ /**
+ * Constructor triggering the error.
+ *
+ * @param string $message Error message
+ * @param string $source Corresponding line [optional]
+ * @return void
+ */
+ public function __construct($file, $line, $message, $source = "")
+ {
+ $this->File = $file;
+ $this->Line = $line;
+ $this->Message = $message;
+ $this->Source = $source;
+ }
+ /**
+ * Returns the error as formatted string.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Message . ($this->Source ? ":
" . $this->Source . "
": "") . "
in file " . $this->File . " at line " . $this->Line;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert a color value in rgb notation to hexadecimal notation.
+ *
+ * Example:
+ *
+ * color: rgb(200,60%,5);
+ *
+ *
+ * Will get converted to:
+ *
+ * color:#c89905;
+ *
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertRgbColorsMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/rgb\s*\(\s*([0-9%]+)\s*,\s*([0-9%]+)\s*,\s*([0-9%]+)\s*\)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "rgb") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ for ($i = 1, $l = count($m); $i < $l; $i++)
+ {
+ if (strpos("%", $m[$i]) !== false)
+ {
+ $m[$i] = substr($m[$i], 0, -1);
+ $m[$i] = (int) (256 * ($m[$i] / 100));
+ }
+ $m[$i] = str_pad(dechex($m[$i]), 2, "0", STR_PAD_LEFT);
+ }
+ $token->Value = str_replace($m[0], "#" . $m[1] . $m[2] . $m[3], $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert named color values to hexadecimal notation.
+ *
+ * Example:
+ *
+ * color: black;
+ * border: 1px solid indigo;
+ *
+ *
+ * Will get converted to:
+ *
+ * color:#000;
+ * border:1px solid #4b0082;
+ *
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertNamedColorsMinifierPlugin extends aCssMinifierPlugin
+{
+
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = null;
+ /**
+ * Transformation table used by the {@link CssConvertNamedColorsMinifierPlugin::reReplace() replacement method}.
+ *
+ * @var array
+ */
+ private $transformation = array
+ (
+ "aliceblue" => "#f0f8ff",
+ "antiquewhite" => "#faebd7",
+ "aqua" => "#0ff",
+ "aquamarine" => "#7fffd4",
+ "azure" => "#f0ffff",
+ "beige" => "#f5f5dc",
+ "black" => "#000",
+ "blue" => "#00f",
+ "blueviolet" => "#8a2be2",
+ "brown" => "#a52a2a",
+ "burlywood" => "#deb887",
+ "cadetblue" => "#5f9ea0",
+ "chartreuse" => "#7fff00",
+ "chocolate" => "#d2691e",
+ "coral" => "#ff7f50",
+ "cornflowerblue" => "#6495ed",
+ "cornsilk" => "#fff8dc",
+ "crimson" => "#dc143c",
+ "darkblue" => "#00008b",
+ "darkcyan" => "#008b8b",
+ "darkgoldenrod" => "#b8860b",
+ "darkgray" => "#a9a9a9",
+ "darkgreen" => "#006400",
+ "darkkhaki" => "#bdb76b",
+ "darkmagenta" => "#8b008b",
+ "darkolivegreen" => "#556b2f",
+ "darkorange" => "#ff8c00",
+ "darkorchid" => "#9932cc",
+ "darkred" => "#8b0000",
+ "darksalmon" => "#e9967a",
+ "darkseagreen" => "#8fbc8f",
+ "darkslateblue" => "#483d8b",
+ "darkslategray" => "#2f4f4f",
+ "darkturquoise" => "#00ced1",
+ "darkviolet" => "#9400d3",
+ "deeppink" => "#ff1493",
+ "deepskyblue" => "#00bfff",
+ "dimgray" => "#696969",
+ "dodgerblue" => "#1e90ff",
+ "firebrick" => "#b22222",
+ "floralwhite" => "#fffaf0",
+ "forestgreen" => "#228b22",
+ "fuchsia" => "#f0f",
+ "gainsboro" => "#dcdcdc",
+ "ghostwhite" => "#f8f8ff",
+ "gold" => "#ffd700",
+ "goldenrod" => "#daa520",
+ "gray" => "#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",
+ "lightgreen" => "#90ee90",
+ "lightgrey" => "#d3d3d3",
+ "lightpink" => "#ffb6c1",
+ "lightsalmon" => "#ffa07a",
+ "lightseagreen" => "#20b2aa",
+ "lightskyblue" => "#87cefa",
+ "lightslategray" => "#789",
+ "lightsteelblue" => "#b0c4de",
+ "lightyellow" => "#ffffe0",
+ "lime" => "#0f0",
+ "limegreen" => "#32cd32",
+ "linen" => "#faf0e6",
+ "maroon" => "#800000",
+ "mediumaquamarine" => "#66cdaa",
+ "mediumblue" => "#0000cd",
+ "mediumorchid" => "#ba55d3",
+ "mediumpurple" => "#9370db",
+ "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" => "#db7093",
+ "papayawhip" => "#ffefd5",
+ "peachpuff" => "#ffdab9",
+ "peru" => "#cd853f",
+ "pink" => "#ffc0cb",
+ "plum" => "#dda0dd",
+ "powderblue" => "#b0e0e6",
+ "purple" => "#800080",
+ "red" => "#f00",
+ "rosybrown" => "#bc8f8f",
+ "royalblue" => "#4169e1",
+ "saddlebrown" => "#8b4513",
+ "salmon" => "#fa8072",
+ "sandybrown" => "#f4a460",
+ "seagreen" => "#2e8b57",
+ "seashell" => "#fff5ee",
+ "sienna" => "#a0522d",
+ "silver" => "#c0c0c0",
+ "skyblue" => "#87ceeb",
+ "slateblue" => "#6a5acd",
+ "slategray" => "#708090",
+ "snow" => "#fffafa",
+ "springgreen" => "#00ff7f",
+ "steelblue" => "#4682b4",
+ "tan" => "#d2b48c",
+ "teal" => "#008080",
+ "thistle" => "#d8bfd8",
+ "tomato" => "#ff6347",
+ "turquoise" => "#40e0d0",
+ "violet" => "#ee82ee",
+ "wheat" => "#f5deb3",
+ "white" => "#fff",
+ "whitesmoke" => "#f5f5f5",
+ "yellow" => "#ff0",
+ "yellowgreen" => "#9acd32"
+ );
+ /**
+ * Overwrites {@link aCssMinifierPlugin::__construct()}.
+ *
+ * The constructor will create the {@link CssConvertNamedColorsMinifierPlugin::$reMatch replace regular expression}
+ * based on the {@link CssConvertNamedColorsMinifierPlugin::$transformation transformation table}.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @param array $configuration Plugin configuration [optional]
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier, array $configuration = array())
+ {
+ $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)) . ")(\s|$)+/iS";
+ parent::__construct($minifier, $configuration);
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ $lcValue = strtolower($token->Value);
+ // Declaration value equals a value in the transformation table => simple replace
+ if (isset($this->transformation[$lcValue]))
+ {
+ $token->Value = $this->transformation[$lcValue];
+ }
+ // Declaration value contains a value in the transformation table => regular expression replace
+ elseif (preg_match($this->reMatch, $token->Value))
+ {
+ $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Callback for replacement value.
+ *
+ * @param array $match
+ * @return string
+ */
+ private function reReplace($match)
+ {
+ return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} triggers on CSS Level 3 properties and will add declaration tokens
+ * with browser-specific properties.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertLevel3PropertiesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Css property transformations table. Used to convert CSS3 and proprietary properties to the browser-specific
+ * counterparts.
+ *
+ * @var array
+ */
+ private $transformations = array
+ (
+ // Property Array(Mozilla, Webkit, Opera, Internet Explorer); NULL values are placeholders and will get ignored
+ "animation" => array(null, "-webkit-animation", null, null),
+ "animation-delay" => array(null, "-webkit-animation-delay", null, null),
+ "animation-direction" => array(null, "-webkit-animation-direction", null, null),
+ "animation-duration" => array(null, "-webkit-animation-duration", null, null),
+ "animation-fill-mode" => array(null, "-webkit-animation-fill-mode", null, null),
+ "animation-iteration-count" => array(null, "-webkit-animation-iteration-count", null, null),
+ "animation-name" => array(null, "-webkit-animation-name", null, null),
+ "animation-play-state" => array(null, "-webkit-animation-play-state", null, null),
+ "animation-timing-function" => array(null, "-webkit-animation-timing-function", null, null),
+ "appearance" => array("-moz-appearance", "-webkit-appearance", null, null),
+ "backface-visibility" => array(null, "-webkit-backface-visibility", null, null),
+ "background-clip" => array(null, "-webkit-background-clip", null, null),
+ "background-composite" => array(null, "-webkit-background-composite", null, null),
+ "background-inline-policy" => array("-moz-background-inline-policy", null, null, null),
+ "background-origin" => array(null, "-webkit-background-origin", null, null),
+ "background-position-x" => array(null, null, null, "-ms-background-position-x"),
+ "background-position-y" => array(null, null, null, "-ms-background-position-y"),
+ "background-size" => array(null, "-webkit-background-size", null, null),
+ "behavior" => array(null, null, null, "-ms-behavior"),
+ "binding" => array("-moz-binding", null, null, null),
+ "border-after" => array(null, "-webkit-border-after", null, null),
+ "border-after-color" => array(null, "-webkit-border-after-color", null, null),
+ "border-after-style" => array(null, "-webkit-border-after-style", null, null),
+ "border-after-width" => array(null, "-webkit-border-after-width", null, null),
+ "border-before" => array(null, "-webkit-border-before", null, null),
+ "border-before-color" => array(null, "-webkit-border-before-color", null, null),
+ "border-before-style" => array(null, "-webkit-border-before-style", null, null),
+ "border-before-width" => array(null, "-webkit-border-before-width", null, null),
+ "border-border-bottom-colors" => array("-moz-border-bottom-colors", null, null, null),
+ "border-bottom-left-radius" => array("-moz-border-radius-bottomleft", "-webkit-border-bottom-left-radius", null, null),
+ "border-bottom-right-radius" => array("-moz-border-radius-bottomright", "-webkit-border-bottom-right-radius", null, null),
+ "border-end" => array("-moz-border-end", "-webkit-border-end", null, null),
+ "border-end-color" => array("-moz-border-end-color", "-webkit-border-end-color", null, null),
+ "border-end-style" => array("-moz-border-end-style", "-webkit-border-end-style", null, null),
+ "border-end-width" => array("-moz-border-end-width", "-webkit-border-end-width", null, null),
+ "border-fit" => array(null, "-webkit-border-fit", null, null),
+ "border-horizontal-spacing" => array(null, "-webkit-border-horizontal-spacing", null, null),
+ "border-image" => array("-moz-border-image", "-webkit-border-image", null, null),
+ "border-left-colors" => array("-moz-border-left-colors", null, null, null),
+ "border-radius" => array("-moz-border-radius", "-webkit-border-radius", null, null),
+ "border-border-right-colors" => array("-moz-border-right-colors", null, null, null),
+ "border-start" => array("-moz-border-start", "-webkit-border-start", null, null),
+ "border-start-color" => array("-moz-border-start-color", "-webkit-border-start-color", null, null),
+ "border-start-style" => array("-moz-border-start-style", "-webkit-border-start-style", null, null),
+ "border-start-width" => array("-moz-border-start-width", "-webkit-border-start-width", null, null),
+ "border-top-colors" => array("-moz-border-top-colors", null, null, null),
+ "border-top-left-radius" => array("-moz-border-radius-topleft", "-webkit-border-top-left-radius", null, null),
+ "border-top-right-radius" => array("-moz-border-radius-topright", "-webkit-border-top-right-radius", null, null),
+ "border-vertical-spacing" => array(null, "-webkit-border-vertical-spacing", null, null),
+ "box-align" => array("-moz-box-align", "-webkit-box-align", null, null),
+ "box-direction" => array("-moz-box-direction", "-webkit-box-direction", null, null),
+ "box-flex" => array("-moz-box-flex", "-webkit-box-flex", null, null),
+ "box-flex-group" => array(null, "-webkit-box-flex-group", null, null),
+ "box-flex-lines" => array(null, "-webkit-box-flex-lines", null, null),
+ "box-ordinal-group" => array("-moz-box-ordinal-group", "-webkit-box-ordinal-group", null, null),
+ "box-orient" => array("-moz-box-orient", "-webkit-box-orient", null, null),
+ "box-pack" => array("-moz-box-pack", "-webkit-box-pack", null, null),
+ "box-reflect" => array(null, "-webkit-box-reflect", null, null),
+ "box-shadow" => array("-moz-box-shadow", "-webkit-box-shadow", null, null),
+ "box-sizing" => array("-moz-box-sizing", null, null, null),
+ "color-correction" => array(null, "-webkit-color-correction", null, null),
+ "column-break-after" => array(null, "-webkit-column-break-after", null, null),
+ "column-break-before" => array(null, "-webkit-column-break-before", null, null),
+ "column-break-inside" => array(null, "-webkit-column-break-inside", null, null),
+ "column-count" => array("-moz-column-count", "-webkit-column-count", null, null),
+ "column-gap" => array("-moz-column-gap", "-webkit-column-gap", null, null),
+ "column-rule" => array("-moz-column-rule", "-webkit-column-rule", null, null),
+ "column-rule-color" => array("-moz-column-rule-color", "-webkit-column-rule-color", null, null),
+ "column-rule-style" => array("-moz-column-rule-style", "-webkit-column-rule-style", null, null),
+ "column-rule-width" => array("-moz-column-rule-width", "-webkit-column-rule-width", null, null),
+ "column-span" => array(null, "-webkit-column-span", null, null),
+ "column-width" => array("-moz-column-width", "-webkit-column-width", null, null),
+ "columns" => array(null, "-webkit-columns", null, null),
+ "filter" => array(__CLASS__, "filter"),
+ "float-edge" => array("-moz-float-edge", null, null, null),
+ "font-feature-settings" => array("-moz-font-feature-settings", null, null, null),
+ "font-language-override" => array("-moz-font-language-override", null, null, null),
+ "font-size-delta" => array(null, "-webkit-font-size-delta", null, null),
+ "font-smoothing" => array(null, "-webkit-font-smoothing", null, null),
+ "force-broken-image-icon" => array("-moz-force-broken-image-icon", null, null, null),
+ "highlight" => array(null, "-webkit-highlight", null, null),
+ "hyphenate-character" => array(null, "-webkit-hyphenate-character", null, null),
+ "hyphenate-locale" => array(null, "-webkit-hyphenate-locale", null, null),
+ "hyphens" => array(null, "-webkit-hyphens", null, null),
+ "force-broken-image-icon" => array("-moz-image-region", null, null, null),
+ "ime-mode" => array(null, null, null, "-ms-ime-mode"),
+ "interpolation-mode" => array(null, null, null, "-ms-interpolation-mode"),
+ "layout-flow" => array(null, null, null, "-ms-layout-flow"),
+ "layout-grid" => array(null, null, null, "-ms-layout-grid"),
+ "layout-grid-char" => array(null, null, null, "-ms-layout-grid-char"),
+ "layout-grid-line" => array(null, null, null, "-ms-layout-grid-line"),
+ "layout-grid-mode" => array(null, null, null, "-ms-layout-grid-mode"),
+ "layout-grid-type" => array(null, null, null, "-ms-layout-grid-type"),
+ "line-break" => array(null, "-webkit-line-break", null, "-ms-line-break"),
+ "line-clamp" => array(null, "-webkit-line-clamp", null, null),
+ "line-grid-mode" => array(null, null, null, "-ms-line-grid-mode"),
+ "logical-height" => array(null, "-webkit-logical-height", null, null),
+ "logical-width" => array(null, "-webkit-logical-width", null, null),
+ "margin-after" => array(null, "-webkit-margin-after", null, null),
+ "margin-after-collapse" => array(null, "-webkit-margin-after-collapse", null, null),
+ "margin-before" => array(null, "-webkit-margin-before", null, null),
+ "margin-before-collapse" => array(null, "-webkit-margin-before-collapse", null, null),
+ "margin-bottom-collapse" => array(null, "-webkit-margin-bottom-collapse", null, null),
+ "margin-collapse" => array(null, "-webkit-margin-collapse", null, null),
+ "margin-end" => array("-moz-margin-end", "-webkit-margin-end", null, null),
+ "margin-start" => array("-moz-margin-start", "-webkit-margin-start", null, null),
+ "margin-top-collapse" => array(null, "-webkit-margin-top-collapse", null, null),
+ "marquee " => array(null, "-webkit-marquee", null, null),
+ "marquee-direction" => array(null, "-webkit-marquee-direction", null, null),
+ "marquee-increment" => array(null, "-webkit-marquee-increment", null, null),
+ "marquee-repetition" => array(null, "-webkit-marquee-repetition", null, null),
+ "marquee-speed" => array(null, "-webkit-marquee-speed", null, null),
+ "marquee-style" => array(null, "-webkit-marquee-style", null, null),
+ "mask" => array(null, "-webkit-mask", null, null),
+ "mask-attachment" => array(null, "-webkit-mask-attachment", null, null),
+ "mask-box-image" => array(null, "-webkit-mask-box-image", null, null),
+ "mask-clip" => array(null, "-webkit-mask-clip", null, null),
+ "mask-composite" => array(null, "-webkit-mask-composite", null, null),
+ "mask-image" => array(null, "-webkit-mask-image", null, null),
+ "mask-origin" => array(null, "-webkit-mask-origin", null, null),
+ "mask-position" => array(null, "-webkit-mask-position", null, null),
+ "mask-position-x" => array(null, "-webkit-mask-position-x", null, null),
+ "mask-position-y" => array(null, "-webkit-mask-position-y", null, null),
+ "mask-repeat" => array(null, "-webkit-mask-repeat", null, null),
+ "mask-repeat-x" => array(null, "-webkit-mask-repeat-x", null, null),
+ "mask-repeat-y" => array(null, "-webkit-mask-repeat-y", null, null),
+ "mask-size" => array(null, "-webkit-mask-size", null, null),
+ "match-nearest-mail-blockquote-color" => array(null, "-webkit-match-nearest-mail-blockquote-color", null, null),
+ "max-logical-height" => array(null, "-webkit-max-logical-height", null, null),
+ "max-logical-width" => array(null, "-webkit-max-logical-width", null, null),
+ "min-logical-height" => array(null, "-webkit-min-logical-height", null, null),
+ "min-logical-width" => array(null, "-webkit-min-logical-width", null, null),
+ "object-fit" => array(null, null, "-o-object-fit", null),
+ "object-position" => array(null, null, "-o-object-position", null),
+ "opacity" => array(__CLASS__, "opacity"),
+ "outline-radius" => array("-moz-outline-radius", null, null, null),
+ "outline-bottom-left-radius" => array("-moz-outline-radius-bottomleft", null, null, null),
+ "outline-bottom-right-radius" => array("-moz-outline-radius-bottomright", null, null, null),
+ "outline-top-left-radius" => array("-moz-outline-radius-topleft", null, null, null),
+ "outline-top-right-radius" => array("-moz-outline-radius-topright", null, null, null),
+ "padding-after" => array(null, "-webkit-padding-after", null, null),
+ "padding-before" => array(null, "-webkit-padding-before", null, null),
+ "padding-end" => array("-moz-padding-end", "-webkit-padding-end", null, null),
+ "padding-start" => array("-moz-padding-start", "-webkit-padding-start", null, null),
+ "perspective" => array(null, "-webkit-perspective", null, null),
+ "perspective-origin" => array(null, "-webkit-perspective-origin", null, null),
+ "perspective-origin-x" => array(null, "-webkit-perspective-origin-x", null, null),
+ "perspective-origin-y" => array(null, "-webkit-perspective-origin-y", null, null),
+ "rtl-ordering" => array(null, "-webkit-rtl-ordering", null, null),
+ "scrollbar-3dlight-color" => array(null, null, null, "-ms-scrollbar-3dlight-color"),
+ "scrollbar-arrow-color" => array(null, null, null, "-ms-scrollbar-arrow-color"),
+ "scrollbar-base-color" => array(null, null, null, "-ms-scrollbar-base-color"),
+ "scrollbar-darkshadow-color" => array(null, null, null, "-ms-scrollbar-darkshadow-color"),
+ "scrollbar-face-color" => array(null, null, null, "-ms-scrollbar-face-color"),
+ "scrollbar-highlight-color" => array(null, null, null, "-ms-scrollbar-highlight-color"),
+ "scrollbar-shadow-color" => array(null, null, null, "-ms-scrollbar-shadow-color"),
+ "scrollbar-track-color" => array(null, null, null, "-ms-scrollbar-track-color"),
+ "stack-sizing" => array("-moz-stack-sizing", null, null, null),
+ "svg-shadow" => array(null, "-webkit-svg-shadow", null, null),
+ "tab-size" => array("-moz-tab-size", null, "-o-tab-size", null),
+ "table-baseline" => array(null, null, "-o-table-baseline", null),
+ "text-align-last" => array(null, null, null, "-ms-text-align-last"),
+ "text-autospace" => array(null, null, null, "-ms-text-autospace"),
+ "text-combine" => array(null, "-webkit-text-combine", null, null),
+ "text-decorations-in-effect" => array(null, "-webkit-text-decorations-in-effect", null, null),
+ "text-emphasis" => array(null, "-webkit-text-emphasis", null, null),
+ "text-emphasis-color" => array(null, "-webkit-text-emphasis-color", null, null),
+ "text-emphasis-position" => array(null, "-webkit-text-emphasis-position", null, null),
+ "text-emphasis-style" => array(null, "-webkit-text-emphasis-style", null, null),
+ "text-fill-color" => array(null, "-webkit-text-fill-color", null, null),
+ "text-justify" => array(null, null, null, "-ms-text-justify"),
+ "text-kashida-space" => array(null, null, null, "-ms-text-kashida-space"),
+ "text-overflow" => array(null, null, "-o-text-overflow", "-ms-text-overflow"),
+ "text-security" => array(null, "-webkit-text-security", null, null),
+ "text-size-adjust" => array(null, "-webkit-text-size-adjust", null, "-ms-text-size-adjust"),
+ "text-stroke" => array(null, "-webkit-text-stroke", null, null),
+ "text-stroke-color" => array(null, "-webkit-text-stroke-color", null, null),
+ "text-stroke-width" => array(null, "-webkit-text-stroke-width", null, null),
+ "text-underline-position" => array(null, null, null, "-ms-text-underline-position"),
+ "transform" => array("-moz-transform", "-webkit-transform", "-o-transform", null),
+ "transform-origin" => array("-moz-transform-origin", "-webkit-transform-origin", "-o-transform-origin", null),
+ "transform-origin-x" => array(null, "-webkit-transform-origin-x", null, null),
+ "transform-origin-y" => array(null, "-webkit-transform-origin-y", null, null),
+ "transform-origin-z" => array(null, "-webkit-transform-origin-z", null, null),
+ "transform-style" => array(null, "-webkit-transform-style", null, null),
+ "transition" => array("-moz-transition", "-webkit-transition", "-o-transition", null),
+ "transition-delay" => array("-moz-transition-delay", "-webkit-transition-delay", "-o-transition-delay", null),
+ "transition-duration" => array("-moz-transition-duration", "-webkit-transition-duration", "-o-transition-duration", null),
+ "transition-property" => array("-moz-transition-property", "-webkit-transition-property", "-o-transition-property", null),
+ "transition-timing-function" => array("-moz-transition-timing-function", "-webkit-transition-timing-function", "-o-transition-timing-function", null),
+ "user-drag" => array(null, "-webkit-user-drag", null, null),
+ "user-focus" => array("-moz-user-focus", null, null, null),
+ "user-input" => array("-moz-user-input", null, null, null),
+ "user-modify" => array("-moz-user-modify", "-webkit-user-modify", null, null),
+ "user-select" => array("-moz-user-select", "-webkit-user-select", null, null),
+ "white-space" => array(__CLASS__, "whiteSpace"),
+ "window-shadow" => array("-moz-window-shadow", null, null, null),
+ "word-break" => array(null, null, null, "-ms-word-break"),
+ "word-wrap" => array(null, null, null, "-ms-word-wrap"),
+ "writing-mode" => array(null, "-webkit-writing-mode", null, "-ms-writing-mode"),
+ "zoom" => array(null, null, null, "-ms-zoom")
+ );
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value large than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ $transformations = &$this->transformations;
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssRulesetDeclarationToken")
+ {
+ $tProperty = $tokens[$i]->Property;
+ if (isset($transformations[$tProperty]))
+ {
+ $result = array();
+ if (is_callable($transformations[$tProperty]))
+ {
+ $result = call_user_func_array($transformations[$tProperty], array($tokens[$i]));
+ if (!is_array($result) && is_object($result))
+ {
+ $result = array($result);
+ }
+ }
+ else
+ {
+ $tValue = $tokens[$i]->Value;
+ $tMediaTypes = $tokens[$i]->MediaTypes;
+ foreach ($transformations[$tProperty] as $property)
+ {
+ if ($property !== null)
+ {
+ $result[] = new CssRulesetDeclarationToken($property, $tValue, $tMediaTypes);
+ }
+ }
+ }
+ if (count($result) > 0)
+ {
+ array_splice($tokens, $i + 1, 0, $result);
+ $i += count($result);
+ $l += count($result);
+ }
+ }
+ }
+ }
+ return $r;
+ }
+ /**
+ * Transforms the Internet Explorer specific declaration property "filter" to Internet Explorer 8+ compatible
+ * declaratiopn property "-ms-filter".
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function filter($token)
+ {
+ $r = array
+ (
+ new CssRulesetDeclarationToken("-ms-filter", "\"" . $token->Value . "\"", $token->MediaTypes),
+ );
+ return $r;
+ }
+ /**
+ * Transforms "opacity: {value}" into browser specific counterparts.
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function opacity($token)
+ {
+ // Calculate the value for Internet Explorer filter statement
+ $ieValue = (int) ((float) $token->Value * 100);
+ $r = array
+ (
+ // Internet Explorer >= 8
+ new CssRulesetDeclarationToken("-ms-filter", "\"alpha(opacity=" . $ieValue . ")\"", $token->MediaTypes),
+ // Internet Explorer >= 4 <= 7
+ new CssRulesetDeclarationToken("filter", "alpha(opacity=" . $ieValue . ")", $token->MediaTypes),
+ new CssRulesetDeclarationToken("zoom", "1", $token->MediaTypes)
+ );
+ return $r;
+ }
+ /**
+ * Transforms "white-space: pre-wrap" into browser specific counterparts.
+ *
+ * @param aCssToken $token
+ * @return array
+ */
+ private static function whiteSpace($token)
+ {
+ if (strtolower($token->Value) === "pre-wrap")
+ {
+ $r = array
+ (
+ // Firefox < 3
+ new CssRulesetDeclarationToken("white-space", "-moz-pre-wrap", $token->MediaTypes),
+ // Webkit
+ new CssRulesetDeclarationToken("white-space", "-webkit-pre-wrap", $token->MediaTypes),
+ // Opera >= 4 <= 6
+ new CssRulesetDeclarationToken("white-space", "-pre-wrap", $token->MediaTypes),
+ // Opera >= 7
+ new CssRulesetDeclarationToken("white-space", "-o-pre-wrap", $token->MediaTypes),
+ // Internet Explorer >= 5.5
+ new CssRulesetDeclarationToken("word-wrap", "break-word", $token->MediaTypes)
+ );
+ return $r;
+ }
+ else
+ {
+ return array();
+ }
+ }
+}
+
+/**
+ * This {@link aCssMinifierFilter minifier filter} will convert @keyframes at-rule block to browser specific counterparts.
+ *
+ * @package CssMin/Minifier/Filters
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertLevel3AtKeyframesMinifierFilter extends aCssMinifierFilter
+{
+ /**
+ * Implements {@link aCssMinifierFilter::filter()}.
+ *
+ * @param array $tokens Array of objects of type aCssToken
+ * @return integer Count of added, changed or removed tokens; a return value larger than 0 will rebuild the array
+ */
+ public function apply(array &$tokens)
+ {
+ $r = 0;
+ $transformations = array("-moz-keyframes", "-webkit-keyframes");
+ for ($i = 0, $l = count($tokens); $i < $l; $i++)
+ {
+ if (get_class($tokens[$i]) === "CssAtKeyframesStartToken")
+ {
+ for ($ii = $i; $ii < $l; $ii++)
+ {
+ if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
+ {
+ break;
+ }
+ }
+ if (get_class($tokens[$ii]) === "CssAtKeyframesEndToken")
+ {
+ $add = array();
+ $source = array();
+ for ($iii = $i; $iii <= $ii; $iii++)
+ {
+ $source[] = clone($tokens[$iii]);
+ }
+ foreach ($transformations as $transformation)
+ {
+ $t = array();
+ foreach ($source as $token)
+ {
+ $t[] = clone($token);
+ }
+ $t[0]->AtRuleName = $transformation;
+ $add = array_merge($add, $t);
+ }
+ if (isset($this->configuration["RemoveSource"]) && $this->configuration["RemoveSource"] === true)
+ {
+ array_splice($tokens, $i, $ii - $i + 1, $add);
+ }
+ else
+ {
+ array_splice($tokens, $ii + 1, 0, $add);
+ }
+ $l = count($tokens);
+ $i = $ii + count($add);
+ $r += count($add);
+ }
+ }
+ }
+ return $r;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert a color value in hsl notation to hexadecimal notation.
+ *
+ * Example:
+ *
+ * color: hsl(232,36%,48%);
+ *
+ *
+ * Will get converted to:
+ *
+ * color:#4e5aa7;
+ *
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertHslColorsMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/^hsl\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*%\s*,\s*([0-9]+)\s*%\s*\)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (stripos($token->Value, "hsl") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $token->Value = str_replace($m[0], $this->hsl2hex($m[1], $m[2], $m[3]), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+ /**
+ * Convert a HSL value to hexadecimal notation.
+ *
+ * Based on: {@link http://www.easyrgb.com/index.php?X=MATH&H=19#text19}.
+ *
+ * @param integer $hue Hue
+ * @param integer $saturation Saturation
+ * @param integer $lightness Lightnesss
+ * @return string
+ */
+ private function hsl2hex($hue, $saturation, $lightness)
+ {
+ $hue = $hue / 360;
+ $saturation = $saturation / 100;
+ $lightness = $lightness / 100;
+ if ($saturation == 0)
+ {
+ $red = $lightness * 255;
+ $green = $lightness * 255;
+ $blue = $lightness * 255;
+ }
+ else
+ {
+ if ($lightness < 0.5 )
+ {
+ $v2 = $lightness * (1 + $saturation);
+ }
+ else
+ {
+ $v2 = ($lightness + $saturation) - ($saturation * $lightness);
+ }
+ $v1 = 2 * $lightness - $v2;
+ $red = 255 * self::hue2rgb($v1, $v2, $hue + (1 / 3));
+ $green = 255 * self::hue2rgb($v1, $v2, $hue);
+ $blue = 255 * self::hue2rgb($v1, $v2, $hue - (1 / 3));
+ }
+ return "#" . str_pad(dechex(round($red)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($green)), 2, "0", STR_PAD_LEFT) . str_pad(dechex(round($blue)), 2, "0", STR_PAD_LEFT);
+ }
+ /**
+ * Apply hue to a rgb color value.
+ *
+ * @param integer $v1 Value 1
+ * @param integer $v2 Value 2
+ * @param integer $hue Hue
+ * @return integer
+ */
+ private function hue2rgb($v1, $v2, $hue)
+ {
+ if ($hue < 0)
+ {
+ $hue += 1;
+ }
+ if ($hue > 1)
+ {
+ $hue -= 1;
+ }
+ if ((6 * $hue) < 1)
+ {
+ return ($v1 + ($v2 - $v1) * 6 * $hue);
+ }
+ if ((2 * $hue) < 1)
+ {
+ return ($v2);
+ }
+ if ((3 * $hue) < 2)
+ {
+ return ($v1 + ($v2 - $v1) * (( 2 / 3) - $hue) * 6);
+ }
+ return $v1;
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert the font-weight values normal and bold to their numeric notation.
+ *
+ * Example:
+ *
+ * font-weight: normal;
+ * font: bold 11px monospace;
+ *
+ *
+ * Will get converted to:
+ *
+ * font-weight:400;
+ * font:700 11px monospace;
+ *
+ *
+ * @package CssMin/Minifier/Pluginsn
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssConvertFontWeightMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Array of included declaration properties this plugin will process; others declaration properties will get
+ * ignored.
+ *
+ * @var array
+ */
+ private $include = array
+ (
+ "font",
+ "font-weight"
+ );
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = null;
+ /**
+ * Transformation table used by the {@link CssConvertFontWeightMinifierPlugin::reReplace() replacement method}.
+ *
+ * @var array
+ */
+ private $transformation = array
+ (
+ "normal" => "400",
+ "bold" => "700"
+ );
+ /**
+ * Overwrites {@link aCssMinifierPlugin::__construct()}.
+ *
+ * The constructor will create the {@link CssConvertFontWeightMinifierPlugin::$reMatch replace regular expression}
+ * based on the {@link CssConvertFontWeightMinifierPlugin::$transformation transformation table}.
+ *
+ * @param CssMinifier $minifier The CssMinifier object of this plugin.
+ * @return void
+ */
+ public function __construct(CssMinifier $minifier)
+ {
+ $this->reMatch = "/(^|\s)+(" . implode("|", array_keys($this->transformation)). ")(\s|$)+/iS";
+ parent::__construct($minifier);
+ }
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (in_array($token->Property, $this->include) && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $token->Value = preg_replace_callback($this->reMatch, array($this, 'reReplace'), $token->Value);
+ }
+ return false;
+ }
+ /**
+ * Callback for replacement value.
+ *
+ * @param array $match
+ * @return string
+ */
+ private function reReplace($match)
+ {
+ return $match[1] . $this->transformation[strtolower($match[2])] . $match[3];
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will compress several unit values to their short notations. Examples:
+ *
+ *
+ * padding: 0.5em;
+ * border: 0px;
+ * margin: 0 0 0 0;
+ *
+ *
+ * Will get compressed to:
+ *
+ *
+ * padding:.5px;
+ * border:0;
+ * margin:0;
+ *
+ *
+ * --
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressUnitValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression used for matching and replacing unit values.
+ *
+ * @var array
+ */
+ private $re = array
+ (
+ "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}.\${2}\${4}",
+ "/(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)/iS" => "\${1}0",
+ );
+ /**
+ * Regular expression used for matching and replacing unit values only for non-blacklisted declarations.
+ *
+ * @var array
+ */
+ private $reBlacklisted = array(
+ "/(^0\s0\s0\s0)|(^0\s0\s0$)|(^0\s0$)/iS" => "0",
+ );
+ /**
+ * Blacklisted properties for the above regular expression.
+ *
+ * @var array
+ */
+ private $propertiesBlacklist = array('background-position');
+ /**
+ * Regular expression matching the value.
+ *
+ * @var string
+ */
+ private $reMatch = "/(^| |-)0\.([0-9]+?)(0+)?(%|em|ex|px|in|cm|mm|pt|pc)|(^| )-?(\.?)0(%|em|ex|px|in|cm|mm|pt|pc)|(^0\s0\s0\s0$)|(^0\s0\s0$)|(^0\s0$)/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (preg_match($this->reMatch, $token->Value))
+ {
+ foreach ($this->re as $reMatch => $reReplace)
+ {
+ $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
+ }
+ if (!in_array($token->Property, $this->propertiesBlacklist))
+ {
+ foreach ($this->reBlacklisted as $reMatch => $reReplace)
+ {
+ $token->Value = preg_replace($reMatch, $reReplace, $token->Value);
+ }
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} compress the content of expresssion() declaration values.
+ *
+ * For compression of expressions {@link https://github.com/rgrove/jsmin-php/ JSMin} will get used. JSMin have to be
+ * already included or loadable via {@link http://goo.gl/JrW54 PHP autoloading}.
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressExpressionValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (class_exists("JSMin") && stripos($token->Value, "expression(") !== false)
+ {
+ $value = $token->Value;
+ $value = substr($token->Value, stripos($token->Value, "expression(") + 10);
+ $value = trim(JSMin::minify($value));
+ $token->Value = "expression(" . $value . ")";
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssMinifierPlugin} will convert hexadecimal color value with 6 chars to their 3 char hexadecimal
+ * notation (if possible).
+ *
+ * Example:
+ *
+ * color: #aabbcc;
+ *
+ *
+ * Will get converted to:
+ *
+ * color:#abc;
+ *
+ *
+ * @package CssMin/Minifier/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCompressColorValuesMinifierPlugin extends aCssMinifierPlugin
+{
+ /**
+ * Regular expression matching 6 char hexadecimal color values.
+ *
+ * @var string
+ */
+ private $reMatch = "/\#([0-9a-f]{6})/iS";
+ /**
+ * Implements {@link aCssMinifierPlugin::minify()}.
+ *
+ * @param aCssToken $token Token to process
+ * @return boolean Return TRUE to break the processing of this token; FALSE to continue
+ */
+ public function apply(aCssToken &$token)
+ {
+ if (strpos($token->Value, "#") !== false && preg_match($this->reMatch, $token->Value, $m))
+ {
+ $value = strtolower($m[1]);
+ if ($value[0] == $value[1] && $value[2] == $value[3] && $value[4] == $value[5])
+ {
+ $token->Value = str_replace($m[0], "#" . $value[0] . $value[2] . $value[4], $token->Value);
+ }
+ }
+ return false;
+ }
+ /**
+ * Implements {@link aMinifierPlugin::getTriggerTokens()}
+ *
+ * @return array
+ */
+ public function getTriggerTokens()
+ {
+ return array
+ (
+ "CssAtFontFaceDeclarationToken",
+ "CssAtPageDeclarationToken",
+ "CssRulesetDeclarationToken"
+ );
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a CSS comment.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCommentToken extends aCssToken
+{
+ /**
+ * Comment as Text.
+ *
+ * @var string
+ */
+ public $Comment = "";
+ /**
+ * Set the properties of a comment token.
+ *
+ * @param string $comment Comment including comment delimiters
+ * @return void
+ */
+ public function __construct($comment)
+ {
+ $this->Comment = $comment;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->Comment;
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing comments.
+ *
+ * Adds a {@link CssCommentToken} to the parser if a comment was found.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssCommentParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("*", "/");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return false;
+ }
+ /**
+ * Stored buffer for restore.
+ *
+ * @var string
+ */
+ private $restoreBuffer = "";
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ if ($char === "*" && $previousChar === "/" && $state !== "T_COMMENT")
+ {
+ $this->parser->pushState("T_COMMENT");
+ $this->parser->setExclusive(__CLASS__);
+ $this->restoreBuffer = substr($this->parser->getAndClearBuffer(), 0, -2);
+ }
+ elseif ($char === "/" && $previousChar === "*" && $state === "T_COMMENT")
+ {
+ $this->parser->popState();
+ $this->parser->unsetExclusive();
+ $this->parser->appendToken(new CssCommentToken("/*" . $this->parser->getAndClearBuffer()));
+ $this->parser->setBuffer($this->restoreBuffer);
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Media types of the @variables at-rule block.
+ *
+ * @var array
+ */
+ public $MediaTypes = array();
+ /**
+ * Set the properties of a @variables at-rule token.
+ *
+ * @param array $mediaTypes Media types
+ * @return void
+ */
+ public function __construct($mediaTypes = null)
+ {
+ $this->MediaTypes = $mediaTypes ? $mediaTypes : array("all");
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @variables at-rule block with including declarations.
+ *
+ * Found @variables at-rule blocks will add a {@link CssAtVariablesStartToken} and {@link CssAtVariablesEndToken} to the
+ * parser; including declarations as {@link CssAtVariablesDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesParserPlugin extends aCssParserPlugin
+{
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerChars()}.
+ *
+ * @return array
+ */
+ public function getTriggerChars()
+ {
+ return array("@", "{", "}", ":", ";");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::getTriggerStates()}.
+ *
+ * @return array
+ */
+ public function getTriggerStates()
+ {
+ return array("T_DOCUMENT", "T_AT_VARIABLES::PREPARE", "T_AT_VARIABLES", "T_AT_VARIABLES_DECLARATION");
+ }
+ /**
+ * Implements {@link aCssParserPlugin::parse()}.
+ *
+ * @param integer $index Current index
+ * @param string $char Current char
+ * @param string $previousChar Previous char
+ * @return mixed TRUE will break the processing; FALSE continue with the next plugin; integer set a new index and break the processing
+ */
+ public function parse($index, $char, $previousChar, $state)
+ {
+ // Start of @variables at-rule block
+ if ($char === "@" && $state === "T_DOCUMENT" && strtolower(substr($this->parser->getSource(), $index, 10)) === "@variables")
+ {
+ $this->parser->pushState("T_AT_VARIABLES::PREPARE");
+ $this->parser->clearBuffer();
+ return $index + 10;
+ }
+ // Start of @variables declarations
+ elseif ($char === "{" && $state === "T_AT_VARIABLES::PREPARE")
+ {
+ $this->parser->setState("T_AT_VARIABLES");
+ $mediaTypes = array_filter(array_map("trim", explode(",", $this->parser->getAndClearBuffer("{"))));
+ $this->parser->appendToken(new CssAtVariablesStartToken($mediaTypes));
+ }
+ // Start of @variables declaration
+ if ($char === ":" && $state === "T_AT_VARIABLES")
+ {
+ $this->buffer = $this->parser->getAndClearBuffer(":");
+ $this->parser->pushState("T_AT_VARIABLES_DECLARATION");
+ }
+ // Unterminated @variables declaration
+ elseif ($char === ":" && $state === "T_AT_VARIABLES_DECLARATION")
+ {
+ // Ignore Internet Explorer filter declarations
+ if ($this->buffer === "filter")
+ {
+ return false;
+ }
+ CssMin::triggerError(new CssError(__FILE__, __LINE__, __METHOD__ . ": Unterminated @variables declaration", $this->buffer . ":" . $this->parser->getBuffer() . "_"));
+ }
+ // End of @variables declaration
+ elseif (($char === ";" || $char === "}") && $state === "T_AT_VARIABLES_DECLARATION")
+ {
+ $value = $this->parser->getAndClearBuffer(";}");
+ if (strtolower(substr($value, -10, 10)) === "!important")
+ {
+ $value = trim(substr($value, 0, -10));
+ $isImportant = true;
+ }
+ else
+ {
+ $isImportant = false;
+ }
+ $this->parser->popState();
+ $this->parser->appendToken(new CssAtVariablesDeclarationToken($this->buffer, $value, $isImportant));
+ $this->buffer = "";
+ }
+ // End of @variables at-rule block
+ elseif ($char === "}" && $state === "T_AT_VARIABLES")
+ {
+ $this->parser->popState();
+ $this->parser->clearBuffer();
+ $this->parser->appendToken(new CssAtVariablesEndToken());
+ }
+ else
+ {
+ return false;
+ }
+ return true;
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the end of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesEndToken extends aCssAtBlockEndToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents a declaration of a @variables at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtVariablesDeclarationToken extends aCssDeclarationToken
+{
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "";
+ }
+}
+
+/**
+ * This {@link aCssToken CSS token} represents the start of a @page at-rule block.
+ *
+ * @package CssMin/Tokens
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla
+ * @license http://opensource.org/licenses/mit-license.php MIT License
+ * @version 3.0.1
+ */
+class CssAtPageStartToken extends aCssAtBlockStartToken
+{
+ /**
+ * Selector.
+ *
+ * @var string
+ */
+ public $Selector = "";
+ /**
+ * Sets the properties of the @page at-rule.
+ *
+ * @param string $selector Selector
+ * @return void
+ */
+ public function __construct($selector = "")
+ {
+ $this->Selector = $selector;
+ }
+ /**
+ * Implements {@link aCssToken::__toString()}.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return "@page" . ($this->Selector ? " " . $this->Selector : "") . "{";
+ }
+}
+
+/**
+ * {@link aCssParserPlugin Parser plugin} for parsing @page at-rule block with including declarations.
+ *
+ * Found @page at-rule blocks will add a {@link CssAtPageStartToken} and {@link CssAtPageEndToken} to the
+ * parser; including declarations as {@link CssAtPageDeclarationToken}.
+ *
+ * @package CssMin/Parser/Plugins
+ * @link http://code.google.com/p/cssmin/
+ * @author Joe Scylla
+ * @copyright 2008 - 2011 Joe Scylla