--- a/adm/style/acp_ext_list.html
+++ b/adm/style/acp_ext_list.html
@@ -7,7 +7,7 @@
 	<p>{L_EXTENSIONS_EXPLAIN}</p>
 
 	<fieldset class="quick">
-		<span class="small"><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
+		<span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.1" target="_blank">{L_BROWSE_EXTENSIONS_DATABASE}</a> &bull; <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
 	</fieldset>
 
 	<form id="version_check_settings" method="post" action="{U_ACTION}" style="display:none">
@@ -98,6 +98,12 @@
 
 	<table class="table1">
 	<tr>
+		<th>{L_EXTENSION_INSTALL_HEADLINE}</th>
+	</tr>
+	<tr>
+		<td class="row3">{L_EXTENSION_INSTALL_EXPLAIN}</td>
+	</tr>
+	<tr>
 		<th>{L_EXTENSION_UPDATE_HEADLINE}</th>
 	</tr>
 	<tr>
--- a/adm/style/acp_forums.html
+++ b/adm/style/acp_forums.html
@@ -343,6 +343,8 @@
 		<!-- EVENT acp_forums_rules_settings_append -->
 		</fieldset>
 	</div>
+	
+	<!-- EVENT acp_forums_custom_settings -->
 
 	<fieldset class="submit-buttons">
 		<legend>{L_SUBMIT}</legend>
--- a/adm/style/acp_language.html
+++ b/adm/style/acp_language.html
@@ -68,6 +68,10 @@
 
 	<p>{L_ACP_LANGUAGE_PACKS_EXPLAIN}</p>
 
+	<fieldset class="quick">
+		<span class="small"><a href="https://www.phpbb.com/go/customise/language-packs/3.1" target="_blank">{L_BROWSE_LANGUAGE_PACKS_DATABASE}</a></span>
+	</fieldset>
+
 	<table class="table1 zebra-table">
 	<thead>
 	<tr>
--- a/adm/style/acp_profile.html
+++ b/adm/style/acp_profile.html
@@ -79,6 +79,7 @@
 			<dt><label for="field_hide">{L_HIDE_PROFILE_FIELD}{L_COLON}</label><br /><span>{L_HIDE_PROFILE_FIELD_EXPLAIN}</span></dt>
 			<dd><input type="checkbox" class="radio" id="field_hide" name="field_hide" value="1"<!-- IF S_FIELD_HIDE --> checked="checked"<!-- ENDIF --> /></dd>
 		</dl>
+		<!-- EVENT acp_profile_contact_before -->
 		<dl>
 			<dt><label for="field_is_contact">{L_FIELD_IS_CONTACT}{L_COLON}</label><br /><span>{L_FIELD_IS_CONTACT_EXPLAIN}</span></dt>
 			<dd><input type="checkbox" class="radio" id="field_is_contact" name="field_is_contact" value="1"<!-- IF S_FIELD_CONTACT --> checked="checked"<!-- ENDIF --> /></dd>
--- a/adm/style/acp_styles.html
+++ b/adm/style/acp_styles.html
@@ -19,7 +19,7 @@
 	{S_HIDDEN_FIELDS}
 
 	<div style="text-align: center;">
-		<input type="submit" name="confirm" value="{L_YES}" class="button2" />&nbsp; 
+		<input type="submit" name="confirm" value="{L_YES}" class="button2" />&nbsp;
 		<input type="submit" name="cancel" value="{L_NO}" class="button2" />
 	</div>
 
@@ -32,6 +32,10 @@
 
 <!-- IF L_EXPLAIN --><p>{L_EXPLAIN}</p><!-- ENDIF -->
 
+<fieldset class="quick">
+	<span class="small"><a href="https://www.phpbb.com/go/customise/styles/3.1" target="_blank">{L_BROWSE_STYLES_DATABASE}</a></span>
+</fieldset>
+
 <form id="acp_styles" method="post" action="{U_ACTION}">
 {S_HIDDEN_FIELDS}
 {S_FORM_TOKEN}
--- a/adm/style/admin.css
+++ b/adm/style/admin.css
@@ -17,6 +17,10 @@
 	font-size: 100%;
 }
 
+abbr {
+	text-decoration: none;
+}
+
 body, div, p, th, td, li, dd {
 	font-size: x-small;
 	voice-family: "\"}\"";
--- a/assets/javascript/core.js
+++ b/assets/javascript/core.js
@@ -394,8 +394,11 @@ phpbb.ajaxify = function(options) {
 				error: errorHandler,
 				cache: false
 			});
+
 			request.always(function() {
-				$loadingIndicator.fadeOut(phpbb.alertTime);
+				if ($loadingIndicator && $loadingIndicator.is(':visible')) {
+					$loadingIndicator.fadeOut(phpbb.alertTime);
+				}
 			});
 		};
 
@@ -1608,6 +1611,21 @@ phpbb.registerPageDropdowns = function() {
 };
 
 /**
+ * Handle avatars to be lazy loaded.
+ */
+phpbb.lazyLoadAvatars = function loadAvatars() {
+	$('.avatar[data-src]').each(function () {
+		var $avatar = $(this);
+
+		$avatar
+			.attr('src', $avatar.data('src'))
+			.removeAttr('data-src');
+	});
+};
+
+$(window).load(phpbb.lazyLoadAvatars);
+
+/**
 * Apply code editor to all textarea elements with data-bbcode attribute
 */
 $(function() {
--- a/assets/javascript/plupload.js
+++ b/assets/javascript/plupload.js
@@ -281,7 +281,7 @@ phpbb.plupload.deleteFile = function(row, attachId) {
 	$.ajax(phpbb.plupload.config.url, {
 		type: 'POST',
 		data: $.extend(fields, phpbb.plupload.getSerializedData()),
-		headers: { 'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest' }
+		headers: phpbb.plupload.config.headers
 	})
 	.always(always)
 	.done(done);
--- a/assets/plupload/plupload.full.min.js
+++ b/assets/plupload/plupload.full.min.js
@@ -1,6 +1,6 @@
 /**
  * mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill
- * v1.2.1
+ * v1.3.4
  *
  * Copyright 2013, Moxiecode Systems AB
  * Released under GPL License.
@@ -8,14 +8,15 @@
  * License: http://www.plupload.com/license
  * Contributing: http://www.plupload.com/contributing
  *
- * Date: 2014-05-14
+ * Date: 2015-07-18
  */
-!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/I18n",l="moxie/core/utils/Mime",d="moxie/core/utils/Env",f="moxie/core/utils/Dom",h="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/core/utils/Encode",g="moxie/runtime/Runtime",v="moxie/runtime/RuntimeClient",y="moxie/file/Blob",w="moxie/file/File",E="moxie/file/FileInput",_="moxie/file/FileDrop",x="moxie/runtime/RuntimeTarget",b="moxie/file/FileReader",R="moxie/core/utils/Url",T="moxie/file/FileReaderSync",A="moxie/xhr/FormData",S="moxie/xhr/XMLHttpRequest",O="moxie/runtime/Transporter",I="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/runtime/html5/file/Blob",L="moxie/core/utils/Events",M="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",H="moxie/runtime/html5/xhr/XMLHttpRequest",P="moxie/runtime/html5/utils/BinaryReader",k="moxie/runtime/html5/image/JPEGHeaders",U="moxie/runtime/html5/image/ExifParser",B="moxie/runtime/html5/image/JPEG",z="moxie/runtime/html5/image/PNG",G="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",X="moxie/runtime/html5/image/Image",j="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/Blob",W="moxie/runtime/flash/file/FileInput",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",et="moxie/runtime/silverlight/file/Blob",tt="moxie/runtime/silverlight/file/FileInput",nt="moxie/runtime/silverlight/file/FileDrop",it="moxie/runtime/silverlight/file/FileReader",rt="moxie/runtime/silverlight/file/FileReaderSync",ot="moxie/runtime/silverlight/xhr/XMLHttpRequest",at="moxie/runtime/silverlight/runtime/Transporter",st="moxie/runtime/silverlight/image/Image",ut="moxie/runtime/html4/Runtime",ct="moxie/runtime/html4/file/FileInput",lt="moxie/runtime/html4/file/FileReader",dt="moxie/runtime/html4/xhr/XMLHttpRequest",ft="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(e,t){var n,i,r,o;if(e){try{n=e.length}catch(a){n=o}if(n===o){for(i in e)if(e.hasOwnProperty(i)&&t(e[i],i)===!1)return}else for(r=0;n>r;r++)if(t(e[r],r)===!1)return}},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},f=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9]+)([mgk]?)$/.exec(e.toLowerCase().replace(/[^0-9mkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),e};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,parseSizeStr:f}}),i(c,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(l,[u,c],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]])-1===e.inArray(s,u)&&u.push(s);else{if(!n||!/^\w+$/.test(r[a]))return[];u.push("."+r[a])}}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(d,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",f="architecture",h="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,f=arguments;n<f.length;n+=2){var h=f[n],p=f[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<h.length;a++)if(l=h[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?t[c[0]]=typeof c[1]==i?c[1].call(this,d):c[1]:3==c.length?t[c[0]]=typeof c[1]!==i||c[1].exec&&c[1].test?d?d.replace(c[1],c[2]):e:d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},y={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},w={browser:[[/(opera\smini)\/((\d+)?[\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/((\d+)?[\w\.-]+)/i,/(opera).+version\/((\d+)?[\w\.]+)/i,/(opera)[\/\s]+((\d+)?[\w\.]+)/i],[u,d,a],[/\s(opr)\/((\d+)?[\w\.]+)/i],[[u,"Opera"],d,a],[/(kindle)\/((\d+)?[\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?((\d+)?[\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?((\d+)?[\w\.]*)/i,/(?:ms|\()(ie)\s((\d+)?[\w\.]+)/i,/(rekonq)((?:\/)[\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron)\/((\d+)?[\w\.-]+)/i],[u,d,a],[/(trident).+rv[:\s]((\d+)?[\w\.]+).+like\sgecko/i],[[u,"IE"],d,a],[/(yabrowser)\/((\d+)?[\w\.]+)/i],[[u,"Yandex"],d,a],[/(comodo_dragon)\/((\d+)?[\w\.]+)/i],[[u,/_/g," "],d,a],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?((\d+)?[\w\.]+)/i],[u,d,a],[/(dolfin)\/((\d+)?[\w\.]+)/i],[[u,"Dolphin"],d,a],[/((?:android.+)crmo|crios)\/((\d+)?[\w\.]+)/i],[[u,"Chrome"],d,a],[/((?:android.+))version\/((\d+)?[\w\.]+)\smobile\ssafari/i],[[u,"Android Browser"],d,a],[/version\/((\d+)?[\w\.]+).+?mobile\/\w+\s(safari)/i],[d,a,[u,"Mobile Safari"]],[/version\/((\d+)?[\w\.]+).+?(mobile\s?safari|safari)/i],[d,a,u],[/webkit.+?(mobile\s?safari|safari)((\/[\w\.]+))/i],[u,[a,v.str,y.browser.oldsafari.major],[d,v.str,y.browser.oldsafari.version]],[/(konqueror)\/((\d+)?[\w\.]+)/i,/(webkit|khtml)\/((\d+)?[\w\.]+)/i],[u,d,a],[/(navigator|netscape)\/((\d+)?[\w\.-]+)/i],[[u,"Netscape"],d,a],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?((\d+)?[\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/((\d+)?[\w\.-]+)/i,/(mozilla)\/((\d+)?[\w\.]+).+rv\:.+gecko\/\d+/i,/(uc\s?browser|polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|qqbrowser)[\/\s]?((\d+)?[\w\.]+)/i,/(links)\s\(((\d+)?[\w\.]+)/i,/(gobrowser)\/?((\d+)?[\w\.]+)*/i,/(ice\s?browser)\/v?((\d+)?[\w\._]+)/i,/(mosaic)[\/\s]((\d+)?[\w\.]+)/i],[u,d,a]],engine:[[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,y.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,y.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)\/([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego)[\/\s-]?([\w\.]+)*/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i],[u,[d,/_/g,"."]],[/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(macintosh|mac(?=_powerpc)|plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,w.browser)},this.getEngine=function(){return v.rgx.apply(this,w.engine)},this.getOS=function(){return v.rgx.apply(this,w.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return(new E).getResult()}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==r.browser||r.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r={can:i,browser:n.browser.name,version:parseFloat(n.browser.major),os:n.os.name,osVersion:n.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return r.OS=r.os,r}),i(f,[d],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(h,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[h,u],function(e,t){function n(){var n={};t.extend(this,{uid:null,init:function(){this.uid||(this.uid=t.guid("uid_"))},addEventListener:function(e,i,r,o){var a=this,s;return e=t.trim(e),/\s/.test(e)?void t.each(e.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(e=e.toLowerCase(),r=parseInt(r,10)||0,s=n[this.uid]&&n[this.uid][e]||[],s.push({fn:i,priority:r,scope:o||this}),n[this.uid]||(n[this.uid]={}),void(n[this.uid][e]=s))},hasEventListener:function(e){return e?!(!n[this.uid]||!n[this.uid][e]):!!n[this.uid]},removeEventListener:function(e,i){e=e.toLowerCase();var r=n[this.uid]&&n[this.uid][e],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete n[this.uid][e],t.isEmptyObj(n[this.uid])&&delete n[this.uid])}},removeAllEventListeners:function(){n[this.uid]&&delete n[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==t.typeOf(i)){if(s=i,"string"!==t.typeOf(s.type))throw new e.EventException(e.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=n[r]&&n[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];t.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&t.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},convertEventPropsToHandlers:function(e){var n;"array"!==t.typeOf(e)&&(e=[e]);for(var i=0;i<e.length;i++)n="on"+e[i],"function"===t.typeOf(this[n])?this.addEventListener(e[i],this[n]):"undefined"===t.typeOf(this[n])&&(this[n]=null)}})}return n.instance=new n,n}),i(m,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(f++)),u=i.indexOf(e.charAt(f++)),c=i.indexOf(e.charAt(f++)),l=i.indexOf(e.charAt(f++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,m[h++]=64==c?String.fromCharCode(r):64==l?String.fromCharCode(r,o):String.fromCharCode(r,o,a);while(f<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&e(t),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,f=0,h=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(f++),o=t.charCodeAt(f++),a=t.charCodeAt(f++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[h++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(f<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(g,[u,f,p],function(e,t,n){function i(n,r,a,s,u){var c=this,l,d=e.guid(r+"_"),f=u||"browser";n=n||{},o[d]=this,a=e.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},a),n.preferred_caps&&(f=i.getMode(s,n.preferred_caps,f)),l=function(){var t={};return{exec:function(e,n,i,r){return l[n]&&(t[e]||(t[e]={context:this,instance:new l[n]}),t[e].instance[i])?t[e].instance[i].apply(this,r):void 0},removeInstance:function(e){delete t[e]},removeAllInstances:function(){var n=this;e.each(t,function(t,i){"function"===e.typeOf(t.instance.destroy)&&t.instance.destroy.call(t.context),n.removeInstance(i)})}}}(),e.extend(this,{initialized:!1,uid:d,type:r,mode:i.getMode(s,n.required_caps,f),shimid:d+"_container",clients:0,options:n,can:function(t,n){var r=arguments[2]||a;if("string"===e.typeOf(t)&&"undefined"===e.typeOf(n)&&(t=i.parseCaps(t)),"object"===e.typeOf(t)){for(var o in t)if(!this.can(o,t[o],r))return!1;return!0}return"function"===e.typeOf(r[t])?r[t].call(this,n):n===r[t]},getShimContainer:function(){var n,i=t.get(this.shimid);return i||(n=this.options.container?t.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,e.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),n.appendChild(i),n=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=t.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete o[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&n.required_caps&&!this.can(n.required_caps)&&(this.mode=!1)}var r={},o={};return i.order="html5,flash,silverlight,html4",i.getRuntime=function(e){return o[e]?o[e]:!1},i.addConstructor=function(e,t){t.prototype=n.instance,r[e]=t},i.getConstructor=function(e){return r[e]||null},i.getInfo=function(e){var t=i.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},i.parseCaps=function(t){var n={};return"string"!==e.typeOf(t)?t||{}:(e.each(t.split(","),function(e){n[e]=!0}),n)},i.can=function(e,t){var n,r=i.getConstructor(e),o;return r?(n=new r({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},i.thatCan=function(e,t){var n=(t||i.order).split(/\s*,\s*/);for(var r in n)if(i.can(n[r],e))return n[r];return null},i.getMode=function(t,n,i){var r=null;if("undefined"===e.typeOf(i)&&(i="browser"),n&&!e.isEmptyObj(t)){if(e.each(n,function(n,i){if(t.hasOwnProperty(i)){var o=t[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=e.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==e.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},i.capTrue=function(){return!0},i.capFalse=function(){return!1},i.capTest=function(e){return function(){return!!e}},i}),i(v,[h,u,g],function(e,t,n){return function i(){var i;t.extend(this,{connectRuntime:function(r){function o(t){var s,u;return t.length?(s=t.shift(),(u=n.getConstructor(s))?(i=new u(r),i.bind("Init",function(){i.initialized=!0,setTimeout(function(){i.clients++,a.trigger("RuntimeInit",i)},1)}),i.bind("Error",function(){i.destroy(),o(t)}),i.mode?void i.init():void i.trigger("Error")):void o(t)):(a.trigger("RuntimeError",new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)),void(i=null))}var a=this,s;if("string"===t.typeOf(r)?s=r:"string"===t.typeOf(r.ruid)&&(s=r.ruid),s){if(i=n.getRuntime(s))return i.clients++,i;throw new e.RuntimeError(e.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||n.order).split(/\s*,\s*/))},getRuntime:function(){return i&&i.uid?i:(i=null,null)},disconnectRuntime:function(){i&&--i.clients<=0&&(i.destroy(),i=null)}})}}),i(y,[u,m,v],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"";var n=e.match(/^data:([^;]*);base64,/);n&&(this.type=n[1],e=t.atob(e.substring(e.indexOf("base64,")+7))),this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(w,[u,l,y],function(e,t,n){function i(i,r){var o,a;if(r||(r={}),a=r.type&&""!==r.type?r.type:t.getFileMime(r.name),r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else{var s=a.split("/")[0];o=e.guid((""!==s?s:"file")+"_"),t.extensions[a]&&(o+="."+t.extensions[a][0])}n.apply(this,arguments),e.extend(this,{type:a||"",name:o||e.guid("file_"),lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(E,[u,l,f,h,p,c,w,g,v],function(e,t,n,i,r,o,a,s,u){function c(r){var c=this,d,f,h;if(-1!==e.inArray(e.typeOf(r),["string","node"])&&(r={browse_button:r}),f=n.get(r.browse_button),!f)throw new i.DOMException(i.DOMException.NOT_FOUND_ERR);h={accept:[{title:o.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:f.parentNode||document.body},r=e.extend({},h,r),"string"==typeof r.required_caps&&(r.required_caps=s.parseCaps(r.required_caps)),"string"==typeof r.accept&&(r.accept=t.mimes2extList(r.accept)),d=n.get(r.container),d||(d=document.body),"static"===n.getStyle(d,"position")&&(d.style.position="relative"),d=f=null,u.call(c),e.extend(c,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){c.convertEventPropsToHandlers(l),c.bind("RuntimeInit",function(t,i){c.ruid=i.uid,c.shimid=i.shimid,c.bind("Ready",function(){c.trigger("Refresh")},999),c.bind("Change",function(){var t=i.exec.call(c,"FileInput","getFiles");c.files=[],e.each(t,function(e){return 0===e.size?!0:void c.files.push(new a(c.ruid,e))})},999),c.bind("Refresh",function(){var t,o,a,s;a=n.get(r.browse_button),s=n.get(i.shimid),a&&(t=n.getPos(a,n.get(r.container)),o=n.getSize(a),s&&e.extend(s.style,{top:t.y+"px",left:t.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),i.exec.call(c,"FileInput","init",r)}),c.connectRuntime(e.extend({},r,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){c.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null}})}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=r.instance,c}),i(_,[c,f,h,u,w,v,p,l],function(e,t,n,i,r,o,a,s){function u(n){var a=this,u;"string"==typeof n&&(n={drop_zone:n}),u={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},u,n):u,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=s.mimes2extList(n.accept)),o.call(a),i.extend(a,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){a.convertEventPropsToHandlers(c),a.bind("RuntimeInit",function(e,t){a.ruid=t.uid,a.bind("Drop",function(){var e=t.exec.call(a,"FileDrop","getFiles");a.files=[],i.each(e,function(e){a.files.push(new r(a.ruid,e))})},999),t.exec.call(a,"FileDrop","init",n),a.dispatchEvent("ready")}),a.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null}})}var c=["ready","dragenter","dragleave","drop","error"];return u.prototype=a.instance,u}),i(x,[u,v,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(b,[u,m,h,p,y,w,x],function(e,t,n,i,r,o,a){function s(){function i(e,i){function l(e){o.readyState=s.DONE,o.error=e,o.trigger("error"),d()}function d(){c.destroy(),c=null,o.trigger("loadend")}function f(t){c.bind("Error",function(e,t){l(t)}),c.bind("Progress",function(e){o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e)}),c.bind("Load",function(e){o.readyState=s.DONE,o.result=t.exec.call(c,"FileReader","getResult"),o.trigger(e),d()}),t.exec.call(c,"FileReader","read",e,i)}if(c=new a,this.convertEventPropsToHandlers(u),this.readyState===s.LOADING)return l(new n.DOMException(n.DOMException.INVALID_STATE_ERR));if(this.readyState=s.LOADING,this.trigger("loadstart"),i instanceof r)if(i.isDetached()){var h=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=h;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(h)}this.readyState=s.DONE,this.trigger("load"),d()}else f(c.connectRuntime(i.ruid));else l(new n.DOMException(n.DOMException.NOT_FOUND_ERR))}var o=this,c;e.extend(this,{uid:e.guid("uid_"),readyState:s.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e)},abort:function(){this.result=null,-1===e.inArray(this.readyState,[s.EMPTY,s.DONE])&&(this.readyState===s.LOADING&&(this.readyState=s.DONE),c&&c.getRuntime().exec.call(this,"FileReader","abort"),this.trigger("abort"),this.trigger("loadend"))
-},destroy:function(){this.abort(),c&&(c.getRuntime().exec.call(this,"FileReader","destroy"),c.disconnectRuntime()),o=c=null}})}var u=["loadstart","progress","load","abort","error","loadend"];return s.EMPTY=0,s.LOADING=1,s.DONE=2,s.prototype=i.instance,s}),i(R,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,/(\/|\/[^\.]+)$/.test(c)?c+="/":c=c.replace(/\/[^\/]+$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i=e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(T,[u,v,m],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(A,[h,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(S,[u,h,p,m,R,g,x,y,T,A,d,l],function(e,t,n,i,r,o,a,s,u,c,l,d){function f(){this.uid=e.guid("uid_")}function h(){function n(e,t){return y.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?y[e]:v[e]:void(l.can("define_property")?y[e]=t:v[e]=t):void 0}function u(t){function i(){k&&(k.destroy(),k=null),s.dispatchEvent("loadend"),s=null}function r(r){k.bind("LoadStart",function(e){n("readyState",h.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),I&&s.upload.dispatchEvent(e)}),k.bind("Progress",function(e){n("readyState")!==h.LOADING&&(n("readyState",h.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),k.bind("UploadProgress",function(e){I&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),k.bind("Load",function(t){n("readyState",h.DONE),n("status",Number(r.exec.call(k,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(k,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),U=r.exec.call(k,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(I&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),k.bind("Abort",function(e){s.dispatchEvent(e),i()}),k.bind("Error",function(e){N=!0,n("readyState",h.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(k,"XMLHttpRequest","send",{url:E,method:_,async:w,user:b,password:R,headers:x,mimeType:A,encoding:T,responseType:s.responseType,withCredentials:s.withCredentials,options:P},t)}var s=this;M=(new Date).getTime(),k=new a,"string"==typeof P.required_caps&&(P.required_caps=o.parseCaps(P.required_caps)),P.required_caps=e.extend({},P.required_caps,{return_response_type:s.responseType}),t instanceof c&&(P.required_caps.send_multipart=!0),L||(P.required_caps.do_cors=!0),P.ruid?r(k.connectRuntime(P)):(k.bind("RuntimeInit",function(e,t){r(t)}),k.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),k.connectRuntime(P))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),M=C=null}var v=this,y={timeout:0,readyState:h.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},w=!0,E,_,x={},b,R,T=null,A=null,S=!1,O=!1,I=!1,D=!1,N=!1,L=!1,M,C,F=null,H=null,P={},k,U="",B;e.extend(this,y,{uid:e.guid("uid_"),upload:new f,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(b=u||l.user,R=c||l.pass,w=s||!0,w===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);S=!w,O=!1,x={},g.call(this),n("readyState",h.OPENED),this.convertEventPropsToHandlers(["readystatechange"]),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(x[r]?x[r]+=", "+o:x[r]=o,!0)},getAllResponseHeaders:function(){return U||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:U&&""!==U&&(B||(B={},e.each(U.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),B[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),B.hasOwnProperty(t))?B[t].header+": "+B[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[h.LOADING,h.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,H=o},send:function(n,r){if(P="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.convertEventPropsToHandlers(m),this.upload.convertEventPropsToHandlers(m),this.readyState!==h.OPENED||O)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)P.ruid=n.ruid,A=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();P.ruid=o.ruid,A=o.type||"application/octet-stream"}}else"string"==typeof n&&(T="UTF-8",A="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=P.required_caps&&P.required_caps.send_browser_cookies&&!L),I=!S&&this.upload.hasEventListener(),N=!1,D=!n,S||(O=!0),u.call(this,n)},abort:function(){if(N=!0,S=!1,~e.inArray(n("readyState"),[h.UNSENT,h.OPENED,h.DONE]))n("readyState",h.UNSENT);else{if(n("readyState",h.DONE),O=!1,!k)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);k.getRuntime().exec.call(k,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){k&&("function"===e.typeOf(k.destroy)&&k.destroy(),k=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}})}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};f.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return h.UNSENT=0,h.OPENED=1,h.HEADERS_RECEIVED=2,h.LOADING=3,h.DONE=4,h.prototype=n.instance,h}),i(O,[u,m,v,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;f>i&&(f=i),n=t.btoa(c.substr(d,f)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,f;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),f=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(I,[u,f,h,T,S,g,v,O,d,p,y,w,m],function(e,t,n,i,r,o,a,s,u,c,l,d,f){function h(){function i(e){e||(e=this.getRuntime().exec.call(this,"Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof h){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)/^data:[^;]*;base64,/.test(t)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){this.bind("Load Resize",function(){i.call(this)},999),this.convertEventPropsToHandlers(p),c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,crop:!1,preserveHeaders:!0};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.getRuntime().exec.call(this,"Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return e||(e="image/jpeg"),"image/jpeg"!==e||t||(t=90),this.getRuntime().exec.call(this,"Image","getAsBlob",e,t)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.getRuntime().exec.call(this,"Image","getAsDataURL",e,t)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return f.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i){function r(){if(u.can("create_canvas")){var t=a.getAsCanvas();if(t)return i.appendChild(t),t=null,a.destroy(),void o.trigger("embedded")}var r=a.getAsDataURL(c,l);if(!r)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",r.length))i.innerHTML='<img src="'+r+'" width="'+a.width+'" height="'+a.height+'" />',a.destroy(),o.trigger("embedded");else{var d=new s;d.bind("TransportingComplete",function(){v=o.connectRuntime(this.result.ruid),o.bind("Embedded",function(){e.extend(v.getShimContainer().style,{top:"0px",left:"0px",width:a.width+"px",height:a.height+"px"}),v=null},999),v.exec.call(o,"ImageView","display",this.result.uid,m,g),a.destroy()}),d.transport(f.atob(r.substring(r.indexOf("base64,")+7)),c,e.extend({},p,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i}))}}var o=this,a,c,l,d,p=arguments[1]||{},m=this.width,g=this.height,v;try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>h.MAX_RESIZE_WIDTH||this.height>h.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);if(c=p.type||this.type||"image/jpeg",l=p.quality||90,d="undefined"!==e.typeOf(p.crop)?p.crop:!1,p.width)m=p.width,g=p.height||m;else{var y=t.getSize(i);y.w&&y.h&&(m=y.w,g=y.h)}return a=new h,a.bind("Resize",function(){r.call(o)}),a.bind("Load",function(){a.downsize(m,g,d,!1)}),a.clone(this,!1),a}catch(w){this.trigger("error",w.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}})}var p=["progress","load","error","resize","embedded"];return h.MAX_RESIZE_WIDTH=6500,h.MAX_RESIZE_HEIGHT=6500,h.prototype=c.instance,h}),i(D,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.version>9)}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.version>=21},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.4","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||"IE"===i.browser&&i.version>=10||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(L,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(M,[D,u,f,L,l,d],function(e,t,n,i,r,o){function a(){var e=[],a;t.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,f,h,p,m;a=s,e=[],f=a.accept.mimes||r.extList2mimes(a.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(a.multiple&&c.can("select_multiple")?"multiple":"")+(a.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(f?' accept="'+f.join(",")+'"':"")+" />",l=n.get(c.uid),t.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),h=n.get(a.browse_button),c.can("summon_file_dialog")&&("static"===n.getStyle(h,"position")&&(h.style.position="relative"),p=parseInt(n.getStyle(h,"z-index"),10)||1,h.style.zIndex=p,d.style.zIndex=p-1,i.addEvent(h,"click",function(e){var t=n.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?h:d,i.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),i.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),i.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),i.addEvent(n.get(a.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(){if(e=[],a.directory?t.each(this.files,function(t){"."!==t.name&&e.push(t)}):e=[].slice.call(this.files),"IE"!==o.browser&&"IEMobile"!==o.browser)this.value="";else{var n=this.cloneNode(!0);this.parentNode.replaceChild(n,this),n.onchange=g}u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},getFiles:function(){return e},disable:function(e){var t=this.getRuntime(),i;(i=n.get(t.uid))&&(i.disabled=!!e)},destroy:function(){var t=this.getRuntime(),r=t.getShim(),o=t.getShimContainer();i.removeAllEvents(o,this.uid),i.removeAllEvents(a&&n.get(a.container),this.uid),i.removeAllEvents(a&&n.get(a.browse_button),this.uid),o&&(o.innerHTML=""),r.removeInstance(this.uid),e=a=o=r=null}})}return e.FileInput=a}),i(C,[D,u,f,L,l],function(e,t,n,i,r){function o(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var n=t.toArray(e.dataTransfer.types||[]);return-1!==t.inArray("Files",n)||-1!==t.inArray("public.file-url",n)||-1!==t.inArray("application/x-moz-file",n)}function o(e){for(var n=[],i=0;i<e.length;i++)[].push.apply(n,e[i].extensions.split(/\s*,\s*/));return-1===t.inArray("*",n)?n:[]}function a(e){if(!f.length)return!0;var n=r.getFileExtension(e.name);return!n||-1!==t.inArray(n,f)}function s(e,n){var i=[];t.each(e,function(e){var t=e.webkitGetAsEntry();if(t)if(t.isFile){var n=e.getAsFile();a(n)&&d.push(n)}else i.push(t)}),i.length?u(i,n):n()}function u(e,n){var i=[];t.each(e,function(e){i.push(function(t){c(e,t)})}),t.inSeries(i,function(){n()})}function c(e,t){e.isFile?e.file(function(e){a(e)&&d.push(e),t()},function(){t()}):e.isDirectory?l(e,t):t()}function l(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){u(i,t)})}var d=[],f=[],h;t.extend(this,{init:function(n){var r=this,u;h=n,f=o(h.accept),u=h.container,i.addEvent(u,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},r.uid),i.addEvent(u,"drop",function(n){e(n)&&(n.preventDefault(),d=[],n.dataTransfer.items&&n.dataTransfer.items[0].webkitGetAsEntry?s(n.dataTransfer.items,function(){r.trigger("drop")}):(t.each(n.dataTransfer.files,function(e){a(e)&&d.push(e)}),r.trigger("drop")))},r.uid),i.addEvent(u,"dragenter",function(e){r.trigger("dragenter")},r.uid),i.addEvent(u,"dragleave",function(e){r.trigger("dragleave")},r.uid)},getFiles:function(){return d},destroy:function(){i.removeAllEvents(h&&n.get(h.container),this.uid),d=f=h=null}})}return e.FileDrop=o}),i(F,[D,m,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(e,t){var o=this;i=new window.FileReader,i.addEventListener("progress",function(e){o.trigger(e)}),i.addEventListener("load",function(e){o.trigger(e)}),i.addEventListener("error",function(e){o.trigger(e,i.error)}),i.addEventListener("loadend",function(){i=null}),"function"===n.typeOf(i[e])?(r=!1,i[e](t.getSource())):"readAsBinaryString"===e&&(r=!0,i.readAsDataURL(t.getSource()))},getResult:function(){return i&&i.result?r?e(i.result):i.result:null},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(H,[D,u,l,R,w,y,A,h,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),f.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.version<8?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return h.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var f=this,h,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.version>=4&&u.version<7,f="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),h=c(),h.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||f)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}h.upload?(n.withCredentials&&(h.withCredentials=!0),h.addEventListener("load",function(e){s.trigger(e)}),h.addEventListener("error",function(e){s.trigger(e)}),h.addEventListener("progress",function(e){s.trigger(e)}),h.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):h.onreadystatechange=function v(){switch(h.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=h.getResponseHeader("Content-Length")||0),h.responseText&&(t=h.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:h.onreadystatechange=function(){},s.trigger(0===h.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){h.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in h&&(h.responseType="json"!==n.responseType||u.can("return_response_type","json")?n.responseType:"text"),m?h.sendAsBinary?h.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);h.send(e.buffer)}():h.send(r),s.trigger("loadstart")},getStatus:function(){try{if(h)return h.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,h.response),o=h.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?h.response:200===h.status&&window.JSON?JSON.parse(h.responseText):null;case"document":return l(h);default:return""!==h.responseText?h.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return h.getAllResponseHeaders()}catch(e){}return""},abort:function(){h&&h.abort()},destroy:function(){f=p=null}})}return e.XMLHttpRequest=c}),i(P,[],function(){return function(){function e(e,t){var n=r?0:-8*(t-1),i=0,a;for(a=0;t>a;a++)i|=o.charCodeAt(e+a)<<Math.abs(n+8*a);return i}function n(e,t,n){n=3===arguments.length?n:o.length-t-1,o=o.substr(0,t)+e+o.substr(n+t)}function i(e,t,i){var o="",a=r?0:-8*(i-1),s;for(s=0;i>s;s++)o+=String.fromCharCode(t>>Math.abs(a+8*s)&255);n(o,e,i)}var r=!1,o;return{II:function(e){return e===t?r:void(r=e)},init:function(e){r=!1,o=e},SEGMENT:function(e,t,i){switch(arguments.length){case 1:return o.substr(e,o.length-e-1);case 2:return o.substr(e,t);case 3:n(i,e,t);break;default:return o}},BYTE:function(t){return e(t,1)},SHORT:function(t){return e(t,2)},LONG:function(n,r){return r===t?e(n,4):void i(n,r,4)},SLONG:function(t){var n=e(t,4);return n>2147483647?n-4294967296:n},STRING:function(t,n){var i="";for(n+=t;n>t;t++)i+=String.fromCharCode(e(t,1));return i}}}}),i(k,[P],function(e){return function t(n){var i=[],r,o,a,s=0;if(r=new e,r.init(n),65496===r.SHORT(0)){for(o=2;o<=n.length;)if(a=r.SHORT(o),a>=65488&&65495>=a)o+=2;else{if(65498===a||65497===a)break;s=r.SHORT(o+2)+2,a>=65505&&65519>=a&&i.push({hex:a,name:"APP"+(15&a),start:o,length:s,segment:r.SEGMENT(o,s)}),o+=s}return r.init(null),{headers:i,restore:function(e){var t,n;for(r.init(e),o=65504==r.SHORT(2)?4+r.SHORT(4):2,n=0,t=i.length;t>n;n++)r.SEGMENT(o,0,i[n].segment),o+=i[n].length;return e=r.SEGMENT(),r.init(null),e},strip:function(e){var n,i,o;for(i=new t(e),n=i.headers,i.purge(),r.init(e),o=n.length;o--;)r.SEGMENT(n[o].start,n[o].length,"");return e=r.SEGMENT(),r.init(null),e},get:function(e){for(var t=[],n=0,r=i.length;r>n;n++)i[n].name===e.toUpperCase()&&t.push(i[n].segment);return t},set:function(e,t){var n=[],r,o,a;for("string"==typeof t?n.push(t):n=t,r=o=0,a=i.length;a>r&&(i[r].name===e.toUpperCase()&&(i[r].segment=n[o],i[r].length=n[o].length,o++),!(o>=n.length));r++);},purge:function(){i=[],r.init(null),r=null}}}}}),i(U,[u,P],function(e,n){return function i(){function i(e,n){var i=a.SHORT(e),r,o,s,u,d,f,h,p,m=[],g={};for(r=0;i>r;r++)if(h=f=e+12*r+2,s=n[a.SHORT(h)],s!==t){switch(u=a.SHORT(h+=2),d=a.LONG(h+=2),h+=4,m=[],u){case 1:case 7:for(d>4&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.BYTE(h+o);break;case 2:d>4&&(h=a.LONG(h)+c.tiffHeader),g[s]=a.STRING(h,d-1);continue;case 3:for(d>2&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.SHORT(h+2*o);break;case 4:for(d>1&&(h=a.LONG(h)+c.tiffHeader),o=0;d>o;o++)m[o]=a.LONG(h+4*o);break;case 5:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.LONG(h+4*o)/a.LONG(h+4*o+4);break;case 9:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o);break;case 10:for(h=a.LONG(h)+c.tiffHeader,o=0;d>o;o++)m[o]=a.SLONG(h+4*o)/a.SLONG(h+4*o+4);break;default:continue}p=1==d?m[0]:m,g[s]=l.hasOwnProperty(s)&&"object"!=typeof p?l[s][p]:p}return g}function r(){var e=c.tiffHeader;return a.II(18761==a.SHORT(e)),42!==a.SHORT(e+=2)?!1:(c.IFD0=c.tiffHeader+a.LONG(e+=2),u=i(c.IFD0,s.tiff),"ExifIFDPointer"in u&&(c.exifIFD=c.tiffHeader+u.ExifIFDPointer,delete u.ExifIFDPointer),"GPSInfoIFDPointer"in u&&(c.gpsIFD=c.tiffHeader+u.GPSInfoIFDPointer,delete u.GPSInfoIFDPointer),!0)}function o(e,t,n){var i,r,o,u=0;if("string"==typeof t){var l=s[e.toLowerCase()];for(var d in l)if(l[d]===t){t=d;break}}i=c[e.toLowerCase()+"IFD"],r=a.SHORT(i);for(var f=0;r>f;f++)if(o=i+12*f+2,a.SHORT(o)==t){u=o+8;break}return u?(a.LONG(u,n),!0):!1}var a,s,u,c={},l;return a=new n,s={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire.",1:"Flash fired.",5:"Strobe return light not detected.",7:"Strobe return light detected.",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},{init:function(e){return c={tiffHeader:10},e!==t&&e.length?(a.init(e),65505===a.SHORT(0)&&"EXIF\x00"===a.STRING(4,5).toUpperCase()?r():!1):!1
-},TIFF:function(){return u},EXIF:function(){var t;if(t=i(c.exifIFD,s.exif),t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var n=0,r="";n<t.ExifVersion.length;n++)r+=String.fromCharCode(t.ExifVersion[n]);t.ExifVersion=r}return t},GPS:function(){var t;return t=i(c.gpsIFD,s.gps),t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join(".")),t},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:o("exif",e,t)},getBinary:function(){return a.SEGMENT()},purge:function(){a.init(null),a=u=null,c={}}}}}),i(B,[u,h,k,P,U],function(e,t,n,i,r){function o(o){function a(){for(var e=0,t,n;e<=u.length;){if(t=c.SHORT(e+=2),t>=65472&&65475>=t)return e+=5,{height:c.SHORT(e),width:c.SHORT(e+=2)};n=c.SHORT(e+=2),e+=n-2}return null}function s(){d&&l&&c&&(d.purge(),l.purge(),c.init(null),u=f=l=d=c=null)}var u,c,l,d,f,h;if(u=o,c=new i,c.init(u),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o),d=new r,h=!!d.init(l.get("app1")[0]),f=a.call(this),e.extend(this,{type:"image/jpeg",size:u.length,width:f&&f.width||0,height:f&&f.height||0,setExif:function(t,n){return h?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.getBinary())):!1},writeHeaders:function(){return arguments.length?l.restore(arguments[0]):u=l.restore(u)},stripHeaders:function(e){return l.strip(e)},purge:function(){s.call(this)}}),h&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS()})}return o}),i(z,[h,u,P],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:u.LONG(t),height:u.LONG(t+=4)}):null}function o(){u&&(u.init(null),s=d=c=l=u=null)}function a(e){var t,n,i,r;return t=u.LONG(e),n=u.STRING(e+=4,4),i=e+=4,r=u.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l,d;s=i,u=new n,u.init(s),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=u.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),d=r.call(this),t.extend(this,{type:"image/png",size:s.length,width:d.width,height:d.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(G,[u,h,B,z],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var f=1024,h=document.createElement("canvas");h.width=h.height=f;for(var p=h.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+f>a?a-g:f,y=0;o>y;){var w=y+f>o?o-y:f;p.clearRect(0,0,f,f),p.drawImage(e,-y,-g);var E=y*s/o+c<<0,_=Math.ceil(w*s/o),x=g*u/a/m+l<<0,b=Math.ceil(v*u/a/m);d.drawImage(h,0,0,w,v,E,x,_,b),y+=f}g+=f}h=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(X,[D,u,h,m,w,G,q,l,d],function(e,t,n,i,r,o,a,s,u){function c(){function e(){if(!E&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return E||y}function c(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function l(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function d(e){var t=this;y=new Image,y.onerror=function(){g.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src=/^data:[^;]*;base64,/.test(e)?e:l(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function h(n,i,r,o){var a=this,s,u,c=0,l=0,d,f,h,g;if(R=o,g=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(g,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(E||(E=document.createElement("canvas")),f=Math.round(d.width*s),h=Math.round(d.height*s),r?(E.width=n,E.height=i,f>n&&(c=Math.round((f-n)/2)),h>i&&(l=Math.round((h-i)/2))):(E.width=f,E.height=h),R||m(E.width,E.height,g),p.call(this,d,E,-c,-l,f,h),this.width=E.width,this.height=E.height,b=!0,void a.trigger("Resize"))}function p(e,t,n,i,r,o){if("iOS"===u.OS)a.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var s=t.getContext("2d");s.drawImage(e,n,i,r,o)}}function m(e,t,n){switch(n){case 5:case 6:case 7:case 8:E.width=t,E.height=e;break;default:E.width=e,E.height=t}var i=E.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function g(){w&&(w.purge(),w=null),_=y=E=x=null,b=!1}var v=this,y,w,E,_,x,b=!1,R=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(_=e.getSource(),void d.call(this,_)):void f.call(this,e.getSource(),function(e){r&&(_=c(e)),d.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new r(null,{name:e.name,size:e.size,type:e.type}),d.call(this,t?_=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!w&&_&&t.can("access_image_binary")&&(w=new o(_)),n={width:e().width||0,height:e().height||0,type:x.type||s.getFileMime(x.name),size:_&&_.length||x.size||0,name:x.name||"",meta:w&&w.meta||this.meta||{}}},downsize:function(){h.apply(this,arguments)},getAsCanvas:function(){return E&&(E.id=this.uid+"_canvas"),E},getAsBlob:function(e,t){return e!==this.type&&h.call(this,this.width,this.height,!1),new r(null,{name:x.name||"",type:e,data:v.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!b)return y.src;if("image/jpeg"!==e)return E.toDataURL("image/png");try{return E.toDataURL("image/jpeg",t/100)}catch(n){return E.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!b)return _||(_=c(v.getAsDataURL(e,t))),_;if("image/jpeg"!==e)_=c(v.getAsDataURL(e,t));else{var n;t||(t=90);try{n=E.toDataURL("image/jpeg",t/100)}catch(i){n=E.toDataURL("image/jpeg")}_=c(n),w&&(_=w.stripHeaders(_),R&&(w.meta&&w.meta.exif&&w.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),_=w.writeHeaders(_)),w.purge(),w=null)}return b=!1,_},destroy:function(){v=null,g.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=c}),i(j,[u,d,f,h,g],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(a){var c=this,l;a=e.extend({swf_url:t.swf_url},a),r.call(this,a,s,{access_binary:function(e){return e&&"browser"===c.mode},access_image_binary:function(e){return e&&"browser"===c.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===c.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===c.mode},return_status_code:function(t){return"browser"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===c.mode},send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"browser"===c.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===c.mode},stream_upload:function(e){return e&&"browser"===c.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===c.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+a.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+a.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="flash",u={};return r.addConstructor(s,a),u}),i(V,[j,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(W,[j],function(e){var t={init:function(e){this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=t}),i(Y,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i="",r={read:function(e,t){var r=this,o=r.getRuntime();return"readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"),r.bind("Progress",function(t,r){r&&(i+=n(r,e))}),o.shimExec.call(this,"FileReader","readAsBase64",t.uid)},getResult:function(){return i},destroy:function(){i=null}};return e.FileReader=r}),i($,[j,m],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[j,u,y,w,T,A,O],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var f=i.getBlob();f.isDetached()?u(f,function(e){f.destroy(),s(d,e)}):s(d,f)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[j,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[j,u,O,y,T],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,d,f,h,g],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(et,[Q,u,V],function(e,t,n){return e.Blob=t.extend({},n)}),i(tt,[Q],function(e){var t={init:function(e){function t(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}this.getRuntime().shimExec.call(this,"FileInput","init",t(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=t}),i(nt,[Q,f,L],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(it,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(rt,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(ot,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(at,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(st,[Q,u,K],function(e,t,n){return e.Image=t.extend({},n,{getInfo:function(){var e=this.getRuntime(),n=["tiff","exif","gps"],i={meta:{}},r=e.shimExec.call(this,"Image","getInfo");return r.meta&&t.each(n,function(e){var t=r.meta[e],n,o,a,s;if(t&&t.keys)for(i.meta[e]={},o=0,a=t.keys.length;a>o;o++)n=t.keys[o],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),i.meta[e][n]=s)}),i.width=parseInt(r.width,10),i.height=parseInt(r.height,10),i.size=parseInt(r.size,10),i.type=r.type,i.name=r.name,i}})}),i(ut,[u,h,g,d],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.version>=28||"IE"===i.browser&&i.version>=10}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:s(function(){return"Firefox"===i.browser&&i.version>=4||"Opera"===i.browser&&i.version>=12||!!~e.inArray(i.browser,["Chrome","Safari"])}()),upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ct,[ut,u,f,L,l,d],function(e,t,n,i,r,o){function a(){function e(){var r=this,l=r.getRuntime(),d,f,h,p,m,g;g=t.guid("uid_"),d=l.getShimContainer(),a&&(h=n.get(a+"_form"),h&&t.extend(h.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),t.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),t.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),t.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===o.browser&&o.version<10&&t.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var t;this.value&&(t=this.files?this.files[0]:{name:this.value},s=[t],this.onchange=function(){},e.call(r),r.bind("change",function i(){var e=n.get(g),t=n.get(g+"_form"),o;r.unbind("change",i),r.files.length&&e&&t&&(o=r.files[0],e.setAttribute("id",o.uid),t.setAttribute("id",o.uid+"_form"),t.setAttribute("target",o.uid+"_iframe")),e=t=null},998),m=p=null,r.trigger("change"))},l.can("summon_file_dialog")&&(f=n.get(c.browse_button),i.removeEvent(f,"click",r.uid),i.addEvent(f,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},r.uid)),a=g,d=h=f=null}var a,s=[],u=[],c;t.extend(this,{init:function(t){var o=this,a=o.getRuntime(),s;c=t,u=t.accept.mimes||r.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,r,u;e=n.get(t.browse_button),a.can("summon_file_dialog")&&("static"===n.getStyle(e,"position")&&(e.style.position="relative"),r=parseInt(n.getStyle(e,"z-index"),10)||1,e.style.zIndex=r,s.style.zIndex=r-1),u=a.can("summon_file_dialog")?e:s,i.addEvent(u,"mouseover",function(){o.trigger("mouseenter")},o.uid),i.addEvent(u,"mouseout",function(){o.trigger("mouseleave")},o.uid),i.addEvent(u,"mousedown",function(){o.trigger("mousedown")},o.uid),i.addEvent(n.get(t.container),"mouseup",function(){o.trigger("mouseup")},o.uid),e=null}(),e.call(this),s=null,o.trigger({type:"ready",async:!0})},getFiles:function(){return s},disable:function(e){var t;(t=n.get(a))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),r=e.getShimContainer();i.removeAllEvents(r,this.uid),i.removeAllEvents(c&&n.get(c.container),this.uid),i.removeAllEvents(c&&n.get(c.browse_button),this.uid),r&&(r.innerHTML=""),t.removeInstance(this.uid),a=s=u=c=r=t=null}})}return e.FileInput=a}),i(lt,[ut,F],function(e,t){return e.FileReader=t}),i(dt,[ut,u,f,R,h,L,y,A],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,f){function h(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),w&&p.trigger({type:"uploadprogress",loaded:w.size||1025,total:w.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,y,w;if(u=c=null,f instanceof s&&f.hasBlob()){if(w=f.getBlob(),g=w.uid,y=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),v.setAttribute("target",g+"_iframe"),m.getShimContainer().appendChild(v);f instanceof s&&f.each(function(e,n){if(e instanceof a)y&&y.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),y?v.insertBefore(i,y):v.appendChild(i)}}),v.setAttribute("action",d.url),h(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(ft,[ut,X],function(e,t){return e.Image=t}),a([u,c,l,d,f,h,p,m,g,v,y,w,E,_,x,b,R,T,A,S,O,I,L])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this);
+!function(e,t){"use strict";function n(e,t){for(var n,i=[],r=0;r<e.length;++r){if(n=s[e[r]]||o(e[r]),!n)throw"module definition dependecy not found: "+e[r];i.push(n)}t.apply(null,i)}function i(e,i,r){if("string"!=typeof e)throw"invalid module definition, module id must be defined and be a string";if(i===t)throw"invalid module definition, dependencies must be specified";if(r===t)throw"invalid module definition, definition function must be specified";n(i,function(){s[e]=r.apply(null,arguments)})}function r(e){return!!s[e]}function o(t){for(var n=e,i=t.split(/[.\/]/),r=0;r<i.length;++r){if(!n[i[r]])return;n=n[i[r]]}return n}function a(n){for(var i=0;i<n.length;i++){for(var r=e,o=n[i],a=o.split(/[.\/]/),u=0;u<a.length-1;++u)r[a[u]]===t&&(r[a[u]]={}),r=r[a[u]];r[a[a.length-1]]=s[o]}}var s={},u="moxie/core/utils/Basic",c="moxie/core/utils/Env",l="moxie/core/I18n",d="moxie/core/utils/Mime",h="moxie/core/utils/Dom",f="moxie/core/Exceptions",p="moxie/core/EventTarget",m="moxie/runtime/Runtime",g="moxie/runtime/RuntimeClient",v="moxie/file/FileInput",w="moxie/core/utils/Encode",y="moxie/file/Blob",E="moxie/file/File",_="moxie/file/FileDrop",b="moxie/file/FileReader",x="moxie/core/utils/Url",R="moxie/runtime/RuntimeTarget",A="moxie/file/FileReaderSync",I="moxie/xhr/FormData",T="moxie/xhr/XMLHttpRequest",S="moxie/runtime/Transporter",O="moxie/image/Image",D="moxie/runtime/html5/Runtime",N="moxie/core/utils/Events",L="moxie/runtime/html5/file/FileInput",C="moxie/runtime/html5/file/Blob",M="moxie/runtime/html5/file/FileDrop",F="moxie/runtime/html5/file/FileReader",P="moxie/runtime/html5/xhr/XMLHttpRequest",H="moxie/runtime/html5/utils/BinaryReader",B="moxie/runtime/html5/image/JPEGHeaders",k="moxie/runtime/html5/image/ExifParser",U="moxie/runtime/html5/image/JPEG",G="moxie/runtime/html5/image/PNG",z="moxie/runtime/html5/image/ImageInfo",q="moxie/runtime/html5/image/MegaPixel",j="moxie/runtime/html5/image/Image",X="moxie/runtime/flash/Runtime",V="moxie/runtime/flash/file/FileInput",W="moxie/runtime/flash/file/Blob",Y="moxie/runtime/flash/file/FileReader",$="moxie/runtime/flash/file/FileReaderSync",J="moxie/runtime/flash/xhr/XMLHttpRequest",Z="moxie/runtime/flash/runtime/Transporter",K="moxie/runtime/flash/image/Image",Q="moxie/runtime/silverlight/Runtime",ee="moxie/runtime/silverlight/file/FileInput",te="moxie/runtime/silverlight/file/Blob",ne="moxie/runtime/silverlight/file/FileDrop",ie="moxie/runtime/silverlight/file/FileReader",re="moxie/runtime/silverlight/file/FileReaderSync",oe="moxie/runtime/silverlight/xhr/XMLHttpRequest",ae="moxie/runtime/silverlight/runtime/Transporter",se="moxie/runtime/silverlight/image/Image",ue="moxie/runtime/html4/Runtime",ce="moxie/runtime/html4/file/FileInput",le="moxie/runtime/html4/file/FileReader",de="moxie/runtime/html4/xhr/XMLHttpRequest",he="moxie/runtime/html4/image/Image";i(u,[],function(){var e=function(e){var t;return e===t?"undefined":null===e?"null":e.nodeType?"node":{}.toString.call(e).match(/\s([a-z|A-Z]+)/)[1].toLowerCase()},t=function(i){var r;return n(arguments,function(o,s){s>0&&n(o,function(n,o){n!==r&&(e(i[o])===e(n)&&~a(e(n),["array","object"])?t(i[o],n):i[o]=n)})}),i},n=function(t,n){var i,r,o,a;if(t)if("number"===e(t.length)){for(o=0,i=t.length;i>o;o++)if(n(t[o],o)===!1)return}else if("object"===e(t))for(r in t)if(t.hasOwnProperty(r)&&n(t[r],r)===!1)return},i=function(t){var n;if(!t||"object"!==e(t))return!0;for(n in t)return!1;return!0},r=function(t,n){function i(r){"function"===e(t[r])&&t[r](function(e){++r<o&&!e?i(r):n(e)})}var r=0,o=t.length;"function"!==e(n)&&(n=function(){}),t&&t.length||n(),i(r)},o=function(e,t){var i=0,r=e.length,o=new Array(r);n(e,function(e,n){e(function(e){if(e)return t(e);var a=[].slice.call(arguments);a.shift(),o[n]=a,i++,i===r&&(o.unshift(null),t.apply(this,o))})})},a=function(e,t){if(t){if(Array.prototype.indexOf)return Array.prototype.indexOf.call(t,e);for(var n=0,i=t.length;i>n;n++)if(t[n]===e)return n}return-1},s=function(t,n){var i=[];"array"!==e(t)&&(t=[t]),"array"!==e(n)&&(n=[n]);for(var r in t)-1===a(t[r],n)&&i.push(t[r]);return i.length?i:!1},u=function(e,t){var i=[];return n(e,function(e){-1!==a(e,t)&&i.push(e)}),i.length?i:null},c=function(e){var t,n=[];for(t=0;t<e.length;t++)n[t]=e[t];return n},l=function(){var e=0;return function(t){var n=(new Date).getTime().toString(32),i;for(i=0;5>i;i++)n+=Math.floor(65535*Math.random()).toString(32);return(t||"o_")+n+(e++).toString(32)}}(),d=function(e){return e?String.prototype.trim?String.prototype.trim.call(e):e.toString().replace(/^\s*/,"").replace(/\s*$/,""):e},h=function(e){if("string"!=typeof e)return e;var t={t:1099511627776,g:1073741824,m:1048576,k:1024},n;return e=/^([0-9\.]+)([tmgk]?)$/.exec(e.toLowerCase().replace(/[^0-9\.tmkg]/g,"")),n=e[2],e=+e[1],t.hasOwnProperty(n)&&(e*=t[n]),Math.floor(e)},f=function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e(t)?t:""})};return{guid:l,typeOf:e,extend:t,each:n,isEmptyObj:i,inSeries:r,inParallel:o,inArray:a,arrayDiff:s,arrayIntersect:u,toArray:c,trim:d,sprintf:f,parseSizeStr:h}}),i(c,[u],function(e){function t(e,t,n){var i=0,r=0,o=0,a={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},s=function(e){return e=(""+e).replace(/[_\-+]/g,"."),e=e.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,"."),e.length?e.split("."):[-8]},u=function(e){return e?isNaN(e)?a[e]||-7:parseInt(e,10):0};for(e=s(e),t=s(t),r=Math.max(e.length,t.length),i=0;r>i;i++)if(e[i]!=t[i]){if(e[i]=u(e[i]),t[i]=u(t[i]),e[i]<t[i]){o=-1;break}if(e[i]>t[i]){o=1;break}}if(!n)return o;switch(n){case">":case"gt":return o>0;case">=":case"ge":return o>=0;case"<=":case"le":return 0>=o;case"==":case"=":case"eq":return 0===o;case"<>":case"!=":case"ne":return 0!==o;case"":case"<":case"lt":return 0>o;default:return null}}var n=function(e){var t="",n="?",i="function",r="undefined",o="object",a="major",s="model",u="name",c="type",l="vendor",d="version",h="architecture",f="console",p="mobile",m="tablet",g={has:function(e,t){return-1!==t.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()}},v={rgx:function(){for(var t,n=0,a,s,u,c,l,d,h=arguments;n<h.length;n+=2){var f=h[n],p=h[n+1];if(typeof t===r){t={};for(u in p)c=p[u],typeof c===o?t[c[0]]=e:t[c]=e}for(a=s=0;a<f.length;a++)if(l=f[a].exec(this.getUA())){for(u=0;u<p.length;u++)d=l[++s],c=p[u],typeof c===o&&c.length>0?2==c.length?typeof c[1]==i?t[c[0]]=c[1].call(this,d):t[c[0]]=c[1]:3==c.length?typeof c[1]!==i||c[1].exec&&c[1].test?t[c[0]]=d?d.replace(c[1],c[2]):e:t[c[0]]=d?c[1].call(this,d,c[2]):e:4==c.length&&(t[c[0]]=d?c[3].call(this,d.replace(c[1],c[2])):e):t[c]=d?d:e;break}if(l)break}return t},str:function(t,i){for(var r in i)if(typeof i[r]===o&&i[r].length>0){for(var a=0;a<i[r].length;a++)if(g.has(i[r][a],t))return r===n?e:r}else if(g.has(i[r],t))return r===n?e:r;return t}},w={browser:{oldsafari:{major:{1:["/8","/1","/3"],2:"/4","?":"/"},version:{"1.0":"/8",1.2:"/1",1.3:"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"}}},device:{sprint:{model:{"Evo Shift 4G":"7373KT"},vendor:{HTC:"APA",Sprint:"Sprint"}}},os:{windows:{version:{ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2000:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2",8.1:"NT 6.3",RT:"ARM"}}}},y={browser:[[/(opera\smini)\/([\w\.-]+)/i,/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i,/(opera).+version\/([\w\.]+)/i,/(opera)[\/\s]+([\w\.]+)/i],[u,d],[/\s(opr)\/([\w\.]+)/i],[[u,"Opera"],d],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,/(?:ms|\()(ie)\s([\w\.]+)/i,/(rekonq)\/([\w\.]+)*/i,/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi)\/([\w\.-]+)/i],[u,d],[/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i],[[u,"IE"],d],[/(edge)\/((\d+)?[\w\.]+)/i],[u,d],[/(yabrowser)\/([\w\.]+)/i],[[u,"Yandex"],d],[/(comodo_dragon)\/([\w\.]+)/i],[[u,/_/g," "],d],[/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,/(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i],[u,d],[/(dolfin)\/([\w\.]+)/i],[[u,"Dolphin"],d],[/((?:android.+)crmo|crios)\/([\w\.]+)/i],[[u,"Chrome"],d],[/XiaoMi\/MiuiBrowser\/([\w\.]+)/i],[d,[u,"MIUI Browser"]],[/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i],[d,[u,"Android Browser"]],[/FBAV\/([\w\.]+);/i],[d,[u,"Facebook"]],[/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i],[d,[u,"Mobile Safari"]],[/version\/([\w\.]+).+?(mobile\s?safari|safari)/i],[d,u],[/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i],[u,[d,v.str,w.browser.oldsafari.version]],[/(konqueror)\/([\w\.]+)/i,/(webkit|khtml)\/([\w\.]+)/i],[u,d],[/(navigator|netscape)\/([\w\.-]+)/i],[[u,"Netscape"],d],[/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i,/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i,/(links)\s\(([\w\.]+)/i,/(gobrowser)\/?([\w\.]+)*/i,/(ice\s?browser)\/v?([\w\._]+)/i,/(mosaic)[\/\s]([\w\.]+)/i],[u,d]],engine:[[/windows.+\sedge\/([\w\.]+)/i],[d,[u,"EdgeHTML"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i,/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i,/(icab)[\/\s]([23]\.[\d\.]+)/i],[u,d],[/rv\:([\w\.]+).*(gecko)/i],[d,u]],os:[[/microsoft\s(windows)\s(vista|xp)/i],[u,d],[/(windows)\snt\s6\.2;\s(arm)/i,/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i],[u,[d,v.str,w.os.windows.version]],[/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i],[[u,"Windows"],[d,v.str,w.os.windows.version]],[/\((bb)(10);/i],[[u,"BlackBerry"],d],[/(blackberry)\w*\/?([\w\.]+)*/i,/(tizen)[\/\s]([\w\.]+)/i,/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,/linux;.+(sailfish);/i],[u,d],[/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i],[[u,"Symbian"],d],[/\((series40);/i],[u],[/mozilla.+\(mobile;.+gecko.+firefox/i],[[u,"Firefox OS"],d],[/(nintendo|playstation)\s([wids3portablevu]+)/i,/(mint)[\/\s\(]?(\w+)*/i,/(mageia|vectorlinux)[;\s]/i,/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,/(hurd|linux)\s?([\w\.]+)*/i,/(gnu)\s?([\w\.]+)*/i],[u,d],[/(cros)\s[\w]+\s([\w\.]+\w)/i],[[u,"Chromium OS"],d],[/(sunos)\s?([\w\.]+\d)*/i],[[u,"Solaris"],d],[/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i],[u,d],[/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i],[[u,"iOS"],[d,/_/g,"."]],[/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,/(macintosh|mac(?=_powerpc)\s)/i],[[u,"Mac OS"],[d,/_/g,"."]],[/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i,/(haiku)\s(\w+)/i,/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i,/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,/(unix)\s?([\w\.]+)*/i],[u,d]]},E=function(e){var n=e||(window&&window.navigator&&window.navigator.userAgent?window.navigator.userAgent:t);this.getBrowser=function(){return v.rgx.apply(this,y.browser)},this.getEngine=function(){return v.rgx.apply(this,y.engine)},this.getOS=function(){return v.rgx.apply(this,y.os)},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS()}},this.getUA=function(){return n},this.setUA=function(e){return n=e,this},this.setUA(n)};return E}(),i=function(){var t={define_property:function(){return!1}(),create_canvas:function(){var e=document.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))}(),return_response_type:function(t){try{if(-1!==e.inArray(t,["","text","document"]))return!0;if(window.XMLHttpRequest){var n=new XMLHttpRequest;if(n.open("get","/"),"responseType"in n)return n.responseType=t,n.responseType!==t?!1:!0}}catch(i){}return!1},use_data_uri:function(){var e=new Image;return e.onload=function(){t.use_data_uri=1===e.width&&1===e.height},setTimeout(function(){e.src="data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="},1),!1}(),use_data_uri_over32kb:function(){return t.use_data_uri&&("IE"!==o.browser||o.version>=9)},use_data_uri_of:function(e){return t.use_data_uri&&33e3>e||t.use_data_uri_over32kb()},use_fileinput:function(){if(navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/))return!1;var e=document.createElement("input");return e.setAttribute("type","file"),!e.disabled}};return function(n){var i=[].slice.call(arguments);return i.shift(),"function"===e.typeOf(t[n])?t[n].apply(this,i):!!t[n]}}(),r=(new n).getResult(),o={can:i,uaParser:n,browser:r.browser.name,version:r.browser.version,os:r.os.name,osVersion:r.os.version,verComp:t,swf_url:"../flash/Moxie.swf",xap_url:"../silverlight/Moxie.xap",global_event_dispatcher:"moxie.core.EventTarget.instance.dispatchEvent"};return o.OS=o.os,o}),i(l,[u],function(e){var t={};return{addI18n:function(n){return e.extend(t,n)},translate:function(e){return t[e]||e},_:function(e){return this.translate(e)},sprintf:function(t){var n=[].slice.call(arguments,1);return t.replace(/%[a-z]/g,function(){var t=n.shift();return"undefined"!==e.typeOf(t)?t:""})}}}),i(d,[u,l],function(e,t){var n="application/msword,doc dot,application/pdf,pdf,application/pgp-signature,pgp,application/postscript,ps ai eps,application/rtf,rtf,application/vnd.ms-excel,xls xlb,application/vnd.ms-powerpoint,ppt pps pot,application/zip,zip,application/x-shockwave-flash,swf swfl,application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx,application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx,application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx,application/vnd.openxmlformats-officedocument.presentationml.template,potx,application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx,application/x-javascript,js,application/json,json,audio/mpeg,mp3 mpga mpega mp2,audio/x-wav,wav,audio/x-m4a,m4a,audio/ogg,oga ogg,audio/aiff,aiff aif,audio/flac,flac,audio/aac,aac,audio/ac3,ac3,audio/x-ms-wma,wma,image/bmp,bmp,image/gif,gif,image/jpeg,jpg jpeg jpe,image/photoshop,psd,image/png,png,image/svg+xml,svg svgz,image/tiff,tiff tif,text/plain,asc txt text diff log,text/html,htm html xhtml,text/css,css,text/csv,csv,text/rtf,rtf,video/mpeg,mpeg mpg mpe m2v,video/quicktime,qt mov,video/mp4,mp4,video/x-m4v,m4v,video/x-flv,flv,video/x-ms-wmv,wmv,video/avi,avi,video/webm,webm,video/3gpp,3gpp 3gp,video/3gpp2,3g2,video/vnd.rn-realvideo,rv,video/ogg,ogv,video/x-matroska,mkv,application/vnd.oasis.opendocument.formula-template,otf,application/octet-stream,exe",i={mimes:{},extensions:{},addMimeType:function(e){var t=e.split(/,/),n,i,r;for(n=0;n<t.length;n+=2){for(r=t[n+1].split(/ /),i=0;i<r.length;i++)this.mimes[r[i]]=t[n];this.extensions[t[n]]=r}},extList2mimes:function(t,n){var i=this,r,o,a,s,u=[];for(o=0;o<t.length;o++)for(r=t[o].extensions.split(/\s*,\s*/),a=0;a<r.length;a++){if("*"===r[a])return[];if(s=i.mimes[r[a]],s&&-1===e.inArray(s,u)&&u.push(s),n&&/^\w+$/.test(r[a]))u.push("."+r[a]);else if(!s)return[]}return u},mimes2exts:function(t){var n=this,i=[];return e.each(t,function(t){if("*"===t)return i=[],!1;var r=t.match(/^(\w+)\/(\*|\w+)$/);r&&("*"===r[2]?e.each(n.extensions,function(e,t){new RegExp("^"+r[1]+"/").test(t)&&[].push.apply(i,n.extensions[t])}):n.extensions[t]&&[].push.apply(i,n.extensions[t]))}),i},mimes2extList:function(n){var i=[],r=[];return"string"===e.typeOf(n)&&(n=e.trim(n).split(/\s*,\s*/)),r=this.mimes2exts(n),i.push({title:t.translate("Files"),extensions:r.length?r.join(","):"*"}),i.mimes=n,i},getFileExtension:function(e){var t=e&&e.match(/\.([^.]+)$/);return t?t[1].toLowerCase():""},getFileMime:function(e){return this.mimes[this.getFileExtension(e)]||""}};return i.addMimeType(n),i}),i(h,[c],function(e){var t=function(e){return"string"!=typeof e?e:document.getElementById(e)},n=function(e,t){if(!e.className)return!1;var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");return n.test(e.className)},i=function(e,t){n(e,t)||(e.className=e.className?e.className.replace(/\s+$/,"")+" "+t:t)},r=function(e,t){if(e.className){var n=new RegExp("(^|\\s+)"+t+"(\\s+|$)");e.className=e.className.replace(n,function(e,t,n){return" "===t&&" "===n?" ":""})}},o=function(e,t){return e.currentStyle?e.currentStyle[t]:window.getComputedStyle?window.getComputedStyle(e,null)[t]:void 0},a=function(t,n){function i(e){var t,n,i=0,r=0;return e&&(n=e.getBoundingClientRect(),t="CSS1Compat"===s.compatMode?s.documentElement:s.body,i=n.left+t.scrollLeft,r=n.top+t.scrollTop),{x:i,y:r}}var r=0,o=0,a,s=document,u,c;if(t=t,n=n||s.body,t&&t.getBoundingClientRect&&"IE"===e.browser&&(!s.documentMode||s.documentMode<8))return u=i(t),c=i(n),{x:u.x-c.x,y:u.y-c.y};for(a=t;a&&a!=n&&a.nodeType;)r+=a.offsetLeft||0,o+=a.offsetTop||0,a=a.offsetParent;for(a=t.parentNode;a&&a!=n&&a.nodeType;)r-=a.scrollLeft||0,o-=a.scrollTop||0,a=a.parentNode;return{x:r,y:o}},s=function(e){return{w:e.offsetWidth||e.clientWidth,h:e.offsetHeight||e.clientHeight}};return{get:t,hasClass:n,addClass:i,removeClass:r,getStyle:o,getPos:a,getSize:s}}),i(f,[u],function(e){function t(e,t){var n;for(n in e)if(e[n]===t)return n;return null}return{RuntimeError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": RuntimeError "+this.code}var i={NOT_INIT_ERR:1,NOT_SUPPORTED_ERR:9,JS_ERR:4};return e.extend(n,i),n.prototype=Error.prototype,n}(),OperationNotAllowedException:function(){function t(e){this.code=e,this.name="OperationNotAllowedException"}return e.extend(t,{NOT_ALLOWED_ERR:1}),t.prototype=Error.prototype,t}(),ImageError:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": ImageError "+this.code}var i={WRONG_FORMAT:1,MAX_RESOLUTION_ERR:2,INVALID_META_ERR:3};return e.extend(n,i),n.prototype=Error.prototype,n}(),FileException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": FileException "+this.code}var i={NOT_FOUND_ERR:1,SECURITY_ERR:2,ABORT_ERR:3,NOT_READABLE_ERR:4,ENCODING_ERR:5,NO_MODIFICATION_ALLOWED_ERR:6,INVALID_STATE_ERR:7,SYNTAX_ERR:8};return e.extend(n,i),n.prototype=Error.prototype,n}(),DOMException:function(){function n(e){this.code=e,this.name=t(i,e),this.message=this.name+": DOMException "+this.code}var i={INDEX_SIZE_ERR:1,DOMSTRING_SIZE_ERR:2,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,INVALID_CHARACTER_ERR:5,NO_DATA_ALLOWED_ERR:6,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INUSE_ATTRIBUTE_ERR:10,INVALID_STATE_ERR:11,SYNTAX_ERR:12,INVALID_MODIFICATION_ERR:13,NAMESPACE_ERR:14,INVALID_ACCESS_ERR:15,VALIDATION_ERR:16,TYPE_MISMATCH_ERR:17,SECURITY_ERR:18,NETWORK_ERR:19,ABORT_ERR:20,URL_MISMATCH_ERR:21,QUOTA_EXCEEDED_ERR:22,TIMEOUT_ERR:23,INVALID_NODE_TYPE_ERR:24,DATA_CLONE_ERR:25};return e.extend(n,i),n.prototype=Error.prototype,n}(),EventException:function(){function t(e){this.code=e,this.name="EventException"}return e.extend(t,{UNSPECIFIED_EVENT_TYPE_ERR:0}),t.prototype=Error.prototype,t}()}}),i(p,[c,f,u],function(e,t,n){function i(){var e={};n.extend(this,{uid:null,init:function(){this.uid||(this.uid=n.guid("uid_"))},addEventListener:function(t,i,r,o){var a=this,s;return this.hasOwnProperty("uid")||(this.uid=n.guid("uid_")),t=n.trim(t),/\s/.test(t)?void n.each(t.split(/\s+/),function(e){a.addEventListener(e,i,r,o)}):(t=t.toLowerCase(),r=parseInt(r,10)||0,s=e[this.uid]&&e[this.uid][t]||[],s.push({fn:i,priority:r,scope:o||this}),e[this.uid]||(e[this.uid]={}),void(e[this.uid][t]=s))},hasEventListener:function(t){var n=t?e[this.uid]&&e[this.uid][t]:e[this.uid];return n?n:!1},removeEventListener:function(t,i){t=t.toLowerCase();var r=e[this.uid]&&e[this.uid][t],o;if(r){if(i){for(o=r.length-1;o>=0;o--)if(r[o].fn===i){r.splice(o,1);break}}else r=[];r.length||(delete e[this.uid][t],n.isEmptyObj(e[this.uid])&&delete e[this.uid])}},removeAllEventListeners:function(){e[this.uid]&&delete e[this.uid]},dispatchEvent:function(i){var r,o,a,s,u={},c=!0,l;if("string"!==n.typeOf(i)){if(s=i,"string"!==n.typeOf(s.type))throw new t.EventException(t.EventException.UNSPECIFIED_EVENT_TYPE_ERR);i=s.type,s.total!==l&&s.loaded!==l&&(u.total=s.total,u.loaded=s.loaded),u.async=s.async||!1}if(-1!==i.indexOf("::")?!function(e){r=e[0],i=e[1]}(i.split("::")):r=this.uid,i=i.toLowerCase(),o=e[r]&&e[r][i]){o.sort(function(e,t){return t.priority-e.priority}),a=[].slice.call(arguments),a.shift(),u.type=i,a.unshift(u);var d=[];n.each(o,function(e){a[0].target=e.scope,d.push(u.async?function(t){setTimeout(function(){t(e.fn.apply(e.scope,a)===!1)},1)}:function(t){t(e.fn.apply(e.scope,a)===!1)})}),d.length&&n.inSeries(d,function(e){c=!e})}return c},bind:function(){this.addEventListener.apply(this,arguments)},unbind:function(){this.removeEventListener.apply(this,arguments)},unbindAll:function(){this.removeAllEventListeners.apply(this,arguments)},trigger:function(){return this.dispatchEvent.apply(this,arguments)},handleEventProps:function(e){var t=this;this.bind(e.join(" "),function(e){var t="on"+e.type.toLowerCase();"function"===n.typeOf(this[t])&&this[t].apply(this,arguments)}),n.each(e,function(e){e="on"+e.toLowerCase(e),"undefined"===n.typeOf(t[e])&&(t[e]=null)})}})}return i.instance=new i,i}),i(m,[c,u,h,p],function(e,t,n,i){function r(e,i,o,s,u){var c=this,l,d=t.guid(i+"_"),h=u||"browser";e=e||{},a[d]=this,o=t.extend({access_binary:!1,access_image_binary:!1,display_media:!1,do_cors:!1,drag_and_drop:!1,filter_by_extension:!0,resize_image:!1,report_upload_progress:!1,return_response_headers:!1,return_response_type:!1,return_status_code:!0,send_custom_headers:!1,select_file:!1,select_folder:!1,select_multiple:!0,send_binary_string:!1,send_browser_cookies:!0,send_multipart:!0,slice_blob:!1,stream_upload:!1,summon_file_dialog:!1,upload_filesize:!0,use_http_method:!0},o),e.preferred_caps&&(h=r.getMode(s,e.preferred_caps,h)),l=function(){var e={};return{exec:function(t,n,i,r){return l[n]&&(e[t]||(e[t]={context:this,instance:new l[n]}),e[t].instance[i])?e[t].instance[i].apply(this,r):void 0},removeInstance:function(t){delete e[t]},removeAllInstances:function(){var n=this;t.each(e,function(e,i){"function"===t.typeOf(e.instance.destroy)&&e.instance.destroy.call(e.context),n.removeInstance(i)})}}}(),t.extend(this,{initialized:!1,uid:d,type:i,mode:r.getMode(s,e.required_caps,h),shimid:d+"_container",clients:0,options:e,can:function(e,n){var i=arguments[2]||o;if("string"===t.typeOf(e)&&"undefined"===t.typeOf(n)&&(e=r.parseCaps(e)),"object"===t.typeOf(e)){for(var a in e)if(!this.can(a,e[a],i))return!1;return!0}return"function"===t.typeOf(i[e])?i[e].call(this,n):n===i[e]},getShimContainer:function(){var e,i=n.get(this.shimid);return i||(e=this.options.container?n.get(this.options.container):document.body,i=document.createElement("div"),i.id=this.shimid,i.className="moxie-shim moxie-shim-"+this.type,t.extend(i.style,{position:"absolute",top:"0px",left:"0px",width:"1px",height:"1px",overflow:"hidden"}),e.appendChild(i),e=null),i},getShim:function(){return l},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec.call(this,this.uid,e,t,n)},exec:function(e,t){var n=[].slice.call(arguments,2);return c[e]&&c[e][t]?c[e][t].apply(this,n):c.shimExec.apply(this,arguments)},destroy:function(){if(c){var e=n.get(this.shimid);e&&e.parentNode.removeChild(e),l&&l.removeAllInstances(),this.unbindAll(),delete a[this.uid],this.uid=null,d=c=l=e=null}}}),this.mode&&e.required_caps&&!this.can(e.required_caps)&&(this.mode=!1)}var o={},a={};return r.order="html5,flash,silverlight,html4",r.getRuntime=function(e){return a[e]?a[e]:!1},r.addConstructor=function(e,t){t.prototype=i.instance,o[e]=t},r.getConstructor=function(e){return o[e]||null},r.getInfo=function(e){var t=r.getRuntime(e);return t?{uid:t.uid,type:t.type,mode:t.mode,can:function(){return t.can.apply(t,arguments)}}:null},r.parseCaps=function(e){var n={};return"string"!==t.typeOf(e)?e||{}:(t.each(e.split(","),function(e){n[e]=!0}),n)},r.can=function(e,t){var n,i=r.getConstructor(e),o;return i?(n=new i({required_caps:t}),o=n.mode,n.destroy(),!!o):!1},r.thatCan=function(e,t){var n=(t||r.order).split(/\s*,\s*/);for(var i in n)if(r.can(n[i],e))return n[i];return null},r.getMode=function(e,n,i){var r=null;if("undefined"===t.typeOf(i)&&(i="browser"),n&&!t.isEmptyObj(e)){if(t.each(n,function(n,i){if(e.hasOwnProperty(i)){var o=e[i](n);if("string"==typeof o&&(o=[o]),r){if(!(r=t.arrayIntersect(r,o)))return r=!1}else r=o}}),r)return-1!==t.inArray(i,r)?i:r[0];if(r===!1)return!1}return i},r.capTrue=function(){return!0},r.capFalse=function(){return!1},r.capTest=function(e){return function(){return!!e}},r}),i(g,[c,f,u,m],function(e,t,n,i){return function r(){var e;n.extend(this,{connectRuntime:function(r){function o(n){var s,u;return n.length?(s=n.shift().toLowerCase(),(u=i.getConstructor(s))?(e=new u(r),e.bind("Init",function(){e.initialized=!0,setTimeout(function(){e.clients++,a.trigger("RuntimeInit",e)},1)}),e.bind("Error",function(){e.destroy(),o(n)}),e.mode?void e.init():void e.trigger("Error")):void o(n)):(a.trigger("RuntimeError",new t.RuntimeError(t.RuntimeError.NOT_INIT_ERR)),void(e=null))}var a=this,s;if("string"===n.typeOf(r)?s=r:"string"===n.typeOf(r.ruid)&&(s=r.ruid),s){if(e=i.getRuntime(s))return e.clients++,e;throw new t.RuntimeError(t.RuntimeError.NOT_INIT_ERR)}o((r.runtime_order||i.order).split(/\s*,\s*/))},disconnectRuntime:function(){e&&--e.clients<=0&&e.destroy(),e=null},getRuntime:function(){return e&&e.uid?e:e=null},exec:function(){return e?e.exec.apply(this,arguments):null}})}}),i(v,[u,c,d,h,f,p,l,m,g],function(e,t,n,i,r,o,a,s,u){function c(t){var o=this,c,d,h;if(-1!==e.inArray(e.typeOf(t),["string","node"])&&(t={browse_button:t}),d=i.get(t.browse_button),!d)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR);h={accept:[{title:a.translate("All Files"),extensions:"*"}],name:"file",multiple:!1,required_caps:!1,container:d.parentNode||document.body},t=e.extend({},h,t),"string"==typeof t.required_caps&&(t.required_caps=s.parseCaps(t.required_caps)),"string"==typeof t.accept&&(t.accept=n.mimes2extList(t.accept)),c=i.get(t.container),c||(c=document.body),"static"===i.getStyle(c,"position")&&(c.style.position="relative"),c=d=null,u.call(o),e.extend(o,{uid:e.guid("uid_"),ruid:null,shimid:null,files:null,init:function(){o.bind("RuntimeInit",function(n,r){o.ruid=r.uid,o.shimid=r.shimid,o.bind("Ready",function(){o.trigger("Refresh")},999),o.bind("Refresh",function(){var n,o,a,s;a=i.get(t.browse_button),s=i.get(r.shimid),a&&(n=i.getPos(a,i.get(t.container)),o=i.getSize(a),s&&e.extend(s.style,{top:n.y+"px",left:n.x+"px",width:o.w+"px",height:o.h+"px"})),s=a=null}),r.exec.call(o,"FileInput","init",t)}),o.connectRuntime(e.extend({},t,{required_caps:{select_file:!0}}))},disable:function(t){var n=this.getRuntime();n&&n.exec.call(this,"FileInput","disable","undefined"===e.typeOf(t)?!0:t)},refresh:function(){o.trigger("Refresh")},destroy:function(){var t=this.getRuntime();t&&(t.exec.call(this,"FileInput","destroy"),this.disconnectRuntime()),"array"===e.typeOf(this.files)&&e.each(this.files,function(e){e.destroy()}),this.files=null,this.unbindAll()}}),this.handleEventProps(l)}var l=["ready","change","cancel","mouseenter","mouseleave","mousedown","mouseup"];return c.prototype=o.instance,c}),i(w,[],function(){var e=function(e){return unescape(encodeURIComponent(e))},t=function(e){return decodeURIComponent(escape(e))},n=function(e,n){if("function"==typeof window.atob)return n?t(window.atob(e)):window.atob(e);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,h=0,f=0,p="",m=[];if(!e)return e;e+="";do s=i.indexOf(e.charAt(h++)),u=i.indexOf(e.charAt(h++)),c=i.indexOf(e.charAt(h++)),l=i.indexOf(e.charAt(h++)),d=s<<18|u<<12|c<<6|l,r=d>>16&255,o=d>>8&255,a=255&d,64==c?m[f++]=String.fromCharCode(r):64==l?m[f++]=String.fromCharCode(r,o):m[f++]=String.fromCharCode(r,o,a);while(h<e.length);return p=m.join(""),n?t(p):p},i=function(t,n){if(n&&(t=e(t)),"function"==typeof window.btoa)return window.btoa(t);var i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",r,o,a,s,u,c,l,d,h=0,f=0,p="",m=[];if(!t)return t;do r=t.charCodeAt(h++),o=t.charCodeAt(h++),a=t.charCodeAt(h++),d=r<<16|o<<8|a,s=d>>18&63,u=d>>12&63,c=d>>6&63,l=63&d,m[f++]=i.charAt(s)+i.charAt(u)+i.charAt(c)+i.charAt(l);while(h<t.length);p=m.join("");var g=t.length%3;return(g?p.slice(0,g-3):p)+"===".slice(g||3)};return{utf8_encode:e,utf8_decode:t,atob:n,btoa:i}}),i(y,[u,w,g],function(e,t,n){function i(o,a){function s(t,n,o){var a,s=r[this.uid];return"string"===e.typeOf(s)&&s.length?(a=new i(null,{type:o,size:n-t}),a.detach(s.substr(t,a.size)),a):null}n.call(this),o&&this.connectRuntime(o),a?"string"===e.typeOf(a)&&(a={data:a}):a={},e.extend(this,{uid:a.uid||e.guid("uid_"),ruid:o,size:a.size||0,type:a.type||"",slice:function(e,t,n){return this.isDetached()?s.apply(this,arguments):this.getRuntime().exec.call(this,"Blob","slice",this.getSource(),e,t,n)},getSource:function(){return r[this.uid]?r[this.uid]:null},detach:function(e){if(this.ruid&&(this.getRuntime().exec.call(this,"Blob","destroy"),this.disconnectRuntime(),this.ruid=null),e=e||"","data:"==e.substr(0,5)){var n=e.indexOf(";base64,");this.type=e.substring(5,n),e=t.atob(e.substring(n+8))}this.size=e.length,r[this.uid]=e},isDetached:function(){return!this.ruid&&"string"===e.typeOf(r[this.uid])},destroy:function(){this.detach(),delete r[this.uid]}}),a.data?this.detach(a.data):r[this.uid]=a}var r={};return i}),i(E,[u,d,y],function(e,t,n){function i(i,r){r||(r={}),n.apply(this,arguments),this.type||(this.type=t.getFileMime(r.name));var o;if(r.name)o=r.name.replace(/\\/g,"/"),o=o.substr(o.lastIndexOf("/")+1);else if(this.type){var a=this.type.split("/")[0];o=e.guid((""!==a?a:"file")+"_"),t.extensions[this.type]&&(o+="."+t.extensions[this.type][0])}e.extend(this,{name:o||e.guid("file_"),relativePath:"",lastModifiedDate:r.lastModifiedDate||(new Date).toLocaleString()})}return i.prototype=n.prototype,i}),i(_,[l,h,f,u,c,E,g,p,d],function(e,t,n,i,r,o,a,s,u){function c(n){var r=this,o;"string"==typeof n&&(n={drop_zone:n}),o={accept:[{title:e.translate("All Files"),extensions:"*"}],required_caps:{drag_and_drop:!0}},n="object"==typeof n?i.extend({},o,n):o,n.container=t.get(n.drop_zone)||document.body,"static"===t.getStyle(n.container,"position")&&(n.container.style.position="relative"),"string"==typeof n.accept&&(n.accept=u.mimes2extList(n.accept)),a.call(r),i.extend(r,{uid:i.guid("uid_"),ruid:null,files:null,init:function(){r.bind("RuntimeInit",function(e,t){r.ruid=t.uid,t.exec.call(r,"FileDrop","init",n),r.dispatchEvent("ready")}),r.connectRuntime(n)},destroy:function(){var e=this.getRuntime();e&&(e.exec.call(this,"FileDrop","destroy"),this.disconnectRuntime()),this.files=null,this.unbindAll()}}),this.handleEventProps(l)}var l=["ready","dragenter","dragleave","drop","error"];return c.prototype=s.instance,c}),i(b,[u,w,f,p,y,g],function(e,t,n,i,r,o){function a(){function i(e,i){var o=this;if(this.trigger("loadstart"),this.readyState===a.LOADING)return this.trigger("error",new n.DOMException(n.DOMException.INVALID_STATE_ERR)),void this.trigger("loadend");if(!(i instanceof r))return this.trigger("error",new n.DOMException(n.DOMException.NOT_FOUND_ERR)),void this.trigger("loadend");if(this.result=null,this.readyState=a.LOADING,i.isDetached()){var s=i.getSource();switch(e){case"readAsText":case"readAsBinaryString":this.result=s;break;case"readAsDataURL":this.result="data:"+i.type+";base64,"+t.btoa(s)}this.readyState=a.DONE,this.trigger("load"),this.trigger("loadend")}else this.connectRuntime(i.ruid),this.exec("FileReader","read",e,i)}o.call(this),e.extend(this,{uid:e.guid("uid_"),readyState:a.EMPTY,result:null,error:null,readAsBinaryString:function(e){i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){i.call(this,"readAsDataURL",e)},readAsText:function(e){i.call(this,"readAsText",e);
+},abort:function(){this.result=null,-1===e.inArray(this.readyState,[a.EMPTY,a.DONE])&&(this.readyState===a.LOADING&&(this.readyState=a.DONE),this.exec("FileReader","abort"),this.trigger("abort"),this.trigger("loadend"))},destroy:function(){this.abort(),this.exec("FileReader","destroy"),this.disconnectRuntime(),this.unbindAll()}}),this.handleEventProps(s),this.bind("Error",function(e,t){this.readyState=a.DONE,this.error=t},999),this.bind("Load",function(e){this.readyState=a.DONE},999)}var s=["loadstart","progress","load","abort","error","loadend"];return a.EMPTY=0,a.LOADING=1,a.DONE=2,a.prototype=i.instance,a}),i(x,[],function(){var e=function(t,n){for(var i=["source","scheme","authority","userInfo","user","pass","host","port","relative","path","directory","file","query","fragment"],r=i.length,o={http:80,https:443},a={},s=/^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\\?([^#]*))?(?:#(.*))?)/,u=s.exec(t||"");r--;)u[r]&&(a[i[r]]=u[r]);if(!a.scheme){n&&"string"!=typeof n||(n=e(n||document.location.href)),a.scheme=n.scheme,a.host=n.host,a.port=n.port;var c="";/^[^\/]/.test(a.path)&&(c=n.path,c=/\/[^\/]*\.[^\/]*$/.test(c)?c.replace(/\/[^\/]+$/,"/"):c.replace(/\/?$/,"/")),a.path=c+(a.path||"")}return a.port||(a.port=o[a.scheme]||80),a.port=parseInt(a.port,10),a.path||(a.path="/"),delete a.source,a},t=function(t){var n={http:80,https:443},i="object"==typeof t?t:e(t);return i.scheme+"://"+i.host+(i.port!==n[i.scheme]?":"+i.port:"")+i.path+(i.query?i.query:"")},n=function(t){function n(e){return[e.scheme,e.host,e.port].join("/")}return"string"==typeof t&&(t=e(t)),n(e())===n(t)};return{parseUrl:e,resolveUrl:t,hasSameOrigin:n}}),i(R,[u,g,p],function(e,t,n){function i(){this.uid=e.guid("uid_"),t.call(this),this.destroy=function(){this.disconnectRuntime(),this.unbindAll()}}return i.prototype=n.instance,i}),i(A,[u,g,w],function(e,t,n){return function(){function i(e,t){if(!t.isDetached()){var i=this.connectRuntime(t.ruid).exec.call(this,"FileReaderSync","read",e,t);return this.disconnectRuntime(),i}var r=t.getSource();switch(e){case"readAsBinaryString":return r;case"readAsDataURL":return"data:"+t.type+";base64,"+n.btoa(r);case"readAsText":for(var o="",a=0,s=r.length;s>a;a++)o+=String.fromCharCode(r[a]);return o}}t.call(this),e.extend(this,{uid:e.guid("uid_"),readAsBinaryString:function(e){return i.call(this,"readAsBinaryString",e)},readAsDataURL:function(e){return i.call(this,"readAsDataURL",e)},readAsText:function(e){return i.call(this,"readAsText",e)}})}}),i(I,[f,u,y],function(e,t,n){function i(){var e,i=[];t.extend(this,{append:function(r,o){var a=this,s=t.typeOf(o);o instanceof n?e={name:r,value:o}:"array"===s?(r+="[]",t.each(o,function(e){a.append(r,e)})):"object"===s?t.each(o,function(e,t){a.append(r+"["+t+"]",e)}):"null"===s||"undefined"===s||"number"===s&&isNaN(o)?a.append(r,"false"):i.push({name:r,value:o.toString()})},hasBlob:function(){return!!this.getBlob()},getBlob:function(){return e&&e.value||null},getBlobName:function(){return e&&e.name||null},each:function(n){t.each(i,function(e){n(e.value,e.name)}),e&&n(e.value,e.name)},destroy:function(){e=null,i=[]}})}return i}),i(T,[u,f,p,w,x,m,R,y,A,I,c,d],function(e,t,n,i,r,o,a,s,u,c,l,d){function h(){this.uid=e.guid("uid_")}function f(){function n(e,t){return w.hasOwnProperty(e)?1===arguments.length?l.can("define_property")?w[e]:v[e]:void(l.can("define_property")?w[e]=t:v[e]=t):void 0}function u(t){function i(){B&&(B.destroy(),B=null),s.dispatchEvent("loadend"),s=null}function r(r){B.bind("LoadStart",function(e){n("readyState",f.LOADING),s.dispatchEvent("readystatechange"),s.dispatchEvent(e),O&&s.upload.dispatchEvent(e)}),B.bind("Progress",function(e){n("readyState")!==f.LOADING&&(n("readyState",f.LOADING),s.dispatchEvent("readystatechange")),s.dispatchEvent(e)}),B.bind("UploadProgress",function(e){O&&s.upload.dispatchEvent({type:"progress",lengthComputable:!1,total:e.total,loaded:e.loaded})}),B.bind("Load",function(t){n("readyState",f.DONE),n("status",Number(r.exec.call(B,"XMLHttpRequest","getStatus")||0)),n("statusText",p[n("status")]||""),n("response",r.exec.call(B,"XMLHttpRequest","getResponse",n("responseType"))),~e.inArray(n("responseType"),["text",""])?n("responseText",n("response")):"document"===n("responseType")&&n("responseXML",n("response")),k=r.exec.call(B,"XMLHttpRequest","getAllResponseHeaders"),s.dispatchEvent("readystatechange"),n("status")>0?(O&&s.upload.dispatchEvent(t),s.dispatchEvent(t)):(N=!0,s.dispatchEvent("error")),i()}),B.bind("Abort",function(e){s.dispatchEvent(e),i()}),B.bind("Error",function(e){N=!0,n("readyState",f.DONE),s.dispatchEvent("readystatechange"),D=!0,s.dispatchEvent(e),i()}),r.exec.call(B,"XMLHttpRequest","send",{url:E,method:_,async:y,user:x,password:R,headers:b,mimeType:I,encoding:A,responseType:s.responseType,withCredentials:s.withCredentials,options:H},t)}var s=this;C=(new Date).getTime(),B=new a,"string"==typeof H.required_caps&&(H.required_caps=o.parseCaps(H.required_caps)),H.required_caps=e.extend({},H.required_caps,{return_response_type:s.responseType}),t instanceof c&&(H.required_caps.send_multipart=!0),e.isEmptyObj(b)||(H.required_caps.send_custom_headers=!0),L||(H.required_caps.do_cors=!0),H.ruid?r(B.connectRuntime(H)):(B.bind("RuntimeInit",function(e,t){r(t)}),B.bind("RuntimeError",function(e,t){s.dispatchEvent("RuntimeError",t)}),B.connectRuntime(H))}function g(){n("responseText",""),n("responseXML",null),n("response",null),n("status",0),n("statusText",""),C=M=null}var v=this,w={timeout:0,readyState:f.UNSENT,withCredentials:!1,status:0,statusText:"",responseType:"",responseXML:null,responseText:null,response:null},y=!0,E,_,b={},x,R,A=null,I=null,T=!1,S=!1,O=!1,D=!1,N=!1,L=!1,C,M,F=null,P=null,H={},B,k="",U;e.extend(this,w,{uid:e.guid("uid_"),upload:new h,open:function(o,a,s,u,c){var l;if(!o||!a)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(/[\u0100-\uffff]/.test(o)||i.utf8_encode(o)!==o)throw new t.DOMException(t.DOMException.SYNTAX_ERR);if(~e.inArray(o.toUpperCase(),["CONNECT","DELETE","GET","HEAD","OPTIONS","POST","PUT","TRACE","TRACK"])&&(_=o.toUpperCase()),~e.inArray(_,["CONNECT","TRACE","TRACK"]))throw new t.DOMException(t.DOMException.SECURITY_ERR);if(a=i.utf8_encode(a),l=r.parseUrl(a),L=r.hasSameOrigin(l),E=r.resolveUrl(a),(u||c)&&!L)throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);if(x=u||l.user,R=c||l.pass,y=s||!0,y===!1&&(n("timeout")||n("withCredentials")||""!==n("responseType")))throw new t.DOMException(t.DOMException.INVALID_ACCESS_ERR);T=!y,S=!1,b={},g.call(this),n("readyState",f.OPENED),this.dispatchEvent("readystatechange")},setRequestHeader:function(r,o){var a=["accept-charset","accept-encoding","access-control-request-headers","access-control-request-method","connection","content-length","cookie","cookie2","content-transfer-encoding","date","expect","host","keep-alive","origin","referer","te","trailer","transfer-encoding","upgrade","user-agent","via"];if(n("readyState")!==f.OPENED||S)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(/[\u0100-\uffff]/.test(r)||i.utf8_encode(r)!==r)throw new t.DOMException(t.DOMException.SYNTAX_ERR);return r=e.trim(r).toLowerCase(),~e.inArray(r,a)||/^(proxy\-|sec\-)/.test(r)?!1:(b[r]?b[r]+=", "+o:b[r]=o,!0)},getAllResponseHeaders:function(){return k||""},getResponseHeader:function(t){return t=t.toLowerCase(),N||~e.inArray(t,["set-cookie","set-cookie2"])?null:k&&""!==k&&(U||(U={},e.each(k.split(/\r\n/),function(t){var n=t.split(/:\s+/);2===n.length&&(n[0]=e.trim(n[0]),U[n[0].toLowerCase()]={header:n[0],value:e.trim(n[1])})})),U.hasOwnProperty(t))?U[t].header+": "+U[t].value:null},overrideMimeType:function(i){var r,o;if(~e.inArray(n("readyState"),[f.LOADING,f.DONE]))throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(i=e.trim(i.toLowerCase()),/;/.test(i)&&(r=i.match(/^([^;]+)(?:;\scharset\=)?(.*)$/))&&(i=r[1],r[2]&&(o=r[2])),!d.mimes[i])throw new t.DOMException(t.DOMException.SYNTAX_ERR);F=i,P=o},send:function(n,r){if(H="string"===e.typeOf(r)?{ruid:r}:r?r:{},this.readyState!==f.OPENED||S)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);if(n instanceof s)H.ruid=n.ruid,I=n.type||"application/octet-stream";else if(n instanceof c){if(n.hasBlob()){var o=n.getBlob();H.ruid=o.ruid,I=o.type||"application/octet-stream"}}else"string"==typeof n&&(A="UTF-8",I="text/plain;charset=UTF-8",n=i.utf8_encode(n));this.withCredentials||(this.withCredentials=H.required_caps&&H.required_caps.send_browser_cookies&&!L),O=!T&&this.upload.hasEventListener(),N=!1,D=!n,T||(S=!0),u.call(this,n)},abort:function(){if(N=!0,T=!1,~e.inArray(n("readyState"),[f.UNSENT,f.OPENED,f.DONE]))n("readyState",f.UNSENT);else{if(n("readyState",f.DONE),S=!1,!B)throw new t.DOMException(t.DOMException.INVALID_STATE_ERR);B.getRuntime().exec.call(B,"XMLHttpRequest","abort",D),D=!0}},destroy:function(){B&&("function"===e.typeOf(B.destroy)&&B.destroy(),B=null),this.unbindAll(),this.upload&&(this.upload.unbindAll(),this.upload=null)}}),this.handleEventProps(m.concat(["readystatechange"])),this.upload.handleEventProps(m)}var p={100:"Continue",101:"Switching Protocols",102:"Processing",200:"OK",201:"Created",202:"Accepted",203:"Non-Authoritative Information",204:"No Content",205:"Reset Content",206:"Partial Content",207:"Multi-Status",226:"IM Used",300:"Multiple Choices",301:"Moved Permanently",302:"Found",303:"See Other",304:"Not Modified",305:"Use Proxy",306:"Reserved",307:"Temporary Redirect",400:"Bad Request",401:"Unauthorized",402:"Payment Required",403:"Forbidden",404:"Not Found",405:"Method Not Allowed",406:"Not Acceptable",407:"Proxy Authentication Required",408:"Request Timeout",409:"Conflict",410:"Gone",411:"Length Required",412:"Precondition Failed",413:"Request Entity Too Large",414:"Request-URI Too Long",415:"Unsupported Media Type",416:"Requested Range Not Satisfiable",417:"Expectation Failed",422:"Unprocessable Entity",423:"Locked",424:"Failed Dependency",426:"Upgrade Required",500:"Internal Server Error",501:"Not Implemented",502:"Bad Gateway",503:"Service Unavailable",504:"Gateway Timeout",505:"HTTP Version Not Supported",506:"Variant Also Negotiates",507:"Insufficient Storage",510:"Not Extended"};h.prototype=n.instance;var m=["loadstart","progress","abort","error","load","timeout","loadend"],g=1,v=2;return f.UNSENT=0,f.OPENED=1,f.HEADERS_RECEIVED=2,f.LOADING=3,f.DONE=4,f.prototype=n.instance,f}),i(S,[u,w,g,p],function(e,t,n,i){function r(){function i(){l=d=0,c=this.result=null}function o(t,n){var i=this;u=n,i.bind("TransportingProgress",function(t){d=t.loaded,l>d&&-1===e.inArray(i.state,[r.IDLE,r.DONE])&&a.call(i)},999),i.bind("TransportingComplete",function(){d=l,i.state=r.DONE,c=null,i.result=u.exec.call(i,"Transporter","getAsBlob",t||"")},999),i.state=r.BUSY,i.trigger("TransportingStarted"),a.call(i)}function a(){var e=this,n,i=l-d;h>i&&(h=i),n=t.btoa(c.substr(d,h)),u.exec.call(e,"Transporter","receive",n,l)}var s,u,c,l,d,h;n.call(this),e.extend(this,{uid:e.guid("uid_"),state:r.IDLE,result:null,transport:function(t,n,r){var a=this;if(r=e.extend({chunk_size:204798},r),(s=r.chunk_size%3)&&(r.chunk_size+=3-s),h=r.chunk_size,i.call(this),c=t,l=t.length,"string"===e.typeOf(r)||r.ruid)o.call(a,n,this.connectRuntime(r));else{var u=function(e,t){a.unbind("RuntimeInit",u),o.call(a,n,t)};this.bind("RuntimeInit",u),this.connectRuntime(r)}},abort:function(){var e=this;e.state=r.IDLE,u&&(u.exec.call(e,"Transporter","clear"),e.trigger("TransportingAborted")),i.call(e)},destroy:function(){this.unbindAll(),u=null,this.disconnectRuntime(),i.call(this)}})}return r.IDLE=0,r.BUSY=1,r.DONE=2,r.prototype=i.instance,r}),i(O,[u,h,f,A,T,m,g,S,c,p,y,E,w],function(e,t,n,i,r,o,a,s,u,c,l,d,h){function f(){function i(e){e||(e=this.exec("Image","getInfo")),this.size=e.size,this.width=e.width,this.height=e.height,this.type=e.type,this.meta=e.meta,""===this.name&&(this.name=e.name)}function c(t){var i=e.typeOf(t);try{if(t instanceof f){if(!t.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);m.apply(this,arguments)}else if(t instanceof l){if(!~e.inArray(t.type,["image/jpeg","image/png"]))throw new n.ImageError(n.ImageError.WRONG_FORMAT);g.apply(this,arguments)}else if(-1!==e.inArray(i,["blob","file"]))c.call(this,new d(null,t),arguments[1]);else if("string"===i)"data:"===t.substr(0,5)?c.call(this,new l(null,{data:t}),arguments[1]):v.apply(this,arguments);else{if("node"!==i||"img"!==t.nodeName.toLowerCase())throw new n.DOMException(n.DOMException.TYPE_MISMATCH_ERR);c.call(this,t.src,arguments[1])}}catch(r){this.trigger("error",r.code)}}function m(t,n){var i=this.connectRuntime(t.ruid);this.ruid=i.uid,i.exec.call(this,"Image","loadFromImage",t,"undefined"===e.typeOf(n)?!0:n)}function g(t,n){function i(e){r.ruid=e.uid,e.exec.call(r,"Image","loadFromBlob",t)}var r=this;r.name=t.name||"",t.isDetached()?(this.bind("RuntimeInit",function(e,t){i(t)}),n&&"string"==typeof n.required_caps&&(n.required_caps=o.parseCaps(n.required_caps)),this.connectRuntime(e.extend({required_caps:{access_image_binary:!0,resize_image:!0}},n))):i(this.connectRuntime(t.ruid))}function v(e,t){var n=this,i;i=new r,i.open("get",e),i.responseType="blob",i.onprogress=function(e){n.trigger(e)},i.onload=function(){g.call(n,i.response,!0)},i.onerror=function(e){n.trigger(e)},i.onloadend=function(){i.destroy()},i.bind("RuntimeError",function(e,t){n.trigger("RuntimeError",t)}),i.send(null,t)}a.call(this),e.extend(this,{uid:e.guid("uid_"),ruid:null,name:"",size:0,width:0,height:0,type:"",meta:{},clone:function(){this.load.apply(this,arguments)},load:function(){c.apply(this,arguments)},downsize:function(t){var i={width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90,crop:!1,preserveHeaders:!0,resample:!1};t="object"==typeof t?e.extend(i,t):e.extend(i,{width:arguments[0],height:arguments[1],crop:arguments[2],preserveHeaders:arguments[3]});try{if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);if(this.width>f.MAX_RESIZE_WIDTH||this.height>f.MAX_RESIZE_HEIGHT)throw new n.ImageError(n.ImageError.MAX_RESOLUTION_ERR);this.exec("Image","downsize",t.width,t.height,t.crop,t.preserveHeaders)}catch(r){this.trigger("error",r.code)}},crop:function(e,t,n){this.downsize(e,t,!0,n)},getAsCanvas:function(){if(!u.can("create_canvas"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);var e=this.connectRuntime(this.ruid);return e.exec.call(this,"Image","getAsCanvas")},getAsBlob:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsBlob",e||"image/jpeg",t||90)},getAsDataURL:function(e,t){if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);return this.exec("Image","getAsDataURL",e||"image/jpeg",t||90)},getAsBinaryString:function(e,t){var n=this.getAsDataURL(e,t);return h.atob(n.substring(n.indexOf("base64,")+7))},embed:function(i,r){function o(t,r){var o=this;if(u.can("create_canvas")){var l=o.getAsCanvas();if(l)return i.appendChild(l),l=null,o.destroy(),void a.trigger("embedded")}var d=o.getAsDataURL(t,r);if(!d)throw new n.ImageError(n.ImageError.WRONG_FORMAT);if(u.can("use_data_uri_of",d.length))i.innerHTML='<img src="'+d+'" width="'+o.width+'" height="'+o.height+'" />',o.destroy(),a.trigger("embedded");else{var f=new s;f.bind("TransportingComplete",function(){c=a.connectRuntime(this.result.ruid),a.bind("Embedded",function(){e.extend(c.getShimContainer().style,{top:"0px",left:"0px",width:o.width+"px",height:o.height+"px"}),c=null},999),c.exec.call(a,"ImageView","display",this.result.uid,width,height),o.destroy()}),f.transport(h.atob(d.substring(d.indexOf("base64,")+7)),t,{required_caps:{display_media:!0},runtime_order:"flash,silverlight",container:i})}}var a=this,c;r=e.extend({width:this.width,height:this.height,type:this.type||"image/jpeg",quality:90},r||{});try{if(!(i=t.get(i)))throw new n.DOMException(n.DOMException.INVALID_NODE_TYPE_ERR);if(!this.size)throw new n.DOMException(n.DOMException.INVALID_STATE_ERR);this.width>f.MAX_RESIZE_WIDTH||this.height>f.MAX_RESIZE_HEIGHT;var l=new f;return l.bind("Resize",function(){o.call(this,r.type,r.quality)}),l.bind("Load",function(){l.downsize(r)}),this.meta.thumb&&this.meta.thumb.width>=r.width&&this.meta.thumb.height>=r.height?l.load(this.meta.thumb.data):l.clone(this,!1),l}catch(d){this.trigger("error",d.code)}},destroy:function(){this.ruid&&(this.getRuntime().exec.call(this,"Image","destroy"),this.disconnectRuntime()),this.unbindAll()}}),this.handleEventProps(p),this.bind("Load Resize",function(){i.call(this)},999)}var p=["progress","load","error","resize","embedded"];return f.MAX_RESIZE_WIDTH=8192,f.MAX_RESIZE_HEIGHT=8192,f.prototype=c.instance,f}),i(D,[u,f,m,c],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue,c=e.extend({access_binary:s(window.FileReader||window.File&&window.File.getAsDataURL),access_image_binary:function(){return r.can("access_binary")&&!!a.Image},display_media:s(i.can("create_canvas")||i.can("use_data_uri_over32kb")),do_cors:s(window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest),drag_and_drop:s(function(){var e=document.createElement("div");return("draggable"in e||"ondragstart"in e&&"ondrop"in e)&&("IE"!==i.browser||i.verComp(i.version,9,">"))}()),filter_by_extension:s(function(){return"Chrome"===i.browser&&i.verComp(i.version,28,">=")||"IE"===i.browser&&i.verComp(i.version,10,">=")||"Safari"===i.browser&&i.verComp(i.version,7,">=")}()),return_response_headers:u,return_response_type:function(e){return"json"===e&&window.JSON?!0:i.can("return_response_type",e)},return_status_code:u,report_upload_progress:s(window.XMLHttpRequest&&(new XMLHttpRequest).upload),resize_image:function(){return r.can("access_binary")&&i.can("create_canvas")},select_file:function(){return i.can("use_fileinput")&&window.File},select_folder:function(){return r.can("select_file")&&"Chrome"===i.browser&&i.verComp(i.version,21,">=")},select_multiple:function(){return!(!r.can("select_file")||"Safari"===i.browser&&"Windows"===i.os||"iOS"===i.os&&i.verComp(i.osVersion,"7.0.0",">")&&i.verComp(i.osVersion,"8.0.0","<"))},send_binary_string:s(window.XMLHttpRequest&&((new XMLHttpRequest).sendAsBinary||window.Uint8Array&&window.ArrayBuffer)),send_custom_headers:s(window.XMLHttpRequest),send_multipart:function(){return!!(window.XMLHttpRequest&&(new XMLHttpRequest).upload&&window.FormData)||r.can("send_binary_string")},slice_blob:s(window.File&&(File.prototype.mozSlice||File.prototype.webkitSlice||File.prototype.slice)),stream_upload:function(){return r.can("slice_blob")&&r.can("send_multipart")},summon_file_dialog:function(){return r.can("select_file")&&("Firefox"===i.browser&&i.verComp(i.version,4,">=")||"Opera"===i.browser&&i.verComp(i.version,12,">=")||"IE"===i.browser&&i.verComp(i.version,10,">=")||!!~e.inArray(i.browser,["Chrome","Safari"]))},upload_filesize:u},arguments[2]);n.call(this,t,arguments[1]||o,c),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html5",a={};return n.addConstructor(o,r),a}),i(N,[u],function(e){function t(){this.returnValue=!1}function n(){this.cancelBubble=!0}var i={},r="moxie_"+e.guid(),o=function(o,a,s,u){var c,l;a=a.toLowerCase(),o.addEventListener?(c=s,o.addEventListener(a,c,!1)):o.attachEvent&&(c=function(){var e=window.event;e.target||(e.target=e.srcElement),e.preventDefault=t,e.stopPropagation=n,s(e)},o.attachEvent("on"+a,c)),o[r]||(o[r]=e.guid()),i.hasOwnProperty(o[r])||(i[o[r]]={}),l=i[o[r]],l.hasOwnProperty(a)||(l[a]=[]),l[a].push({func:c,orig:s,key:u})},a=function(t,n,o){var a,s;if(n=n.toLowerCase(),t[r]&&i[t[r]]&&i[t[r]][n]){a=i[t[r]][n];for(var u=a.length-1;u>=0&&(a[u].orig!==o&&a[u].key!==o||(t.removeEventListener?t.removeEventListener(n,a[u].func,!1):t.detachEvent&&t.detachEvent("on"+n,a[u].func),a[u].orig=null,a[u].func=null,a.splice(u,1),o===s));u--);if(a.length||delete i[t[r]][n],e.isEmptyObj(i[t[r]])){delete i[t[r]];try{delete t[r]}catch(c){t[r]=s}}}},s=function(t,n){t&&t[r]&&e.each(i[t[r]],function(e,i){a(t,i,n)})};return{addEvent:o,removeEvent:a,removeAllEvents:s}}),i(L,[D,E,u,h,N,d,c],function(e,t,n,i,r,o,a){function s(){var e;n.extend(this,{init:function(s){var u=this,c=u.getRuntime(),l,d,h,f,p,m;e=s,h=e.accept.mimes||o.extList2mimes(e.accept,c.can("filter_by_extension")),d=c.getShimContainer(),d.innerHTML='<input id="'+c.uid+'" type="file" style="font-size:999px;opacity:0;"'+(e.multiple&&c.can("select_multiple")?"multiple":"")+(e.directory&&c.can("select_folder")?"webkitdirectory directory":"")+(h?' accept="'+h.join(",")+'"':"")+" />",l=i.get(c.uid),n.extend(l.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),f=i.get(e.browse_button),c.can("summon_file_dialog")&&("static"===i.getStyle(f,"position")&&(f.style.position="relative"),p=parseInt(i.getStyle(f,"z-index"),10)||1,f.style.zIndex=p,d.style.zIndex=p-1,r.addEvent(f,"click",function(e){var t=i.get(c.uid);t&&!t.disabled&&t.click(),e.preventDefault()},u.uid)),m=c.can("summon_file_dialog")?f:d,r.addEvent(m,"mouseover",function(){u.trigger("mouseenter")},u.uid),r.addEvent(m,"mouseout",function(){u.trigger("mouseleave")},u.uid),r.addEvent(m,"mousedown",function(){u.trigger("mousedown")},u.uid),r.addEvent(i.get(e.container),"mouseup",function(){u.trigger("mouseup")},u.uid),l.onchange=function g(i){if(u.files=[],n.each(this.files,function(n){var i="";return e.directory&&"."==n.name?!0:(n.webkitRelativePath&&(i="/"+n.webkitRelativePath.replace(/^\//,"")),n=new t(c.uid,n),n.relativePath=i,void u.files.push(n))}),"IE"!==a.browser&&"IEMobile"!==a.browser)this.value="";else{var r=this.cloneNode(!0);this.parentNode.replaceChild(r,this),r.onchange=g}u.files.length&&u.trigger("change")},u.trigger({type:"ready",async:!0}),d=null},disable:function(e){var t=this.getRuntime(),n;(n=i.get(t.uid))&&(n.disabled=!!e)},destroy:function(){var t=this.getRuntime(),n=t.getShim(),o=t.getShimContainer();r.removeAllEvents(o,this.uid),r.removeAllEvents(e&&i.get(e.container),this.uid),r.removeAllEvents(e&&i.get(e.browse_button),this.uid),o&&(o.innerHTML=""),n.removeInstance(this.uid),e=o=n=null}})}return e.FileInput=s}),i(C,[D,y],function(e,t){function n(){function e(e,t,n){var i;if(!window.File.prototype.slice)return(i=window.File.prototype.webkitSlice||window.File.prototype.mozSlice)?i.call(e,t,n):null;try{return e.slice(),e.slice(t,n)}catch(r){return e.slice(t,n-t)}}this.slice=function(){return new t(this.getRuntime().uid,e.apply(this,arguments))}}return e.Blob=n}),i(M,[D,E,u,h,N,d],function(e,t,n,i,r,o){function a(){function e(e){if(!e.dataTransfer||!e.dataTransfer.types)return!1;var t=n.toArray(e.dataTransfer.types||[]);return-1!==n.inArray("Files",t)||-1!==n.inArray("public.file-url",t)||-1!==n.inArray("application/x-moz-file",t)}function a(e,n){if(u(e)){var i=new t(g,e);i.relativePath=n||"",f.push(i)}}function s(e){for(var t=[],i=0;i<e.length;i++)[].push.apply(t,e[i].extensions.split(/\s*,\s*/));return-1===n.inArray("*",t)?t:[]}function u(e){if(!p.length)return!0;var t=o.getFileExtension(e.name);return!t||-1!==n.inArray(t,p)}function c(e,t){var i=[];n.each(e,function(e){var t=e.webkitGetAsEntry();t&&(t.isFile?a(e.getAsFile(),t.fullPath):i.push(t))}),i.length?l(i,t):t()}function l(e,t){var i=[];n.each(e,function(e){i.push(function(t){d(e,t)})}),n.inSeries(i,function(){t()})}function d(e,t){e.isFile?e.file(function(n){a(n,e.fullPath),t()},function(){t()}):e.isDirectory?h(e,t):t()}function h(e,t){function n(e){r.readEntries(function(t){t.length?([].push.apply(i,t),n(e)):e()},e)}var i=[],r=e.createReader();n(function(){l(i,t)})}var f=[],p=[],m,g;n.extend(this,{init:function(t){var i=this,o;m=t,g=i.ruid,p=s(m.accept),o=m.container,r.addEvent(o,"dragover",function(t){e(t)&&(t.preventDefault(),t.dataTransfer.dropEffect="copy")},i.uid),r.addEvent(o,"drop",function(t){e(t)&&(t.preventDefault(),f=[],t.dataTransfer.items&&t.dataTransfer.items[0].webkitGetAsEntry?c(t.dataTransfer.items,function(){i.files=f,i.trigger("drop")}):(n.each(t.dataTransfer.files,function(e){a(e)}),i.files=f,i.trigger("drop")))},i.uid),r.addEvent(o,"dragenter",function(e){i.trigger("dragenter")},i.uid),r.addEvent(o,"dragleave",function(e){i.trigger("dragleave")},i.uid)},destroy:function(){r.removeAllEvents(m&&i.get(m.container),this.uid),g=f=p=m=null}})}return e.FileDrop=a}),i(F,[D,w,u],function(e,t,n){function i(){function e(e){return t.atob(e.substring(e.indexOf("base64,")+7))}var i,r=!1;n.extend(this,{read:function(t,o){var a=this;a.result="",i=new window.FileReader,i.addEventListener("progress",function(e){a.trigger(e)}),i.addEventListener("load",function(t){a.result=r?e(i.result):i.result,a.trigger(t)}),i.addEventListener("error",function(e){a.trigger(e,i.error)}),i.addEventListener("loadend",function(e){i=null,a.trigger(e)}),"function"===n.typeOf(i[t])?(r=!1,i[t](o.getSource())):"readAsBinaryString"===t&&(r=!0,i.readAsDataURL(o.getSource()))},abort:function(){i&&i.abort()},destroy:function(){i=null}})}return e.FileReader=i}),i(P,[D,u,d,x,E,y,I,f,c],function(e,t,n,i,r,o,a,s,u){function c(){function e(e,t){var n=this,i,r;i=t.getBlob().getSource(),r=new window.FileReader,r.onload=function(){t.append(t.getBlobName(),new o(null,{type:i.type,data:r.result})),h.send.call(n,e,t)},r.readAsBinaryString(i)}function c(){return!window.XMLHttpRequest||"IE"===u.browser&&u.verComp(u.version,8,"<")?function(){for(var e=["Msxml2.XMLHTTP.6.0","Microsoft.XMLHTTP"],t=0;t<e.length;t++)try{return new ActiveXObject(e[t])}catch(n){}}():new window.XMLHttpRequest}function l(e){var t=e.responseXML,n=e.responseText;return"IE"===u.browser&&n&&t&&!t.documentElement&&/[^\/]+\/[^\+]+\+xml/.test(e.getResponseHeader("Content-Type"))&&(t=new window.ActiveXObject("Microsoft.XMLDOM"),t.async=!1,t.validateOnParse=!1,t.loadXML(n)),t&&("IE"===u.browser&&0!==t.parseError||!t.documentElement||"parsererror"===t.documentElement.tagName)?null:t}function d(e){var t="----moxieboundary"+(new Date).getTime(),n="--",i="\r\n",r="",a=this.getRuntime();if(!a.can("send_binary_string"))throw new s.RuntimeError(s.RuntimeError.NOT_SUPPORTED_ERR);return f.setRequestHeader("Content-Type","multipart/form-data; boundary="+t),e.each(function(e,a){r+=e instanceof o?n+t+i+'Content-Disposition: form-data; name="'+a+'"; filename="'+unescape(encodeURIComponent(e.name||"blob"))+'"'+i+"Content-Type: "+(e.type||"application/octet-stream")+i+i+e.getSource()+i:n+t+i+'Content-Disposition: form-data; name="'+a+'"'+i+i+unescape(encodeURIComponent(e))+i}),r+=n+t+n+i}var h=this,f,p;t.extend(this,{send:function(n,r){var s=this,l="Mozilla"===u.browser&&u.verComp(u.version,4,">=")&&u.verComp(u.version,7,"<"),h="Android Browser"===u.browser,m=!1;if(p=n.url.replace(/^.+?\/([\w\-\.]+)$/,"$1").toLowerCase(),f=c(),f.open(n.method,n.url,n.async,n.user,n.password),r instanceof o)r.isDetached()&&(m=!0),r=r.getSource();else if(r instanceof a){if(r.hasBlob())if(r.getBlob().isDetached())r=d.call(s,r),m=!0;else if((l||h)&&"blob"===t.typeOf(r.getBlob().getSource())&&window.FileReader)return void e.call(s,n,r);if(r instanceof a){var g=new window.FormData;r.each(function(e,t){e instanceof o?g.append(t,e.getSource()):g.append(t,e)}),r=g}}f.upload?(n.withCredentials&&(f.withCredentials=!0),f.addEventListener("load",function(e){s.trigger(e)}),f.addEventListener("error",function(e){s.trigger(e)}),f.addEventListener("progress",function(e){s.trigger(e)}),f.upload.addEventListener("progress",function(e){s.trigger({type:"UploadProgress",loaded:e.loaded,total:e.total})})):f.onreadystatechange=function v(){switch(f.readyState){case 1:break;case 2:break;case 3:var e,t;try{i.hasSameOrigin(n.url)&&(e=f.getResponseHeader("Content-Length")||0),f.responseText&&(t=f.responseText.length)}catch(r){e=t=0}s.trigger({type:"progress",lengthComputable:!!e,total:parseInt(e,10),loaded:t});break;case 4:f.onreadystatechange=function(){},s.trigger(0===f.status?"error":"load")}},t.isEmptyObj(n.headers)||t.each(n.headers,function(e,t){f.setRequestHeader(t,e)}),""!==n.responseType&&"responseType"in f&&("json"!==n.responseType||u.can("return_response_type","json")?f.responseType=n.responseType:f.responseType="text"),m?f.sendAsBinary?f.sendAsBinary(r):!function(){for(var e=new Uint8Array(r.length),t=0;t<r.length;t++)e[t]=255&r.charCodeAt(t);f.send(e.buffer)}():f.send(r),s.trigger("loadstart")},getStatus:function(){try{if(f)return f.status}catch(e){}return 0},getResponse:function(e){var t=this.getRuntime();try{switch(e){case"blob":var i=new r(t.uid,f.response),o=f.getResponseHeader("Content-Disposition");if(o){var a=o.match(/filename=([\'\"'])([^\1]+)\1/);a&&(p=a[2])}return i.name=p,i.type||(i.type=n.getFileMime(p)),i;case"json":return u.can("return_response_type","json")?f.response:200===f.status&&window.JSON?JSON.parse(f.responseText):null;case"document":return l(f);default:return""!==f.responseText?f.responseText:null}}catch(s){return null}},getAllResponseHeaders:function(){try{return f.getAllResponseHeaders()}catch(e){}return""},abort:function(){f&&f.abort()},destroy:function(){h=p=null}})}return e.XMLHttpRequest=c}),i(H,[u],function(e){function t(e){e instanceof ArrayBuffer?n.apply(this,arguments):i.apply(this,arguments)}function n(t){var n=new DataView(t);e.extend(this,{readByteAt:function(e){return n.getUint8(e)},writeByteAt:function(e,t){n.setUint8(e,t)},SEGMENT:function(e,i,r){switch(arguments.length){case 2:return t.slice(e,e+i);case 1:return t.slice(e);case 3:if(null===r&&(r=new ArrayBuffer),r instanceof ArrayBuffer){var o=new Uint8Array(this.length()-i+r.byteLength);e>0&&o.set(new Uint8Array(t.slice(0,e)),0),o.set(new Uint8Array(r),e),o.set(new Uint8Array(t.slice(e+i)),e+r.byteLength),this.clear(),t=o.buffer,n=new DataView(t);break}default:return t}},length:function(){return t?t.byteLength:0},clear:function(){n=t=null}})}function i(t){function n(e,n,i){i=3===arguments.length?i:t.length-n-1,t=t.substr(0,n)+e+t.substr(i+n)}e.extend(this,{readByteAt:function(e){return t.charCodeAt(e)},writeByteAt:function(e,t){n(String.fromCharCode(t),e,1)},SEGMENT:function(e,i,r){switch(arguments.length){case 1:return t.substr(e);case 2:return t.substr(e,i);case 3:n(null!==r?r:"",e,i);break;default:return t}},length:function(){return t?t.length:0},clear:function(){t=null}})}return e.extend(t.prototype,{littleEndian:!1,read:function(e,t){var n,i,r;if(e+t>this.length())throw new Error("You are trying to read outside the source boundaries.");for(i=this.littleEndian?0:-8*(t-1),r=0,n=0;t>r;r++)n|=this.readByteAt(e+r)<<Math.abs(i+8*r);return n},write:function(e,t,n){var i,r,o="";if(e>this.length())throw new Error("You are trying to write outside the source boundaries.");for(i=this.littleEndian?0:-8*(n-1),r=0;n>r;r++)this.writeByteAt(e+r,t>>Math.abs(i+8*r)&255)},BYTE:function(e){return this.read(e,1)},SHORT:function(e){return this.read(e,2)},LONG:function(e){return this.read(e,4)},SLONG:function(e){var t=this.read(e,4);return t>2147483647?t-4294967296:t},CHAR:function(e){return String.fromCharCode(this.read(e,1))},STRING:function(e,t){return this.asArray("CHAR",e,t).join("")},asArray:function(e,t,n){for(var i=[],r=0;n>r;r++)i[r]=this[e](t+r);return i}}),t}),i(B,[H,f],function(e,t){return function n(i){var r=[],o,a,s,u=0;if(o=new e(i),65496!==o.SHORT(0))throw o.clear(),new t.ImageError(t.ImageError.WRONG_FORMAT);for(a=2;a<=o.length();)if(s=o.SHORT(a),s>=65488&&65495>=s)a+=2;else{if(65498===s||65497===s)break;u=o.SHORT(a+2)+2,s>=65505&&65519>=s&&r.push({hex:s,name:"APP"+(15&s),start:a,length:u,segment:o.SEGMENT(a,u)}),a+=u}return o.clear(),{headers:r,restore:function(t){var n,i,o;for(o=new e(t),a=65504==o.SHORT(2)?4+o.SHORT(4):2,i=0,n=r.length;n>i;i++)o.SEGMENT(a,0,r[i].segment),a+=r[i].length;return t=o.SEGMENT(),o.clear(),t},strip:function(t){var i,r,o,a;for(o=new n(t),r=o.headers,o.purge(),i=new e(t),a=r.length;a--;)i.SEGMENT(r[a].start,r[a].length,"");return t=i.SEGMENT(),i.clear(),t},get:function(e){for(var t=[],n=0,i=r.length;i>n;n++)r[n].name===e.toUpperCase()&&t.push(r[n].segment);return t},
+set:function(e,t){var n=[],i,o,a;for("string"==typeof t?n.push(t):n=t,i=o=0,a=r.length;a>i&&(r[i].name===e.toUpperCase()&&(r[i].segment=n[o],r[i].length=n[o].length,o++),!(o>=n.length));i++);},purge:function(){this.headers=r=[]}}}}),i(k,[u,H,f],function(e,n,i){function r(o){function a(n,r){var o=this,a,s,u,c,h,f,p,m,g=[],v={},w={1:"BYTE",7:"UNDEFINED",2:"ASCII",3:"SHORT",4:"LONG",5:"RATIONAL",9:"SLONG",10:"SRATIONAL"},y={BYTE:1,UNDEFINED:1,ASCII:1,SHORT:2,LONG:4,RATIONAL:8,SLONG:4,SRATIONAL:8};for(a=o.SHORT(n),s=0;a>s;s++)if(g=[],p=n+2+12*s,u=r[o.SHORT(p)],u!==t){if(c=w[o.SHORT(p+=2)],h=o.LONG(p+=2),f=y[c],!f)throw new i.ImageError(i.ImageError.INVALID_META_ERR);if(p+=4,f*h>4&&(p=o.LONG(p)+d.tiffHeader),p+f*h>=this.length())throw new i.ImageError(i.ImageError.INVALID_META_ERR);"ASCII"!==c?(g=o.asArray(c,p,h),m=1==h?g[0]:g,l.hasOwnProperty(u)&&"object"!=typeof m?v[u]=l[u][m]:v[u]=m):v[u]=e.trim(o.STRING(p,h).replace(/\0$/,""))}return v}function s(e,t,n){var i,r,o,a=0;if("string"==typeof t){var s=c[e.toLowerCase()];for(var u in s)if(s[u]===t){t=u;break}}i=d[e.toLowerCase()+"IFD"],r=this.SHORT(i);for(var l=0;r>l;l++)if(o=i+12*l+2,this.SHORT(o)==t){a=o+8;break}if(!a)return!1;try{this.write(a,n,4)}catch(h){return!1}return!0}var u,c,l,d,h,f;if(n.call(this,o),c={tiff:{274:"Orientation",270:"ImageDescription",271:"Make",272:"Model",305:"Software",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer"},exif:{36864:"ExifVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",36867:"DateTimeOriginal",33434:"ExposureTime",33437:"FNumber",34855:"ISOSpeedRatings",37377:"ShutterSpeedValue",37378:"ApertureValue",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37386:"FocalLength",41986:"ExposureMode",41987:"WhiteBalance",41990:"SceneCaptureType",41988:"DigitalZoomRatio",41992:"Contrast",41993:"Saturation",41994:"Sharpness"},gps:{0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude"},thumb:{513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength"}},l={ColorSpace:{1:"sRGB",0:"Uncalibrated"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{1:"Daylight",2:"Fliorescent",3:"Tungsten",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 -5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},ExposureMode:{0:"Auto exposure",1:"Manual exposure",2:"Auto bracket"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},GPSLatitudeRef:{N:"North latitude",S:"South latitude"},GPSLongitudeRef:{E:"East longitude",W:"West longitude"}},d={tiffHeader:10},h=d.tiffHeader,u={clear:this.clear},e.extend(this,{read:function(){try{return r.prototype.read.apply(this,arguments)}catch(e){throw new i.ImageError(i.ImageError.INVALID_META_ERR)}},write:function(){try{return r.prototype.write.apply(this,arguments)}catch(e){throw new i.ImageError(i.ImageError.INVALID_META_ERR)}},UNDEFINED:function(){return this.BYTE.apply(this,arguments)},RATIONAL:function(e){return this.LONG(e)/this.LONG(e+4)},SRATIONAL:function(e){return this.SLONG(e)/this.SLONG(e+4)},ASCII:function(e){return this.CHAR(e)},TIFF:function(){return f||null},EXIF:function(){var t=null;if(d.exifIFD){try{t=a.call(this,d.exifIFD,c.exif)}catch(n){return null}if(t.ExifVersion&&"array"===e.typeOf(t.ExifVersion)){for(var i=0,r="";i<t.ExifVersion.length;i++)r+=String.fromCharCode(t.ExifVersion[i]);t.ExifVersion=r}}return t},GPS:function(){var t=null;if(d.gpsIFD){try{t=a.call(this,d.gpsIFD,c.gps)}catch(n){return null}t.GPSVersionID&&"array"===e.typeOf(t.GPSVersionID)&&(t.GPSVersionID=t.GPSVersionID.join("."))}return t},thumb:function(){if(d.IFD1)try{var e=a.call(this,d.IFD1,c.thumb);if("JPEGInterchangeFormat"in e)return this.SEGMENT(d.tiffHeader+e.JPEGInterchangeFormat,e.JPEGInterchangeFormatLength)}catch(t){}return null},setExif:function(e,t){return"PixelXDimension"!==e&&"PixelYDimension"!==e?!1:s.call(this,"exif",e,t)},clear:function(){u.clear(),o=c=l=f=d=u=null}}),65505!==this.SHORT(0)||"EXIF\x00"!==this.STRING(4,5).toUpperCase())throw new i.ImageError(i.ImageError.INVALID_META_ERR);if(this.littleEndian=18761==this.SHORT(h),42!==this.SHORT(h+=2))throw new i.ImageError(i.ImageError.INVALID_META_ERR);d.IFD0=d.tiffHeader+this.LONG(h+=2),f=a.call(this,d.IFD0,c.tiff),"ExifIFDPointer"in f&&(d.exifIFD=d.tiffHeader+f.ExifIFDPointer,delete f.ExifIFDPointer),"GPSInfoIFDPointer"in f&&(d.gpsIFD=d.tiffHeader+f.GPSInfoIFDPointer,delete f.GPSInfoIFDPointer),e.isEmptyObj(f)&&(f=null);var p=this.LONG(d.IFD0+12*this.SHORT(d.IFD0)+2);p&&(d.IFD1=d.tiffHeader+p)}return r.prototype=n.prototype,r}),i(U,[u,f,B,H,k],function(e,t,n,i,r){function o(o){function a(e){var t=0,n,i;for(e||(e=c);t<=e.length();){if(n=e.SHORT(t+=2),n>=65472&&65475>=n)return t+=5,{height:e.SHORT(t),width:e.SHORT(t+=2)};i=e.SHORT(t+=2),t+=i-2}return null}function s(){var e=d.thumb(),t,n;return e&&(t=new i(e),n=a(t),t.clear(),n)?(n.data=e,n):null}function u(){d&&l&&c&&(d.clear(),l.purge(),c.clear(),h=l=d=c=null)}var c,l,d,h;if(c=new i(o),65496!==c.SHORT(0))throw new t.ImageError(t.ImageError.WRONG_FORMAT);l=new n(o);try{d=new r(l.get("app1")[0])}catch(f){}h=a.call(this),e.extend(this,{type:"image/jpeg",size:c.length(),width:h&&h.width||0,height:h&&h.height||0,setExif:function(t,n){return d?("object"===e.typeOf(t)?e.each(t,function(e,t){d.setExif(t,e)}):d.setExif(t,n),void l.set("app1",d.SEGMENT())):!1},writeHeaders:function(){return l.restore(arguments.length?arguments[0]:o)},stripHeaders:function(e){return l.strip(e)},purge:function(){u.call(this)}}),d&&(this.meta={tiff:d.TIFF(),exif:d.EXIF(),gps:d.GPS(),thumb:s()})}return o}),i(G,[f,u,H],function(e,t,n){function i(i){function r(){var e,t;return e=a.call(this,8),"IHDR"==e.type?(t=e.start,{width:s.LONG(t),height:s.LONG(t+=4)}):null}function o(){s&&(s.clear(),i=l=u=c=s=null)}function a(e){var t,n,i,r;return t=s.LONG(e),n=s.STRING(e+=4,4),i=e+=4,r=s.LONG(e+t),{length:t,type:n,start:i,CRC:r}}var s,u,c,l;s=new n(i),function(){var t=0,n=0,i=[35152,20039,3338,6666];for(n=0;n<i.length;n++,t+=2)if(i[n]!=s.SHORT(t))throw new e.ImageError(e.ImageError.WRONG_FORMAT)}(),l=r.call(this),t.extend(this,{type:"image/png",size:s.length(),width:l.width,height:l.height,purge:function(){o.call(this)}}),o.call(this)}return i}),i(z,[u,f,U,G],function(e,t,n,i){return function(r){var o=[n,i],a;a=function(){for(var e=0;e<o.length;e++)try{return new o[e](r)}catch(n){}throw new t.ImageError(t.ImageError.WRONG_FORMAT)}(),e.extend(this,{type:"",size:0,width:0,height:0,setExif:function(){},writeHeaders:function(e){return e},stripHeaders:function(e){return e},purge:function(){r=null}}),e.extend(this,a),this.purge=function(){a.purge(),a=null}}}),i(q,[],function(){function e(e,i,r){var o=e.naturalWidth,a=e.naturalHeight,s=r.width,u=r.height,c=r.x||0,l=r.y||0,d=i.getContext("2d");t(e)&&(o/=2,a/=2);var h=1024,f=document.createElement("canvas");f.width=f.height=h;for(var p=f.getContext("2d"),m=n(e,o,a),g=0;a>g;){for(var v=g+h>a?a-g:h,w=0;o>w;){var y=w+h>o?o-w:h;p.clearRect(0,0,h,h),p.drawImage(e,-w,-g);var E=w*s/o+c<<0,_=Math.ceil(y*s/o),b=g*u/a/m+l<<0,x=Math.ceil(v*u/a/m);d.drawImage(f,0,0,y,v,E,b,_,x),w+=h}g+=h}f=p=null}function t(e){var t=e.naturalWidth,n=e.naturalHeight;if(t*n>1048576){var i=document.createElement("canvas");i.width=i.height=1;var r=i.getContext("2d");return r.drawImage(e,-t+1,0),0===r.getImageData(0,0,1,1).data[3]}return!1}function n(e,t,n){var i=document.createElement("canvas");i.width=1,i.height=n;var r=i.getContext("2d");r.drawImage(e,0,0);for(var o=r.getImageData(0,0,1,n).data,a=0,s=n,u=n;u>a;){var c=o[4*(u-1)+3];0===c?s=u:a=u,u=s+a>>1}i=null;var l=u/n;return 0===l?1:l}return{isSubsampled:t,renderTo:e}}),i(j,[D,u,f,w,y,E,z,q,d,c],function(e,t,n,i,r,o,a,s,u,c){function l(){function e(){if(!_&&!y)throw new n.ImageError(n.DOMException.INVALID_STATE_ERR);return _||y}function l(e){return i.atob(e.substring(e.indexOf("base64,")+7))}function d(e,t){return"data:"+(t||"")+";base64,"+i.btoa(e)}function h(e){var t=this;y=new Image,y.onerror=function(){v.call(this),t.trigger("error",n.ImageError.WRONG_FORMAT)},y.onload=function(){t.trigger("load")},y.src="data:"==e.substr(0,5)?e:d(e,x.type)}function f(e,t){var i=this,r;return window.FileReader?(r=new FileReader,r.onload=function(){t(this.result)},r.onerror=function(){i.trigger("error",n.ImageError.WRONG_FORMAT)},r.readAsDataURL(e),void 0):t(e.getAsDataURL())}function p(n,i,r,o){var a=this,s,u,c=0,l=0,d,h,f,p;if(A=o,p=this.meta&&this.meta.tiff&&this.meta.tiff.Orientation||1,-1!==t.inArray(p,[5,6,7,8])){var v=n;n=i,i=v}return d=e(),r?(n=Math.min(n,d.width),i=Math.min(i,d.height),s=Math.max(n/d.width,i/d.height)):s=Math.min(n/d.width,i/d.height),s>1&&!r&&o?void this.trigger("Resize"):(_||(_=document.createElement("canvas")),h=Math.round(d.width*s),f=Math.round(d.height*s),r?(_.width=n,_.height=i,h>n&&(c=Math.round((h-n)/2)),f>i&&(l=Math.round((f-i)/2))):(_.width=h,_.height=f),A||g(_.width,_.height,p),m.call(this,d,_,-c,-l,h,f),this.width=_.width,this.height=_.height,R=!0,void a.trigger("Resize"))}function m(e,t,n,i,r,o){if("iOS"===c.OS)s.renderTo(e,t,{width:r,height:o,x:n,y:i});else{var a=t.getContext("2d");a.drawImage(e,n,i,r,o)}}function g(e,t,n){switch(n){case 5:case 6:case 7:case 8:_.width=t,_.height=e;break;default:_.width=e,_.height=t}var i=_.getContext("2d");switch(n){case 2:i.translate(e,0),i.scale(-1,1);break;case 3:i.translate(e,t),i.rotate(Math.PI);break;case 4:i.translate(0,t),i.scale(1,-1);break;case 5:i.rotate(.5*Math.PI),i.scale(1,-1);break;case 6:i.rotate(.5*Math.PI),i.translate(0,-t);break;case 7:i.rotate(.5*Math.PI),i.translate(e,-t),i.scale(-1,1);break;case 8:i.rotate(-.5*Math.PI),i.translate(-e,0)}}function v(){E&&(E.purge(),E=null),b=y=_=x=null,R=!1}var w=this,y,E,_,b,x,R=!1,A=!0;t.extend(this,{loadFromBlob:function(e){var t=this,i=t.getRuntime(),r=arguments.length>1?arguments[1]:!0;if(!i.can("access_binary"))throw new n.RuntimeError(n.RuntimeError.NOT_SUPPORTED_ERR);return x=e,e.isDetached()?(b=e.getSource(),void h.call(this,b)):void f.call(this,e.getSource(),function(e){r&&(b=l(e)),h.call(t,e)})},loadFromImage:function(e,t){this.meta=e.meta,x=new o(null,{name:e.name,size:e.size,type:e.type}),h.call(this,t?b=e.getAsBinaryString():e.getAsDataURL())},getInfo:function(){var t=this.getRuntime(),n;return!E&&b&&t.can("access_image_binary")&&(E=new a(b)),n={width:e().width||0,height:e().height||0,type:x.type||u.getFileMime(x.name),size:b&&b.length||x.size||0,name:x.name||"",meta:E&&E.meta||this.meta||{}},!n.meta||!n.meta.thumb||n.meta.thumb.data instanceof r||(n.meta.thumb.data=new r(null,{type:"image/jpeg",data:n.meta.thumb.data})),n},downsize:function(){p.apply(this,arguments)},getAsCanvas:function(){return _&&(_.id=this.uid+"_canvas"),_},getAsBlob:function(e,t){return e!==this.type&&p.call(this,this.width,this.height,!1),new o(null,{name:x.name||"",type:e,data:w.getAsBinaryString.call(this,e,t)})},getAsDataURL:function(e){var t=arguments[1]||90;if(!R)return y.src;if("image/jpeg"!==e)return _.toDataURL("image/png");try{return _.toDataURL("image/jpeg",t/100)}catch(n){return _.toDataURL("image/jpeg")}},getAsBinaryString:function(e,t){if(!R)return b||(b=l(w.getAsDataURL(e,t))),b;if("image/jpeg"!==e)b=l(w.getAsDataURL(e,t));else{var n;t||(t=90);try{n=_.toDataURL("image/jpeg",t/100)}catch(i){n=_.toDataURL("image/jpeg")}b=l(n),E&&(b=E.stripHeaders(b),A&&(E.meta&&E.meta.exif&&E.setExif({PixelXDimension:this.width,PixelYDimension:this.height}),b=E.writeHeaders(b)),E.purge(),E=null)}return R=!1,b},destroy:function(){w=null,v.call(this),this.getRuntime().getShim().removeInstance(this.uid)}})}return e.Image=l}),i(X,[u,c,h,f,m],function(e,t,n,i,r){function o(){var e;try{e=navigator.plugins["Shockwave Flash"],e=e.description}catch(t){try{e=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version")}catch(n){e="0.0"}}return e=e.match(/\d+/g),parseFloat(e[0]+"."+e[1])}function a(e){var i=n.get(e);i&&"OBJECT"==i.nodeName&&("IE"===t.browser?(i.style.display="none",function r(){4==i.readyState?s(e):setTimeout(r,10)}()):i.parentNode.removeChild(i))}function s(e){var t=n.get(e);if(t){for(var i in t)"function"==typeof t[i]&&(t[i]=null);t.parentNode.removeChild(t)}}function u(s){var u=this,d;s=e.extend({swf_url:t.swf_url},s),r.call(this,s,c,{access_binary:function(e){return e&&"browser"===u.mode},access_image_binary:function(e){return e&&"browser"===u.mode},display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:function(){return"client"===u.mode},resize_image:r.capTrue,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!e.arrayDiff(t,["","text","document"])||"browser"===u.mode},return_status_code:function(t){return"browser"===u.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:function(e){return e&&"browser"===u.mode},send_browser_cookies:function(e){return e&&"browser"===u.mode},send_custom_headers:function(e){return e&&"browser"===u.mode},send_multipart:r.capTrue,slice_blob:function(e){return e&&"browser"===u.mode},stream_upload:function(e){return e&&"browser"===u.mode},summon_file_dialog:!1,upload_filesize:function(t){return e.parseSizeStr(t)<=2097152||"client"===u.mode},use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}},{access_binary:function(e){return e?"browser":"client"},access_image_binary:function(e){return e?"browser":"client"},report_upload_progress:function(e){return e?"browser":"client"},return_response_type:function(t){return e.arrayDiff(t,["","text","json","document"])?"browser":["client","browser"]},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"browser":["client","browser"]},send_binary_string:function(e){return e?"browser":"client"},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"browser":"client"},stream_upload:function(e){return e?"client":"browser"},upload_filesize:function(t){return e.parseSizeStr(t)>=2097152?"client":"browser"}},"client"),o()<10&&(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid)},shimExec:function(e,t){var n=[].slice.call(arguments,2);return u.getShim().exec(this.uid,e,t,n)},init:function(){var n,r,o;o=this.getShimContainer(),e.extend(o.style,{position:"absolute",top:"-8px",left:"-8px",width:"9px",height:"9px",overflow:"hidden"}),n='<object id="'+this.uid+'" type="application/x-shockwave-flash" data="'+s.swf_url+'" ',"IE"===t.browser&&(n+='classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '),n+='width="100%" height="100%" style="outline:0"><param name="movie" value="'+s.swf_url+'" /><param name="flashvars" value="uid='+escape(this.uid)+"&target="+t.global_event_dispatcher+'" /><param name="wmode" value="transparent" /><param name="allowscriptaccess" value="always" /></object>',"IE"===t.browser?(r=document.createElement("div"),o.appendChild(r),r.outerHTML=n,r=o=null):o.innerHTML=n,d=setTimeout(function(){u&&!u.initialized&&u.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},5e3)},destroy:function(e){return function(){a(u.uid),e.call(u),clearTimeout(d),s=d=e=u=null}}(this.destroy)},l)}var c="flash",l={};return r.addConstructor(c,u),l}),i(V,[X,E,u],function(e,t,n){var i={init:function(e){var i=this,r=this.getRuntime();this.bind("Change",function(){var e=r.shimExec.call(i,"FileInput","getFiles");i.files=[],n.each(e,function(e){i.files.push(new t(r.uid,e))})},999),this.getRuntime().shimExec.call(this,"FileInput","init",{name:e.name,accept:e.accept,multiple:e.multiple}),this.trigger("ready")}};return e.FileInput=i}),i(W,[X,y],function(e,t){var n={slice:function(e,n,i,r){var o=this.getRuntime();return 0>n?n=Math.max(e.size+n,0):n>0&&(n=Math.min(n,e.size)),0>i?i=Math.max(e.size+i,0):i>0&&(i=Math.min(i,e.size)),e=o.shimExec.call(this,"Blob","slice",n,i,r||""),e&&(e=new t(o.uid,e)),e}};return e.Blob=n}),i(Y,[X,w],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i=this;return i.result="","readAsDataURL"===e&&(i.result="data:"+(t.type||"")+";base64,"),i.bind("Progress",function(t,r){r&&(i.result+=n(r,e))},999),i.getRuntime().shimExec.call(this,"FileReader","readAsBase64",t.uid)}};return e.FileReader=i}),i($,[X,w],function(e,t){function n(e,n){switch(n){case"readAsText":return t.atob(e,"utf8");case"readAsBinaryString":return t.atob(e);case"readAsDataURL":return e}return null}var i={read:function(e,t){var i,r=this.getRuntime();return(i=r.shimExec.call(this,"FileReaderSync","readAsBase64",t.uid))?("readAsDataURL"===e&&(i="data:"+(t.type||"")+";base64,"+i),n(i,e,t.type)):null}};return e.FileReaderSync=i}),i(J,[X,u,y,E,A,I,S],function(e,t,n,i,r,o,a){var s={send:function(e,i){function r(){e.transport=l.mode,l.shimExec.call(c,"XMLHttpRequest","send",e,i)}function s(e,t){l.shimExec.call(c,"XMLHttpRequest","appendBlob",e,t.uid),i=null,r()}function u(e,t){var n=new a;n.bind("TransportingComplete",function(){t(this.result)}),n.transport(e.getSource(),e.type,{ruid:l.uid})}var c=this,l=c.getRuntime();if(t.isEmptyObj(e.headers)||t.each(e.headers,function(e,t){l.shimExec.call(c,"XMLHttpRequest","setRequestHeader",t,e.toString())}),i instanceof o){var d;if(i.each(function(e,t){e instanceof n?d=t:l.shimExec.call(c,"XMLHttpRequest","append",t,e)}),i.hasBlob()){var h=i.getBlob();h.isDetached()?u(h,function(e){h.destroy(),s(d,e)}):s(d,h)}else i=null,r()}else i instanceof n?i.isDetached()?u(i,function(e){i.destroy(),i=e.uid,r()}):(i=i.uid,r()):r()},getResponse:function(e){var n,o,a=this.getRuntime();if(o=a.shimExec.call(this,"XMLHttpRequest","getResponseAsBlob")){if(o=new i(a.uid,o),"blob"===e)return o;try{if(n=new r,~t.inArray(e,["","text"]))return n.readAsText(o);if("json"===e&&window.JSON)return JSON.parse(n.readAsText(o))}finally{o.destroy()}}return null},abort:function(e){var t=this.getRuntime();t.shimExec.call(this,"XMLHttpRequest","abort"),this.dispatchEvent("readystatechange"),this.dispatchEvent("abort")}};return e.XMLHttpRequest=s}),i(Z,[X,y],function(e,t){var n={getAsBlob:function(e){var n=this.getRuntime(),i=n.shimExec.call(this,"Transporter","getAsBlob",e);return i?new t(n.uid,i):null}};return e.Transporter=n}),i(K,[X,u,S,y,A],function(e,t,n,i,r){var o={loadFromBlob:function(e){function t(e){r.shimExec.call(i,"Image","loadFromBlob",e.uid),i=r=null}var i=this,r=i.getRuntime();if(e.isDetached()){var o=new n;o.bind("TransportingComplete",function(){t(o.result.getSource())}),o.transport(e.getSource(),e.type,{ruid:r.uid})}else t(e.getSource())},loadFromImage:function(e){var t=this.getRuntime();return t.shimExec.call(this,"Image","loadFromImage",e.uid)},getInfo:function(){var e=this.getRuntime(),t=e.shimExec.call(this,"Image","getInfo");return!t.meta||!t.meta.thumb||t.meta.thumb.data instanceof i||(t.meta.thumb.data=new i(e.uid,t.meta.thumb.data)),t},getAsBlob:function(e,t){var n=this.getRuntime(),r=n.shimExec.call(this,"Image","getAsBlob",e,t);return r?new i(n.uid,r):null},getAsDataURL:function(){var e=this.getRuntime(),t=e.Image.getAsBlob.apply(this,arguments),n;return t?(n=new r,n.readAsDataURL(t)):null}};return e.Image=o}),i(Q,[u,c,h,f,m],function(e,t,n,i,r){function o(e){var t=!1,n=null,i,r,o,a,s,u=0;try{try{n=new ActiveXObject("AgControl.AgControl"),n.IsVersionSupported(e)&&(t=!0),n=null}catch(c){var l=navigator.plugins["Silverlight Plug-In"];if(l){for(i=l.description,"1.0.30226.2"===i&&(i="2.0.30226.2"),r=i.split(".");r.length>3;)r.pop();for(;r.length<4;)r.push(0);for(o=e.split(".");o.length>4;)o.pop();do a=parseInt(o[u],10),s=parseInt(r[u],10),u++;while(u<o.length&&a===s);s>=a&&!isNaN(a)&&(t=!0)}}}catch(d){t=!1}return t}function a(a){var c=this,l;a=e.extend({xap_url:t.xap_url},a),r.call(this,a,s,{access_binary:r.capTrue,access_image_binary:r.capTrue,display_media:r.capTrue,do_cors:r.capTrue,drag_and_drop:!1,report_upload_progress:r.capTrue,resize_image:r.capTrue,return_response_headers:function(e){return e&&"client"===c.mode},return_response_type:function(e){return"json"!==e?!0:!!window.JSON},return_status_code:function(t){return"client"===c.mode||!e.arrayDiff(t,[200,404])},select_file:r.capTrue,select_multiple:r.capTrue,send_binary_string:r.capTrue,send_browser_cookies:function(e){return e&&"browser"===c.mode},send_custom_headers:function(e){return e&&"client"===c.mode},send_multipart:r.capTrue,slice_blob:r.capTrue,stream_upload:!0,summon_file_dialog:!1,upload_filesize:r.capTrue,use_http_method:function(t){return"client"===c.mode||!e.arrayDiff(t,["GET","POST"])}},{return_response_headers:function(e){return e?"client":"browser"},return_status_code:function(t){return e.arrayDiff(t,[200,404])?"client":["client","browser"]},send_browser_cookies:function(e){return e?"browser":"client"},send_custom_headers:function(e){return e?"client":"browser"},use_http_method:function(t){return e.arrayDiff(t,["GET","POST"])?"client":["client","browser"]}}),o("2.0.31005.0")&&"Opera"!==t.browser||(this.mode=!1),e.extend(this,{getShim:function(){return n.get(this.uid).content.Moxie},shimExec:function(e,t){var n=[].slice.call(arguments,2);return c.getShim().exec(this.uid,e,t,n)},init:function(){var e;e=this.getShimContainer(),e.innerHTML='<object id="'+this.uid+'" data="data:application/x-silverlight," type="application/x-silverlight-2" width="100%" height="100%" style="outline:none;"><param name="source" value="'+a.xap_url+'"/><param name="background" value="Transparent"/><param name="windowless" value="true"/><param name="enablehtmlaccess" value="true"/><param name="initParams" value="uid='+this.uid+",target="+t.global_event_dispatcher+'"/></object>',l=setTimeout(function(){c&&!c.initialized&&c.trigger("Error",new i.RuntimeError(i.RuntimeError.NOT_INIT_ERR))},"Windows"!==t.OS?1e4:5e3)},destroy:function(e){return function(){e.call(c),clearTimeout(l),a=l=e=c=null}}(this.destroy)},u)}var s="silverlight",u={};return r.addConstructor(s,a),u}),i(ee,[Q,E,u],function(e,t,n){var i={init:function(e){function i(e){for(var t="",n=0;n<e.length;n++)t+=(""!==t?"|":"")+e[n].title+" | *."+e[n].extensions.replace(/,/g,";*.");return t}var r=this,o=this.getRuntime();this.bind("Change",function(){var e=o.shimExec.call(r,"FileInput","getFiles");r.files=[],n.each(e,function(e){r.files.push(new t(o.uid,e))})},999),this.getRuntime().shimExec.call(this,"FileInput","init",i(e.accept),e.name,e.multiple),this.trigger("ready")}};return e.FileInput=i}),i(te,[Q,u,W],function(e,t,n){return e.Blob=t.extend({},n)}),i(ne,[Q,h,N],function(e,t,n){var i={init:function(){var e=this,i=e.getRuntime(),r;return r=i.getShimContainer(),n.addEvent(r,"dragover",function(e){e.preventDefault(),e.stopPropagation(),e.dataTransfer.dropEffect="copy"},e.uid),n.addEvent(r,"dragenter",function(e){e.preventDefault();var n=t.get(i.uid).dragEnter(e);n&&e.stopPropagation()},e.uid),n.addEvent(r,"drop",function(e){e.preventDefault();var n=t.get(i.uid).dragDrop(e);n&&e.stopPropagation()},e.uid),i.shimExec.call(this,"FileDrop","init")}};return e.FileDrop=i}),i(ie,[Q,u,Y],function(e,t,n){return e.FileReader=t.extend({},n)}),i(re,[Q,u,$],function(e,t,n){return e.FileReaderSync=t.extend({},n)}),i(oe,[Q,u,J],function(e,t,n){return e.XMLHttpRequest=t.extend({},n)}),i(ae,[Q,u,Z],function(e,t,n){return e.Transporter=t.extend({},n)}),i(se,[Q,u,y,K],function(e,t,n,i){return e.Image=t.extend({},i,{getInfo:function(){var e=this.getRuntime(),i=["tiff","exif","gps","thumb"],r={meta:{}},o=e.shimExec.call(this,"Image","getInfo");return o.meta&&(t.each(i,function(e){var t=o.meta[e],n,i,a,s;if(t&&t.keys)for(r.meta[e]={},i=0,a=t.keys.length;a>i;i++)n=t.keys[i],s=t[n],s&&(/^(\d|[1-9]\d+)$/.test(s)?s=parseInt(s,10):/^\d*\.\d+$/.test(s)&&(s=parseFloat(s)),r.meta[e][n]=s)}),!r.meta||!r.meta.thumb||r.meta.thumb.data instanceof n||(r.meta.thumb.data=new n(e.uid,r.meta.thumb.data))),r.width=parseInt(o.width,10),r.height=parseInt(o.height,10),r.size=parseInt(o.size,10),r.type=o.type,r.name=o.name,r}})}),i(ue,[u,f,m,c],function(e,t,n,i){function r(t){var r=this,s=n.capTest,u=n.capTrue;n.call(this,t,o,{access_binary:s(window.FileReader||window.File&&File.getAsDataURL),access_image_binary:!1,display_media:s(a.Image&&(i.can("create_canvas")||i.can("use_data_uri_over32kb"))),do_cors:!1,drag_and_drop:!1,filter_by_extension:s(function(){return"Chrome"===i.browser&&i.verComp(i.version,28,">=")||"IE"===i.browser&&i.verComp(i.version,10,">=")||"Safari"===i.browser&&i.verComp(i.version,7,">=")}()),resize_image:function(){return a.Image&&r.can("access_binary")&&i.can("create_canvas")},report_upload_progress:!1,return_response_headers:!1,return_response_type:function(t){return"json"===t&&window.JSON?!0:!!~e.inArray(t,["text","document",""])},return_status_code:function(t){return!e.arrayDiff(t,[200,404])},select_file:function(){return i.can("use_fileinput")},select_multiple:!1,send_binary_string:!1,send_custom_headers:!1,send_multipart:!0,slice_blob:!1,stream_upload:function(){return r.can("select_file")},summon_file_dialog:function(){return r.can("select_file")&&("Firefox"===i.browser&&i.verComp(i.version,4,">=")||"Opera"===i.browser&&i.verComp(i.version,12,">=")||"IE"===i.browser&&i.verComp(i.version,10,">=")||!!~e.inArray(i.browser,["Chrome","Safari"]))},upload_filesize:u,use_http_method:function(t){return!e.arrayDiff(t,["GET","POST"])}}),e.extend(this,{init:function(){this.trigger("Init")},destroy:function(e){return function(){e.call(r),e=r=null}}(this.destroy)}),e.extend(this.getShim(),a)}var o="html4",a={};return n.addConstructor(o,r),a}),i(ce,[ue,E,u,h,N,d,c],function(e,t,n,i,r,o,a){function s(){function e(){var o=this,l=o.getRuntime(),d,h,f,p,m,g;g=n.guid("uid_"),d=l.getShimContainer(),s&&(f=i.get(s+"_form"),f&&n.extend(f.style,{top:"100%"})),p=document.createElement("form"),p.setAttribute("id",g+"_form"),p.setAttribute("method","post"),p.setAttribute("enctype","multipart/form-data"),p.setAttribute("encoding","multipart/form-data"),n.extend(p.style,{overflow:"hidden",position:"absolute",top:0,left:0,width:"100%",height:"100%"}),m=document.createElement("input"),m.setAttribute("id",g),m.setAttribute("type","file"),m.setAttribute("name",c.name||"Filedata"),m.setAttribute("accept",u.join(",")),n.extend(m.style,{fontSize:"999px",opacity:0}),p.appendChild(m),d.appendChild(p),n.extend(m.style,{position:"absolute",top:0,left:0,width:"100%",height:"100%"}),"IE"===a.browser&&a.verComp(a.version,10,"<")&&n.extend(m.style,{filter:"progid:DXImageTransform.Microsoft.Alpha(opacity=0)"}),m.onchange=function(){var n;if(this.value){if(this.files){if(n=this.files[0],0===n.size)return void p.parentNode.removeChild(p)}else n={name:this.value};n=new t(l.uid,n),this.onchange=function(){},e.call(o),o.files=[n],m.setAttribute("id",n.uid),p.setAttribute("id",n.uid+"_form"),o.trigger("change"),m=p=null}},l.can("summon_file_dialog")&&(h=i.get(c.browse_button),r.removeEvent(h,"click",o.uid),r.addEvent(h,"click",function(e){m&&!m.disabled&&m.click(),e.preventDefault()},o.uid)),s=g,d=f=h=null}var s,u=[],c;n.extend(this,{init:function(t){var n=this,a=n.getRuntime(),s;c=t,u=t.accept.mimes||o.extList2mimes(t.accept,a.can("filter_by_extension")),s=a.getShimContainer(),function(){var e,o,u;e=i.get(t.browse_button),a.can("summon_file_dialog")&&("static"===i.getStyle(e,"position")&&(e.style.position="relative"),o=parseInt(i.getStyle(e,"z-index"),10)||1,e.style.zIndex=o,s.style.zIndex=o-1),u=a.can("summon_file_dialog")?e:s,r.addEvent(u,"mouseover",function(){n.trigger("mouseenter")},n.uid),r.addEvent(u,"mouseout",function(){n.trigger("mouseleave")},n.uid),r.addEvent(u,"mousedown",function(){n.trigger("mousedown")},n.uid),r.addEvent(i.get(t.container),"mouseup",function(){n.trigger("mouseup")},n.uid),e=null}(),e.call(this),s=null,n.trigger({type:"ready",async:!0})},disable:function(e){var t;(t=i.get(s))&&(t.disabled=!!e)},destroy:function(){var e=this.getRuntime(),t=e.getShim(),n=e.getShimContainer();r.removeAllEvents(n,this.uid),r.removeAllEvents(c&&i.get(c.container),this.uid),r.removeAllEvents(c&&i.get(c.browse_button),this.uid),n&&(n.innerHTML=""),t.removeInstance(this.uid),s=u=c=n=t=null}})}return e.FileInput=s}),i(le,[ue,F],function(e,t){return e.FileReader=t}),i(de,[ue,u,h,x,f,N,y,I],function(e,t,n,i,r,o,a,s){function u(){function e(e){var t=this,i,r,a,s,u=!1;if(l){if(i=l.id.replace(/_iframe$/,""),r=n.get(i+"_form")){for(a=r.getElementsByTagName("input"),s=a.length;s--;)switch(a[s].getAttribute("type")){case"hidden":a[s].parentNode.removeChild(a[s]);break;case"file":u=!0}a=[],u||r.parentNode.removeChild(r),r=null}setTimeout(function(){o.removeEvent(l,"load",t.uid),l.parentNode&&l.parentNode.removeChild(l);var n=t.getRuntime().getShimContainer();n.children.length||n.parentNode.removeChild(n),n=l=null,e()},1)}}var u,c,l;t.extend(this,{send:function(d,h){function f(){var n=m.getShimContainer()||document.body,r=document.createElement("div");r.innerHTML='<iframe id="'+g+'_iframe" name="'+g+'_iframe" src="javascript:&quot;&quot;" style="display:none"></iframe>',l=r.firstChild,n.appendChild(l),o.addEvent(l,"load",function(){var n;try{n=l.contentWindow.document||l.contentDocument||window.frames[l.id].document,/^4(0[0-9]|1[0-7]|2[2346])\s/.test(n.title)?u=n.title.replace(/^(\d+).*$/,"$1"):(u=200,c=t.trim(n.body.innerHTML),p.trigger({type:"progress",loaded:c.length,total:c.length}),y&&p.trigger({type:"uploadprogress",loaded:y.size||1025,total:y.size||1025}))}catch(r){if(!i.hasSameOrigin(d.url))return void e.call(p,function(){p.trigger("error")});u=404}e.call(p,function(){p.trigger("load")})},p.uid)}var p=this,m=p.getRuntime(),g,v,w,y;if(u=c=null,h instanceof s&&h.hasBlob()){if(y=h.getBlob(),g=y.uid,w=n.get(g),v=n.get(g+"_form"),!v)throw new r.DOMException(r.DOMException.NOT_FOUND_ERR)}else g=t.guid("uid_"),v=document.createElement("form"),v.setAttribute("id",g+"_form"),v.setAttribute("method",d.method),v.setAttribute("enctype","multipart/form-data"),v.setAttribute("encoding","multipart/form-data"),m.getShimContainer().appendChild(v);v.setAttribute("target",g+"_iframe"),h instanceof s&&h.each(function(e,n){if(e instanceof a)w&&w.setAttribute("name",n);else{var i=document.createElement("input");t.extend(i,{type:"hidden",name:n,value:e}),w?v.insertBefore(i,w):v.appendChild(i)}}),v.setAttribute("action",d.url),f(),v.submit(),p.trigger("loadstart")},getStatus:function(){return u},getResponse:function(e){if("json"===e&&"string"===t.typeOf(c)&&window.JSON)try{
+return JSON.parse(c.replace(/^\s*<pre[^>]*>/,"").replace(/<\/pre>\s*$/,""))}catch(n){return null}return c},abort:function(){var t=this;l&&l.contentWindow&&(l.contentWindow.stop?l.contentWindow.stop():l.contentWindow.document.execCommand?l.contentWindow.document.execCommand("Stop"):l.src="about:blank"),e.call(this,function(){t.dispatchEvent("abort")})}})}return e.XMLHttpRequest=u}),i(he,[ue,j],function(e,t){return e.Image=t}),a([u,c,l,d,h,f,p,m,g,v,w,y,E,_,b,x,R,A,I,T,S,O,N])}(this);;(function(e){"use strict";var t={},n=e.moxie.core.utils.Basic.inArray;return function r(e){var i,s;for(i in e)s=typeof e[i],s==="object"&&!~n(i,["Exceptions","Env","Mime"])?r(e[i]):s==="function"&&(t[i]=e[i])}(e.moxie),t.Env=e.moxie.core.utils.Env,t.Mime=e.moxie.core.utils.Mime,t.Exceptions=e.moxie.core.Exceptions,e.mOxie=t,e.o||(e.o=t),t})(this);
 /**
  * Plupload - multi-runtime File Uploader
- * v2.1.2
+ * v2.1.8
  *
  * Copyright 2013, Moxiecode Systems AB
  * Released under GPL License.
@@ -23,6 +24,6 @@
  * License: http://www.plupload.com/license
  * Contributing: http://www.plupload.com/contributing
  *
- * Date: 2014-05-14
+ * Date: 2015-07-21
  */
-;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.2",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.file&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},bind:function(e,t,n){var r=this;o.Uploader.prototype.bind.call(this,e,function(){var e=[].slice.call(arguments);return e.splice(0,1,r),t.apply(this,e)},0,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie);
\ No newline at end of file
+;(function(e,t,n){function s(e){function r(e,t,r){var i={chunks:"slice_blob",jpgresize:"send_binary_string",pngresize:"send_binary_string",progress:"report_upload_progress",multi_selection:"select_multiple",dragdrop:"drag_and_drop",drop_element:"drag_and_drop",headers:"send_custom_headers",urlstream_upload:"send_binary_string",canSendBinary:"send_binary",triggerDialog:"summon_file_dialog"};i[e]?n[i[e]]=t:r||(n[e]=t)}var t=e.required_features,n={};if(typeof t=="string")o.each(t.split(/\s*,\s*/),function(e){r(e,!0)});else if(typeof t=="object")o.each(t,function(e,t){r(t,e)});else if(t===!0){e.chunk_size>0&&(n.slice_blob=!0);if(e.resize.enabled||!e.multipart)n.send_binary_string=!0;o.each(e,function(e,t){r(t,!!e,!0)})}return n}var r=e.setTimeout,i={},o={VERSION:"2.1.8",STOPPED:1,STARTED:2,QUEUED:1,UPLOADING:2,FAILED:4,DONE:5,GENERIC_ERROR:-100,HTTP_ERROR:-200,IO_ERROR:-300,SECURITY_ERROR:-400,INIT_ERROR:-500,FILE_SIZE_ERROR:-600,FILE_EXTENSION_ERROR:-601,FILE_DUPLICATE_ERROR:-602,IMAGE_FORMAT_ERROR:-700,MEMORY_ERROR:-701,IMAGE_DIMENSIONS_ERROR:-702,mimeTypes:t.mimes,ua:t.ua,typeOf:t.typeOf,extend:t.extend,guid:t.guid,get:function(n){var r=[],i;t.typeOf(n)!=="array"&&(n=[n]);var s=n.length;while(s--)i=t.get(n[s]),i&&r.push(i);return r.length?r:null},each:t.each,getPos:t.getPos,getSize:t.getSize,xmlEncode:function(e){var t={"<":"lt",">":"gt","&":"amp",'"':"quot","'":"#39"},n=/[<>&\"\']/g;return e?(""+e).replace(n,function(e){return t[e]?"&"+t[e]+";":e}):e},toArray:t.toArray,inArray:t.inArray,addI18n:t.addI18n,translate:t.translate,isEmptyObj:t.isEmptyObj,hasClass:t.hasClass,addClass:t.addClass,removeClass:t.removeClass,getStyle:t.getStyle,addEvent:t.addEvent,removeEvent:t.removeEvent,removeAllEvents:t.removeAllEvents,cleanName:function(e){var t,n;n=[/[\300-\306]/g,"A",/[\340-\346]/g,"a",/\307/g,"C",/\347/g,"c",/[\310-\313]/g,"E",/[\350-\353]/g,"e",/[\314-\317]/g,"I",/[\354-\357]/g,"i",/\321/g,"N",/\361/g,"n",/[\322-\330]/g,"O",/[\362-\370]/g,"o",/[\331-\334]/g,"U",/[\371-\374]/g,"u"];for(t=0;t<n.length;t+=2)e=e.replace(n[t],n[t+1]);return e=e.replace(/\s+/g,"_"),e=e.replace(/[^a-z0-9_\-\.]+/gi,""),e},buildUrl:function(e,t){var n="";return o.each(t,function(e,t){n+=(n?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(e)}),n&&(e+=(e.indexOf("?")>0?"&":"?")+n),e},formatSize:function(e){function t(e,t){return Math.round(e*Math.pow(10,t))/Math.pow(10,t)}if(e===n||/\D/.test(e))return o.translate("N/A");var r=Math.pow(1024,4);return e>r?t(e/r,1)+" "+o.translate("tb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("gb"):e>(r/=1024)?t(e/r,1)+" "+o.translate("mb"):e>1024?Math.round(e/1024)+" "+o.translate("kb"):e+" "+o.translate("b")},parseSize:t.parseSizeStr,predictRuntime:function(e,n){var r,i;return r=new o.Uploader(e),i=t.Runtime.thatCan(r.getOption().required_features,n||e.runtimes),r.destroy(),i},addFileFilter:function(e,t){i[e]=t}};o.addFileFilter("mime_types",function(e,t,n){e.length&&!e.regexp.test(t.name)?(this.trigger("Error",{code:o.FILE_EXTENSION_ERROR,message:o.translate("File extension error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("max_file_size",function(e,t,n){var r;e=o.parseSize(e),t.size!==r&&e&&t.size>e?(this.trigger("Error",{code:o.FILE_SIZE_ERROR,message:o.translate("File size error."),file:t}),n(!1)):n(!0)}),o.addFileFilter("prevent_duplicates",function(e,t,n){if(e){var r=this.files.length;while(r--)if(t.name===this.files[r].name&&t.size===this.files[r].size){this.trigger("Error",{code:o.FILE_DUPLICATE_ERROR,message:o.translate("Duplicate file error."),file:t}),n(!1);return}}n(!0)}),o.Uploader=function(e){function g(){var e,t=0,n;if(this.state==o.STARTED){for(n=0;n<f.length;n++)!e&&f[n].status==o.QUEUED?(e=f[n],this.trigger("BeforeUpload",e)&&(e.status=o.UPLOADING,this.trigger("UploadFile",e))):t++;t==f.length&&(this.state!==o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged")),this.trigger("UploadComplete",f))}}function y(e){e.percent=e.size>0?Math.ceil(e.loaded/e.size*100):100,b()}function b(){var e,t;d.reset();for(e=0;e<f.length;e++)t=f[e],t.size!==n?(d.size+=t.origSize,d.loaded+=t.loaded*t.origSize/t.size):d.size=n,t.status==o.DONE?d.uploaded++:t.status==o.FAILED?d.failed++:d.queued++;d.size===n?d.percent=f.length>0?Math.ceil(d.uploaded/f.length*100):0:(d.bytesPerSec=Math.ceil(d.loaded/((+(new Date)-p||1)/1e3)),d.percent=d.size>0?Math.ceil(d.loaded/d.size*100):0)}function w(){var e=c[0]||h[0];return e?e.getRuntime().uid:!1}function E(e,n){if(e.ruid){var r=t.Runtime.getInfo(e.ruid);if(r)return r.can(n)}return!1}function S(){this.bind("FilesAdded FilesRemoved",function(e){e.trigger("QueueChanged"),e.refresh()}),this.bind("CancelUpload",O),this.bind("BeforeUpload",C),this.bind("UploadFile",k),this.bind("UploadProgress",L),this.bind("StateChanged",A),this.bind("QueueChanged",b),this.bind("Error",_),this.bind("FileUploaded",M),this.bind("Destroy",D)}function x(e,n){var r=this,i=0,s=[],u={runtime_order:e.runtimes,required_caps:e.required_features,preferred_caps:l,swf_url:e.flash_swf_url,xap_url:e.silverlight_xap_url};o.each(e.runtimes.split(/\s*,\s*/),function(t){e[t]&&(u[t]=e[t])}),e.browse_button&&o.each(e.browse_button,function(n){s.push(function(s){var a=new t.FileInput(o.extend({},u,{accept:e.filters.mime_types,name:e.file_data_name,multiple:e.multi_selection,container:e.container,browse_button:n}));a.onready=function(){var e=t.Runtime.getInfo(this.ruid);t.extend(r.features,{chunks:e.can("slice_blob"),multipart:e.can("send_multipart"),multi_selection:e.can("select_multiple")}),i++,c.push(this),s()},a.onchange=function(){r.addFile(this.files)},a.bind("mouseenter mouseleave mousedown mouseup",function(r){v||(e.browse_button_hover&&("mouseenter"===r.type?t.addClass(n,e.browse_button_hover):"mouseleave"===r.type&&t.removeClass(n,e.browse_button_hover)),e.browse_button_active&&("mousedown"===r.type?t.addClass(n,e.browse_button_active):"mouseup"===r.type&&t.removeClass(n,e.browse_button_active)))}),a.bind("mousedown",function(){r.trigger("Browse")}),a.bind("error runtimeerror",function(){a=null,s()}),a.init()})}),e.drop_element&&o.each(e.drop_element,function(e){s.push(function(n){var s=new t.FileDrop(o.extend({},u,{drop_zone:e}));s.onready=function(){var e=t.Runtime.getInfo(this.ruid);r.features.dragdrop=e.can("drag_and_drop"),i++,h.push(this),n()},s.ondrop=function(){r.addFile(this.files)},s.bind("error runtimeerror",function(){s=null,n()}),s.init()})}),t.inSeries(s,function(){typeof n=="function"&&n(i)})}function T(e,r,i){var s=new t.Image;try{s.onload=function(){if(r.width>this.width&&r.height>this.height&&r.quality===n&&r.preserve_headers&&!r.crop)return this.destroy(),i(e);s.downsize(r.width,r.height,r.crop,r.preserve_headers)},s.onresize=function(){i(this.getAsBlob(e.type,r.quality)),this.destroy()},s.onerror=function(){i(e)},s.load(e)}catch(o){i(e)}}function N(e,n,r){function f(e,t,n){var r=a[e];switch(e){case"max_file_size":e==="max_file_size"&&(a.max_file_size=a.filters.max_file_size=t);break;case"chunk_size":if(t=o.parseSize(t))a[e]=t,a.send_file_name=!0;break;case"multipart":a[e]=t,t||(a.send_file_name=!0);break;case"unique_names":a[e]=t,t&&(a.send_file_name=!0);break;case"filters":o.typeOf(t)==="array"&&(t={mime_types:t}),n?o.extend(a.filters,t):a.filters=t,t.mime_types&&(a.filters.mime_types.regexp=function(e){var t=[];return o.each(e,function(e){o.each(e.extensions.split(/,/),function(e){/^\s*\*\s*$/.test(e)?t.push("\\.*"):t.push("\\."+e.replace(new RegExp("["+"/^$.*+?|()[]{}\\".replace(/./g,"\\$&")+"]","g"),"\\$&"))})}),new RegExp("("+t.join("|")+")$","i")}(a.filters.mime_types));break;case"resize":n?o.extend(a.resize,t,{enabled:!0}):a.resize=t;break;case"prevent_duplicates":a.prevent_duplicates=a.filters.prevent_duplicates=!!t;break;case"browse_button":case"drop_element":t=o.get(t);case"container":case"runtimes":case"multi_selection":case"flash_swf_url":case"silverlight_xap_url":a[e]=t,n||(u=!0);break;default:a[e]=t}n||i.trigger("OptionChanged",e,t,r)}var i=this,u=!1;typeof e=="object"?o.each(e,function(e,t){f(t,e,r)}):f(e,n,r),r?(a.required_features=s(o.extend({},a)),l=s(o.extend({},a,{required_features:!0}))):u&&(i.trigger("Destroy"),x.call(i,a,function(e){e?(i.runtime=t.Runtime.getInfo(w()).type,i.trigger("Init",{runtime:i.runtime}),i.trigger("PostInit")):i.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})}))}function C(e,t){if(e.settings.unique_names){var n=t.name.match(/\.([^.]+)$/),r="part";n&&(r=n[1]),t.target_name=t.id+"."+r}}function k(e,n){function h(){u-->0?r(p,1e3):(n.loaded=f,e.trigger("Error",{code:o.HTTP_ERROR,message:o.translate("HTTP Error."),file:n,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}))}function p(){var d,v,g={},y;if(n.status!==o.UPLOADING||e.state===o.STOPPED)return;e.settings.send_file_name&&(g.name=n.target_name||n.name),s&&a.chunks&&c.size>s?(y=Math.min(s,c.size-f),d=c.slice(f,f+y)):(y=c.size,d=c),s&&a.chunks&&(e.settings.send_chunk_number?(g.chunk=Math.ceil(f/s),g.chunks=Math.ceil(c.size/s)):(g.offset=f,g.total=c.size)),m=new t.XMLHttpRequest,m.upload&&(m.upload.onprogress=function(t){n.loaded=Math.min(n.size,f+t.loaded),e.trigger("UploadProgress",n)}),m.onload=function(){if(m.status>=400){h();return}u=e.settings.max_retries,y<c.size?(d.destroy(),f+=y,n.loaded=Math.min(f,c.size),e.trigger("ChunkUploaded",n,{offset:n.loaded,total:c.size,response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()}),t.Env.browser==="Android Browser"&&e.trigger("UploadProgress",n)):n.loaded=n.size,d=v=null,!f||f>=c.size?(n.size!=n.origSize&&(c.destroy(),c=null),e.trigger("UploadProgress",n),n.status=o.DONE,e.trigger("FileUploaded",n,{response:m.responseText,status:m.status,responseHeaders:m.getAllResponseHeaders()})):r(p,1)},m.onerror=function(){h()},m.onloadend=function(){this.destroy(),m=null},e.settings.multipart&&a.multipart?(m.open("post",i,!0),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),v=new t.FormData,o.each(o.extend(g,e.settings.multipart_params),function(e,t){v.append(t,e)}),v.append(e.settings.file_data_name,d),m.send(v,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url})):(i=o.buildUrl(e.settings.url,o.extend(g,e.settings.multipart_params)),m.open("post",i,!0),m.setRequestHeader("Content-Type","application/octet-stream"),o.each(e.settings.headers,function(e,t){m.setRequestHeader(t,e)}),m.send(d,{runtime_order:e.settings.runtimes,required_caps:e.settings.required_features,preferred_caps:l,swf_url:e.settings.flash_swf_url,xap_url:e.settings.silverlight_xap_url}))}var i=e.settings.url,s=e.settings.chunk_size,u=e.settings.max_retries,a=e.features,f=0,c;n.loaded&&(f=n.loaded=s?s*Math.floor(n.loaded/s):0),c=n.getSource(),e.settings.resize.enabled&&E(c,"send_binary_string")&&!!~t.inArray(c.type,["image/jpeg","image/png"])?T.call(this,c,e.settings.resize,function(e){c=e,n.size=e.size,p()}):p()}function L(e,t){y(t)}function A(e){if(e.state==o.STARTED)p=+(new Date);else if(e.state==o.STOPPED)for(var t=e.files.length-1;t>=0;t--)e.files[t].status==o.UPLOADING&&(e.files[t].status=o.QUEUED,b())}function O(){m&&m.abort()}function M(e){b(),r(function(){g.call(e)},1)}function _(e,t){t.code===o.INIT_ERROR?e.destroy():t.code===o.HTTP_ERROR&&(t.file.status=o.FAILED,y(t.file),e.state==o.STARTED&&(e.trigger("CancelUpload"),r(function(){g.call(e)},1)))}function D(e){e.stop(),o.each(f,function(e){e.destroy()}),f=[],c.length&&(o.each(c,function(e){e.destroy()}),c=[]),h.length&&(o.each(h,function(e){e.destroy()}),h=[]),l={},v=!1,p=m=null,d.reset()}var u=o.guid(),a,f=[],l={},c=[],h=[],p,d,v=!1,m;a={runtimes:t.Runtime.order,max_retries:0,chunk_size:0,multipart:!0,multi_selection:!0,file_data_name:"file",flash_swf_url:"js/Moxie.swf",silverlight_xap_url:"js/Moxie.xap",filters:{mime_types:[],prevent_duplicates:!1,max_file_size:0},resize:{enabled:!1,preserve_headers:!0,crop:!1},send_file_name:!0,send_chunk_number:!0},N.call(this,e,null,!0),d=new o.QueueProgress,o.extend(this,{id:u,uid:u,state:o.STOPPED,features:{},runtime:null,files:f,settings:a,total:d,init:function(){var e=this;typeof a.preinit=="function"?a.preinit(e):o.each(a.preinit,function(t,n){e.bind(n,t)}),S.call(this);if(!a.browse_button||!a.url){this.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")});return}x.call(this,a,function(n){typeof a.init=="function"?a.init(e):o.each(a.init,function(t,n){e.bind(n,t)}),n?(e.runtime=t.Runtime.getInfo(w()).type,e.trigger("Init",{runtime:e.runtime}),e.trigger("PostInit")):e.trigger("Error",{code:o.INIT_ERROR,message:o.translate("Init error.")})})},setOption:function(e,t){N.call(this,e,t,!this.runtime)},getOption:function(e){return e?a[e]:a},refresh:function(){c.length&&o.each(c,function(e){e.trigger("Refresh")}),this.trigger("Refresh")},start:function(){this.state!=o.STARTED&&(this.state=o.STARTED,this.trigger("StateChanged"),g.call(this))},stop:function(){this.state!=o.STOPPED&&(this.state=o.STOPPED,this.trigger("StateChanged"),this.trigger("CancelUpload"))},disableBrowse:function(){v=arguments[0]!==n?arguments[0]:!0,c.length&&o.each(c,function(e){e.disable(v)}),this.trigger("DisableBrowse",v)},getFile:function(e){var t;for(t=f.length-1;t>=0;t--)if(f[t].id===e)return f[t]},addFile:function(e,n){function c(e,n){var r=[];t.each(s.settings.filters,function(t,n){i[n]&&r.push(function(r){i[n].call(s,t,e,function(e){r(!e)})})}),t.inSeries(r,n)}function h(e){var i=t.typeOf(e);if(e instanceof t.File){if(!e.ruid&&!e.isDetached()){if(!l)return!1;e.ruid=l,e.connectRuntime(l)}h(new o.File(e))}else e instanceof t.Blob?(h(e.getSource()),e.destroy()):e instanceof o.File?(n&&(e.name=n),u.push(function(t){c(e,function(n){n||(f.push(e),a.push(e),s.trigger("FileFiltered",e)),r(t,1)})})):t.inArray(i,["file","blob"])!==-1?h(new t.File(null,e)):i==="node"&&t.typeOf(e.files)==="filelist"?t.each(e.files,h):i==="array"&&(n=null,t.each(e,h))}var s=this,u=[],a=[],l;l=w(),h(e),u.length&&t.inSeries(u,function(){a.length&&s.trigger("FilesAdded",a)})},removeFile:function(e){var t=typeof e=="string"?e:e.id;for(var n=f.length-1;n>=0;n--)if(f[n].id===t)return this.splice(n,1)[0]},splice:function(e,t){var r=f.splice(e===n?0:e,t===n?f.length:t),i=!1;return this.state==o.STARTED&&(o.each(r,function(e){if(e.status===o.UPLOADING)return i=!0,!1}),i&&this.stop()),this.trigger("FilesRemoved",r),o.each(r,function(e){e.destroy()}),i&&this.start(),r},dispatchEvent:function(e){var t,n,r;e=e.toLowerCase(),t=this.hasEventListener(e);if(t){t.sort(function(e,t){return t.priority-e.priority}),n=[].slice.call(arguments),n.shift(),n.unshift(this);for(var i=0;i<t.length;i++)if(t[i].fn.apply(t[i].scope,n)===!1)return!1}return!0},bind:function(e,t,n,r){o.Uploader.prototype.bind.call(this,e,t,r,n)},destroy:function(){this.trigger("Destroy"),a=d=null,this.unbindAll()}})},o.Uploader.prototype=t.EventTarget.instance,o.File=function(){function n(n){o.extend(this,{id:o.guid(),name:n.name||n.fileName,type:n.type||"",size:n.size||n.fileSize,origSize:n.size||n.fileSize,loaded:0,percent:0,status:o.QUEUED,lastModifiedDate:n.lastModifiedDate||(new Date).toLocaleString(),getNative:function(){var e=this.getSource().getSource();return t.inArray(t.typeOf(e),["blob","file"])!==-1?e:null},getSource:function(){return e[this.id]?e[this.id]:null},destroy:function(){var t=this.getSource();t&&(t.destroy(),delete e[this.id])}}),e[this.id]=n}var e={};return n}(),o.QueueProgress=function(){var e=this;e.size=0,e.loaded=0,e.uploaded=0,e.failed=0,e.queued=0,e.percent=0,e.bytesPerSec=0,e.reset=function(){e.size=e.loaded=e.uploaded=e.failed=e.queued=e.percent=e.bytesPerSec=0}},e.plupload=o})(window,mOxie);
\ No newline at end of file
--- a/composer.json
+++ b/composer.json
@@ -34,7 +34,7 @@
 		"symfony/http-kernel": "2.3.*",
 		"symfony/routing": "2.3.*",
 		"symfony/yaml": "2.3.*",
-		"twig/twig": "1.13.*"
+		"twig/twig": "1.*"
 	},
 	"require-dev": {
 		"fabpot/goutte": "1.0.*",
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "17b51553237b78392baf2ec78bfdfbc0",
+    "hash": "5864f5064e1ca81dd9817ee2674b5dfd",
     "packages": [
         {
             "name": "lusitanian/oauth",
@@ -650,25 +650,25 @@
         },
         {
             "name": "twig/twig",
-            "version": "v1.13.2",
+            "version": "v1.20.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755"
+                "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/6d6a1009427d1f398c9d40904147bf9f723d5755",
-                "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
+                "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.2.4"
+                "php": ">=5.2.7"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.13-dev"
+                    "dev-master": "1.20-dev"
                 }
             },
             "autoload": {
@@ -683,11 +683,19 @@
             "authors": [
                 {
                     "name": "Fabien Potencier",
-                    "email": "fabien@symfony.com"
+                    "email": "fabien@symfony.com",
+                    "homepage": "http://fabien.potencier.org",
+                    "role": "Lead Developer"
                 },
                 {
                     "name": "Armin Ronacher",
-                    "email": "armin.ronacher@active-4.com"
+                    "email": "armin.ronacher@active-4.com",
+                    "role": "Project Founder"
+                },
+                {
+                    "name": "Twig Team",
+                    "homepage": "http://twig.sensiolabs.org/contributors",
+                    "role": "Contributors"
                 }
             ],
             "description": "Twig, the flexible, fast, and secure template language for PHP",
@@ -695,7 +703,7 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2013-08-03 15:35:31"
+            "time": "2015-08-12 15:56:39"
         }
     ],
     "packages-dev": [
@@ -761,12 +769,12 @@
             "target-dir": "Guzzle/Common",
             "source": {
                 "type": "git",
-                "url": "https://github.com/guzzle/common.git",
+                "url": "https://github.com/Guzzle3/common.git",
                 "reference": "bf73c87375f60861f8c7ccc7b95878023ade5306"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/common/zipball/bf73c87375f60861f8c7ccc7b95878023ade5306",
+                "url": "https://api.github.com/repos/Guzzle3/common/zipball/bf73c87375f60861f8c7ccc7b95878023ade5306",
                 "reference": "bf73c87375f60861f8c7ccc7b95878023ade5306",
                 "shasum": ""
             },
@@ -805,12 +813,12 @@
             "target-dir": "Guzzle/Http",
             "source": {
                 "type": "git",
-                "url": "https://github.com/guzzle/http.git",
+                "url": "https://github.com/Guzzle3/http.git",
                 "reference": "1034125dfd906b73119e535f03153a62fccb1989"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/http/zipball/1034125dfd906b73119e535f03153a62fccb1989",
+                "url": "https://api.github.com/repos/Guzzle3/http/zipball/1034125dfd906b73119e535f03153a62fccb1989",
                 "reference": "1034125dfd906b73119e535f03153a62fccb1989",
                 "shasum": ""
             },
@@ -862,12 +870,12 @@
             "target-dir": "Guzzle/Parser",
             "source": {
                 "type": "git",
-                "url": "https://github.com/guzzle/parser.git",
+                "url": "https://github.com/Guzzle3/parser.git",
                 "reference": "a25c2ddda1c52fb69a4ee56eb530b13ddd9573c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/parser/zipball/a25c2ddda1c52fb69a4ee56eb530b13ddd9573c2",
+                "url": "https://api.github.com/repos/Guzzle3/parser/zipball/a25c2ddda1c52fb69a4ee56eb530b13ddd9573c2",
                 "reference": "a25c2ddda1c52fb69a4ee56eb530b13ddd9573c2",
                 "shasum": ""
             },
@@ -906,12 +914,12 @@
             "target-dir": "Guzzle/Stream",
             "source": {
                 "type": "git",
-                "url": "https://github.com/guzzle/stream.git",
+                "url": "https://github.com/Guzzle3/stream.git",
                 "reference": "a86111d9ac7db31d65a053c825869409fe8fc83f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/guzzle/stream/zipball/a86111d9ac7db31d65a053c825869409fe8fc83f",
+                "url": "https://api.github.com/repos/Guzzle3/stream/zipball/a86111d9ac7db31d65a053c825869409fe8fc83f",
                 "reference": "a86111d9ac7db31d65a053c825869409fe8fc83f",
                 "shasum": ""
             },
@@ -1543,12 +1551,12 @@
             "version": "v1.0.2",
             "source": {
                 "type": "git",
-                "url": "https://github.com/fabpot/Pimple.git",
+                "url": "https://github.com/silexphp/Pimple.git",
                 "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/fabpot/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
+                "url": "https://api.github.com/repos/silexphp/Pimple/zipball/ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
                 "reference": "ae11e57e8c2bb414b2ff93396dbbfc0eb92feb94",
                 "shasum": ""
             },
--- a/config/avatar.yml
+++ b/config/avatar.yml
@@ -60,6 +60,7 @@ services:
             - %core.php_ext%
             - @path_helper
             - @mimetype.guesser
+            - @dispatcher
             - @cache.driver
         calls:
             - [set_name, [avatar.driver.upload]]
--- a/config/cron.yml
+++ b/config/cron.yml
@@ -120,6 +120,7 @@ services:
             - @config
             - @dbal.conn
             - @user
+            - @dispatcher
         calls:
             - [set_name, [cron.task.core.tidy_search]]
         tags:
--- a/docs/CHANGELOG.html
+++ b/docs/CHANGELOG.html
@@ -6,7 +6,7 @@
 <meta name="description" content="phpBB 3.1.x Changelog" />
 <title>phpBB &bull; Changelog</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -49,6 +49,7 @@
 <ol>
 	<li><a href="#changelog">Changelog</a>
 	<ul>
+		<li><a href="#v315">Changes since 3.1.5</a></li>
 		<li><a href="#v314">Changes since 3.1.4</a></li>
 		<li><a href="#v313">Changes since 3.1.3</a></li>
 		<li><a href="#v313rc1">Changes since 3.1.3-RC1</a></li>
@@ -112,6 +113,94 @@
 
 		<div class="content">
 
+			<a name="v315"></a><h3>Changes since 3.1.5</h3>
+
+	<h4>Bug</h4>
+	<ul>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10711">PHPBB3-10711</a>] - SQL error DUPLICATE for KEY in FORUMS_TRACK_TABLE </li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13711">PHPBB3-13711</a>] - disabled accounts receive mails</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13815">PHPBB3-13815</a>] - Event parameters in posting do not affect behavior as expected</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13903">PHPBB3-13903</a>] - Container naming doesn't allow Windows' semicolon</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13930">PHPBB3-13930</a>] - Check for correct spacing between keyword &amp; parenthesis in codesniffer</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13941">PHPBB3-13941</a>] - One test is blocked in an inifinite loop on php 5.5+ and with sqlite3</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13948">PHPBB3-13948</a>] - Only reports top level WHOIS IP for a user in ACP</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13949">PHPBB3-13949</a>] - Replace colon with colon lang key in memberlist search page</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13951">PHPBB3-13951</a>] - Jump to page function does not work since 3.1.5 upgrade</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13952">PHPBB3-13952</a>] - Fulltext Native errors from tidy_search cron task</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13955">PHPBB3-13955</a>] - 3.1.5 not loading CDN resources</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13962">PHPBB3-13962</a>] - Forum dropdown in MCP queue could expand beyond screen size</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13966">PHPBB3-13966</a>] - Change post's author --&gt; error message</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13967">PHPBB3-13967</a>] - BBCode guide - loading phpBB logo image breaks https</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13980">PHPBB3-13980</a>] - Current avatar not removed when uploading with different extension</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13984">PHPBB3-13984</a>] - AJAX Loading Indicator broken</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14037">PHPBB3-14037</a>] - Memberlist profile fields headlines not computed from same way as data</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14049">PHPBB3-14049</a>] - Plupload delete request should use config headers</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14069">PHPBB3-14069</a>] - Incorrect sql_fetchfield call in style_update_p1 migration</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14077">PHPBB3-14077</a>] - Select all code not work in Microsoft Edge</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14082">PHPBB3-14082</a>] - Fix wrong variables in fulltext native search for keyworded results</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14083">PHPBB3-14083</a>] - Fix wrong variables in fulltext mysql search for author search</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14093">PHPBB3-14093</a>] - Hardcoded language in ucp_pm_viewfolder.html</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14103">PHPBB3-14103</a>] - Underline in abbreviations in Firefox 40</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14104">PHPBB3-14104</a>] - Fix missing variable in fulltext native search query for total results for author</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14115">PHPBB3-14115</a>] - Microdata is not valid in prosilver</li>
+	</ul>
+	<h4>Improvement</h4>
+	<ul>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11530">PHPBB3-11530</a>] - Remove quotes that are too deep automatically</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12952">PHPBB3-12952</a>] - Display HTTP Output along with Status code in case assertion fails in functional tests</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13598">PHPBB3-13598</a>] - Add an option to post a locked topic</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13786">PHPBB3-13786</a>] - Add core events to add MCP post options</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13818">PHPBB3-13818</a>] - Browse Extensions Database link in Extension Manager</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13843">PHPBB3-13843</a>] - Add templates events to insert custom panel-tab into posting editor</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13863">PHPBB3-13863</a>] - [Template] - topiclist_row_append/topiclist_row_prepend in mcp_forum.html</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13879">PHPBB3-13879</a>] - We're using px most places but ems in others</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13882">PHPBB3-13882</a>] - Avatars in notifications should be lazy loaded</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13899">PHPBB3-13899</a>] - Add items to core.search_results_modify_search_title</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13911">PHPBB3-13911</a>] - Add configuration options to profile fields</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13931">PHPBB3-13931</a>] - Wrong order in docs/events.md</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13968">PHPBB3-13968</a>] - [PHP] - core.user_setup_after</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13971">PHPBB3-13971</a>] - Add draft_id variable to event core.posting_modify_template_vars</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13981">PHPBB3-13981</a>] - Events to intercept uploaded avatar deletion</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13995">PHPBB3-13995</a>] - Invalid HTML using Projection Media Type</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14002">PHPBB3-14002</a>] - Add template events before/after user details in ucp_main_front.html</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14005">PHPBB3-14005</a>] - Allow extensions control post buttons displaying</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14014">PHPBB3-14014</a>] - [PHP] - mcp_forum_view_actions</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14064">PHPBB3-14064</a>] - Add template events to ucp_pm_history.html</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14065">PHPBB3-14065</a>] - Add template events to attachment.html</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14067">PHPBB3-14067</a>] - Add template events to overall_header.html around feeds</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14068">PHPBB3-14068</a>] - New events around poll panel in viewtopic</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14072">PHPBB3-14072</a>] - Add core event to the function format_display()</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14085">PHPBB3-14085</a>] - [Template] - posting_topic_title_prepend</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14086">PHPBB3-14086</a>] - [Template] - Add mcp_forum_topic_title_*</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14090">PHPBB3-14090</a>] - [Template] - mcp_topic_topic_title_*</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14091">PHPBB3-14091</a>] - [Template] - mcp_topic_subject_*</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14101">PHPBB3-14101</a>] - Add core event to the download/file.php</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14116">PHPBB3-14116</a>] - sql_affectedrows has no arguments</li>
+	</ul>
+	<h4>New Feature</h4>
+	<ul>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12692">PHPBB3-12692</a>] - Add a console command to manage the thumbnail</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13311">PHPBB3-13311</a>] - Add php event to acp manage_forums when deleting content</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13974">PHPBB3-13974</a>] - Add php event for altering data when changing a post's poster</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13997">PHPBB3-13997</a>] - [Template] - posting_editor_submit_buttons</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14006">PHPBB3-14006</a>] - [PHP] - core.ucp_register_agreement</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14041">PHPBB3-14041</a>] - [Template] - viewtopic_dropdown_top_custom</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14042">PHPBB3-14042</a>] - [Template] - viewtopic_dropdown_bottom_custom</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14043">PHPBB3-14043</a>] - [PHP] - core.get_avatar_after</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14087">PHPBB3-14087</a>] - Add an event to ucp_activate.php.</li>
+	</ul>
+	<h4>Sub-task</h4>
+	<ul>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13694">PHPBB3-13694</a>] - Allow modifying the Postgres author search query for results</li>
+	</ul>
+	<h4>Task</h4>
+	<ul>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13947">PHPBB3-13947</a>] - Add CHItA to developer list</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14010">PHPBB3-14010</a>] - Update Plupload to 2.1.8</li>
+		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14099">PHPBB3-14099</a>] - Update Twig to 1.20</li>
+	</ul>
+
+
 	<a name="v314"></a><h3>Changes since 3.1.4</h3>
 
 	<h4>Bug</h4>
@@ -4979,7 +5068,7 @@
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/CREDITS.txt
+++ b/docs/CREDITS.txt
@@ -23,6 +23,7 @@ phpBB Project Manager:   Marshalrusty (Yuriy Rusko)
 phpBB Lead Developer:    naderman (Nils Adermann)
 
 phpBB Developers:        bantu (Andreas Fischer)
+                         CHItA (Máté Bartus)
                          dhruv.goel92 (Dhruv Goel)
                          Elsensee (Oliver Schramm)
                          marc1706 (Marc Alexander)
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -6,7 +6,7 @@
 <meta name="description" content="phpBB 3.1.x frequently asked questions" />
 <title>phpBB &bull; FAQ</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -343,7 +343,7 @@ I want to sue you because i think you host an illegal board!</h2>
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/INSTALL.html
+++ b/docs/INSTALL.html
@@ -6,7 +6,7 @@
 <meta name="description" content="phpBB 3.1.x Installation, updating and conversion informations" />
 <title>phpBB &bull; Install</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -507,7 +507,7 @@
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/README.html
+++ b/docs/README.html
@@ -6,7 +6,7 @@
 <meta name="description" content="phpBB 3.1.x Readme" />
 <title>phpBB &bull; Readme</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -366,7 +366,7 @@
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/auth_api.html
+++ b/docs/auth_api.html
@@ -6,7 +6,7 @@
 <meta name="description" content="This is an explanation of how to use the phpBB auth/acl API" />
 <title>phpBB3 &bull; Auth API</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -110,7 +110,7 @@ $auth = new phpbb\auth\auth();</pre>
 	<p>Following are the methods you are able to use.</p>
 
 	<a name="acl"></a><h3>2.i. acl</h3>
-	
+
 	<p>The <code>acl</code> method is the initialisation routine for all the acl functions. If you intend calling any acl method you must first call this. The method takes as its one and only required parameter an associative array containing user information as stored in the database. This array must contain at least the following information; user_id, user_permissions and user_type. It is called in the following way:</p>
 
 	<div class="codebox"><pre>
@@ -285,7 +285,7 @@ $auth_admin = new auth_admin();</pre>
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/coding-guidelines.html
+++ b/docs/coding-guidelines.html
@@ -6,7 +6,7 @@
 <meta name="description" content="Ascraeus coding guidelines document" />
 <title>phpBB3 &bull; Coding Guidelines</title>
 
-<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen, projection" />
+<link href="assets/css/stylesheet.css" rel="stylesheet" type="text/css" media="screen" />
 
 </head>
 
@@ -300,9 +300,9 @@ PHPBB_QA                   (Set board to QA-Mode, which means the updater also c
 	<div class="indent">
 		<p><code>$current_user</code> is right, but <code>$currentuser</code> and <code> $currentUser</code> are not.</p>
 	</div>
-	
+
 	<p>In JavaScript, variable names should use camel case:</p>
-	
+
 	<div class="indent">
 		<p><code>currentUser</code> is right, but <code>currentuser</code> and <code>current_user</code> are not.</p>
 	</div>
@@ -431,7 +431,7 @@ function do_stuff()
 	...
 }</pre>
 	</div>
-	
+
 	<p>In JavaScript code, braces always go on the same line:</p>
 
 	<div class="codebox"><pre>
@@ -2568,7 +2568,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
 </div></div>
 
 <div>
-	<a id="bottom" name="bottom" accesskey="z"></a>
+	<a id="bottom" accesskey="z"></a>
 </div>
 
 </body>
--- a/docs/events.md
+++ b/docs/events.md
@@ -22,6 +22,12 @@ acp_email_options_after
 * Since: 3.1.2-RC1
 * Purpose: Add settings to mass email form
 
+acp_forums_custom_settings
+===
+* Location: adm/style/acp_forums.html
+* Since: 3.1.6-RC1
+* Purpose: Add its own box (fieldset) for extension settings
+
 acp_forums_main_settings_append
 ===
 * Location: adm/style/acp_forums.html
@@ -133,6 +139,13 @@ acp_posting_buttons_before
 * Since: 3.1.0-b4
 * Purpose: Add content before BBCode posting buttons in the ACP
 
+acp_profile_contact_before
+===
+* Locations:
+    + adm/style/acp_profile.html
+* Since: 3.1.6-RC1
+* Purpose: Add extra options to custom profile field configuration in the ACP
+
 acp_ranks_edit_after
 ===
 * Locations:
@@ -277,6 +290,38 @@ acp_users_prefs_view_prepend
 * Since: 3.1.0-b3
 * Purpose: Add user options fieldset to the top of ACP users view prefs settings
 
+attachment_file_after
+===
+* Locations:
+    + styles/prosilver/template/attachment.html
+    + styles/subsilver2/template/attachment.html
+* Since: 3.1.6-RC1
+* Purpose: Add content after the attachment.
+
+attachment_file_append
+===
+* Locations:
+    + styles/prosilver/template/attachment.html
+    + styles/subsilver2/template/attachment.html
+* Since: 3.1.6-RC1
+* Purpose: Add custom attachment types displaying to the bottom of attachment block.
+
+attachment_file_before
+===
+* Locations:
+    + styles/prosilver/template/attachment.html
+    + styles/subsilver2/template/attachment.html
+* Since: 3.1.6-RC1
+* Purpose: Add content before the attachment.
+
+attachment_file_prepend
+===
+* Locations:
+    + styles/prosilver/template/attachment.html
+    + styles/subsilver2/template/attachment.html
+* Since: 3.1.6-RC1
+* Purpose: Add custom attachment types displaying to the top of attachment block.
+
 forumlist_body_category_header_after
 ===
 * Locations:
@@ -491,6 +536,22 @@ mcp_ban_unban_before
 * Since: 3.1.0-RC3
 * Purpose: Add additional fields to the unban form in MCP
 
+mcp_forum_topic_title_before
+===
+* Locations:
+    + styles/prosilver/template/mcp_forum.html
+    + styles/subsilver2/template/mcp_forum.html
+* Since: 3.1.6-RC1
+* Purpose: Add some information before the topic title
+
+mcp_forum_topic_title_after
+===
+* Locations:
+    + styles/prosilver/template/mcp_forum.html
+    + styles/subsilver2/template/mcp_forum.html
+* Since: 3.1.6-RC1
+* Purpose: Add some information after the topic title
+
 mcp_front_latest_logs_after
 ===
 * Locations:
@@ -539,6 +600,88 @@ mcp_post_additional_options
 * Since: 3.1.5-RC1
 * Purpose: Add content within the list of post moderation actions
 
+mcp_topic_options_after
+===
+* Locations:
+    + styles/prosilver/template/mcp_topic.html
+    + styles/subsilver2/template/mcp_topic.html
+* Since: 3.1.6-RC1
+* Purpose: Add some options (field, checkbox, ...) after the subject field when split a subject
+
+mcp_topic_options_before
+===
+* Locations:
+    + styles/prosilver/template/mcp_topic.html
+    + styles/subsilver2/template/mcp_topic.html
+* Since: 3.1.6-RC1
+* Purpose: Add some options (field, checkbox, ...) before the subject field when split a subject
+
+mcp_topic_topic_title_after
+===
+* Locations:
+    + styles/prosilver/template/mcp_topic.html
+    + styles/subsilver2/template/mcp_topic.html
+* Since: 3.1.6-RC1
+* Purpose: Add some information after the topic title
+
+mcp_topic_topic_title_before
+===
+* Locations:
+    + styles/prosilver/template/mcp_topic.html
+    + styles/subsilver2/template/mcp_topic.html
+* Since: 3.1.6-RC1
+* Purpose: Add some information before the topic title
+
+mcp_warn_post_add_warning_field_after
+===
+* Locations:
+    + styles/prosilver/template/mcp_warn_post.html
+    + styles/subsilver2/template/mcp_warn_post.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning for a post - after add warning field.
+
+mcp_warn_post_add_warning_field_before
+===
+* Locations:
+    + styles/prosilver/template/mcp_warn_post.html
+    + styles/subsilver2/template/mcp_warn_post.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning for a post - before add warning field.
+
+mcp_warn_user_add_warning_field_after
+===
+* Locations:
+    + styles/prosilver/template/mcp_warn_user.html
+    + styles/subsilver2/template/mcp_warn_user.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning a user - after add warning field.
+
+mcp_warn_user_add_warning_field_before
+===
+* Locations:
+    + styles/prosilver/template/mcp_warn_user.html
+    + styles/subsilver2/template/mcp_warn_user.html
+* Since: 3.1.0-RC4
+* Purpose: Add content during warning a user - before add warning field.
+
+memberlist_body_rank_append
+===
+* Locations:
+    + styles/prosilver/template/memberlist_body.html
+    + styles/subsilver2/template/memberlist_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add information after rank in memberlist. Works in
+all display modes (leader, group and normal memberlist).
+
+memberlist_body_rank_prepend
+===
+* Locations:
+    + styles/prosilver/template/memberlist_body.html
+    + styles/subsilver2/template/memberlist_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add information before rank in memberlist. Works in
+all display modes (leader, group and normal memberlist).
+
 memberlist_body_username_append
 ===
 * Locations:
@@ -613,53 +756,63 @@ memberlist_view_content_prepend
 * Since: 3.1.0-b3
 * Purpose: Add custom content to the user profile view before the main content
 
-memberlist_view_user_statistics_after
+memberlist_view_rank_after
 ===
 * Locations:
-    + styles/prosilver/template/memberlist_view.html
     + styles/subsilver2/template/memberlist_view.html
-* Since: 3.1.0-a1
-* Purpose: Add entries after the user statistics part of any user profile
+* Since: 3.1.6-RC1
+* Purpose: Add information after rank in memberlist
 
-memberlist_view_user_statistics_before
+memberlist_view_rank_avatar_after
 ===
 * Locations:
     + styles/prosilver/template/memberlist_view.html
+* Since: 3.1.6-RC1
+* Purpose: Add information after rank in memberlist (with avatar)
+
+memberlist_view_rank_avatar_before
+===
+* Locations:
+    + styles/prosilver/template/memberlist_view.html
+* Since: 3.1.6-RC1
+* Purpose: Add information before rank in memberlist (with avatar)
+
+memberlist_view_rank_before
+===
+* Locations:
     + styles/subsilver2/template/memberlist_view.html
-* Since: 3.1.0-a1
-* Purpose: Add entries before the user statistics part of any user profile
+* Since: 3.1.6-RC1
+* Purpose: Add information after rank in memberlist
 
-mcp_warn_post_add_warning_field_after
+memberlist_view_rank_no_avatar_after
 ===
 * Locations:
-    + styles/prosilver/template/mcp_warn_post.html
-    + styles/subsilver2/template/mcp_warn_post.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning for a post - after add warning field.
+    + styles/prosilver/template/memberlist_view.html
+* Since: 3.1.6-RC1
+* Purpose: Add information after rank in memberlist (without avatar)
 
-mcp_warn_post_add_warning_field_before
+memberlist_view_rank_no_avatar_before
 ===
 * Locations:
-    + styles/prosilver/template/mcp_warn_post.html
-    + styles/subsilver2/template/mcp_warn_post.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning for a post - before add warning field.
+    + styles/prosilver/template/memberlist_view.html
+* Since: 3.1.6-RC1
+* Purpose: Add information before rank in memberlist (without avatar)
 
-mcp_warn_user_add_warning_field_after
+memberlist_view_user_statistics_after
 ===
 * Locations:
-    + styles/prosilver/template/mcp_warn_user.html
-    + styles/subsilver2/template/mcp_warn_user.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning a user - after add warning field.
+    + styles/prosilver/template/memberlist_view.html
+    + styles/subsilver2/template/memberlist_view.html
+* Since: 3.1.0-a1
+* Purpose: Add entries after the user statistics part of any user profile
 
-mcp_warn_user_add_warning_field_before
+memberlist_view_user_statistics_before
 ===
 * Locations:
-    + styles/prosilver/template/mcp_warn_user.html
-    + styles/subsilver2/template/mcp_warn_user.html
-* Since: 3.1.0-RC4
-* Purpose: Add content during warning a user - before add warning field.
+    + styles/prosilver/template/memberlist_view.html
+    + styles/subsilver2/template/memberlist_view.html
+* Since: 3.1.0-a1
+* Purpose: Add entries before the user statistics part of any user profile
 
 navbar_header_logged_out_content
 ===
@@ -854,6 +1007,14 @@ overall_header_content_before
 * Since: 3.1.0-a3
 * Purpose: Add content on all pages before the main content, after the header
 
+overall_header_feeds
+===
+* Locations:
+    + styles/prosilver/template/overall_header.html
+    + styles/subsilver2/template/overall_header.html
+* Since: 3.1.6-RC1
+* Purpose: Add custom feeds
+
 overall_header_head_append
 ===
 * Locations:
@@ -926,6 +1087,13 @@ overall_header_stylesheets_after
 * Purpose: Add asset calls after stylesheets within the `</head>` tag.
 Note that INCLUDECSS will not work with this event.
 
+posting_editor_add_panel_tab
+===
+* Locations:
+    + styles/prosilver/template/posting_editor.html
+* Since: 3.1.6-RC1
+* Purpose: Add custom panel to post editor
+
 posting_editor_bbcode_status_after
 ===
 * Locations:
@@ -1014,6 +1182,21 @@ posting_editor_subject_before
 * Since: 3.1.0-a2
 * Purpose: Add field (e.g. textbox) to the posting screen before the subject
 
+posting_editor_submit_buttons
+===
+* Locations:
+    + styles/prosilver/template/posting_editor.html
+    + styles/subsilver2/template/posting_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add custom buttons in the posting editor
+
+posting_layout_include_panel_body
+===
+* Locations:
+    + styles/prosilver/template/posting_layout.html
+* Since: 3.1.6-RC1
+* Purpose: Add include of custom panel template body in posting editor
+
 posting_pm_header_find_username_after
 ===
 * Locations:
@@ -1052,6 +1235,14 @@ posting_poll_body_options_after
 * Since: 3.1.4-RC1
 * Purpose: Add content after the poll options on creating a poll
 
+posting_topic_title_before
+===
+* Locations:
+    + styles/prosilver/template/posting_layout.html
+    + styles/subsilver2/template/posting_body.html
+* Since: 3.1.6-RC1
+* Purpose: Allows to add some information on the left of the topic title in the posting form
+
 quickreply_editor_panel_after
 ===
 * Locations:
@@ -1200,9 +1391,12 @@ topiclist_row_prepend
 * Locations:
     + styles/prosilver/template/search_results.html
     + styles/prosilver/template/viewforum_body.html
+    + styles/prosilver/template/mcp_forum.html
     + styles/subsilver2/template/search_results.html
     + styles/subsilver2/template/viewforum_body.html
+    + styles/subsilver2/template/mcp_forum.html
 * Since: 3.1.0-a1
+* Changed: 3.1.6-RC1 Added event to mcp_forum.html
 * Purpose: Add content into topic rows (inside the elements containing topic titles)
 
 topiclist_row_append
@@ -1210,9 +1404,12 @@ topiclist_row_append
 * Locations:
     + styles/prosilver/template/search_results.html
     + styles/prosilver/template/viewforum_body.html
+    + styles/prosilver/template/mcp_forum.html
     + styles/subsilver2/template/search_results.html
     + styles/subsilver2/template/viewforum_body.html
+    + styles/subsilver2/template/mcp_forum.html
 * Since: 3.1.0-a1
+* Changed: 3.1.6-RC1 Added event to mcp_forum.html
 * Purpose: Add content into topic rows (inside the elements containing topic titles)
 
 ucp_agreement_terms_after
@@ -1231,6 +1428,72 @@ ucp_agreement_terms_before
 * Since: 3.1.0-b3
 * Purpose: Add content before the terms of agreement text at user registration
 
+ucp_main_front_user_activity_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_main_front.html
+    + styles/subsilver2/template/ucp_main_front.html
+* Since: 3.1.6-RC1
+* Purpose: Add content right after the user activity info viewing UCP front page
+
+ucp_main_front_user_activity_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_main_front.html
+    + styles/subsilver2/template/ucp_main_front.html
+* Since: 3.1.6-RC1
+* Purpose: Add content right before the user activity info viewing UCP front page
+
+ucp_pm_history_post_buttons_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+    + styles/subsilver2/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button to private messages in history review (next to quote etc), at
+the end of the list.
+
+ucp_pm_history_post_buttons_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+    + styles/subsilver2/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button to private messages in history review (next to quote etc), at
+the start of the list.
+
+ucp_pm_history_post_buttons_list_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button custom list to private messages in history review (next to quote etc),
+after the original list.
+
+ucp_pm_history_post_buttons_list_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button custom list to private messages in history review (next to quote etc),
+before the original list.
+
+ucp_pm_history_review_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+    + styles/subsilver2/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add content after the private messages history review.
+
+ucp_pm_history_review_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_history.html
+    + styles/subsilver2/template/ucp_pm_history.html
+* Since: 3.1.6-RC1
+* Purpose: Add content before the private messages history review.
+
 ucp_pm_viewmessage_avatar_after
 ===
 * Locations:
@@ -1295,6 +1558,22 @@ ucp_pm_viewmessage_post_buttons_before
 * Purpose: Add post button to private messages (next to edit, quote etc), at
 the start of the list.
 
+ucp_pm_viewmessage_post_buttons_list_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button custom list to private messages (next to edit, quote etc),
+after the original list.
+
+ucp_pm_viewmessage_post_buttons_list_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.6-RC1
+* Purpose: Add post button custom list to private messages (next to edit, quote etc),
+before the original list.
+
 ucp_pm_viewmessage_print_head_append
 ===
 * Locations:
@@ -1303,6 +1582,22 @@ ucp_pm_viewmessage_print_head_append
 * Since: 3.1.0-a1
 * Purpose: Add asset calls directly before the `</head>` tag of the Print PM screen
 
+ucp_pm_viewmessage_rank_after
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.6-RC1
+* Purpose: Add data after the rank on the user profile when viewing
+a private message
+
+ucp_pm_viewmessage_rank_before
+===
+* Locations:
+    + styles/prosilver/template/ucp_pm_viewmessage.html
+* Since: 3.1.6-RC1
+* Purpose: Add data before the rank on the user profile when viewing
+a private message
+
 ucp_prefs_personal_prepend
 ===
 * Locations:
@@ -1523,6 +1818,20 @@ viewtopic_buttons_top_after
 * Since: 3.1.0-RC5
 * Purpose: Add buttons after Post Reply button on the top of the posts's list
 
+viewtopic_dropdown_bottom_custom
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Create a custom dropdown menu
+
+viewtopic_dropdown_top_custom
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Create a custom dropdown menu
+
 viewforum_forum_name_append
 ===
 * Locations:
@@ -1613,6 +1922,22 @@ viewtopic_body_footer_before
 and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in
 Subsilver2.
 
+viewtopic_body_poll_after
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+    + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add content after the poll panel.
+
+viewtopic_body_poll_before
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+    + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add content before the poll panel.
+
 viewtopic_body_poll_option_after
 ===
 * Locations:
@@ -1771,6 +2096,24 @@ viewtopic_body_postrow_post_notices_before
 * Since: 3.1.0-b2
 * Purpose: Add posts specific custom notices at the notices top.
 
+viewtopic_body_postrow_rank_after
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+    + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add data after the rank on the user profile when viewing
+a post
+
+viewtopic_body_postrow_rank_before
+===
+* Locations:
+    + styles/prosilver/template/viewtopic_body.html
+    + styles/subsilver2/template/viewtopic_body.html
+* Since: 3.1.6-RC1
+* Purpose: Add data before the rank on the user profile when viewing
+a post
+
 viewtopic_body_topic_actions_before
 ===
 * Locations:
--- a/download/file.php
+++ b/download/file.php
@@ -250,6 +250,30 @@ else
 		$display_cat = ATTACHMENT_CATEGORY_NONE;
 	}
 
+	/**
+	* Event to modify data before sending file to browser
+	*
+	* @event core.download_file_send_to_browser_before
+	* @var	int		attach_id			The attachment ID
+	* @var	array	attachment			Array with attachment data
+	* @var	int		display_cat			Attachment category
+	* @var	int		download_mode		File extension specific download mode
+	* @var	array	extension			Array with file extensions data
+	* @var	string	mode				Download mode
+	* @var	bool	thumbnail			Flag indicating if the file is a thumbnail
+	* @since 3.1.6-RC1
+	*/
+	$vars = array(
+		'attach_id',
+		'attachment',
+		'display_cat',
+		'download_mode',
+		'extension',
+		'mode',
+		'thumbnail',
+	);
+	extract($phpbb_dispatcher->trigger_event('core.download_file_send_to_browser_before', compact($vars)));
+
 	if ($thumbnail)
 	{
 		$attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename'];
--- a/includes/acp/acp_database.php
+++ b/includes/acp/acp_database.php
@@ -1558,7 +1558,7 @@ class mssql_extractor extends base_extractor
 		{
 			$this->write_data_mssql($table_name);
 		}
-		else if($db->get_sql_layer() === 'mssqlnative')
+		else if ($db->get_sql_layer() === 'mssqlnative')
 		{
 			$this->write_data_mssqlnative($table_name);
 		}
--- a/includes/acp/acp_extensions.php
+++ b/includes/acp/acp_extensions.php
@@ -76,7 +76,7 @@ class acp_extensions
 			{
 				$md_manager->get_metadata('all');
 			}
-			catch(\phpbb\extension\exception $e)
+			catch (\phpbb\extension\exception $e)
 			{
 				trigger_error($e, E_USER_WARNING);
 			}
@@ -352,7 +352,7 @@ class acp_extensions
 				$enabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
 				$enabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
 			}
-			catch(\phpbb\extension\exception $e)
+			catch (\phpbb\extension\exception $e)
 			{
 				$this->template->assign_block_vars('disabled', array(
 					'META_DISPLAY_NAME'		=> $this->user->lang('EXTENSION_INVALID_LIST', $name, $e),
@@ -408,7 +408,7 @@ class acp_extensions
 				$disabled_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
 				$disabled_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
 			}
-			catch(\phpbb\extension\exception $e)
+			catch (\phpbb\extension\exception $e)
 			{
 				$this->template->assign_block_vars('disabled', array(
 					'META_DISPLAY_NAME'		=> $this->user->lang('EXTENSION_INVALID_LIST', $name, $e),
@@ -467,7 +467,7 @@ class acp_extensions
 				$available_extension_meta_data[$name]['S_VERSIONCHECK'] = true;
 				$available_extension_meta_data[$name]['U_VERSIONCHECK_FORCE'] = $this->u_action . '&amp;action=details&amp;versioncheck_force=1&amp;ext_name=' . urlencode($md_manager->get_metadata('name'));
 			}
-			catch(\phpbb\extension\exception $e)
+			catch (\phpbb\extension\exception $e)
 			{
 				$this->template->assign_block_vars('disabled', array(
 					'META_DISPLAY_NAME'		=> $this->user->lang('EXTENSION_INVALID_LIST', $name, $e),
--- a/includes/acp/acp_forums.php
+++ b/includes/acp/acp_forums.php
@@ -1786,7 +1786,7 @@ class acp_forums
 	*/
 	function delete_forum_content($forum_id)
 	{
-		global $db, $config, $phpbb_root_path, $phpEx;
+		global $db, $config, $phpbb_root_path, $phpEx, $phpbb_dispatcher;
 
 		include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
 
@@ -1918,6 +1918,24 @@ class acp_forums
 
 		$table_ary = array(FORUMS_ACCESS_TABLE, FORUMS_TRACK_TABLE, FORUMS_WATCH_TABLE, LOG_TABLE, MODERATOR_CACHE_TABLE, POSTS_TABLE, TOPICS_TABLE, TOPICS_TRACK_TABLE);
 
+		/**
+		 * Perform additional actions before forum content deletion
+		 *
+		 * @event core.delete_forum_content_before_query
+		 * @var	array	table_ary	Array of tables from which all rows will be deleted that hold the forum_id
+		 * @var	int		forum_id	the forum id
+		 * @var	array	topic_ids	Array of the topic ids from the forum to be deleted
+		 * @var	array	post_counts	Array of counts of posts in the forum, by poster_id
+		 * @since 3.1.6-RC1
+		 */
+		$vars = array(
+				'table_ary',
+				'forum_id',
+				'topic_ids',
+				'post_counts',
+		);
+		extract($phpbb_dispatcher->trigger_event('core.delete_forum_content_before_query', compact($vars)));
+
 		foreach ($table_ary as $table)
 		{
 			$db->sql_query("DELETE FROM $table WHERE forum_id = $forum_id");
--- a/includes/acp/acp_profile.php
+++ b/includes/acp/acp_profile.php
@@ -31,7 +31,7 @@ class acp_profile
 	{
 		global $config, $db, $user, $auth, $template, $cache;
 		global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix;
-		global $request, $phpbb_container;
+		global $request, $phpbb_container, $phpbb_dispatcher;
 
 		include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
 		include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
@@ -369,6 +369,32 @@ class acp_profile
 					'field_is_contact',
 				);
 
+				/**
+				* Event to add initialization for new profile field table fields
+				*
+				* @event core.acp_profile_create_edit_init
+				* @var	string	action			create|edit
+				* @var	int		step			Configuration step (1|2|3)
+				* @var	bool	submit			Form has been submitted
+				* @var	bool	save			Configuration should be saved
+				* @var	string	field_type		Type of the field we are dealing with
+				* @var	array	field_row		Array of data about the field
+				* @var	array	exclude			Array of excluded fields by step
+				* @var	array	visibility_ary	Array of fields that are visibility related
+				* @since 3.1.6-RC1
+				*/
+				$vars = array(
+					'action',
+					'step',
+					'submit',
+					'save',
+					'field_type',
+					'field_row',
+					'exclude',
+					'visibility_ary',
+				);
+				extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_init', compact($vars)));
+
 				$options = $profile_field->prepare_options_form($exclude, $visibility_ary);
 
 				$cp->vars['field_ident']		= ($action == 'create' && $step == 1) ? utf8_clean_string(request_var('field_ident', $field_row['field_ident'], true)) : request_var('field_ident', $field_row['field_ident']);
@@ -644,6 +670,33 @@ class acp_profile
 					break;
 				}
 
+				$field_data = $cp->vars;
+				/**
+				* Event to add template variables for new profile field table fields
+				*
+				* @event core.acp_profile_create_edit_after
+				* @var	string	action			create|edit
+				* @var	int		step			Configuration step (1|2|3)
+				* @var	bool	submit			Form has been submitted
+				* @var	bool	save			Configuration should be saved
+				* @var	string	field_type		Type of the field we are dealing with
+				* @var	array	field_data		Array of data about the field
+				* @var	array	s_hidden_fields	Array of hidden fields in case this needs modification
+				* @var	array	options			Array of options specific to this step
+				* @since 3.1.6-RC1
+				*/
+				$vars = array(
+					'action',
+					'step',
+					'submit',
+					'save',
+					'field_type',
+					'field_data',
+					's_hidden_fields',
+					'options',
+				);
+				extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_after', compact($vars)));
+
 				$template->assign_vars(array(
 					'S_HIDDEN_FIELDS'	=> $s_hidden_fields)
 				);
@@ -810,7 +863,7 @@ class acp_profile
 	*/
 	function save_profile_field(&$cp, $field_type, $action = 'create')
 	{
-		global $db, $config, $user, $phpbb_container;
+		global $db, $config, $user, $phpbb_container, $phpbb_dispatcher;
 
 		$field_id = request_var('field_id', 0);
 
@@ -852,6 +905,25 @@ class acp_profile
 			'field_contact_url'		=> $cp->vars['field_contact_url'],
 		);
 
+		$field_data = $cp->vars;
+		/**
+		* Event to modify profile field configuration data before saving to database
+		*
+		* @event core.acp_profile_create_edit_save_before
+		* @var	string	action			create|edit
+		* @var	string	field_type		Type of the field we are dealing with
+		* @var	array	field_data		Array of data about the field
+		* @var	array	profile_fields	Array of fields to be sent to the database
+		* @since 3.1.6-RC1
+		*/
+		$vars = array(
+			'action',
+			'field_type',
+			'field_data',
+			'profile_fields',
+		);
+		extract($phpbb_dispatcher->trigger_event('core.acp_profile_create_edit_save_before', compact($vars)));
+
 		if ($action == 'create')
 		{
 			$profile_fields += array(
--- a/includes/acp/acp_styles.php
+++ b/includes/acp/acp_styles.php
@@ -995,7 +995,7 @@ class acp_styles
 
 		// Assign template variables
 		$this->template->assign_block_vars('styles_list', $row);
-		foreach($actions as $action)
+		foreach ($actions as $action)
 		{
 			$this->template->assign_block_vars('styles_list.actions', $action);
 		}
--- a/includes/constants.php
+++ b/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
 */
 
 // phpBB Version
-define('PHPBB_VERSION', '3.1.5');
+define('PHPBB_VERSION', '3.1.6');
 
 // QA-related
 // define('PHPBB_QA', 1);
--- a/includes/functions.php
+++ b/includes/functions.php
@@ -1258,6 +1258,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
 		{
 			$forum_id = array($forum_id);
 		}
+		else
+		{
+			$forum_id = array_unique($forum_id);
+		}
 
 		$phpbb_notifications = $phpbb_container->get('notification_manager');
 
@@ -4779,13 +4783,14 @@ function phpbb_build_hidden_fields_for_query_params($request, $exclude = null)
 * @param array $user_row Row from the users table
 * @param string $alt Optional language string for alt tag within image, can be a language key or text
 * @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
 *
 * @return string Avatar html
 */
-function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false)
+function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
 {
 	$row = \phpbb\avatar\manager::clean_row($user_row, 'user');
-	return phpbb_get_avatar($row, $alt, $ignore_config);
+	return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
 }
 
 /**
@@ -4794,13 +4799,14 @@ function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config =
 * @param array $group_row Row from the groups table
 * @param string $alt Optional language string for alt tag within image, can be a language key or text
 * @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
 *
 * @return string Avatar html
 */
-function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false)
+function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
 {
 	$row = \phpbb\avatar\manager::clean_row($user_row, 'group');
-	return phpbb_get_avatar($row, $alt, $ignore_config);
+	return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
 }
 
 /**
@@ -4809,14 +4815,15 @@ function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config
 * @param array $row Row cleaned by \phpbb\avatar\manager::clean_row
 * @param string $alt Optional language string for alt tag within image, can be a language key or text
 * @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
 *
 * @return string Avatar html
 */
-function phpbb_get_avatar($row, $alt, $ignore_config = false)
+function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false)
 {
 	global $user, $config, $cache, $phpbb_root_path, $phpEx;
 	global $request;
-	global $phpbb_container;
+	global $phpbb_container, $phpbb_dispatcher;
 
 	if (!$config['allow_avatar'] && !$ignore_config)
 	{
@@ -4850,12 +4857,47 @@ function phpbb_get_avatar($row, $alt, $ignore_config = false)
 
 	if (!empty($avatar_data['src']))
 	{
-		$html = '<img src="' . $avatar_data['src'] . '" ' .
+		if ($lazy)
+		{
+			// Determine board url - we may need it later
+			$board_url = generate_board_url() . '/';
+			// This path is sent with the base template paths in the assign_vars()
+			// call below. We need to correct it in case we are accessing from a
+			// controller because the web paths will be incorrect otherwise.
+			$phpbb_path_helper = $phpbb_container->get('path_helper');
+			$corrected_path = $phpbb_path_helper->get_web_root_path();
+
+			$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
+
+			$theme = "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme';
+
+			$src = 'src="' . $theme . '/images/no_avatar.gif" data-src="' . $avatar_data['src'] . '"';
+		}
+		else
+		{
+			$src = 'src="' . $avatar_data['src'] . '"';
+		}
+
+		$html = '<img class="avatar" ' . $src . ' ' .
 			($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') .
 			($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') .
 			'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
 	}
 
+	/**
+	* Event to modify HTML <img> tag of avatar
+	*
+	* @event core.get_avatar_after
+	* @var	array	row				Row cleaned by \phpbb\avatar\manager::clean_row
+	* @var	string	alt				Optional language string for alt tag within image, can be a language key or text
+	* @var	bool	ignore_config	Ignores the config-setting, to be still able to view the avatar in the UCP
+	* @var	array	avatar_data		The HTML attributes for avatar <img> tag
+	* @var	string	html			The HTML <img> tag of generated avatar
+	* @since 3.1.6-RC1
+	*/
+	$vars = array('row', 'alt', 'ignore_config', 'avatar_data', 'html');
+	extract($phpbb_dispatcher->trigger_event('core.get_avatar_after', compact($vars)));
+
 	return $html;
 }
 
--- a/includes/functions_compatibility.php
+++ b/includes/functions_compatibility.php
@@ -30,10 +30,11 @@ if (!defined('IN_PHPBB'))
 * @param string $avatar_height Height of users avatar
 * @param string $alt Optional language string for alt tag within image, can be a language key or text
 * @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
 *
 * @return string Avatar image
 */
-function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false)
+function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
 {
 	// map arguments to new function phpbb_get_avatar()
 	$row = array(
@@ -43,7 +44,7 @@ function get_user_avatar($avatar, $avatar_type, $avatar_width, $avatar_height, $
 		'avatar_height'	=> $avatar_height,
 	);
 
-	return phpbb_get_avatar($row, $alt, $ignore_config);
+	return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
 }
 
 /**
--- a/includes/functions_convert.php
+++ b/includes/functions_convert.php
@@ -966,7 +966,7 @@ function get_remote_avatar_dim($src, $axis)
 	$protocol = (isset($url_info['scheme'])) ? $url_info['scheme'] : 'http';
 	if (empty($port))
 	{
-		switch(strtolower($protocol))
+		switch (strtolower($protocol))
 		{
 			case 'ftp':
 				$port = 21;
--- a/includes/functions_posting.php
+++ b/includes/functions_posting.php
@@ -1542,7 +1542,14 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
 		return false;
 	}
 
-	$current_time = time();
+	if (!empty($data['post_time']))
+	{
+		$current_time = $data['post_time'];
+	}
+	else
+	{
+		$current_time = time();
+	}
 
 	if ($mode == 'post')
 	{
@@ -1738,6 +1745,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
 				'topic_type'				=> $topic_type,
 				'topic_time_limit'			=> ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
 				'topic_attachment'			=> (!empty($data['attachment_data'])) ? 1 : 0,
+				'topic_status'				=> (isset($data['topic_status'])) ? $data['topic_status'] : ITEM_UNLOCKED,
 			);
 
 			if (isset($poll['poll_options']) && !empty($poll['poll_options']))
--- a/includes/functions_user.php
+++ b/includes/functions_user.php
@@ -1402,7 +1402,7 @@ function user_ipwhois($ip)
 	$match = array();
 
 	// Test for referrals from $whois_host to other whois databases, roll on rwhois
-	if (preg_match('#ReferralServer: whois://(.+)#im', $ipwhois, $match))
+	if (preg_match('#ReferralServer:[\x20]*whois://(.+)#im', $ipwhois, $match))
 	{
 		if (strpos($match[1], ':') !== false)
 		{
--- a/includes/mcp/mcp_forum.php
+++ b/includes/mcp/mcp_forum.php
@@ -77,6 +77,30 @@ function mcp_forum_view($id, $mode, $action, $forum_info)
 		break;
 	}
 
+	/**
+	* Get some data in order to execute other actions.
+	*
+	* @event core.mcp_forum_view_before
+	* @var	string	action				The action
+	* @var	array	forum_info			Array with forum infos
+	* @var	int		start				Start value
+	* @var	array	topic_id_list		Array of topics ids
+	* @var	array	post_id_list		Array of posts ids
+	* @var	array	source_topic_ids	Array of source topics ids
+	* @var	int		to_topic_id			Array of destination topics ids
+	* @since 3.1.6-RC1
+	*/
+	$vars = array(
+		'action',
+		'forum_info',
+		'start',
+		'topic_id_list',
+		'post_id_list',
+		'source_topic_ids',
+		'to_topic_id',
+	);
+	extract($phpbb_dispatcher->trigger_event('core.mcp_forum_view_before', compact($vars)));
+
 	$pagination = $phpbb_container->get('pagination');
 
 	$selected_ids = '';
--- a/includes/mcp/mcp_post.php
+++ b/includes/mcp/mcp_post.php
@@ -461,7 +461,7 @@ function mcp_post_details($id, $mode, $action)
 */
 function change_poster(&$post_info, $userdata)
 {
-	global $auth, $db, $config, $phpbb_root_path, $phpEx, $user;
+	global $auth, $db, $config, $phpbb_root_path, $phpEx, $user, $phpbb_dispatcher;
 
 	if (empty($userdata) || $userdata['user_id'] == $post_info['user_id'])
 	{
@@ -559,6 +559,17 @@ function change_poster(&$post_info, $userdata)
 
 	$post_info = $post_info[$post_id];
 
+	/**
+	* This event allows you to perform additional tasks after changing a post's poster
+	*
+	* @event core.mcp_change_poster_after
+	* @var	array	userdata	Information on a post's new poster
+	* @var	array	post_info	Information on the affected post
+	* @since 3.1.6-RC1
+	*/
+	$vars = array('userdata', 'post_info');
+	extract($phpbb_dispatcher->trigger_event('core.mcp_change_poster_after', compact($vars)));
+
 	// Now add log entry
 	add_log('mod', $post_info['forum_id'], $post_info['topic_id'], 'LOG_MCP_CHANGE_POSTER', $post_info['topic_title'], $from_username, $to_username);
 }
--- a/includes/mcp/mcp_queue.php
+++ b/includes/mcp/mcp_queue.php
@@ -404,7 +404,7 @@ class mcp_queue
 				$forum_options = '<option value="0"' . (($forum_id == 0) ? ' selected="selected"' : '') . '>' . $user->lang['ALL_FORUMS'] . '</option>';
 				foreach ($forum_list_approve as $row)
 				{
-					$forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp; &nbsp;', $row['padding']) . $row['forum_name'] . '</option>';
+					$forum_options .= '<option value="' . $row['forum_id'] . '"' . (($forum_id == $row['forum_id']) ? ' selected="selected"' : '') . '>' . str_repeat('&nbsp; &nbsp;', $row['padding']) . truncate_string($row['forum_name'], 30, 255, false, $user->lang['ELLIPSIS']) . '</option>';
 				}
 
 				$sort_days = $total = 0;
--- a/includes/message_parser.php
+++ b/includes/message_parser.php
@@ -791,28 +791,6 @@ class bbcode_firstpass extends bbcode
 				else if (preg_match('#^quote(?:=&quot;(.*?)&quot;)?$#is', $buffer, $m) && substr($out, -1, 1) == '[')
 				{
 					$this->parsed_items['quote']++;
-
-					// the buffer holds a valid opening tag
-					if ($config['max_quote_depth'] && sizeof($close_tags) >= $config['max_quote_depth'])
-					{
-						if ($config['max_quote_depth'] == 1)
-						{
-							// Depth 1 - no nesting is allowed
-							$error_ary['quote_depth'] = $user->lang('QUOTE_NO_NESTING');
-						}
-						else
-						{
-							// There are too many nested quotes
-							$error_ary['quote_depth'] = $user->lang('QUOTE_DEPTH_EXCEEDED', (int) $config['max_quote_depth']);
-						}
-
-						$out .= $buffer . $tok;
-						$tok = '[]';
-						$buffer = '';
-
-						continue;
-					}
-
 					array_push($close_tags, '/quote:' . $this->bbcode_uid);
 
 					if (isset($m[1]) && $m[1])
@@ -1277,6 +1255,12 @@ class parse_message extends bbcode_firstpass
 			return $update_this_message ? $this->warn_msg : $return_message;
 		}
 
+		// Remove quotes that are nested too deep
+		if ($config['max_quote_depth'] > 0)
+		{
+			$this->remove_nested_quotes($config['max_quote_depth']);
+		}
+
 		// Check for "empty" message. We do not check here for maximum length, because bbcode, smilies, etc. can add to the length.
 		// The maximum length check happened before any parsings.
 		if ($mode === 'post' && utf8_clean_string($this->message) === '')
@@ -1317,6 +1301,29 @@ class parse_message extends bbcode_firstpass
 			$return_message = &$this->message;
 		}
 
+		$text = $this->message;
+		$uid = $this->bbcode_uid;
+
+		/**
+		* Event to modify the text before it is parsed
+		*
+		* @event core.modify_format_display_text_before
+		* @var string	text				The message text to parse
+		* @var string	uid					The bbcode uid
+		* @var bool		allow_bbcode		Do we allow bbcodes
+		* @var bool		allow_magic_url		Do we allow magic urls
+		* @var bool		allow_smilies		Do we allow smilies
+		* @var bool		update_this_message	Do we update the internal message
+		*									with the parsed result
+		* @since 3.1.6-RC1
+		*/
+		$vars = array('text', 'uid', 'allow_bbcode', 'allow_magic_url', 'allow_smilies', 'update_this_message');
+		extract($phpbb_dispatcher->trigger_event('core.modify_format_display_text_before', compact($vars)));
+
+		$this->message = $text;
+		$this->bbcode_uid = $uid;
+		unset($text, $uid);
+
 		if ($this->message_status == 'plain')
 		{
 			// Force updating message - of course.
@@ -1856,6 +1863,50 @@ class parse_message extends bbcode_firstpass
 	}
 
 	/**
+	* Remove nested quotes at given depth in current parsed message
+	*
+	* @param  integer $max_depth Depth limit
+	* @return null
+	*/
+	public function remove_nested_quotes($max_depth)
+	{
+		// Capture all [quote] and [/quote] tags
+		preg_match_all('(\\[/?quote(?:=&quot;(.*?)&quot;)?:' . $this->bbcode_uid . '\\])', $this->message, $matches, PREG_OFFSET_CAPTURE);
+
+		// Iterate over the quote tags to mark the ranges that must be removed
+		$depth = 0;
+		$ranges = array();
+		$start_pos = 0;
+		foreach ($matches[0] as $match)
+		{
+			if ($match[0][1] === '/')
+			{
+				--$depth;
+				if ($depth == $max_depth)
+				{
+					$end_pos = $match[1] + strlen($match[0]);
+					$length = $end_pos - $start_pos;
+					$ranges[] = array($start_pos, $length);
+				}
+			}
+			else
+			{
+				++$depth;
+				if ($depth == $max_depth + 1)
+				{
+					$start_pos = $match[1];
+				}
+			}
+		}
+
+		foreach (array_reverse($ranges) as $range)
+		{
+			list($start_pos, $length) = $range;
+			$this->message = substr_replace($this->message, '', $start_pos, $length);
+		}
+	}
+
+	/**
 	* Setter function for passing the plupload object
 	*
 	* @param \phpbb\plupload\plupload $plupload The plupload object
--- a/includes/startup.php
+++ b/includes/startup.php
@@ -94,7 +94,11 @@ if (version_compare(PHP_VERSION, '5.4.0-dev', '>='))
 }
 else
 {
-	@set_magic_quotes_runtime(0);
+	if (get_magic_quotes_runtime())
+	{
+		// Deactivate
+		@set_magic_quotes_runtime(0);
+	}
 
 	// Be paranoid with passed vars
 	if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on' || !function_exists('ini_get'))
--- a/includes/ucp/ucp_activate.php
+++ b/includes/ucp/ucp_activate.php
@@ -30,7 +30,7 @@ class ucp_activate
 	function main($id, $mode)
 	{
 		global $config, $phpbb_root_path, $phpEx;
-		global $db, $user, $auth, $template, $phpbb_container;
+		global $db, $user, $auth, $template, $phpbb_container, $phpbb_dispatcher;
 
 		$user_id = request_var('u', 0);
 		$key = request_var('k', '');
@@ -143,6 +143,17 @@ class ucp_activate
 			}
 		}
 
+		/**
+		* This event can be used to modify data after user account's activation
+		*
+		* @event core.ucp_activate_after
+		* @var	array	user_row	Array with some user data
+		* @var	string	message		Language string of the message that will be displayed to the user
+		* @since 3.1.6-RC1
+		*/
+		$vars = array('user_row', 'message');
+		extract($phpbb_dispatcher->trigger_event('core.ucp_activate_after', compact($vars)));
+
 		meta_refresh(3, append_sid("{$phpbb_root_path}index.$phpEx"));
 		trigger_error($user->lang[$message]);
 	}
--- a/includes/ucp/ucp_notifications.php
+++ b/includes/ucp/ucp_notifications.php
@@ -52,11 +52,11 @@ class ucp_notifications
 
 					$notification_methods = $phpbb_notifications->get_subscription_methods();
 
-					foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+					foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
 					{
-						foreach($subscription_types as $type => $data)
+						foreach ($subscription_types as $type => $data)
 						{
-							foreach($notification_methods as $method => $method_data)
+							foreach ($notification_methods as $method => $method_data)
 							{
 								if ($request->is_set_post(str_replace('.', '_', $type . '_' . $method_data['id'])) && (!isset($subscriptions[$type]) || !in_array($method_data['id'], $subscriptions[$type])))
 								{
@@ -180,13 +180,13 @@ class ucp_notifications
 	{
 		$notification_methods = $phpbb_notifications->get_subscription_methods();
 
-		foreach($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
+		foreach ($phpbb_notifications->get_subscription_types() as $group => $subscription_types)
 		{
 			$template->assign_block_vars($block, array(
 				'GROUP_NAME'	=> $user->lang($group),
 			));
 
-			foreach($subscription_types as $type => $data)
+			foreach ($subscription_types as $type => $data)
 			{
 				$template->assign_block_vars($block, array(
 					'TYPE'				=> $type,
@@ -197,7 +197,7 @@ class ucp_notifications
 					'SUBSCRIBED'		=> (isset($subscriptions[$type])) ? true : false,
 				));
 
-				foreach($notification_methods as $method => $method_data)
+				foreach ($notification_methods as $method => $method_data)
 				{
 					$template->assign_block_vars($block . '.notification_methods', array(
 						'METHOD'			=> $method_data['id'],
@@ -227,7 +227,7 @@ class ucp_notifications
 	{
 		$notification_methods = $phpbb_notifications->get_subscription_methods();
 
-		foreach($notification_methods as $method => $method_data)
+		foreach ($notification_methods as $method => $method_data)
 		{
 			$template->assign_block_vars($block, array(
 				'METHOD'			=> $method_data['id'],
--- a/includes/ucp/ucp_pm_viewmessage.php
+++ b/includes/ucp/ucp_pm_viewmessage.php
@@ -265,7 +265,9 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
 	* @var	array	message_row	Array with message data
 	* @var	array	cp_row		Array with senders custom profile field data
 	* @var	array	msg_data	Template array with message data
+	* @var 	array	user_info	User data of the sender
 	* @since 3.1.0-a1
+	* @changed 3.1.6-RC1		Added user_info into event
 	*/
 	$vars = array(
 		'id',
@@ -276,6 +278,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row)
 		'message_row',
 		'cp_row',
 		'msg_data',
+		'user_info',
 	);
 	extract($phpbb_dispatcher->trigger_event('core.ucp_pm_view_messsage', compact($vars)));
 
--- a/includes/ucp/ucp_register.php
+++ b/includes/ucp/ucp_register.php
@@ -176,6 +176,16 @@ class ucp_register
 			}
 			unset($lang_row);
 
+			/**
+			* Allows to modify the agreements.
+			*
+			* To assign data to the template, use $template->assign_vars()
+			*
+			* @event core.ucp_register_agreement
+			* @since 3.1.6-RC1
+			*/
+			$phpbb_dispatcher->dispatch('core.ucp_register_agreement');
+
 			$this->tpl_name = 'ucp_agreement';
 			return;
 		}
--- a/language/en/acp/extensions.php
+++ b/language/en/acp/extensions.php
@@ -68,6 +68,12 @@ $lang = array_merge($lang, array(
 	'EXTENSION_NAME'			=> 'Extension Name',
 	'EXTENSION_ACTIONS'			=> 'Actions',
 	'EXTENSION_OPTIONS'			=> 'Options',
+	'EXTENSION_INSTALL_HEADLINE'=> 'Installing an extension',
+	'EXTENSION_INSTALL_EXPLAIN'	=> '<ol>
+			<li>Download an extension from phpBB’s extensions database</li>
+			<li>Unzip the extension and upload it to the <samp>ext/</samp> directory of your phpBB board</li>
+			<li>Enable the extension, here in the Extensions manager</li>
+		</ol>',
 	'EXTENSION_UPDATE_HEADLINE'	=> 'Updating an extension',
 	'EXTENSION_UPDATE_EXPLAIN'	=> '<ol>
 			<li>Disable the extension</li>
@@ -119,6 +125,8 @@ $lang = array_merge($lang, array(
 	'FORCE_UNSTABLE'					=> 'Always check for unstable versions',
 	'EXTENSIONS_VERSION_CHECK_SETTINGS'	=> 'Version check settings',
 
+	'BROWSE_EXTENSIONS_DATABASE'		=> 'Browse extensions database',
+
 	'META_FIELD_NOT_SET'	=> 'Required meta field %s has not been set.',
 	'META_FIELD_INVALID'	=> 'Meta field %s is invalid.',
 ));
--- a/language/en/acp/language.php
+++ b/language/en/acp/language.php
@@ -73,4 +73,6 @@ $lang = array_merge($lang, array(
 	'THOSE_MISSING_LANG_VARIABLES'		=> 'The following language variables are missing from the “%s” language pack',
 
 	'UNINSTALLED_LANGUAGE_PACKS'	=> 'Uninstalled language packs',
+
+	'BROWSE_LANGUAGE_PACKS_DATABASE'	=> 'Browse language packs database',
 ));
--- a/language/en/acp/styles.php
+++ b/language/en/acp/styles.php
@@ -83,4 +83,6 @@ $lang = array_merge($lang, array(
 	'STYLE_USED_BY'				=> 'Used by (including robots)',
 
 	'UNINSTALL_DEFAULT'		=> 'You cannot uninstall the default style.',
+
+	'BROWSE_STYLES_DATABASE'	=> 'Browse styles database',
 ));
--- a/language/en/help_bbcode.php
+++ b/language/en/help_bbcode.php
@@ -90,7 +90,7 @@ $help = array(
 	),
 	array(
 		0 => 'Linking to another site',
-		1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.<ul><li>The first of these uses the <strong>[url=][/url]</strong> tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:<br /><br /><strong>[url=http://www.phpbb.com/]</strong>Visit phpBB!<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">Visit phpBB!</a> Please notice that the link opens in the same window or a new window depending on the users browser preferences.</li><li>If you want the URL itself displayed as the link you can do this by simply using:<br /><br /><strong>[url]</strong>http://www.phpbb.com/<strong>[/url]</strong><br /><br />This would generate the following link, <a href="http://www.phpbb.com/">http://www.phpbb.com/</a></li><li>Additionally, phpBB features something called <i>Magic Links</i>, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading http://. For example typing www.phpbb.com into your message will automatically lead to <a href="http://www.phpbb.com/">www.phpbb.com</a> being output when you view the message.</li><li>The same thing applies equally to email addresses, you can either specify an address explicitly for example:<br /><br /><strong>[email]</strong>no.one@domain.adr<strong>[/email]</strong><br /><br />which will output <a href="mailto:no.one@domain.adr">no.one@domain.adr</a> or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.</li></ul>As with all the BBCode tags you can wrap URLs around any of the other tags such as <strong>[img][/img]</strong> (see next entry), <strong>[b][/b]</strong>, etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:<br /><br /><strong>[url=http://www.phpbb.com/][img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/url][/img]</strong><br /><br />is <span style="text-decoration: underline">not</span> correct which may lead to your post being deleted so take care.'
+		1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.<ul><li>The first of these uses the <strong>[url=][/url]</strong> tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:<br /><br /><strong>[url=https://www.phpbb.com/]</strong>Visit phpBB!<strong>[/url]</strong><br /><br />This would generate the following link, <a href="https://www.phpbb.com/">Visit phpBB!</a> Please notice that the link opens in the same window or a new window depending on the users browser preferences.</li><li>If you want the URL itself displayed as the link you can do this by simply using:<br /><br /><strong>[url]</strong>https://www.phpbb.com/<strong>[/url]</strong><br /><br />This would generate the following link, <a href="https://www.phpbb.com/">https://www.phpbb.com/</a></li><li>Additionally, phpBB features something called <i>Magic Links</i>, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading https://. For example typing www.phpbb.com into your message will automatically lead to <a href="https://www.phpbb.com/">www.phpbb.com</a> being output when you view the message.</li><li>The same thing applies equally to email addresses, you can either specify an address explicitly for example:<br /><br /><strong>[email]</strong>no.one@domain.adr<strong>[/email]</strong><br /><br />which will output <a href="mailto:no.one@domain.adr">no.one@domain.adr</a> or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.</li></ul>As with all the BBCode tags you can wrap URLs around any of the other tags such as <strong>[img][/img]</strong> (see next entry), <strong>[b][/b]</strong>, etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:<br /><br /><strong>[url=https://www.phpbb.com/][img]</strong>https://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/url][/img]</strong><br /><br />is <span style="text-decoration: underline">not</span> correct which may lead to your post being deleted so take care.'
 	),
 	array(
 		0 => '--',
@@ -98,7 +98,7 @@ $help = array(
 	),
 	array(
 		0 => 'Adding an image to a post',
-		1 => 'phpBB BBCode incorporates a tag for including images in your posts. Two very important things to remember when using this tag are: many users do not appreciate lots of images being shown in posts and secondly the image you display must already be available on the internet (it cannot exist only on your computer for example, unless you run a webserver!). To display an image you must surround the URL pointing to the image with <strong>[img][/img]</strong> tags. For example:<br /><br /><strong>[img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img]</strong><br /><br />As noted in the URL section above you can wrap an image in a <strong>[url][/url]</strong> tag if you wish, e.g.<br /><br /><strong>[url=http://www.phpbb.com/][img]</strong>http://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img][/url]</strong><br /><br />would generate:<br /><br /><a href="http://www.phpbb.com/"><img src="http://www.phpbb.com/theme/images/logos/blue/160x52.png" alt="" /></a>'
+		1 => 'phpBB BBCode incorporates a tag for including images in your posts. Two very important things to remember when using this tag are: many users do not appreciate lots of images being shown in posts and secondly the image you display must already be available on the internet (it cannot exist only on your computer for example, unless you run a webserver!). To display an image you must surround the URL pointing to the image with <strong>[img][/img]</strong> tags. For example:<br /><br /><strong>[img]</strong>https://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img]</strong><br /><br />As noted in the URL section above you can wrap an image in a <strong>[url][/url]</strong> tag if you wish, e.g.<br /><br /><strong>[url=https://www.phpbb.com/][img]</strong>https://www.phpbb.com/theme/images/logos/blue/160x52.png<strong>[/img][/url]</strong><br /><br />would generate:<br /><br /><a href="https://www.phpbb.com/"><img src="https://www.phpbb.com/theme/images/logos/blue/160x52.png" alt="" /></a>'
 	),
 	array(
 		0 => 'Adding attachments into a post',
--- a/phpbb/avatar/driver/upload.php
+++ b/phpbb/avatar/driver/upload.php
@@ -24,6 +24,11 @@ class upload extends \phpbb\avatar\driver\driver
 	protected $mimetype_guesser;
 
 	/**
+	* @var \phpbb\event\dispatcher_interface
+	*/
+	protected $dispatcher;
+
+	/**
 	* Construct a driver object
 	*
 	* @param \phpbb\config\config $config phpBB configuration
@@ -31,15 +36,17 @@ class upload extends \phpbb\avatar\driver\driver
 	* @param string $php_ext PHP file extension
 	* @param \phpbb_path_helper $path_helper phpBB path helper
 	* @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser
+	* @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object
 	* @param \phpbb\cache\driver\driver_interface $cache Cache driver
 	*/
-	public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null)
+	public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\cache\driver\driver_interface $cache = null)
 	{
 		$this->config = $config;
 		$this->phpbb_root_path = $phpbb_root_path;
 		$this->php_ext = $php_ext;
 		$this->path_helper = $path_helper;
 		$this->mimetype_guesser = $mimetype_guesser;
+		$this->dispatcher = $dispatcher;
 		$this->cache = $cache;
 	}
 
@@ -137,6 +144,15 @@ class upload extends \phpbb\avatar\driver\driver
 		$prefix = $this->config['avatar_salt'] . '_';
 		$file->clean_filename('avatar', $prefix, $row['id']);
 
+		// If there was an error during upload, then abort operation
+		if (sizeof($file->error))
+		{
+			$file->remove();
+			$error = $file->error;
+			return false;
+		}
+
+		// Calculate new destination
 		$destination = $this->config['avatar_path'];
 
 		// Adjust destination path (no trailing slash)
@@ -151,16 +167,45 @@ class upload extends \phpbb\avatar\driver\driver
 			$destination = '';
 		}
 
-		// Move file and overwrite any existing image
-		$file->move_file($destination, true);
+		/**
+		* Before moving new file in place (and eventually overwriting the existing avatar with the newly uploaded avatar)
+		*
+		* @event core.avatar_driver_upload_move_file_before
+		* @var	string	destination			Destination directory where the file is going to be moved
+		* @var	string	prefix				Prefix for the avatar filename
+		* @var	array	row					Array with avatar row data
+		* @var	array	error				Array of errors, if filled in by this event file will not be moved
+		* @since 3.1.6-RC1
+		*/
+		$vars = array(
+			'destination',
+			'prefix',
+			'row',
+			'error',
+		);
+		extract($this->dispatcher->trigger_event('core.avatar_driver_upload_move_file_before', compact($vars)));
 
-		if (sizeof($file->error))
+		if (!sizeof($error))
+		{
+			// Move file and overwrite any existing image
+			$file->move_file($destination, true);
+		}
+
+		// If there was an error during move, then clean up leftovers
+		$error = array_merge($error, $file->error);
+		if (sizeof($error))
 		{
 			$file->remove();
-			$error = array_merge($error, $file->error);
 			return false;
 		}
 
+		// Delete current avatar if not overwritten
+		$ext = substr(strrchr($row['avatar'], '.'), 1);
+		if ($ext && $ext !== $file->get('extension'))
+		{
+			$this->delete($row);
+		}
+
 		return array(
 			'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'),
 			'avatar_width' => $file->get('width'),
@@ -185,10 +230,32 @@ class upload extends \phpbb\avatar\driver\driver
 	*/
 	public function delete($row)
 	{
+
+		$error = array();
+		$destination = $this->config['avatar_path'];
+		$prefix = $this->config['avatar_salt'] . '_';
 		$ext = substr(strrchr($row['avatar'], '.'), 1);
-		$filename = $this->phpbb_root_path . $this->config['avatar_path'] . '/' . $this->config['avatar_salt'] . '_' . $row['id'] . '.' . $ext;
+		$filename = $this->phpbb_root_path . $destination . '/' . $prefix . $row['id'] . '.' . $ext;
+
+		/**
+		* Before deleting an existing avatar
+		*
+		* @event core.avatar_driver_upload_delete_before
+		* @var	string	destination			Destination directory where the file is going to be deleted
+		* @var	string	prefix				Prefix for the avatar filename
+		* @var	array	row					Array with avatar row data
+		* @var	array	error				Array of errors, if filled in by this event file will not be deleted
+		* @since 3.1.6-RC1
+		*/
+		$vars = array(
+			'destination',
+			'prefix',
+			'row',
+			'error',
+		);
+		extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars)));
 
-		if (file_exists($filename))
+		if (!sizeof($error) && file_exists($filename))
 		{
 			@unlink($filename);
 		}
--- a/phpbb/cache/driver/memcache.php
+++ b/phpbb/cache/driver/memcache.php
@@ -50,7 +50,7 @@ class memcache extends \phpbb\cache\driver\memory
 		parent::__construct();
 
 		$this->memcache = new \Memcache;
-		foreach(explode(',', PHPBB_ACM_MEMCACHE) as $u)
+		foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u)
 		{
 			$parts = explode('/', $u);
 			$this->memcache->addServer(trim($parts[0]), trim($parts[1]));
--- a/phpbb/captcha/plugins/qa.php
+++ b/phpbb/captcha/plugins/qa.php
@@ -350,7 +350,7 @@ class qa
 				),
 		);
 
-		foreach($schemas as $table => $schema)
+		foreach ($schemas as $table => $schema)
 		{
 			if (!$db_tool->sql_table_exists($table))
 			{
--- a/phpbb/config/db_text.php
+++ b/phpbb/config/db_text.php
@@ -100,9 +100,9 @@ class db_text
 			$sql = 'UPDATE ' . $this->table . "
 				SET config_value = '" . $this->db->sql_escape($value) . "'
 				WHERE config_name = '" . $this->db->sql_escape($key) . "'";
-			$result = $this->db->sql_query($sql);
+			$this->db->sql_query($sql);
 
-			if (!$this->db->sql_affectedrows($result))
+			if (!$this->db->sql_affectedrows())
 			{
 				$sql = 'INSERT INTO ' . $this->table . ' ' . $this->db->sql_build_array('INSERT', array(
 					'config_name'	=> (string) $key,
--- a/phpbb/cron/task/core/tidy_search.php
+++ b/phpbb/cron/task/core/tidy_search.php
@@ -20,24 +20,60 @@ namespace phpbb\cron\task\core;
 */
 class tidy_search extends \phpbb\cron\task\base
 {
+	/**
+	* phpBB root path
+	* @var string
+	*/
 	protected $phpbb_root_path;
+
+	/**
+	* PHP file extension
+	* @var string
+	*/
 	protected $php_ext;
+
+	/**
+	* Auth object
+	* @var \phpbb\auth\auth
+	*/
 	protected $auth;
+
+	/**
+	* Config object
+	* @var \phpbb\config\config
+	*/
 	protected $config;
+
+	/**
+	* Database object
+	* @var \phpbb\db\driver\driver_interface
+	*/
 	protected $db;
+
+	/**
+	* User object
+	* @var \phpbb\user
+	*/
 	protected $user;
 
 	/**
+	* Event dispatcher object
+	* @var \phpbb\event\dispatcher_interface
+	*/
+	protected $phpbb_dispatcher;
+
+	/**
 	* Constructor.
 	*
-	* @param string $phpbb_root_path The root path
+	* @param string $phpbb_root_path The phpBB root path
 	* @param string $php_ext The PHP file extension
-	* @param \phpbb\auth\auth $auth The auth
-	* @param \phpbb\config\config $config The config
-	* @param \phpbb\db\driver\driver_interface $db The db connection
-	* @param \phpbb\user $user The user
+	* @param \phpbb\auth\auth $auth The auth object
+	* @param \phpbb\config\config $config The config object
+	* @param \phpbb\db\driver\driver_interface $db The database object
+	* @param \phpbb\user $user The user object
+	* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher The event dispatcher object
 	*/
-	public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user)
+	public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
 	{
 		$this->phpbb_root_path = $phpbb_root_path;
 		$this->php_ext = $php_ext;
@@ -45,6 +81,7 @@ class tidy_search extends \phpbb\cron\task\base
 		$this->config = $config;
 		$this->db = $db;
 		$this->user = $user;
+		$this->phpbb_dispatcher = $phpbb_dispatcher;
 	}
 
 	/**
@@ -58,7 +95,7 @@ class tidy_search extends \phpbb\cron\task\base
 
 		// We do some additional checks in the module to ensure it can actually be utilised
 		$error = false;
-		$search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user);
+		$search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user, $this->phpbb_dispatcher);
 
 		if (!$error)
 		{
--- a/phpbb/db/driver/driver.php
+++ b/phpbb/db/driver/driver.php
@@ -962,7 +962,7 @@ abstract class driver implements driver_interface
 				{
 					if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query))
 					{
-						$this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows($this->query_result) . '</b> | ';
+						$this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows() . '</b> | ';
 					}
 					$this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $this->curtime) . 's</b>';
 				}
--- a/phpbb/db/migration/data/v310/style_update_p1.php
+++ b/phpbb/db/migration/data/v310/style_update_p1.php
@@ -160,7 +160,7 @@ class style_update_p1 extends \phpbb\db\migration\migration
 				FROM ' . STYLES_TABLE . "
 				WHERE style_name = 'prosilver'";
 			$result = $this->sql_query($sql);
-			$default_style = $this->db->sql_fetchfield($result);
+			$default_style = $this->db->sql_fetchfield('style_id');
 			$this->db->sql_freeresult($result);
 
 			$this->config->set('default_style', $default_style);
--- /dev/null
+++ b/phpbb/db/migration/data/v31x/v316.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class v316 extends \phpbb\db\migration\migration
+{
+	static public function depends_on()
+	{
+		return array(
+			'\phpbb\db\migration\data\v31x\v316rc1',
+		);
+	}
+
+	public function update_data()
+	{
+		return array(
+			array('config.update', array('version', '3.1.6')),
+		);
+	}
+}
--- /dev/null
+++ b/phpbb/db/migration/data/v31x/v316rc1.php
@@ -0,0 +1,31 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v31x;
+
+class v316rc1 extends \phpbb\db\migration\migration
+{
+	static public function depends_on()
+	{
+		return array(
+			'\phpbb\db\migration\data\v31x\v315',
+		);
+	}
+
+	public function update_data()
+	{
+		return array(
+			array('config.update', array('version', '3.1.6-RC1')),
+		);
+	}
+}
--- a/phpbb/di/container_builder.php
+++ b/phpbb/di/container_builder.php
@@ -399,7 +399,6 @@ class container_builder
 	*/
 	protected function get_container_filename()
 	{
-		$filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path);
-		return $this->phpbb_root_path . 'cache/container_' . $filename . '.' . $this->php_ext;
+		return $this->phpbb_root_path . 'cache/container_' . md5($this->phpbb_root_path) . '.' . $this->php_ext;
 	}
 }
--- a/phpbb/log/log.php
+++ b/phpbb/log/log.php
@@ -535,7 +535,7 @@ class log implements \phpbb\log\log_interface
 			'ORDER_BY' => $sort_by,
 		);
 
-		if($log_time)
+		if ($log_time)
 		{
 			$get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . '
 					AND ' . $get_logs_sql_ary['WHERE'];
--- a/phpbb/notification/method/messenger_base.php
+++ b/phpbb/notification/method/messenger_base.php
@@ -69,7 +69,7 @@ abstract class messenger_base extends \phpbb\notification\method\base
 
 			$user = $this->user_loader->get_user($notification->user_id);
 
-			if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users))
+			if ($user['user_type'] == USER_IGNORE || ($user['user_type'] == USER_INACTIVE && $user['user_inactive_reason'] == INACTIVE_MANUAL) || in_array($notification->user_id, $banned_users))
 			{
 				continue;
 			}
--- a/phpbb/notification/type/admin_activate_user.php
+++ b/phpbb/notification/type/admin_activate_user.php
@@ -104,7 +104,7 @@ class admin_activate_user extends \phpbb\notification\type\base
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->item_id);
+		return $this->user_loader->get_avatar($this->item_id, false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/group_request.php
+++ b/phpbb/notification/type/group_request.php
@@ -96,7 +96,7 @@ class group_request extends \phpbb\notification\type\base
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->item_id);
+		return $this->user_loader->get_avatar($this->item_id, false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/pm.php
+++ b/phpbb/notification/type/pm.php
@@ -100,7 +100,7 @@ class pm extends \phpbb\notification\type\base
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('from_user_id'));
+		return $this->user_loader->get_avatar($this->get_data('from_user_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/post.php
+++ b/phpbb/notification/type/post.php
@@ -165,7 +165,7 @@ class post extends \phpbb\notification\type\base
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('poster_id'));
+		return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/report_pm.php
+++ b/phpbb/notification/type/report_pm.php
@@ -223,7 +223,7 @@ class report_pm extends \phpbb\notification\type\pm
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('reporter_id'));
+		return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/report_pm_closed.php
+++ b/phpbb/notification/type/report_pm_closed.php
@@ -130,7 +130,7 @@ class report_pm_closed extends \phpbb\notification\type\pm
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('closer_id'));
+		return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/report_post.php
+++ b/phpbb/notification/type/report_post.php
@@ -196,7 +196,7 @@ class report_post extends \phpbb\notification\type\post_in_queue
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('reporter_id'));
+		return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/report_post_closed.php
+++ b/phpbb/notification/type/report_post_closed.php
@@ -137,7 +137,7 @@ class report_post_closed extends \phpbb\notification\type\post
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('closer_id'));
+		return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true);
 	}
 
 	/**
--- a/phpbb/notification/type/topic.php
+++ b/phpbb/notification/type/topic.php
@@ -119,7 +119,7 @@ class topic extends \phpbb\notification\type\base
 	*/
 	public function get_avatar()
 	{
-		return $this->user_loader->get_avatar($this->get_data('poster_id'));
+		return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true);
 	}
 
 	/**
--- a/phpbb/profilefields/manager.php
+++ b/phpbb/profilefields/manager.php
@@ -276,12 +276,32 @@ class manager
 			$profile_field = $this->type_collection[$field_data['field_type']];
 
 			$tpl_fields[] = array(
+				'PROFILE_FIELD_IDENT'	=> $field_ident,
 				'PROFILE_FIELD_TYPE'	=> $field_data['field_type'],
 				'PROFILE_FIELD_NAME'	=> $profile_field->get_field_name($field_data['lang_name']),
 				'PROFILE_FIELD_EXPLAIN'	=> $this->user->lang($field_data['lang_explain']),
 			);
 		}
 
+		$profile_cache = $this->profile_cache;
+
+		/**
+		* Event to modify template headlines of the generated profile fields
+		*
+		* @event core.generate_profile_fields_template_headlines
+		* @var	string	restrict_option	Restrict the published fields to a certain profile field option
+		* @var	array	tpl_fields		Array with template data fields
+		* @var	array	profile_cache	A copy of the profile cache to make additional checks
+		* @since 3.1.6-RC1
+		*/
+		$vars = array(
+			'restrict_option',
+			'tpl_fields',
+			'profile_cache',
+		);
+		extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_headlines', compact($vars)));
+		unset($profile_cache);
+
 		return $tpl_fields;
 	}
 
--- a/phpbb/search/fulltext_mysql.php
+++ b/phpbb/search/fulltext_mysql.php
@@ -685,6 +685,7 @@ class fulltext_mysql extends \phpbb\search\base
 		*									Set to 0 to force a re-count
 		* @var	string	sql_sort_table		CROSS JOIN'ed table to allow doing the sort chosen
 		* @var	string	sql_sort_join		Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
+		* @var	string	type				Either "posts" or "topics" specifying the type of search being made
 		* @var	array	author_ary			Array of user_id containing the users to filter the results to
 		* @var	string	author_name			An extra username to search on
 		* @var	string	sql_author			SQL WHERE condition for the post author ids
@@ -697,6 +698,7 @@ class fulltext_mysql extends \phpbb\search\base
 		* @var	string	sort_days			Time, in days, that the oldest post showing can have
 		* @var	string	sql_time			The SQL to search on the time specifyed by sort_days
 		* @var	bool	firstpost_only		Wether or not to search only on the first post of the topics
+		* @var	string	sql_firstpost		The SQL with the conditions to join the tables when using firstpost_only
 		* @var	array	ex_fid_ary			Forum ids that must not be searched on
 		* @var	array	sql_fora			SQL query for ex_fid_ary
 		* @var	string	m_approve_fid_sql	WHERE clause condition on post_visibility restrictions
@@ -707,6 +709,7 @@ class fulltext_mysql extends \phpbb\search\base
 			'result_count',
 			'sql_sort_table',
 			'sql_sort_join',
+			'type',
 			'author_ary',
 			'author_name',
 			'sql_author',
@@ -719,6 +722,7 @@ class fulltext_mysql extends \phpbb\search\base
 			'sort_days',
 			'sql_time',
 			'firstpost_only',
+			'sql_firstpost',
 			'ex_fid_ary',
 			'sql_fora',
 			'm_approve_fid_sql',
--- a/phpbb/search/fulltext_native.php
+++ b/phpbb/search/fulltext_native.php
@@ -733,9 +733,10 @@ class fulltext_native extends \phpbb\search\base
 		* @var	array	must_not_contain_ids	Ids that cannot be taken into account for the results
 		* @var	array	must_exclude_one_ids	Ids that cannot be on the results
 		* @var	array	must_contain_ids		Ids that must be on the results
-		* @var	int		result_count			The previous result count for the format of the query
+		* @var	int		total_results			The previous result count for the format of the query
 		*										Set to 0 to force a re-count
-		* @var	bool	join_topic				Weather or not TOPICS_TABLE should be CROSS JOIN'ED
+		* @var	array	sql_array				The data on how to search in the DB at this point
+		* @var	bool	left_join_topics		Whether or not TOPICS_TABLE should be CROSS JOIN'ED
 		* @var	array	author_ary				Array of user_id containing the users to filter the results to
 		* @var	string	author_name				An extra username to search on (!empty(author_ary) must be true, to be relevant)
 		* @var	array	ex_fid_ary				Which forums not to search on
@@ -748,7 +749,7 @@ class fulltext_native extends \phpbb\search\base
 		* @var	string	sql_where				An array of the current WHERE clause conditions
 		* @var	string	sql_match				Which columns to do the search on
 		* @var	string	sql_match_where			Extra conditions to use to properly filter the matching process
-		* @var	string	group_by				Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause
+		* @var	bool	group_by				Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause
 		* @var	string	sort_by_sql				The possible predefined sort types
 		* @var	string	sort_key				The sort type used from the possible sort types
 		* @var	string	sort_dir				"a" for ASC or "d" dor DESC for the sort order used
@@ -761,8 +762,9 @@ class fulltext_native extends \phpbb\search\base
 			'must_not_contain_ids',
 			'must_exclude_one_ids',
 			'must_contain_ids',
-			'result_count',
-			'join_topic',
+			'total_results',
+			'sql_array',
+			'left_join_topics',
 			'author_ary',
 			'author_name',
 			'ex_fid_ary',
@@ -1048,6 +1050,7 @@ class fulltext_native extends \phpbb\search\base
 		* @event core.search_native_author_count_query_before
 		* @var	int		total_results		The previous result count for the format of the query.
 		*									Set to 0 to force a re-count
+		* @var	string	type				The type of search being made
 		* @var	string	select				SQL SELECT clause for what to get
 		* @var	string	sql_sort_table		CROSS JOIN'ed table to allow doing the sort chosen
 		* @var	string	sql_sort_join		Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table
@@ -1060,6 +1063,7 @@ class fulltext_native extends \phpbb\search\base
 		* @var	string	sort_days			Time, in days, that the oldest post showing can have
 		* @var	string	sql_time			The SQL to search on the time specifyed by sort_days
 		* @var	bool	firstpost_only		Wether or not to search only on the first post of the topics
+		* @var	string	sql_firstpost		The SQL used in the WHERE claused to filter by firstpost.
 		* @var	array	ex_fid_ary			Forum ids that must not be searched on
 		* @var	array	sql_fora			SQL query for ex_fid_ary
 		* @var	int		start				How many posts to skip in the search results (used for pagination)
@@ -1067,6 +1071,7 @@ class fulltext_native extends \phpbb\search\base
 		*/
 		$vars = array(
 			'total_results',
+			'type',
 			'select',
 			'sql_sort_table',
 			'sql_sort_join',
@@ -1079,6 +1084,7 @@ class fulltext_native extends \phpbb\search\base
 			'sort_days',
 			'sql_time',
 			'firstpost_only',
+			'sql_firstpost',
 			'ex_fid_ary',
 			'sql_fora',
 			'start',
--- a/phpbb/search/fulltext_sphinx.php
+++ b/phpbb/search/fulltext_sphinx.php
@@ -146,7 +146,7 @@ class fulltext_sphinx
 		// Initialize \phpbb\db\tools object
 		$this->db_tools = new \phpbb\db\tools($this->db);
 
-		if(!$this->config['fulltext_sphinx_id'])
+		if (!$this->config['fulltext_sphinx_id'])
 		{
 			set_config('fulltext_sphinx_id', unique_id());
 		}
--- a/phpbb/session.php
+++ b/phpbb/session.php
@@ -519,7 +519,7 @@ class session
 	*/
 	function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
 	{
-		global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container;
+		global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
 
 		$this->data = array();
 
@@ -893,6 +893,19 @@ class session
 			$_SID = '';
 		}
 
+		$session_data = $sql_ary;
+		/**
+		* Event to send new session data to extension
+		* Read-only event
+		*
+		* @event core.session_create_after
+		* @var	array		session_data				Associative array of session keys to be updated
+		* @since 3.1.6-RC1
+		*/
+		$vars = array('session_data');
+		extract($phpbb_dispatcher->trigger_event('core.session_create_after', compact($vars)));
+		unset($session_data);
+
 		return true;
 	}
 
@@ -906,13 +919,30 @@ class session
 	*/
 	function session_kill($new_session = true)
 	{
-		global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
+		global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
 
 		$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
 			WHERE session_id = '" . $db->sql_escape($this->session_id) . "'
 				AND session_user_id = " . (int) $this->data['user_id'];
 		$db->sql_query($sql);
 
+		$user_id = (int) $this->data['user_id'];
+		$session_id = $this->session_id;
+		/**
+		* Event to send session kill information to extension
+		* Read-only event
+		*
+		* @event core.session_kill_after
+		* @var	int		user_id				user_id of the session user.
+		* @var	string		session_id				current user's session_id
+		* @var	bool	new_session 	should we create new session for user
+		* @since 3.1.6-RC1
+		*/
+		$vars = array('user_id', 'session_id', 'new_session');
+		extract($phpbb_dispatcher->trigger_event('core.session_kill_after', compact($vars)));
+		unset($user_id);
+		unset($session_id);
+
 		// Allow connecting logout with external auth method logout
 		$provider_collection = $phpbb_container->get('auth.provider_collection');
 		$provider = $provider_collection->get_provider();
@@ -980,7 +1010,7 @@ class session
 	*/
 	function session_gc()
 	{
-		global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
+		global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
 
 		$batch_size = 10;
 
@@ -1048,6 +1078,14 @@ class session
 			$db->sql_query($sql);
 		}
 
+		/**
+		* Event to trigger extension on session_gc
+		*
+		* @event core.session_gc_after
+		* @since 3.1.6-RC1
+		*/
+		$phpbb_dispatcher->dispatch('core.session_gc_after');
+
 		return;
 	}
 
@@ -1541,12 +1579,24 @@ class session
 	*/
 	public function update_session($session_data, $session_id = null)
 	{
-		global $db;
+		global $db, $phpbb_dispatcher;
 
 		$session_id = ($session_id) ? $session_id : $this->session_id;
 
 		$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $session_data) . "
 			WHERE session_id = '" . $db->sql_escape($session_id) . "'";
 		$db->sql_query($sql);
+
+		/**
+		* Event to send update session information to extension
+		* Read-only event
+		*
+		* @event core.update_session_after
+		* @var	array		session_data				Associative array of session keys to be updated
+		* @var	string		session_id				current user's session_id
+		* @since 3.1.6-RC1
+		*/
+		$vars = array('session_data', 'session_id');
+		extract($phpbb_dispatcher->trigger_event('core.update_session_after', compact($vars)));
 	}
 }
--- a/phpbb/template/asset.php
+++ b/phpbb/template/asset.php
@@ -152,6 +152,24 @@ class asset
 	*/
 	public function set_path($path, $urlencode = false)
 	{
+		// Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory.
+		$real_root_path = realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR;
+
+		// If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path
+		if (substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
+		{
+			$path = $this->path_helper->get_phpbb_root_path() . str_replace('\\', '/', substr($path, strlen($real_root_path)));
+		}
+		else
+		{
+			// Else we make the path relative to the current working directory
+			$real_root_path = realpath('.') . DIRECTORY_SEPARATOR;
+			if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
+			{
+				$path = str_replace('\\', '/', substr($path, strlen($real_root_path)));
+			}
+		}
+
 		if ($urlencode)
 		{
 			$paths = explode('/', $path);
@@ -161,6 +179,7 @@ class asset
 			}
 			$path = implode('/', $paths);
 		}
+
 		$this->components['path'] = $path;
 	}
 
--- a/phpbb/template/twig/node/includecss.php
+++ b/phpbb/template/twig/node/includecss.php
@@ -31,7 +31,7 @@ class includecss extends \phpbb\template\twig\node\includeasset
 		$compiler
 			->raw("<link href=\"' . ")
 			->raw("\$asset_file . '\"")
-			->raw(' rel="stylesheet" type="text/css" media="screen, projection" />')
+			->raw(' rel="stylesheet" type="text/css" media="screen" />')
 		;
 	}
 }
--- a/phpbb/tree/nestedset.php
+++ b/phpbb/tree/nestedset.php
@@ -837,7 +837,10 @@ abstract class nestedset implements \phpbb\tree\tree_interface
 				' . $this->get_sql_where('AND') . '
 			ORDER BY ' . $this->column_left_id . ', ' . $this->column_item_id . ' ASC';
 		$result = $this->db->sql_query($sql);
-		while ($row = $this->db->sql_fetchrow($result))
+		$rows = $this->db->sql_fetchrowset($result);
+		$this->db->sql_freeresult($result);
+
+		foreach ($rows as $row)
 		{
 			// First we update the left_id for this module
 			if ($row[$this->column_left_id] != $new_id)
@@ -862,7 +865,6 @@ abstract class nestedset implements \phpbb\tree\tree_interface
 			}
 			$new_id++;
 		}
-		$this->db->sql_freeresult($result);
 
 		if ($acquired_new_lock)
 		{
--- a/phpbb/user.php
+++ b/phpbb/user.php
@@ -301,6 +301,14 @@ class user extends \phpbb\session
 		// After calling it we continue script execution...
 		phpbb_user_session_handler();
 
+		/**
+		* Execute code at the end of user setup
+		*
+		* @event core.user_setup_after
+		* @since 3.1.6-RC1
+		*/
+		$phpbb_dispatcher->dispatch('core.user_setup_after');
+
 		// If this function got called from the error handler we are finished here.
 		if (defined('IN_ERROR_HANDLER'))
 		{
--- a/phpbb/user_loader.php
+++ b/phpbb/user_loader.php
@@ -179,9 +179,10 @@ class user_loader
 	* @param bool $query Should we query the database if this user has not yet been loaded?
 	* 						Typically this should be left as false and you should make sure
 	* 						you load users ahead of time with load_users()
+	* @param bool @lazy If true, will be lazy loaded (requires JS)
 	* @return string
 	*/
-	public function get_avatar($user_id, $query = false)
+	public function get_avatar($user_id, $query = false, $lazy = false)
 	{
 		if (!($user = $this->get_user($user_id, $query)))
 		{
@@ -193,7 +194,7 @@ class user_loader
 			include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
 		}
 
-		return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height']);
+		return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height'], 'USER_AVATAR', false, $lazy);
 	}
 
 	/**
--- a/posting.php
+++ b/posting.php
@@ -624,6 +624,11 @@ if ($mode != 'edit')
 	$post_data['enable_urls']		= true;
 }
 
+if ($mode == 'post')
+{
+	$post_data['topic_status']		= ($request->is_set_post('lock_topic') && $auth->acl_gets('m_lock', 'f_user_lock', $forum_id)) ? ITEM_LOCKED : ITEM_UNLOCKED;
+}
+
 $post_data['enable_magic_url'] = $post_data['drafts'] = false;
 
 // User own some drafts?
@@ -1325,7 +1330,6 @@ if ($submit || $preview || $refresh)
 				'enable_urls'			=> (bool) $post_data['enable_urls'],
 				'enable_indexing'		=> (bool) $post_data['enable_indexing'],
 				'message_md5'			=> (string) $message_md5,
-				'post_time'				=> (isset($post_data['post_time'])) ? (int) $post_data['post_time'] : $current_time,
 				'post_checksum'			=> (isset($post_data['post_checksum'])) ? (string) $post_data['post_checksum'] : '',
 				'post_edit_reason'		=> $post_data['post_edit_reason'],
 				'post_edit_user'		=> ($mode == 'edit') ? $user->data['user_id'] : ((isset($post_data['post_edit_user'])) ? (int) $post_data['post_edit_user'] : 0),
@@ -1340,6 +1344,7 @@ if ($submit || $preview || $refresh)
 				'message'				=> $message_parser->message,
 				'attachment_data'		=> $message_parser->attachment_data,
 				'filename_data'			=> $message_parser->filename_data,
+				'topic_status'			=> $post_data['topic_status'],
 
 				'topic_visibility'			=> (isset($post_data['topic_visibility'])) ? $post_data['topic_visibility'] : false,
 				'post_visibility'			=> (isset($post_data['post_visibility'])) ? $post_data['post_visibility'] : false,
@@ -1374,10 +1379,9 @@ if ($submit || $preview || $refresh)
 			* @var	string	post_author_name	Author name for guest posts
 			* @var	bool	update_message		Boolean if the post message was changed
 			* @var	bool	update_subject		Boolean if the post subject was changed
-			* @var	bool	submit		Whether or not the form has been submitted
-			* @var	array	error		Any error strings; a non-empty array aborts form submission.
 			*				NOTE: Should be actual language strings, NOT language keys.
 			* @since 3.1.0-RC5
+			* @changed 3.1.6-RC1 remove submit and error from event  Submit and Error are checked previously prior to running event
 			*/
 			$vars = array(
 				'post_data',
@@ -1391,8 +1395,6 @@ if ($submit || $preview || $refresh)
 				'post_author_name',
 				'update_message',
 				'update_subject',
-				'submit',
-				'error',
 			);
 			extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_before', compact($vars)));
 
@@ -1416,10 +1418,9 @@ if ($submit || $preview || $refresh)
 			* @var	bool	update_message		Boolean if the post message was changed
 			* @var	bool	update_subject		Boolean if the post subject was changed
 			* @var	string	redirect_url		URL the user is going to be redirected to
-			* @var	bool	submit		Whether or not the form has been submitted
-			* @var	array	error		Any error strings; a non-empty array aborts form submission.
 			*				NOTE: Should be actual language strings, NOT language keys.
 			* @since 3.1.0-RC5
+			* @changed 3.1.6-RC1 remove submit and error from event  Submit and Error are checked previously prior to running event
 			*/
 			$vars = array(
 				'post_data',
@@ -1434,8 +1435,6 @@ if ($submit || $preview || $refresh)
 				'update_message',
 				'update_subject',
 				'redirect_url',
-				'submit',
-				'error',
 			);
 			extract($phpbb_dispatcher->trigger_event('core.posting_modify_submit_post_after', compact($vars)));
 
@@ -1573,11 +1572,21 @@ if (!sizeof($error) && $preview)
 	}
 }
 
+// Remove quotes that would become nested too deep before decoding the text
+$generate_quote = ($mode == 'quote' && !$submit && !$preview && !$refresh);
+if ($generate_quote && $config['max_quote_depth'] > 0)
+{
+	$tmp_bbcode_uid = $message_parser->bbcode_uid;
+	$message_parser->bbcode_uid = $post_data['bbcode_uid'];
+	$message_parser->remove_nested_quotes($config['max_quote_depth'] - 1);
+	$message_parser->bbcode_uid = $tmp_bbcode_uid;
+}
+
 // Decode text for message display
 $post_data['bbcode_uid'] = ($mode == 'quote' && !$preview && !$refresh && !sizeof($error)) ? $post_data['bbcode_uid'] : $message_parser->bbcode_uid;
 $message_parser->decode_message($post_data['bbcode_uid']);
 
-if ($mode == 'quote' && !$submit && !$preview && !$refresh)
+if ($generate_quote)
 {
 	if ($config['allow_bbcode'])
 	{
@@ -1768,7 +1777,7 @@ $page_data = array(
 	'S_SIGNATURE_CHECKED'		=> ($sig_checked) ? ' checked="checked"' : '',
 	'S_NOTIFY_ALLOWED'			=> (!$user->data['is_registered'] || ($mode == 'edit' && $user->data['user_id'] != $post_data['poster_id']) || !$config['allow_topic_notify'] || !$config['email_enable']) ? false : true,
 	'S_NOTIFY_CHECKED'			=> ($notify_checked) ? ' checked="checked"' : '',
-	'S_LOCK_TOPIC_ALLOWED'		=> (($mode == 'edit' || $mode == 'reply' || $mode == 'quote') && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED))) ? true : false,
+	'S_LOCK_TOPIC_ALLOWED'		=> (($mode == 'edit' || $mode == 'reply' || $mode == 'quote' || $mode == 'post') && ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && !empty($post_data['topic_poster']) && $user->data['user_id'] == $post_data['topic_poster'] && $post_data['topic_status'] == ITEM_UNLOCKED))) ? true : false,
 	'S_LOCK_TOPIC_CHECKED'		=> ($lock_topic_checked) ? ' checked="checked"' : '',
 	'S_LOCK_POST_ALLOWED'		=> ($mode == 'edit' && $auth->acl_get('m_edit', $forum_id)) ? true : false,
 	'S_LOCK_POST_CHECKED'		=> ($lock_post_checked) ? ' checked="checked"' : '',
@@ -1835,6 +1844,7 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_
 * @var	int	post_id		ID of the post
 * @var	int	topic_id	ID of the topic
 * @var	int	forum_id	ID of the forum
+* @var	int	draft_id	ID of the draft
 * @var	bool	submit		Whether or not the form has been submitted
 * @var	bool	preview		Whether or not the post is being previewed
 * @var	bool	save		Whether or not a draft is being saved
@@ -1857,6 +1867,7 @@ if (($mode == 'post' || ($mode == 'edit' && $post_id == $post_data['topic_first_
 *		delete, cancel, refresh, error, page_data, message_parser
 * @change 3.1.2-RC1 Removed 'delete' var as it does not exist
 * @change 3.1.5-RC1 Added poll variables to the page_data array
+* @change 3.1.6-RC1 Added 'draft_id' var
 */
 $vars = array(
 	'post_data',
@@ -1870,6 +1881,7 @@ $vars = array(
 	'post_id',
 	'topic_id',
 	'forum_id',
+	'draft_id',
 	'submit',
 	'preview',
 	'save',
--- a/search.php
+++ b/search.php
@@ -1167,14 +1167,25 @@ if ($keywords || $author || $author_id || $search_id || $submit)
 	* Modify the title and/or load data for the search results page
 	*
 	* @event core.search_results_modify_search_title
-	* @var	int		author_id		ID of the author to search by
-	* @var	string	l_search_title	The title of the search page
-	* @var	string	search_id		Predefined search type name
-	* @var	string	show_results	Search results output mode - topics or posts
-	* @var	int		start			The starting id of the results
+	* @var	int		author_id			ID of the author to search by
+	* @var	string	l_search_title		The title of the search page
+	* @var	string	search_id			Predefined search type name
+	* @var	string	show_results		Search results output mode - topics or posts
+	* @var	int		start				The starting id of the results
+	* @var	int		total_match_count	The count of search results
+	* @var	string	keywords			The search keywords
 	* @since 3.1.0-RC4
+	* @changed 3.1.6-RC1 Added total_match_count and keywords
 	*/
-	$vars = array('author_id', 'l_search_title', 'search_id', 'show_results', 'start');
+	$vars = array(
+		'author_id',
+		'l_search_title',
+		'search_id',
+		'show_results',
+		'start',
+		'total_match_count',
+		'keywords',
+	);
 	extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars)));
 
 	page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);
--- a/styles/prosilver/style.cfg
+++ b/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
 # General Information about this style
 name = prosilver
 copyright = © phpBB Limited, 2007
-style_version = 3.1.5
-phpbb_version = 3.1.5
+style_version = 3.1.6
+phpbb_version = 3.1.6
 
 # Defining a different template bitfield
 # template_bitfield = lNg=
--- a/styles/prosilver/template/attachment.html
+++ b/styles/prosilver/template/attachment.html
@@ -1,8 +1,10 @@
+<!-- EVENT attachment_file_before -->
 
 <!-- BEGIN _file -->
 	<!-- IF _file.S_DENIED -->
 	<p>[{_file.DENIED_MESSAGE}]</p>
 	<!-- ELSE -->
+		<!-- EVENT attachment_file_prepend -->
 
 		<!-- IF _file.S_THUMBNAIL -->
 		<dl class="thumbnail">
@@ -11,7 +13,6 @@
 		</dl>
 		<!-- ENDIF -->
 
-
 		<!-- IF _file.S_IMAGE -->
 		<dl class="file">
 			<dt class="attach-image"><img src="{_file.U_INLINE_LINK}" class="postimage" alt="{_file.DOWNLOAD_NAME}" onclick="viewableArea(this);" /></dt>
@@ -28,8 +29,6 @@
 		</dl>
 		<!-- ENDIF -->
 
-
-
 		<!-- IF _file.S_WM_FILE -->
 			<!-- method used here from http://alistapart.com/articles/byebyeembed / autosizing seems to not work always, this will not fix -->
 			<object width="320" height="285" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" id="wmstream_{_file.ATTACH_ID}">
@@ -118,5 +117,7 @@
 			<a href="{_file.U_DOWNLOAD_LINK}">{_file.DOWNLOAD_NAME}</a> [ {_file.FILESIZE} {_file.SIZE_LANG} | {_file.L_DOWNLOAD_COUNT} ]</p>
 		<!-- ENDIF -->
 
+		<!-- EVENT attachment_file_append -->
 	<!-- ENDIF -->
 <!-- END _file -->
+<!-- EVENT attachment_file_after -->
--- a/styles/prosilver/template/forum_fn.js
+++ b/styles/prosilver/template/forum_fn.js
@@ -34,7 +34,7 @@ function popup(url, width, height, name) {
 function pageJump(item) {
 	'use strict';
 
-	var page = item.val(),
+	var page = parseInt(item.val(), 10),
 		perPage = item.attr('data-per-page'),
 		baseUrl = item.attr('data-base-url'),
 		startName = item.attr('data-start-name');
@@ -156,7 +156,11 @@ function selectCode(a) {
 		// Safari and Chrome
 		if (s.setBaseAndExtent) {
 			var l = (e.innerText.length > 1) ? e.innerText.length - 1 : 1;
-			s.setBaseAndExtent(e, 0, e, l);
+			try {
+				s.setBaseAndExtent(e, 0, e, l);
+			} catch (error) {
+				s.setBaseAndExtent(e, 0, e, 1);
+			}
 		}
 		// Firefox and Opera
 		else {
--- a/styles/prosilver/template/mcp_forum.html
+++ b/styles/prosilver/template/mcp_forum.html
@@ -13,9 +13,9 @@
 	<div class="action-bar top">
 		<div class="pagination">
 			{TOTAL_TOPICS}
-			<!-- IF .pagination --> 
+			<!-- IF .pagination -->
 				<!-- INCLUDE pagination.html -->
-			<!-- ELSE --> 
+			<!-- ELSE -->
 				 &bull; {PAGE_NUMBER}
 			<!-- ENDIF -->
 		</div>
@@ -40,9 +40,11 @@
 				<dt <!-- IF topicrow.TOPIC_ICON_IMG -->style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF -->>
 					<!-- IF topicrow.S_UNREAD_TOPIC --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF -->
 					<div class="list-inner">
-
+					<!-- EVENT topiclist_row_prepend -->
 					<!-- IF topicrow.S_SELECT_TOPIC --><a href="{topicrow.U_SELECT_TOPIC}" class="topictitle">[ {L_SELECT_MERGE} ]</a>&nbsp;&nbsp; <!-- ENDIF -->
+					<!-- EVENT mcp_forum_topic_title_before -->
 					<a href="{topicrow.U_VIEW_TOPIC}" class="topictitle">{topicrow.TOPIC_TITLE}</a>
+					<!-- EVENT mcp_forum_topic_title_after -->
 					<!-- IF topicrow.S_TOPIC_UNAPPROVED or topicrow.S_POSTS_UNAPPROVED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.UNAPPROVED_IMG}</a> <!-- ENDIF -->
 					<!-- IF topicrow.S_TOPIC_DELETED or topicrow.S_POSTS_DELETED --><a href="{topicrow.U_MCP_QUEUE}">{topicrow.DELETED_IMG}</a> <!-- ENDIF -->
 					<!-- IF topicrow.S_TOPIC_REPORTED --><a href="{topicrow.U_MCP_REPORT}">{REPORTED_IMG}</a><!-- ENDIF -->
@@ -74,7 +76,7 @@
 						<!-- IF topicrow.ATTACH_ICON_IMG -->{topicrow.ATTACH_ICON_IMG} <!-- ENDIF -->
 						{L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} &raquo; {topicrow.FIRST_POST_TIME}
 					</div>
-
+					<!-- EVENT topiclist_row_append -->
 					</div>
 				</dt>
 				<dd class="posts">{topicrow.REPLIES} <dfn>{L_REPLIES}</dfn></dd>
@@ -107,9 +109,9 @@
 	<div class="action-bar bottom">
 		<div class="pagination">
 			{TOTAL_TOPICS}
-			<!-- IF .pagination --> 
+			<!-- IF .pagination -->
 				<!-- INCLUDE pagination.html -->
-			<!-- ELSE --> 
+			<!-- ELSE -->
 				 &bull; {PAGE_NUMBER}
 			<!-- ENDIF -->
 		</div>
--- a/styles/prosilver/template/mcp_topic.html
+++ b/styles/prosilver/template/mcp_topic.html
@@ -54,10 +54,12 @@
 		</dl>
 	<!-- ENDIF -->
 
+	<!-- EVENT mcp_topic_options_before -->
 	<dl>
 		<dt><label for="subject">{L_SPLIT_SUBJECT}{L_COLON}</label></dt>
 		<dd><input type="text" name="subject" id="subject" size="45" maxlength="124" tabindex="2" value="{SPLIT_SUBJECT}" title="{L_SPLIT_SUBJECT}" class="inputbox" /></dd>
 	</dl>
+	<!-- EVENT mcp_topic_options_after -->
 	<dl>
 		<dt><label>{L_SPLIT_FORUM}{L_COLON}</label></dt>
 		<dd><select name="to_forum_id">{S_FORUM_SELECT}</select></dd>
@@ -87,7 +89,7 @@
 
 	<h3 id="review">
 		<span class="right-box"><a href="#review" onclick="viewableArea(getElementById('topicreview'), true); var rev_text = getElementById('review').getElementsByTagName('a').item(0).firstChild; if (rev_text.data == '{LA_EXPAND_VIEW}'){rev_text.data = '{LA_COLLAPSE_VIEW}'; } else if (rev_text.data == '{LA_COLLAPSE_VIEW}'){rev_text.data = '{LA_EXPAND_VIEW}'};">{L_EXPAND_VIEW}</a></span>
-		{L_TOPIC_REVIEW}{L_COLON} {TOPIC_TITLE}
+		{L_TOPIC_REVIEW}{L_COLON} <!-- EVENT mcp_topic_topic_title_before -->{TOPIC_TITLE}<!-- EVENT mcp_topic_topic_title_after -->
 	</h3>
 
 	<div id="topicreview">
@@ -153,9 +155,9 @@
 	<div class="action-bar bottom">
 		<div class="pagination">
 			{TOTAL_POSTS}
-			<!-- IF .pagination --> 
+			<!-- IF .pagination -->
 				<!-- INCLUDE pagination.html -->
-			<!-- ELSE --> 
+			<!-- ELSE -->
 				 &bull; {PAGE_NUMBER}
 			<!-- ENDIF -->
 		</div>
--- a/styles/prosilver/template/memberlist_body.html
+++ b/styles/prosilver/template/memberlist_body.html
@@ -102,7 +102,7 @@
 			<!-- ENDIF -->
 
 	<tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->">
-		<td><!-- IF memberrow.RANK_IMG --><span class="rank-img">{memberrow.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{memberrow.RANK_TITLE}</span><!-- ENDIF --><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- ENDIF --></td>
+		<td><span class="rank-img"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></span><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- ENDIF --></td>
 		<td class="posts"><!-- IF memberrow.POSTS and S_DISPLAY_SEARCH --><a href="{memberrow.U_SEARCH_USER}" title="{L_SEARCH_USER_POSTS}">{memberrow.POSTS}</a><!-- ELSE -->{memberrow.POSTS}<!-- ENDIF --></td>
 		<td class="info"><!-- BEGIN custom_fields --><div>{memberrow.custom_fields.PROFILE_FIELD_VALUE}</div><!-- BEGINELSE -->&nbsp;<!-- END custom_fields --></td>
 		<td>{memberrow.JOINED}</td>
--- a/styles/prosilver/template/memberlist_search.html
+++ b/styles/prosilver/template/memberlist_search.html
@@ -32,7 +32,7 @@
 <!-- ENDIF -->
 <!-- IF S_JABBER_ENABLED -->
 	<dl>
-		<dt><label for="jabber">{L_JABBER}:</label></dt>
+		<dt><label for="jabber">{L_JABBER}{L_COLON}</label></dt>
 		<dd><input type="text" name="jabber" id="jabber" value="{JABBER}" class="inputbox" /></dd>
 	</dl>
 <!-- ENDIF -->
--- a/styles/prosilver/template/memberlist_view.html
+++ b/styles/prosilver/template/memberlist_view.html
@@ -11,8 +11,10 @@
 	<!-- IF AVATAR_IMG -->
 		<dl class="left-box">
 			<dt class="profile-avatar">{AVATAR_IMG}</dt>
+			<!-- EVENT memberlist_view_rank_avatar_before -->
 			<!-- IF RANK_TITLE --><dd style="text-align: center;">{RANK_TITLE}</dd><!-- ENDIF -->
 			<!-- IF RANK_IMG --><dd style="text-align: center;">{RANK_IMG}</dd><!-- ENDIF -->
+			<!-- EVENT memberlist_view_rank_avatar_after -->
 		</dl>
 	<!-- ENDIF -->
 
@@ -26,8 +28,10 @@
 			<!-- IF U_SWITCH_PERMISSIONS --> [ <a href="{U_SWITCH_PERMISSIONS}">{L_USE_PERMISSIONS}</a> ]<!-- ENDIF -->
 		</dd>
 		<!-- IF not AVATAR_IMG -->
+			<!-- EVENT memberlist_view_rank_no_avatar_before -->
 			<!-- IF RANK_TITLE --><dt>{L_RANK}{L_COLON}</dt> <dd>{RANK_TITLE}</dd><!-- ENDIF -->
 			<!-- IF RANK_IMG --><dt><!-- IF RANK_TITLE -->&nbsp;<!-- ELSE -->{L_RANK}{L_COLON}<!-- ENDIF --></dt> <dd>{RANK_IMG}</dd><!-- ENDIF -->
+			<!-- EVENT memberlist_view_rank_no_avatar_after -->
 		<!-- ENDIF -->
 		<!-- IF S_USER_INACTIVE --><dt>{L_USER_IS_INACTIVE}{L_COLON}</dt> <dd>{USER_INACTIVE_REASON}</dd><!-- ENDIF -->
 		<!-- IF AGE !== '' --><dt>{L_AGE}{L_COLON}</dt> <dd>{AGE}</dd><!-- ENDIF -->
--- a/styles/prosilver/template/navbar_header.html
+++ b/styles/prosilver/template/navbar_header.html
@@ -93,12 +93,12 @@
 		<!-- DEFINE $MICRODATA = ' itemtype="http://data-vocabulary.org/Breadcrumb" itemscope=""' -->
 		<!-- EVENT overall_header_breadcrumbs_before -->
 		<li class="small-icon icon-home breadcrumbs">
-			<!-- IF U_SITE_HOME --><span class="crumb"><a href="{U_SITE_HOME}"{$MICRODATA} data-navbar-reference="home">{L_SITE_HOME}</a></span><!-- ENDIF -->
+			<!-- IF U_SITE_HOME --><span class="crumb"{$MICRODATA}><a href="{U_SITE_HOME}" data-navbar-reference="home" itemprop="url"><span itemprop="title">{L_SITE_HOME}</span></a></span><!-- ENDIF -->
 			<!-- EVENT overall_header_breadcrumb_prepend -->
-			<span class="crumb"><a href="{U_INDEX}" accesskey="h"{$MICRODATA} data-navbar-reference="index">{L_INDEX}</a></span>
+			<span class="crumb"{$MICRODATA}><a href="{U_INDEX}" accesskey="h" data-navbar-reference="index" itemprop="url"><span itemprop="title">{L_INDEX}</span></a></span>
 			<!-- BEGIN navlinks -->
 				<!-- EVENT overall_header_navlink_prepend -->
-				<span class="crumb"><a href="{navlinks.U_VIEW_FORUM}"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->>{navlinks.FORUM_NAME}</a></span>
+				<span class="crumb"{$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemprop="url"><span itemprop="title">{navlinks.FORUM_NAME}</span></a></span>
 				<!-- EVENT overall_header_navlink_append -->
 			<!-- END navlinks -->
 			<!-- EVENT overall_header_breadcrumb_append -->
--- a/styles/prosilver/template/overall_header.html
+++ b/styles/prosilver/template/overall_header.html
@@ -14,6 +14,7 @@
 	<!-- IF S_ENABLE_FEEDS_TOPICS_ACTIVE --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FEED_TOPICS_ACTIVE}" href="{U_FEED}?mode=topics_active"><!-- ENDIF -->
 	<!-- IF S_ENABLE_FEEDS_FORUM and S_FORUM_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_FORUM} - {FORUM_NAME}" href="{U_FEED}?f={S_FORUM_ID}"><!-- ENDIF -->
 	<!-- IF S_ENABLE_FEEDS_TOPIC and S_TOPIC_ID --><link rel="alternate" type="application/atom+xml" title="{L_FEED} - {L_TOPIC} - {TOPIC_TITLE}" href="{U_FEED}?f={S_FORUM_ID}&amp;t={S_TOPIC_ID}"><!-- ENDIF -->
+	<!-- EVENT overall_header_feeds -->
 <!-- ENDIF -->
 
 <!-- IF U_CANONICAL -->
@@ -31,7 +32,7 @@
 <script>
 	WebFontConfig = {
 		google: {
-			families: ['Open Sans:n6']
+			families: ['Open+Sans:600:cyrillic-ext,latin,greek-ext,greek,vietnamese,latin-ext,cyrillic']
 		}
 	};
 
--- a/styles/prosilver/template/posting_editor.html
+++ b/styles/prosilver/template/posting_editor.html
@@ -89,6 +89,7 @@
 		<fieldset class="submit-buttons">
 			{S_HIDDEN_ADDRESS_FIELD}
 			{S_HIDDEN_FIELDS}
+			<!-- EVENT posting_editor_submit_buttons -->
 			<!-- IF S_HAS_DRAFTS --><input type="submit" accesskey="d" tabindex="8" name="load" value="{L_LOAD_DRAFT}" class="button2" onclick="load_draft = true;" />&nbsp; <!-- ENDIF -->
 			<!-- IF S_SAVE_ALLOWED --><input type="submit" accesskey="k" tabindex="7" name="save" value="{L_SAVE_DRAFT}" class="button2" />&nbsp; <!-- ENDIF -->
 			<input type="submit" tabindex="5" name="preview" value="{L_PREVIEW}" class="button1"<!-- IF not S_PRIVMSGS --> onclick="document.getElementById('postform').action += '#preview';"<!-- ENDIF --> />&nbsp;
@@ -116,6 +117,7 @@
 						<a href="#tabs" data-subpanel="poll-panel" role="tab" aria-controls="poll-panel">{L_ADD_POLL}</a>
 					</li>
 				<!-- ENDIF -->
+				<!-- EVENT posting_editor_add_panel_tab -->
 			</ul>
 		</div>
 	<!-- ENDIF -->
--- a/styles/prosilver/template/posting_layout.html
+++ b/styles/prosilver/template/posting_layout.html
@@ -1,7 +1,7 @@
 <!-- INCLUDE overall_header.html -->
 
 <!-- IF TOPIC_TITLE -->
-	<h2 class="posting-title"><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
+	<h2 class="posting-title"><!-- EVENT posting_topic_title_before --><a href="{U_VIEW_TOPIC}">{TOPIC_TITLE}</a></h2>
 <!-- ELSE -->
 	<h2 class="posting-title"><a href="{U_VIEW_FORUM}">{FORUM_NAME}</a></h2>
  <!-- ENDIF -->
@@ -77,6 +77,8 @@
 
 <!-- IF S_SHOW_POLL_BOX or S_POLL_DELETE --><!-- INCLUDE posting_poll_body.html --><!-- ENDIF -->
 
+<!-- EVENT posting_layout_include_panel_body -->
+
 <!-- IF S_DISPLAY_REVIEW --><!-- INCLUDE posting_topic_review.html --><!-- ENDIF -->
 
 </form>
--- a/styles/prosilver/template/simple_header.html
+++ b/styles/prosilver/template/simple_header.html
@@ -10,7 +10,7 @@
 <script>
 	WebFontConfig = {
 		google: {
-			families: ['Open Sans:n6']
+			families: ['Open+Sans:600:cyrillic-ext,latin,greek-ext,greek,vietnamese,latin-ext,cyrillic']
 		}
 	};
 
--- a/styles/prosilver/template/ucp_main_front.html
+++ b/styles/prosilver/template/ucp_main_front.html
@@ -53,6 +53,7 @@
 
 	<h3>{L_YOUR_DETAILS}</h3>
 
+<!-- EVENT ucp_main_front_user_activity_before -->
 	<dl class="details">
 		<dt>{L_JOINED}{L_COLON}</dt> <dd>{JOINED}</dd>
 		<dt>{L_LAST_ACTIVE}{L_COLON}</dt> <dd>{LAST_VISIT_YOU}</dd>
@@ -61,6 +62,7 @@
 		<!-- IF ACTIVE_TOPIC != '' --><dt>{L_ACTIVE_IN_TOPIC}{L_COLON}</dt> <dd><strong><a href="{U_ACTIVE_TOPIC}">{ACTIVE_TOPIC}</a></strong><br />({ACTIVE_TOPIC_POSTS} / {ACTIVE_TOPIC_PCT})</dd><!-- ENDIF -->
 		<!-- IF WARNINGS --><dt>{L_YOUR_WARNINGS}{L_COLON}</dt> <dd class="error">{WARNING_IMG} [{WARNINGS}]</dd><!-- ENDIF -->
 	</dl>
+<!-- EVENT ucp_main_front_user_activity_after -->
 
 	</div>
 </div>
--- a/styles/prosilver/template/ucp_pm_history.html
+++ b/styles/prosilver/template/ucp_pm_history.html
@@ -4,6 +4,7 @@
 	{L_MESSAGE_HISTORY}{L_COLON}
 </h3>
 
+<!-- EVENT ucp_pm_history_review_before -->
 <div id="topicreview">
 	<script type="text/javascript">
 	// <![CDATA[
@@ -17,15 +18,22 @@
 		<div class="postbody" id="pr{history_row.MSG_ID}">
 			<h3><a href="{history_row.U_VIEW_MESSAGE}" <!-- IF history_row.S_CURRENT_MSG -->class="current"<!-- ENDIF -->>{history_row.SUBJECT}</a></h3>
 
-			<!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE -->
+			<!-- DEFINE $SHOW_PM_HISTORY_POST_BUTTONS = (history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE) -->
+			<!-- EVENT ucp_pm_history_post_buttons_list_before -->
+			<!-- IF $SHOW_PM_HISTORY_POST_BUTTONS -->
 			<ul class="post-buttons">
+				<!-- EVENT ucp_pm_history_post_buttons_before -->
+				<!-- IF history_row.U_QUOTE or history_row.MESSAGE_AUTHOR_QUOTE -->
 				<li>
 					<a <!-- IF history_row.U_QUOTE -->href="{history_row.U_QUOTE}"<!-- ELSE -->href="#postingbox" onclick="addquote({history_row.MSG_ID}, '{history_row.MESSAGE_AUTHOR_QUOTE}', '{LA_WROTE}');"<!-- ENDIF --> title="{L_QUOTE} {history_row.MESSAGE_AUTHOR}" class="button icon-button quote-icon">
 						<span>{L_QUOTE} {history_row.MESSAGE_AUTHOR}</span>
 					</a>
 				</li>
+				<!-- ENDIF -->
+				<!-- EVENT ucp_pm_history_post_buttons_after -->
 			</ul>
 			<!-- ENDIF -->
+			<!-- EVENT ucp_pm_history_post_buttons_list_after -->
 
 			<p class="author">{history_row.MINI_POST_IMG} {L_SENT_AT}{L_COLON} <strong>{history_row.SENT_DATE}</strong><br />
 				{L_MESSAGE_BY_AUTHOR} {history_row.MESSAGE_AUTHOR_FULL}</p>
@@ -37,6 +45,7 @@
 	</div>
 	<!-- END history_row -->
 </div>
+<!-- EVENT ucp_pm_history_review_after -->
 
 <hr />
 <p><a href="#cp-main" class="top2">{L_BACK_TO_TOP}</a></p>
--- a/styles/prosilver/template/ucp_pm_viewfolder.html
+++ b/styles/prosilver/template/ucp_pm_viewfolder.html
@@ -25,7 +25,7 @@
 	<fieldset class="submit-buttons">
 		<input type="hidden" name="export_option" value="CSV" />
 		<input class="button1" type="submit" name="submit_export" value="{L_EXPORT_FOLDER}" />&nbsp;
-		<input class="button2" type="reset" value="Reset" name="reset" />&nbsp;
+		<input class="button2" type="reset" value="{L_RESET}" name="reset" />&nbsp;
 		{S_FORM_TOKEN}
 	</fieldset>
 	</form>
--- a/styles/prosilver/template/ucp_pm_viewmessage.html
+++ b/styles/prosilver/template/ucp_pm_viewmessage.html
@@ -27,7 +27,9 @@
 			{MESSAGE_AUTHOR_FULL}
 		</dt>
 
+		<!-- EVENT ucp_pm_viewmessage_rank_before -->
 		<!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF -->
+		<!-- EVENT ucp_pm_viewmessage_rank_after -->
 
 		<dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF U_AUTHOR_POSTS != '' --><a href="{U_AUTHOR_POSTS}">{AUTHOR_POSTS}</a><!-- ELSE -->{AUTHOR_POSTS}<!-- ENDIF --></dd>
 		<!-- IF AUTHOR_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF -->
@@ -73,7 +75,9 @@
 	<div class="postbody">
 		<h3 class="first">{SUBJECT}</h3>
 
-		<!-- IF U_DELETE or U_EDIT or U_QUOTE or U_REPORT -->
+		<!-- DEFINE $SHOW_PM_POST_BUTTONS = (U_EDIT or U_DELETE or U_REPORT or U_QUOTE) -->
+		<!-- EVENT ucp_pm_viewmessage_post_buttons_list_before -->
+		<!-- IF $SHOW_PM_POST_BUTTONS -->
 		<ul class="post-buttons">
 			<!-- EVENT ucp_pm_viewmessage_post_buttons_before -->
 			<!-- IF U_EDIT -->
@@ -99,6 +103,7 @@
 			<!-- EVENT ucp_pm_viewmessage_post_buttons_after -->
 		</ul>
 		<!-- ENDIF -->
+		<!-- EVENT ucp_pm_viewmessage_post_buttons_list_after -->
 
 		<p class="author">
 			<strong>{L_SENT_AT}{L_COLON}</strong> {SENT_DATE}
--- a/styles/prosilver/template/viewtopic_body.html
+++ b/styles/prosilver/template/viewtopic_body.html
@@ -40,6 +40,7 @@
 	</div>
 
 	<!-- INCLUDE viewtopic_topic_tools.html -->
+	<!-- EVENT viewtopic_dropdown_top_custom -->
 
 	<!-- IF S_DISPLAY_SEARCHBOX -->
 		<div class="search-box" role="search">
@@ -67,6 +68,8 @@
 	<!-- EVENT viewtopic_body_pagination_top_after -->
 </div>
 
+<!-- EVENT viewtopic_body_poll_before -->
+
 <!-- IF S_HAS_POLL -->
 	<form method="post" action="{S_POLL_ACTION}" data-ajax="vote_poll" class="topic_poll">
 
@@ -120,6 +123,8 @@
 	<hr />
 <!-- ENDIF -->
 
+<!-- EVENT viewtopic_body_poll_after -->
+
 <!-- BEGIN postrow -->
 	<!-- EVENT viewtopic_body_postrow_post_before -->
 	<!-- IF postrow.S_FIRST_UNREAD -->
@@ -142,7 +147,9 @@
 				<!-- EVENT viewtopic_body_post_author_after -->
 			</dt>
 
+			<!-- EVENT viewtopic_body_postrow_rank_before -->
 			<!-- IF postrow.RANK_TITLE or postrow.RANK_IMG --><dd class="profile-rank">{postrow.RANK_TITLE}<!-- IF postrow.RANK_TITLE and postrow.RANK_IMG --><br /><!-- ENDIF -->{postrow.RANK_IMG}</dd><!-- ENDIF -->
+			<!-- EVENT viewtopic_body_postrow_rank_after -->
 
 		<!-- IF postrow.POSTER_POSTS != '' --><dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF postrow.U_SEARCH !== '' --><a href="{postrow.U_SEARCH}"><!-- ENDIF -->{postrow.POSTER_POSTS}<!-- IF postrow.U_SEARCH !== '' --></a><!-- ENDIF --></dd><!-- ENDIF -->
 		<!-- IF postrow.POSTER_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {postrow.POSTER_JOINED}</dd><!-- ENDIF -->
@@ -210,9 +217,10 @@
 
 			<h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3>
 
+		<!-- DEFINE $SHOW_POST_BUTTONS = (postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE) -->
 		<!-- EVENT viewtopic_body_post_buttons_list_before -->
 		<!-- IF not S_IS_BOT -->
-			<!-- IF postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE -->
+			<!-- IF $SHOW_POST_BUTTONS -->
 				<ul class="post-buttons">
 					<!-- EVENT viewtopic_body_post_buttons_before -->
 					<!-- IF postrow.U_EDIT -->
@@ -375,6 +383,8 @@
 			</div>
 		</div>
 	<!-- ENDIF -->
+	
+	<!-- EVENT viewtopic_dropdown_bottom_custom -->
 
 	<!-- IF .pagination or TOTAL_POSTS -->
 		<div class="pagination">
--- a/styles/prosilver/theme/buttons.css
+++ b/styles/prosilver/theme/buttons.css
@@ -5,8 +5,7 @@
 	cursor: pointer;
 	display: inline-block;
 	height: 18px;
-	line-height: 18px;
-	font-size: 13px;
+	font-size: 1.2em;
 	white-space: nowrap;
 	border: 1px solid transparent;
 	border-radius: 4px;
--- a/styles/prosilver/theme/common.css
+++ b/styles/prosilver/theme/common.css
@@ -43,6 +43,9 @@ table {
 	border-collapse: collapse;
 	border-spacing: 0;
 }
+abbr {
+	text-decoration: none;
+}
 
 /* General Markup Styles
 ---------------------------------------- */
@@ -327,10 +330,10 @@ ul.linklist li.responsive-menu {
 ul.linklist li.responsive-menu a.responsive-menu-link {
 	display: inline-block;
 	margin: 0 5px;
-	font-size: 16px;
+	font-size: 1.455em;
 	position: relative;
 	width: 16px;
-	line-height: 20px;
+	line-height: 1.2em;
 	text-decoration: none;
 }
 
@@ -799,7 +802,7 @@ fieldset.fields1 dl.pmlist dd.recipients {
 /* Action-bars (container for post/reply buttons, pagination, etc.)
 ---------------------------------------- */
 .action-bar {
-	font-size: 11px;
+	font-size: 1.1em;
 	margin: 4px 0;
 }
 
@@ -811,7 +814,6 @@ fieldset.fields1 dl.pmlist dd.recipients {
 ---------------------------------------- */
 .pagination {
 	float: right;
-	font-size: 11px;
 	margin-top: 3px;
 	text-align: right;
 	width: auto;
@@ -841,7 +843,7 @@ fieldset.fields1 dl.pmlist dd.recipients {
 	display: block;
 	font-size: 0.9em;
 	font-weight: normal;
-	line-height: 13px;
+	line-height: 1.4em;
 	min-width: 10px;
 	padding: 3px;
 	text-align: center;
@@ -1156,12 +1158,11 @@ ul.linklist:after,
 .dropdown-extended .header {
 	padding: 0 10px;
 	font-family: Arial, "Helvetica Neue", Helvetica, Arial, sans-serif;
-	font-size: 11px;
 	font-weight: bold;
 	text-align: left;
 	text-shadow: 1px 1px 1px white;
 	text-transform: uppercase;
-	line-height: 30px;
+	line-height: 3em;
 	border-bottom: 1px solid;
 	border-radius: 5px 5px 0 0;
 }
@@ -1213,7 +1214,7 @@ ul.linklist:after,
 }
 
 .notification_list p.notification-time {
-	font-size: 10px;
+	font-size: 0.9em;
 	margin: 0;
 	text-align: right;
 }
@@ -1229,7 +1230,7 @@ ul.linklist:after,
 
 .notification_list p.notifications_title {
 	font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
-	font-size: 13px !important;
+	font-size: 1.2em !important;
 }
 
 .notification_list p.notifications_title strong {
@@ -1237,7 +1238,7 @@ ul.linklist:after,
 }
 
 .notification_list p.notifications_time {
-	font-size: 10px !important;
+	font-size: 0.9em !important;
 }
 
 .notification_text {
@@ -1260,12 +1261,14 @@ ul.linklist:after,
 }
 
 #quick-links a.responsive-menu-link:before {
-	font-size: 16px;
+	font-size: 1.455em;
 	line-height: 16.5px;
 }
 
 .compact #quick-links a.responsive-menu-link {
-	font-size: 0;
+	width: 0;
+	overflow: hidden;
+	white-space: nowrap;
 }
 
 .compact .icon-notification > a > span, .compact .icon-pm > a > span {
--- a/styles/prosilver/theme/cp.css
+++ b/styles/prosilver/theme/cp.css
@@ -114,7 +114,7 @@ ul.cplist {
 	float: left;
 	font-size: 1em;
 	font-weight: bold;
-	line-height: 14px;
+	line-height: 1.4em;
 }
 
 #tabs .tab > a, #minitabs .tab > a {
@@ -172,10 +172,10 @@ ul.cplist {
 
 .responsive-tab > a.responsive-tab-link {
 	display: block;
-	font-size: 16px;
+	font-size: 1.6em;
 	position: relative;
 	width: 16px;
-	line-height: 14px;
+	line-height: 0.9em;
 	text-decoration: none;
 }
 
--- a/vendor/autoload.php
+++ b/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500::getLoader();
+return ComposerAutoloaderInit814f006b1edecd862adaa89c194918bc::getLoader();
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -514,6 +514,7 @@ return array(
     'Symfony\\Component\\Yaml\\Unescaper' => $vendorDir . '/symfony/yaml/Symfony/Component/Yaml/Unescaper.php',
     'Symfony\\Component\\Yaml\\Yaml' => $vendorDir . '/symfony/yaml/Symfony/Component/Yaml/Yaml.php',
     'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
+    'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
     'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
     'Twig_CompilerInterface' => $vendorDir . '/twig/twig/lib/Twig/CompilerInterface.php',
     'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
@@ -529,9 +530,11 @@ return array(
     'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
     'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
     'Twig_Extension_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/Extension/Optimizer.php',
+    'Twig_Extension_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Extension/Profiler.php',
     'Twig_Extension_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Extension/Sandbox.php',
     'Twig_Extension_Staging' => $vendorDir . '/twig/twig/lib/Twig/Extension/Staging.php',
     'Twig_Extension_StringLoader' => $vendorDir . '/twig/twig/lib/Twig/Extension/StringLoader.php',
+    'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
     'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
     'Twig_FilterCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterCallableInterface.php',
     'Twig_FilterInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterInterface.php',
@@ -565,6 +568,7 @@ return array(
     'Twig_Node_Block' => $vendorDir . '/twig/twig/lib/Twig/Node/Block.php',
     'Twig_Node_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/BlockReference.php',
     'Twig_Node_Body' => $vendorDir . '/twig/twig/lib/Twig/Node/Body.php',
+    'Twig_Node_CheckSecurity' => $vendorDir . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
     'Twig_Node_Do' => $vendorDir . '/twig/twig/lib/Twig/Node/Do.php',
     'Twig_Node_Embed' => $vendorDir . '/twig/twig/lib/Twig/Node/Embed.php',
     'Twig_Node_Expression' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression.php',
@@ -578,6 +582,7 @@ return array(
     'Twig_Node_Expression_Binary_BitwiseXor' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
     'Twig_Node_Expression_Binary_Concat' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
     'Twig_Node_Expression_Binary_Div' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
+    'Twig_Node_Expression_Binary_EndsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
     'Twig_Node_Expression_Binary_Equal' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
     'Twig_Node_Expression_Binary_FloorDiv' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
     'Twig_Node_Expression_Binary_Greater' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
@@ -585,6 +590,7 @@ return array(
     'Twig_Node_Expression_Binary_In' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
     'Twig_Node_Expression_Binary_Less' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
     'Twig_Node_Expression_Binary_LessEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
+    'Twig_Node_Expression_Binary_Matches' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
     'Twig_Node_Expression_Binary_Mod' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
     'Twig_Node_Expression_Binary_Mul' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
     'Twig_Node_Expression_Binary_NotEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
@@ -592,6 +598,7 @@ return array(
     'Twig_Node_Expression_Binary_Or' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
     'Twig_Node_Expression_Binary_Power' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
     'Twig_Node_Expression_Binary_Range' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
+    'Twig_Node_Expression_Binary_StartsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
     'Twig_Node_Expression_Binary_Sub' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
     'Twig_Node_Expression_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
     'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
@@ -628,7 +635,6 @@ return array(
     'Twig_Node_Module' => $vendorDir . '/twig/twig/lib/Twig/Node/Module.php',
     'Twig_Node_Print' => $vendorDir . '/twig/twig/lib/Twig/Node/Print.php',
     'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
-    'Twig_Node_SandboxedModule' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedModule.php',
     'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
     'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
     'Twig_Node_SetTemp' => $vendorDir . '/twig/twig/lib/Twig/Node/SetTemp.php',
@@ -636,7 +642,17 @@ return array(
     'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
     'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
     'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
+    'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
+    'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
+    'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
+    'Twig_Profiler_NodeVisitor_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
+    'Twig_Profiler_Node_EnterProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
+    'Twig_Profiler_Node_LeaveProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
+    'Twig_Profiler_Profile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Profile.php',
     'Twig_Sandbox_SecurityError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
+    'Twig_Sandbox_SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
+    'Twig_Sandbox_SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
+    'Twig_Sandbox_SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
     'Twig_Sandbox_SecurityPolicy' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
     'Twig_Sandbox_SecurityPolicyInterface' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
     'Twig_SimpleFilter' => $vendorDir . '/twig/twig/lib/Twig/SimpleFilter.php',
--- a/vendor/composer/autoload_real.php
+++ b/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
 
 // autoload_real.php @generated by Composer
 
-class ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500
+class ComposerAutoloaderInit814f006b1edecd862adaa89c194918bc
 {
     private static $loader;
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500
             return self::$loader;
         }
 
-        spl_autoload_register(array('ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500', 'loadClassLoader'), true, true);
+        spl_autoload_register(array('ComposerAutoloaderInit814f006b1edecd862adaa89c194918bc', 'loadClassLoader'), true, true);
         self::$loader = $loader = new \Composer\Autoload\ClassLoader();
-        spl_autoload_unregister(array('ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500', 'loadClassLoader'));
+        spl_autoload_unregister(array('ComposerAutoloaderInit814f006b1edecd862adaa89c194918bc', 'loadClassLoader'));
 
         $map = require __DIR__ . '/autoload_namespaces.php';
         foreach ($map as $namespace => $path) {
@@ -44,7 +44,7 @@ class ComposerAutoloaderInit6cde395dbad8cbdae8a9172d56203500
     }
 }
 
-function composerRequire6cde395dbad8cbdae8a9172d56203500($file)
+function composerRequire814f006b1edecd862adaa89c194918bc($file)
 {
     require $file;
 }
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -667,27 +667,27 @@
     },
     {
         "name": "twig/twig",
-        "version": "v1.13.2",
-        "version_normalized": "1.13.2.0",
+        "version": "v1.20.0",
+        "version_normalized": "1.20.0.0",
         "source": {
             "type": "git",
             "url": "https://github.com/twigphp/Twig.git",
-            "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755"
+            "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844"
         },
         "dist": {
             "type": "zip",
-            "url": "https://api.github.com/repos/twigphp/Twig/zipball/6d6a1009427d1f398c9d40904147bf9f723d5755",
-            "reference": "6d6a1009427d1f398c9d40904147bf9f723d5755",
+            "url": "https://api.github.com/repos/twigphp/Twig/zipball/1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
+            "reference": "1ea4e5f81c6d005fe84d0b38e1c4f1955eb86844",
             "shasum": ""
         },
         "require": {
-            "php": ">=5.2.4"
+            "php": ">=5.2.7"
         },
-        "time": "2013-08-03 15:35:31",
+        "time": "2015-08-12 15:56:39",
         "type": "library",
         "extra": {
             "branch-alias": {
-                "dev-master": "1.13-dev"
+                "dev-master": "1.20-dev"
             }
         },
         "installation-source": "dist",
@@ -703,11 +703,19 @@
         "authors": [
             {
                 "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
+                "email": "fabien@symfony.com",
+                "homepage": "http://fabien.potencier.org",
+                "role": "Lead Developer"
             },
             {
                 "name": "Armin Ronacher",
-                "email": "armin.ronacher@active-4.com"
+                "email": "armin.ronacher@active-4.com",
+                "role": "Project Founder"
+            },
+            {
+                "name": "Twig Team",
+                "homepage": "http://twig.sensiolabs.org/contributors",
+                "role": "Contributors"
             }
         ],
         "description": "Twig, the flexible, fast, and secure template language for PHP",
--- a/vendor/twig/twig/LICENSE
+++ b/vendor/twig/twig/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details.
+Copyright (c) 2009-2014 by the Twig Team.
 
 Some rights reserved.
 
--- /dev/null
+++ b/vendor/twig/twig/README.rst
@@ -0,0 +1,15 @@
+Twig, the flexible, fast, and secure template language for PHP
+==============================================================
+
+Twig is a template language for PHP, released under the new BSD license (code
+and documentation).
+
+Twig uses a syntax similar to the Django and Jinja template languages which
+inspired the Twig runtime environment.
+
+More Information
+----------------
+
+Read the `documentation`_ for more information.
+
+.. _documentation: http://twig.sensiolabs.org/documentation
--- a/vendor/twig/twig/composer.json
+++ b/vendor/twig/twig/composer.json
@@ -8,15 +8,26 @@
     "authors": [
         {
             "name": "Fabien Potencier",
-            "email": "fabien@symfony.com"
+            "email": "fabien@symfony.com",
+            "homepage": "http://fabien.potencier.org",
+            "role": "Lead Developer"
+        },
+        {
+            "name": "Twig Team",
+            "homepage": "http://twig.sensiolabs.org/contributors",
+            "role": "Contributors"
         },
         {
             "name": "Armin Ronacher",
-            "email": "armin.ronacher@active-4.com"
+            "email": "armin.ronacher@active-4.com",
+            "role": "Project Founder"
         }
     ],
+    "support": {
+        "forum": "https://groups.google.com/forum/#!forum/twig-users"
+    },
     "require": {
-        "php": ">=5.2.4"
+        "php": ">=5.2.7"
     },
     "autoload": {
         "psr-0" : {
@@ -25,7 +36,7 @@
     },
     "extra": {
         "branch-alias": {
-            "dev-master": "1.13-dev"
+            "dev-master": "1.20-dev"
         }
     }
 }
--- a/vendor/twig/twig/lib/Twig/Autoloader.php
+++ b/vendor/twig/twig/lib/Twig/Autoloader.php
@@ -19,14 +19,14 @@ class Twig_Autoloader
     /**
      * Registers Twig_Autoloader as an SPL autoloader.
      *
-     * @param Boolean $prepend Whether to prepend the autoloader or not.
+     * @param bool $prepend Whether to prepend the autoloader or not.
      */
     public static function register($prepend = false)
     {
-        if (version_compare(phpversion(), '5.3.0', '>=')) {
-            spl_autoload_register(array(new self, 'autoload'), true, $prepend);
+        if (PHP_VERSION_ID < 50300) {
+            spl_autoload_register(array(__CLASS__, 'autoload'));
         } else {
-            spl_autoload_register(array(new self, 'autoload'));
+            spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
         }
     }
 
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Twig_BaseNodeVisitor can be used to make node visitors compatible with Twig 1.x and 2.x.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    final public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if (!$node instanceof Twig_Node) {
+            throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.');
+        }
+
+        return $this->doEnterNode($node, $env);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    final public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    {
+        if (!$node instanceof Twig_Node) {
+            throw new LogicException('Twig_BaseNodeVisitor only supports Twig_Node instances.');
+        }
+
+        return $this->doLeaveNode($node, $env);
+    }
+
+    /**
+     * Called before child nodes are visited.
+     *
+     * @param Twig_Node         $node The node to visit
+     * @param Twig_Environment  $env  The Twig environment instance
+     *
+     * @return Twig_Node The modified node
+     */
+    abstract protected function doEnterNode(Twig_Node $node, Twig_Environment $env);
+
+    /**
+     * Called after child nodes are visited.
+     *
+     * @param Twig_Node        $node The node to visit
+     * @param Twig_Environment $env  The Twig environment instance
+     *
+     * @return Twig_Node|false The modified node or false if the node must be removed
+     */
+    abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env);
+}
--- a/vendor/twig/twig/lib/Twig/Compiler.php
+++ b/vendor/twig/twig/lib/Twig/Compiler.php
@@ -66,7 +66,7 @@ class Twig_Compiler implements Twig_CompilerInterface
      * Compiles a node.
      *
      * @param Twig_NodeInterface $node        The node to compile
-     * @param integer            $indentation The current indentation
+     * @param int                $indentation The current indentation
      *
      * @return Twig_Compiler The current compiler instance
      */
@@ -74,6 +74,7 @@ class Twig_Compiler implements Twig_CompilerInterface
     {
         $this->lastLine = null;
         $this->source = '';
+        $this->debugInfo = array();
         $this->sourceOffset = 0;
         // source code starts at 1 (as we then increment it when we encounter new lines)
         $this->sourceLine = 1;
@@ -180,14 +181,15 @@ class Twig_Compiler implements Twig_CompilerInterface
             $this->raw($value ? 'true' : 'false');
         } elseif (is_array($value)) {
             $this->raw('array(');
-            $i = 0;
-            foreach ($value as $key => $value) {
-                if ($i++) {
+            $first = true;
+            foreach ($value as $key => $v) {
+                if (!$first) {
                     $this->raw(', ');
                 }
+                $first = false;
                 $this->repr($key);
                 $this->raw(' => ');
-                $this->repr($value);
+                $this->repr($v);
             }
             $this->raw(')');
         } else {
@@ -207,7 +209,7 @@ class Twig_Compiler implements Twig_CompilerInterface
     public function addDebugInfo(Twig_NodeInterface $node)
     {
         if ($node->getLine() != $this->lastLine) {
-            $this->write("// line {$node->getLine()}\n");
+            $this->write(sprintf("// line %d\n", $node->getLine()));
 
             // when mbstring.func_overload is set to 2
             // mb_substr_count() replaces substr_count()
@@ -229,13 +231,15 @@ class Twig_Compiler implements Twig_CompilerInterface
 
     public function getDebugInfo()
     {
+        ksort($this->debugInfo);
+
         return $this->debugInfo;
     }
 
     /**
      * Indents the generated code.
      *
-     * @param integer $step The number of indentation to add
+     * @param int $step The number of indentation to add
      *
      * @return Twig_Compiler The current compiler instance
      */
@@ -249,9 +253,11 @@ class Twig_Compiler implements Twig_CompilerInterface
     /**
      * Outdents the generated code.
      *
-     * @param integer $step The number of indentation to remove
+     * @param int $step The number of indentation to remove
      *
      * @return Twig_Compiler The current compiler instance
+     *
+     * @throws LogicException When trying to outdent too much so the indentation would become negative
      */
     public function outdent($step = 1)
     {
@@ -264,4 +270,9 @@ class Twig_Compiler implements Twig_CompilerInterface
 
         return $this;
     }
+
+    public function getVarName()
+    {
+        return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
+    }
 }
--- a/vendor/twig/twig/lib/Twig/CompilerInterface.php
+++ b/vendor/twig/twig/lib/Twig/CompilerInterface.php
@@ -13,7 +13,8 @@
  * Interface implemented by compiler classes.
  *
  * @author Fabien Potencier <fabien@symfony.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_CompilerInterface
 {
--- a/vendor/twig/twig/lib/Twig/Environment.php
+++ b/vendor/twig/twig/lib/Twig/Environment.php
@@ -16,7 +16,7 @@
  */
 class Twig_Environment
 {
-    const VERSION = '1.13.2';
+    const VERSION = '1.20.0';
 
     protected $charset;
     protected $loader;
@@ -61,9 +61,9 @@ class Twig_Environment
      *  * cache: An absolute path where to store the compiled templates, or
      *           false to disable compilation cache (default).
      *
-     *  * auto_reload: Whether to reload the template is the original source changed.
+     *  * auto_reload: Whether to reload the template if the original source changed.
      *                 If you don't provide the auto_reload option, it will be
-     *                 determined automatically base on the debug value.
+     *                 determined automatically based on the debug value.
      *
      *  * strict_variables: Whether to ignore invalid variables in templates
      *                      (default to false).
@@ -72,6 +72,7 @@ class Twig_Environment
      *                  * false: disable auto-escaping
      *                  * true: equivalent to html
      *                  * html, js: set the autoescaping to one of the supported strategies
+     *                  * filename: set the autoescaping strategy based on the template filename extension
      *                  * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename"
      *
      *  * optimizations: A flag that indicates which optimizations to apply
@@ -88,21 +89,21 @@ class Twig_Environment
         }
 
         $options = array_merge(array(
-            'debug'               => false,
-            'charset'             => 'UTF-8',
+            'debug' => false,
+            'charset' => 'UTF-8',
             'base_template_class' => 'Twig_Template',
-            'strict_variables'    => false,
-            'autoescape'          => 'html',
-            'cache'               => false,
-            'auto_reload'         => null,
-            'optimizations'       => -1,
+            'strict_variables' => false,
+            'autoescape' => 'html',
+            'cache' => false,
+            'auto_reload' => null,
+            'optimizations' => -1,
         ), $options);
 
-        $this->debug              = (bool) $options['debug'];
-        $this->charset            = strtoupper($options['charset']);
-        $this->baseTemplateClass  = $options['base_template_class'];
-        $this->autoReload         = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
-        $this->strictVariables    = (bool) $options['strict_variables'];
+        $this->debug = (bool) $options['debug'];
+        $this->charset = strtoupper($options['charset']);
+        $this->baseTemplateClass = $options['base_template_class'];
+        $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
+        $this->strictVariables = (bool) $options['strict_variables'];
         $this->runtimeInitialized = false;
         $this->setCache($options['cache']);
         $this->functionCallbacks = array();
@@ -154,7 +155,7 @@ class Twig_Environment
     /**
      * Checks if debug mode is enabled.
      *
-     * @return Boolean true if debug mode is enabled, false otherwise
+     * @return bool true if debug mode is enabled, false otherwise
      */
     public function isDebug()
     {
@@ -180,7 +181,7 @@ class Twig_Environment
     /**
      * Checks if the auto_reload option is enabled.
      *
-     * @return Boolean true if auto_reload is enabled, false otherwise
+     * @return bool true if auto_reload is enabled, false otherwise
      */
     public function isAutoReload()
     {
@@ -206,7 +207,7 @@ class Twig_Environment
     /**
      * Checks if the strict_variables option is enabled.
      *
-     * @return Boolean true if strict_variables is enabled, false otherwise
+     * @return bool true if strict_variables is enabled, false otherwise
      */
     public function isStrictVariables()
     {
@@ -223,12 +224,12 @@ class Twig_Environment
         return $this->cache;
     }
 
-     /**
-      * Sets the cache directory or false if cache is disabled.
-      *
-      * @param string|false $cache The absolute path to the compiled templates,
-      *                            or false to disable cache
-      */
+    /**
+     * Sets the cache directory or false if cache is disabled.
+     *
+     * @param string|false $cache The absolute path to the compiled templates,
+     *                            or false to disable cache
+     */
     public function setCache($cache)
     {
         $this->cache = $cache ? $cache : false;
@@ -239,7 +240,7 @@ class Twig_Environment
      *
      * @param string $name The template name
      *
-     * @return string The cache file name
+     * @return string|false The cache file name or false when caching is disabled
      */
     public function getCacheFilename($name)
     {
@@ -249,20 +250,20 @@ class Twig_Environment
 
         $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
 
-        return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
+        return $this->getCache().'/'.$class[0].'/'.$class[1].'/'.$class.'.php';
     }
 
     /**
      * Gets the template class associated with the given string.
      *
-     * @param string  $name  The name for which to calculate the template class name
-     * @param integer $index The index if it is an embedded template
+     * @param string $name  The name for which to calculate the template class name
+     * @param int    $index The index if it is an embedded template
      *
      * @return string The template class name
      */
     public function getTemplateClass($name, $index = null)
     {
-        return $this->templateClassPrefix.md5($this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index);
+        return $this->templateClassPrefix.hash('sha256', $this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index);
     }
 
     /**
@@ -282,6 +283,10 @@ class Twig_Environment
      * @param array  $context An array of parameters to pass to the template
      *
      * @return string The rendered template
+     *
+     * @throws Twig_Error_Loader  When the template cannot be found
+     * @throws Twig_Error_Syntax  When an error occurred during compilation
+     * @throws Twig_Error_Runtime When an error occurred during rendering
      */
     public function render($name, array $context = array())
     {
@@ -293,6 +298,10 @@ class Twig_Environment
      *
      * @param string $name    The template name
      * @param array  $context An array of parameters to pass to the template
+     *
+     * @throws Twig_Error_Loader  When the template cannot be found
+     * @throws Twig_Error_Syntax  When an error occurred during compilation
+     * @throws Twig_Error_Runtime When an error occurred during rendering
      */
     public function display($name, array $context = array())
     {
@@ -302,10 +311,13 @@ class Twig_Environment
     /**
      * Loads a template by name.
      *
-     * @param string  $name  The template name
-     * @param integer $index The index if it is an embedded template
+     * @param string $name  The template name
+     * @param int    $index The index if it is an embedded template
      *
      * @return Twig_TemplateInterface A template instance representing the given template name
+     *
+     * @throws Twig_Error_Loader When the template cannot be found
+     * @throws Twig_Error_Syntax When an error occurred during compilation
      */
     public function loadTemplate($name, $index = null)
     {
@@ -335,16 +347,50 @@ class Twig_Environment
     }
 
     /**
+     * Creates a template from source.
+     *
+     * This method should not be used as a generic way to load templates.
+     *
+     * @param string $template The template name
+     *
+     * @return Twig_Template A template instance representing the given template name
+     *
+     * @throws Twig_Error_Loader When the template cannot be found
+     * @throws Twig_Error_Syntax When an error occurred during compilation
+     */
+    public function createTemplate($template)
+    {
+        $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false));
+
+        $loader = new Twig_Loader_Chain(array(
+            new Twig_Loader_Array(array($name => $template)),
+            $current = $this->getLoader(),
+        ));
+
+        $this->setLoader($loader);
+        try {
+            $template = $this->loadTemplate($name);
+        } catch (Exception $e) {
+            $this->setLoader($current);
+
+            throw $e;
+        }
+        $this->setLoader($current);
+
+        return $template;
+    }
+
+    /**
      * Returns true if the template is still fresh.
      *
      * Besides checking the loader for freshness information,
      * this method also checks if the enabled extensions have
      * not changed.
      *
-     * @param string    $name The template name
-     * @param timestamp $time The last modification time of the cached template
+     * @param string $name The template name
+     * @param int    $time The last modification time of the cached template
      *
-     * @return Boolean true if the template is fresh, false otherwise
+     * @return bool true if the template is fresh, false otherwise
      */
     public function isTemplateFresh($name, $time)
     {
@@ -358,6 +404,19 @@ class Twig_Environment
         return $this->getLoader()->isFresh($name, $time);
     }
 
+    /**
+     * Tries to load a template consecutively from an array.
+     *
+     * Similar to loadTemplate() but it also accepts Twig_TemplateInterface instances and an array
+     * of templates where each is tried to be loaded.
+     *
+     * @param string|Twig_Template|array $names A template or an array of templates to try consecutively
+     *
+     * @return Twig_Template
+     *
+     * @throws Twig_Error_Loader When none of the templates can be found
+     * @throws Twig_Error_Syntax When an error occurred during compilation
+     */
     public function resolveTemplate($names)
     {
         if (!is_array($names)) {
@@ -384,6 +443,8 @@ class Twig_Environment
 
     /**
      * Clears the internal template cache.
+     *
+     * @deprecated since 1.18.3 (to be removed in 2.0)
      */
     public function clearTemplateCache()
     {
@@ -423,7 +484,7 @@ class Twig_Environment
     /**
      * Sets the Lexer instance.
      *
-     * @param Twig_LexerInterface A Twig_LexerInterface instance
+     * @param Twig_LexerInterface $lexer A Twig_LexerInterface instance
      */
     public function setLexer(Twig_LexerInterface $lexer)
     {
@@ -437,6 +498,8 @@ class Twig_Environment
      * @param string $name   The template name
      *
      * @return Twig_TokenStream A Twig_TokenStream instance
+     *
+     * @throws Twig_Error_Syntax When the code is syntactically wrong
      */
     public function tokenize($source, $name = null)
     {
@@ -460,7 +523,7 @@ class Twig_Environment
     /**
      * Sets the Parser instance.
      *
-     * @param Twig_ParserInterface A Twig_ParserInterface instance
+     * @param Twig_ParserInterface $parser A Twig_ParserInterface instance
      */
     public function setParser(Twig_ParserInterface $parser)
     {
@@ -468,15 +531,17 @@ class Twig_Environment
     }
 
     /**
-     * Parses a token stream.
+     * Converts a token stream to a node tree.
+     *
+     * @param Twig_TokenStream $stream A token stream instance
      *
-     * @param Twig_TokenStream $tokens A Twig_TokenStream instance
+     * @return Twig_Node_Module A node tree
      *
-     * @return Twig_Node_Module A Node tree
+     * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
      */
-    public function parse(Twig_TokenStream $tokens)
+    public function parse(Twig_TokenStream $stream)
     {
-        return $this->getParser()->parse($tokens);
+        return $this->getParser()->parse($stream);
     }
 
     /**
@@ -504,7 +569,7 @@ class Twig_Environment
     }
 
     /**
-     * Compiles a Node.
+     * Compiles a node and returns the PHP code.
      *
      * @param Twig_NodeInterface $node A Twig_NodeInterface instance
      *
@@ -522,6 +587,8 @@ class Twig_Environment
      * @param string $name   The template name
      *
      * @return string The compiled PHP source code
+     *
+     * @throws Twig_Error_Syntax When there was an error during tokenizing, parsing or compiling
      */
     public function compileSource($source, $name = null)
     {
@@ -531,7 +598,7 @@ class Twig_Environment
             $e->setTemplateFile($name);
             throw $e;
         } catch (Exception $e) {
-            throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
+            throw new Twig_Error_Syntax(sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $name, $e);
         }
     }
 
@@ -596,7 +663,7 @@ class Twig_Environment
      *
      * @param string $name The extension name
      *
-     * @return Boolean Whether the extension is registered or not
+     * @return bool Whether the extension is registered or not
      */
     public function hasExtension($name)
     {
@@ -764,11 +831,11 @@ class Twig_Environment
             $filter = $name;
             $name = $filter->getName();
         }
-        
+
         if ($this->extensionInitialized) {
             throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
         }
-        
+
         $this->staging->addFilter($name, $filter);
     }
 
@@ -853,7 +920,7 @@ class Twig_Environment
             $test = $name;
             $name = $test->getName();
         }
-        
+
         if ($this->extensionInitialized) {
             throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
         }
@@ -911,11 +978,11 @@ class Twig_Environment
             $function = $name;
             $name = $function->getName();
         }
-        
+
         if ($this->extensionInitialized) {
             throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
         }
-        
+
         $this->staging->addFunction($name, $function);
     }
 
@@ -1202,14 +1269,17 @@ class Twig_Environment
     {
         $dir = dirname($file);
         if (!is_dir($dir)) {
-            if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
-                throw new RuntimeException(sprintf("Unable to create the cache directory (%s).", $dir));
+            if (false === @mkdir($dir, 0777, true)) {
+                clearstatcache(false, $dir);
+                if (!is_dir($dir)) {
+                    throw new RuntimeException(sprintf('Unable to create the cache directory (%s).', $dir));
+                }
             }
         } elseif (!is_writable($dir)) {
-            throw new RuntimeException(sprintf("Unable to write in the cache directory (%s).", $dir));
+            throw new RuntimeException(sprintf('Unable to write in the cache directory (%s).', $dir));
         }
 
-        $tmpFile = tempnam(dirname($file), basename($file));
+        $tmpFile = tempnam($dir, basename($file));
         if (false !== @file_put_contents($tmpFile, $content)) {
             // rename does not work on Win32 before 5.2.6
             if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
--- a/vendor/twig/twig/lib/Twig/Error.php
+++ b/vendor/twig/twig/lib/Twig/Error.php
@@ -51,13 +51,13 @@ class Twig_Error extends Exception
      * By default, automatic guessing is enabled.
      *
      * @param string    $message  The error message
-     * @param integer   $lineno   The template line where the error occurred
+     * @param int       $lineno   The template line where the error occurred
      * @param string    $filename The template file name where the error occurred
      * @param Exception $previous The previous exception
      */
     public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
     {
-        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+        if (PHP_VERSION_ID < 50300) {
             $this->previous = $previous;
             parent::__construct('');
         } else {
@@ -111,7 +111,7 @@ class Twig_Error extends Exception
     /**
      * Gets the template line where the error occurred.
      *
-     * @return integer The template line
+     * @return int The template line
      */
     public function getTemplateLine()
     {
@@ -121,7 +121,7 @@ class Twig_Error extends Exception
     /**
      * Sets the template line where the error occurred.
      *
-     * @param integer $lineno The template line
+     * @param int $lineno The template line
      */
     public function setTemplateLine($lineno)
     {
@@ -188,7 +188,7 @@ class Twig_Error extends Exception
         $template = null;
         $templateClass = null;
 
-        if (version_compare(phpversion(), '5.3.6', '>=')) {
+        if (PHP_VERSION_ID >= 50306) {
             $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT);
         } else {
             $backtrace = debug_backtrace();
@@ -217,6 +217,11 @@ class Twig_Error extends Exception
         $r = new ReflectionObject($template);
         $file = $r->getFileName();
 
+        // hhvm has a bug where eval'ed files comes out as the current directory
+        if (is_dir($file)) {
+            $file = '';
+        }
+
         $exceptions = array($e = $this);
         while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
             $exceptions[] = $e;
@@ -224,6 +229,8 @@ class Twig_Error extends Exception
 
         while ($e = array_pop($exceptions)) {
             $traces = $e->getTrace();
+            array_unshift($traces, array('file' => $e->getFile(), 'line' => $e->getLine()));
+
             while ($trace = array_shift($traces)) {
                 if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
                     continue;
--- a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php
+++ b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php
@@ -13,7 +13,8 @@
  * Adds an exists() method for loaders.
  *
  * @author Florin Patan <florinpatan@gmail.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_ExistsLoaderInterface
 {
@@ -22,7 +23,7 @@ interface Twig_ExistsLoaderInterface
      *
      * @param string $name The name of the template to check if we can load
      *
-     * @return boolean If the template source code is handled by this loader or not
+     * @return bool If the template source code is handled by this loader or not
      */
     public function exists($name);
 }
--- a/vendor/twig/twig/lib/Twig/ExpressionParser.php
+++ b/vendor/twig/twig/lib/Twig/ExpressionParser.php
@@ -86,18 +86,15 @@ class Twig_ExpressionParser
 
     protected function parseConditionalExpression($expr)
     {
-        while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) {
-            $this->parser->getStream()->next();
-            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
+        while ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, '?')) {
+            if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
                 $expr2 = $this->parseExpression();
-                if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
-                    $this->parser->getStream()->next();
+                if ($this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
                     $expr3 = $this->parseExpression();
                 } else {
                     $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine());
                 }
             } else {
-                $this->parser->getStream()->next();
                 $expr2 = $expr;
                 $expr3 = $this->parseExpression();
             }
@@ -161,13 +158,36 @@ class Twig_ExpressionParser
                 $node = $this->parseStringExpression();
                 break;
 
+            case Twig_Token::OPERATOR_TYPE:
+                if (preg_match(Twig_Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
+                    // in this context, string operators are variable names
+                    $this->parser->getStream()->next();
+                    $node = new Twig_Node_Expression_Name($token->getValue(), $token->getLine());
+                    break;
+                } elseif (isset($this->unaryOperators[$token->getValue()])) {
+                    $class = $this->unaryOperators[$token->getValue()]['class'];
+
+                    $ref = new ReflectionClass($class);
+                    $negClass = 'Twig_Node_Expression_Unary_Neg';
+                    $posClass = 'Twig_Node_Expression_Unary_Pos';
+                    if (!(in_array($ref->getName(), array($negClass, $posClass)) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass))) {
+                        throw new Twig_Error_Syntax(sprintf('Unexpected unary operator "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename());
+                    }
+
+                    $this->parser->getStream()->next();
+                    $expr = $this->parsePrimaryExpression();
+
+                    $node = new $class($expr, $token->getLine());
+                    break;
+                }
+
             default:
                 if ($token->test(Twig_Token::PUNCTUATION_TYPE, '[')) {
                     $node = $this->parseArrayExpression();
                 } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
                     $node = $this->parseHashExpression();
                 } else {
-                    throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine(), $this->parser->getFilename());
+                    throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getFilename());
                 }
         }
 
@@ -182,12 +202,10 @@ class Twig_ExpressionParser
         // a string cannot be followed by another string in a single expression
         $nextCanBeString = true;
         while (true) {
-            if ($stream->test(Twig_Token::STRING_TYPE) && $nextCanBeString) {
-                $token = $stream->next();
+            if ($nextCanBeString && $token = $stream->nextIf(Twig_Token::STRING_TYPE)) {
                 $nodes[] = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
                 $nextCanBeString = false;
-            } elseif ($stream->test(Twig_Token::INTERPOLATION_START_TYPE)) {
-                $stream->next();
+            } elseif ($stream->nextIf(Twig_Token::INTERPOLATION_START_TYPE)) {
                 $nodes[] = $this->parseExpression();
                 $stream->expect(Twig_Token::INTERPOLATION_END_TYPE);
                 $nextCanBeString = true;
@@ -253,15 +271,14 @@ class Twig_ExpressionParser
             //  * a string -- 'a'
             //  * a name, which is equivalent to a string -- a
             //  * an expression, which must be enclosed in parentheses -- (1 + 2)
-            if ($stream->test(Twig_Token::STRING_TYPE) || $stream->test(Twig_Token::NAME_TYPE) || $stream->test(Twig_Token::NUMBER_TYPE)) {
-                $token = $stream->next();
+            if (($token = $stream->nextIf(Twig_Token::STRING_TYPE)) || ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) || $token = $stream->nextIf(Twig_Token::NUMBER_TYPE)) {
                 $key = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
             } elseif ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
                 $key = $this->parseExpression();
             } else {
                 $current = $stream->getCurrent();
 
-                throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
+                throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $this->parser->getFilename());
             }
 
             $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
@@ -298,7 +315,7 @@ class Twig_ExpressionParser
     {
         switch ($name) {
             case 'parent':
-                $args = $this->parseArguments();
+                $this->parseArguments();
                 if (!count($this->parser->getBlockStack())) {
                     throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename());
                 }
@@ -316,7 +333,7 @@ class Twig_ExpressionParser
                     throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename());
                 }
 
-                return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line);
+                return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
             default:
                 if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
                     $arguments = new Twig_Node_Expression_Array(array(), $line);
@@ -343,7 +360,7 @@ class Twig_ExpressionParser
         $token = $stream->next();
         $lineno = $token->getLine();
         $arguments = new Twig_Node_Expression_Array(array(), $lineno);
-        $type = Twig_TemplateInterface::ANY_CALL;
+        $type = Twig_Template::ANY_CALL;
         if ($token->getValue() == '.') {
             $token = $stream->next();
             if (
@@ -370,13 +387,19 @@ class Twig_ExpressionParser
                     throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename());
                 }
 
-                $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno);
+                $name = $arg->getAttribute('value');
+
+                if ($this->parser->isReservedMacroName($name)) {
+                    throw new Twig_Error_Syntax(sprintf('"%s" cannot be called as macro as it is a reserved keyword', $name), $token->getLine(), $this->parser->getFilename());
+                }
+
+                $node = new Twig_Node_Expression_MethodCall($node, 'get'.$name, $arguments, $lineno);
                 $node->setAttribute('safe', true);
 
                 return $node;
             }
         } else {
-            $type = Twig_TemplateInterface::ARRAY_CALL;
+            $type = Twig_Template::ARRAY_CALL;
 
             // slice?
             $slice = false;
@@ -387,9 +410,8 @@ class Twig_ExpressionParser
                 $arg = $this->parseExpression();
             }
 
-            if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) {
+            if ($stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ':')) {
                 $slice = true;
-                $stream->next();
             }
 
             if ($slice) {
@@ -450,8 +472,12 @@ class Twig_ExpressionParser
     /**
      * Parses arguments.
      *
-     * @param Boolean $namedArguments Whether to allow named arguments or not
-     * @param Boolean $definition     Whether we are parsing arguments for a function definition
+     * @param bool $namedArguments Whether to allow named arguments or not
+     * @param bool $definition     Whether we are parsing arguments for a function definition
+     *
+     * @return Twig_Node
+     *
+     * @throws Twig_Error_Syntax
      */
     public function parseArguments($namedArguments = false, $definition = false)
     {
@@ -472,8 +498,7 @@ class Twig_ExpressionParser
             }
 
             $name = null;
-            if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) {
-                $token = $stream->next();
+            if ($namedArguments && $token = $stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
                 if (!$value instanceof Twig_Node_Expression_Name) {
                     throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename());
                 }
@@ -519,10 +544,9 @@ class Twig_ExpressionParser
             }
             $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine());
 
-            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+            if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
                 break;
             }
-            $this->parser->getStream()->next();
         }
 
         return new Twig_Node($targets);
@@ -533,10 +557,9 @@ class Twig_ExpressionParser
         $targets = array();
         while (true) {
             $targets[] = $this->parseExpression();
-            if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+            if (!$this->parser->getStream()->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
                 break;
             }
-            $this->parser->getStream()->next();
         }
 
         return new Twig_Node($targets);
@@ -585,7 +608,9 @@ class Twig_ExpressionParser
     // checks that the node only contains "constant" elements
     protected function checkConstantExpression(Twig_NodeInterface $node)
     {
-        if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) {
+        if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array
+            || $node instanceof Twig_Node_Expression_Unary_Neg || $node instanceof Twig_Node_Expression_Unary_Pos
+        )) {
             return false;
         }
 
--- a/vendor/twig/twig/lib/Twig/Extension.php
+++ b/vendor/twig/twig/lib/Twig/Extension.php
@@ -34,7 +34,7 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
     /**
      * Returns the node visitor instances to add to the existing list.
      *
-     * @return array An array of Twig_NodeVisitorInterface instances
+     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
      */
     public function getNodeVisitors()
     {
--- a/vendor/twig/twig/lib/Twig/Extension/Core.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Core.php
@@ -1,7 +1,8 @@
 <?php
 
 if (!defined('ENT_SUBSTITUTE')) {
-    define('ENT_SUBSTITUTE', 8);
+    // use 0 as hhvm does not support several flags yet
+    define('ENT_SUBSTITUTE', 0);
 }
 
 /*
@@ -17,6 +18,28 @@ class Twig_Extension_Core extends Twig_Extension
     protected $dateFormats = array('F j, Y H:i', '%d days');
     protected $numberFormat = array(0, '.', ',');
     protected $timezone = null;
+    protected $escapers = array();
+
+    /**
+     * Defines a new escaper to be used via the escape filter.
+     *
+     * @param string   $strategy The strategy name that should be used as a strategy in the escape call
+     * @param callable $callable A valid PHP callable
+     */
+    public function setEscaper($strategy, $callable)
+    {
+        $this->escapers[$strategy] = $callable;
+    }
+
+    /**
+     * Gets all defined escapers.
+     *
+     * @return array An array of escapers
+     */
+    public function getEscapers()
+    {
+        return $this->escapers;
+    }
 
     /**
      * Sets the default format to be used by the date filter.
@@ -72,9 +95,9 @@ class Twig_Extension_Core extends Twig_Extension
     /**
      * Sets the default format to be used by the number_format filter.
      *
-     * @param integer $decimal      The number of decimal places to use.
-     * @param string  $decimalPoint The character(s) to use for the decimal point.
-     * @param string  $thousandSep  The character(s) to use for the thousands separator.
+     * @param int    $decimal      The number of decimal places to use.
+     * @param string $decimalPoint The character(s) to use for the decimal point.
+     * @param string $thousandSep  The character(s) to use for the thousands separator.
      */
     public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
     {
@@ -94,7 +117,7 @@ class Twig_Extension_Core extends Twig_Extension
     /**
      * Returns the token parser instance to add to the existing list.
      *
-     * @return array An array of Twig_TokenParser instances
+     * @return Twig_TokenParser[] An array of Twig_TokenParser instances
      */
     public function getTokenParsers()
     {
@@ -132,6 +155,7 @@ class Twig_Extension_Core extends Twig_Extension
             new Twig_SimpleFilter('replace', 'strtr'),
             new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)),
             new Twig_SimpleFilter('abs', 'abs'),
+            new Twig_SimpleFilter('round', 'twig_round'),
 
             // encoding
             new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'),
@@ -149,7 +173,7 @@ class Twig_Extension_Core extends Twig_Extension
 
             // array helpers
             new Twig_SimpleFilter('join', 'twig_join_filter'),
-            new Twig_SimpleFilter('split', 'twig_split_filter'),
+            new Twig_SimpleFilter('split', 'twig_split_filter', array('needs_environment' => true)),
             new Twig_SimpleFilter('sort', 'twig_sort_filter'),
             new Twig_SimpleFilter('merge', 'twig_array_merge'),
             new Twig_SimpleFilter('batch', 'twig_array_batch'),
@@ -186,12 +210,15 @@ class Twig_Extension_Core extends Twig_Extension
     public function getFunctions()
     {
         return array(
+            new Twig_SimpleFunction('max', 'max'),
+            new Twig_SimpleFunction('min', 'min'),
             new Twig_SimpleFunction('range', 'range'),
             new Twig_SimpleFunction('constant', 'twig_constant'),
             new Twig_SimpleFunction('cycle', 'twig_cycle'),
             new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)),
             new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)),
             new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true, 'is_safe' => array('all'))),
+            new Twig_SimpleFunction('source', 'twig_source', array('needs_environment' => true, 'is_safe' => array('all'))),
         );
     }
 
@@ -207,9 +234,11 @@ class Twig_Extension_Core extends Twig_Extension
             new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')),
             new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')),
             new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
+            new Twig_SimpleTest('same as', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')),
             new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
             new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')),
             new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
+            new Twig_SimpleTest('divisible by', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')),
             new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')),
             new Twig_SimpleTest('empty', 'twig_test_empty'),
             new Twig_SimpleTest('iterable', 'twig_test_iterable'),
@@ -226,70 +255,94 @@ class Twig_Extension_Core extends Twig_Extension
         return array(
             array(
                 'not' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
-                '-'   => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Neg'),
-                '+'   => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
+                '-' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Neg'),
+                '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'),
             ),
             array(
-                'or'     => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'and'    => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'b-or'   => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'b-xor'  => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'b-and'  => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '=='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '!='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '<'      => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '>'      => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '>='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '<='     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '>' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Greater', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '>=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_GreaterEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '<=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_LessEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
                 'not in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotIn', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'in'     => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '..'     => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '+'      => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '-'      => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '~'      => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '*'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '/'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '//'     => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '%'      => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                'is'     => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'in' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_In', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'matches' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Matches', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'starts with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_StartsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'ends with' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_EndsWith', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '..' => array('precedence' => 25, 'class' => 'Twig_Node_Expression_Binary_Range', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '+' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Add', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '-' => array('precedence' => 30, 'class' => 'Twig_Node_Expression_Binary_Sub', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '~' => array('precedence' => 40, 'class' => 'Twig_Node_Expression_Binary_Concat', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '*' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mul', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '/' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Div', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '//' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_FloorDiv', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                '%' => array('precedence' => 60, 'class' => 'Twig_Node_Expression_Binary_Mod', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
+                'is' => array('precedence' => 100, 'callable' => array($this, 'parseTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
                 'is not' => array('precedence' => 100, 'callable' => array($this, 'parseNotTestExpression'), 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
-                '**'     => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
+                '**' => array('precedence' => 200, 'class' => 'Twig_Node_Expression_Binary_Power', 'associativity' => Twig_ExpressionParser::OPERATOR_RIGHT),
             ),
         );
     }
 
-    public function parseNotTestExpression(Twig_Parser $parser, $node)
+    public function parseNotTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
     {
         return new Twig_Node_Expression_Unary_Not($this->parseTestExpression($parser, $node), $parser->getCurrentToken()->getLine());
     }
 
-    public function parseTestExpression(Twig_Parser $parser, $node)
+    public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
     {
         $stream = $parser->getStream();
-        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+        $name = $this->getTestName($parser, $node->getLine());
+        $class = $this->getTestNodeClass($parser, $name);
         $arguments = null;
         if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
             $arguments = $parser->getExpressionParser()->parseArguments(true);
         }
 
-        $class = $this->getTestNodeClass($parser, $name, $node->getLine());
-
         return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
     }
 
-    protected function getTestNodeClass(Twig_Parser $parser, $name, $line)
+    protected function getTestName(Twig_Parser $parser, $line)
     {
+        $stream = $parser->getStream();
+        $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
         $env = $parser->getEnvironment();
         $testMap = $env->getTests();
-        if (!isset($testMap[$name])) {
-            $message = sprintf('The test "%s" does not exist', $name);
-            if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) {
-                $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
+
+        if (isset($testMap[$name])) {
+            return $name;
+        }
+
+        if ($stream->test(Twig_Token::NAME_TYPE)) {
+            // try 2-words tests
+            $name = $name.' '.$parser->getCurrentToken()->getValue();
+
+            if (isset($testMap[$name])) {
+                $parser->getStream()->next();
+
+                return $name;
             }
+        }
 
-            throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
+        $message = sprintf('The test "%s" does not exist', $name);
+        if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) {
+            $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
         }
 
+        throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
+    }
+
+    protected function getTestNodeClass(Twig_Parser $parser, $name)
+    {
+        $env = $parser->getEnvironment();
+        $testMap = $env->getTests();
+
         if ($testMap[$name] instanceof Twig_SimpleTest) {
             return $testMap[$name]->getNodeClass();
         }
@@ -312,7 +365,7 @@ class Twig_Extension_Core extends Twig_Extension
  * Cycles over a value.
  *
  * @param ArrayAccess|array $values   An array or an ArrayAccess instance
- * @param integer           $position The cycle position
+ * @param int               $position The cycle position
  *
  * @return string The next value in the cycle
  */
@@ -329,10 +382,10 @@ function twig_cycle($values, $position)
  * Returns a random value depending on the supplied parameter type:
  * - a random item from a Traversable or array
  * - a random character from a string
- * - a random integer between 0 and the integer parameter
+ * - a random integer between 0 and the integer parameter.
  *
  * @param Twig_Environment                 $env    A Twig_Environment instance
- * @param Traversable|array|integer|string $values The values to pick a random item from
+ * @param Traversable|array|int|string     $values The values to pick a random item from
  *
  * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is).
  *
@@ -391,10 +444,10 @@ function twig_random(Twig_Environment $env, $values = null)
  *   {{ post.published_at|date("m/d/Y") }}
  * </pre>
  *
- * @param Twig_Environment             $env      A Twig_Environment instance
- * @param DateTime|DateInterval|string $date     A date
- * @param string                       $format   A format
- * @param DateTimeZone|string          $timezone A timezone
+ * @param Twig_Environment                               $env      A Twig_Environment instance
+ * @param DateTime|DateTimeInterface|DateInterval|string $date     A date
+ * @param string|null                                    $format   The target format, null to use the default
+ * @param DateTimeZone|string|null|false                 $timezone The target timezone, null to use the default, false to leave unchanged
  *
  * @return string The formatted date
  */
@@ -413,7 +466,7 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $
 }
 
 /**
- * Returns a new date object modified
+ * Returns a new date object modified.
  *
  * <pre>
  *   {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
@@ -428,9 +481,12 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $
 function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
 {
     $date = twig_date_converter($env, $date, false);
-    $date->modify($modifier);
+    $resultDate = $date->modify($modifier);
 
-    return $date;
+    // This is a hack to ensure PHP 5.2 support and support for DateTimeImmutable
+    // DateTime::modify does not return the modified DateTime object < 5.3.0
+    // and DateTimeImmutable does not modify $date.
+    return null === $resultDate ? $date : $resultDate;
 }
 
 /**
@@ -442,27 +498,32 @@ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
  *    {% endif %}
  * </pre>
  *
- * @param Twig_Environment    $env      A Twig_Environment instance
- * @param DateTime|string     $date     A date
- * @param DateTimeZone|string $timezone A timezone
+ * @param Twig_Environment                       $env      A Twig_Environment instance
+ * @param DateTime|DateTimeInterface|string|null $date     A date
+ * @param DateTimeZone|string|null|false         $timezone The target timezone, null to use the default, false to leave unchanged
  *
  * @return DateTime A DateTime instance
  */
 function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null)
 {
     // determine the timezone
-    if (!$timezone) {
-        $defaultTimezone = $env->getExtension('core')->getTimezone();
-    } elseif (!$timezone instanceof DateTimeZone) {
-        $defaultTimezone = new DateTimeZone($timezone);
-    } else {
-        $defaultTimezone = $timezone;
+    if (false !== $timezone) {
+        if (null === $timezone) {
+            $timezone = $env->getExtension('core')->getTimezone();
+        } elseif (!$timezone instanceof DateTimeZone) {
+            $timezone = new DateTimeZone($timezone);
+        }
+    }
+
+    // immutable dates
+    if ($date instanceof DateTimeImmutable) {
+        return false !== $timezone ? $date->setTimezone($timezone) : $date;
     }
 
-    if ($date instanceof DateTime) {
+    if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
         $date = clone $date;
         if (false !== $timezone) {
-            $date->setTimezone($defaultTimezone);
+            $date->setTimezone($timezone);
         }
 
         return $date;
@@ -473,15 +534,37 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
         $date = '@'.$date;
     }
 
-    $date = new DateTime($date, $defaultTimezone);
+    $date = new DateTime($date, $env->getExtension('core')->getTimezone());
     if (false !== $timezone) {
-        $date->setTimezone($defaultTimezone);
+        $date->setTimezone($timezone);
     }
 
     return $date;
 }
 
 /**
+ * Rounds a number.
+ *
+ * @param int|float     $value     The value to round
+ * @param int|float     $precision The rounding precision
+ * @param string        $method    The method to use for rounding
+ *
+ * @return int|float     The rounded number
+ */
+function twig_round($value, $precision = 0, $method = 'common')
+{
+    if ('common' == $method) {
+        return round($value, $precision);
+    }
+
+    if ('ceil' != $method && 'floor' != $method) {
+        throw new Twig_Error_Runtime('The round filter only supports the "common", "ceil", and "floor" methods.');
+    }
+
+    return $method($value * pow(10, $precision)) / pow(10, $precision);
+}
+
+/**
  * Number format filter.
  *
  * All of the formatting options can be left null, in that case the defaults will
@@ -490,7 +573,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
  *
  * @param Twig_Environment    $env          A Twig_Environment instance
  * @param mixed               $number       A float/int/string of the number to format
- * @param integer             $decimal      The number of decimal points to display.
+ * @param int                 $decimal      The number of decimal points to display.
  * @param string              $decimalPoint The character(s) to use for the decimal point.
  * @param string              $thousandSep  The character(s) to use for the thousands separator.
  *
@@ -515,32 +598,31 @@ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = nu
 }
 
 /**
- * URL encodes a string as a path segment or an array as a query string.
+ * URL encodes (RFC 3986) a string as a path segment or an array as a query string.
  *
  * @param string|array $url A URL or an array of query parameters
- * @param bool         $raw true to use rawurlencode() instead of urlencode
  *
  * @return string The URL encoded value
  */
-function twig_urlencode_filter($url, $raw = false)
+function twig_urlencode_filter($url)
 {
     if (is_array($url)) {
-        return http_build_query($url, '', '&');
-    }
+        if (defined('PHP_QUERY_RFC3986')) {
+            return http_build_query($url, '', '&', PHP_QUERY_RFC3986);
+        }
 
-    if ($raw) {
-        return rawurlencode($url);
+        return http_build_query($url, '', '&');
     }
 
-    return urlencode($url);
+    return rawurlencode($url);
 }
 
-if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+if (PHP_VERSION_ID < 50300) {
     /**
      * JSON encodes a variable.
      *
-     * @param mixed   $value   The value to encode.
-     * @param integer $options Not used on PHP 5.2.x
+     * @param mixed $value   The value to encode.
+     * @param int   $options Not used on PHP 5.2.x
      *
      * @return mixed The JSON encoded value
      */
@@ -558,8 +640,8 @@ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
     /**
      * JSON encodes a variable.
      *
-     * @param mixed   $value   The value to encode.
-     * @param integer $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
+     * @param mixed $value   The value to encode.
+     * @param int   $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
      *
      * @return mixed The JSON encoded value
      */
@@ -601,7 +683,7 @@ function _twig_markup2string(&$value)
 function twig_array_merge($arr1, $arr2)
 {
     if (!is_array($arr1) || !is_array($arr2)) {
-        throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.');
+        throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or hashes; %s and %s given.', gettype($arr1), gettype($arr2)));
     }
 
     return array_merge($arr1, $arr2);
@@ -612,16 +694,28 @@ function twig_array_merge($arr1, $arr2)
  *
  * @param Twig_Environment $env          A Twig_Environment instance
  * @param mixed            $item         A variable
- * @param integer          $start        Start of the slice
- * @param integer          $length       Size of the slice
- * @param Boolean          $preserveKeys Whether to preserve key or not (when the input is an array)
+ * @param int              $start        Start of the slice
+ * @param int              $length       Size of the slice
+ * @param bool             $preserveKeys Whether to preserve key or not (when the input is an array)
  *
  * @return mixed The sliced variable
  */
 function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
 {
     if ($item instanceof Traversable) {
-        $item = iterator_to_array($item, false);
+        if ($item instanceof IteratorAggregate) {
+            $item = $item->getIterator();
+        }
+
+        if ($start >= 0 && $length >= 0 && $item instanceof Iterator) {
+            try {
+                return iterator_to_array(new LimitIterator($item, $start, $length === null ? -1 : $length), $preserveKeys);
+            } catch (OutOfBoundsException $exception) {
+                return array();
+            }
+        }
+
+        $item = iterator_to_array($item, $preserveKeys);
     }
 
     if (is_array($item)) {
@@ -631,10 +725,10 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
     $item = (string) $item;
 
     if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
-        return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
+        return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
     }
 
-    return null === $length ? substr($item, $start) : substr($item, $start, $length);
+    return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length));
 }
 
 /**
@@ -649,7 +743,7 @@ function twig_first(Twig_Environment $env, $item)
 {
     $elements = twig_slice($env, $item, 0, 1, false);
 
-    return is_string($elements) ? $elements[0] : current($elements);
+    return is_string($elements) ? $elements : current($elements);
 }
 
 /**
@@ -664,7 +758,7 @@ function twig_last(Twig_Environment $env, $item)
 {
     $elements = twig_slice($env, $item, -1, 1, false);
 
-    return is_string($elements) ? $elements[0] : current($elements);
+    return is_string($elements) ? $elements : current($elements);
 }
 
 /**
@@ -713,17 +807,35 @@ function twig_join_filter($value, $glue = '')
  *
  * @param string  $value     A string
  * @param string  $delimiter The delimiter
- * @param integer $limit     The limit
+ * @param int     $limit     The limit
  *
  * @return array The split string as an array
  */
-function twig_split_filter($value, $delimiter, $limit = null)
+function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = null)
 {
-    if (empty($delimiter)) {
+    if (!empty($delimiter)) {
+        return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
+    }
+
+    if (!function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
         return str_split($value, null === $limit ? 1 : $limit);
     }
 
-    return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
+    if ($limit <= 1) {
+        return preg_split('/(?<!^)(?!$)/u', $value);
+    }
+
+    $length = mb_strlen($value, $charset);
+    if ($length < $limit) {
+        return array($value);
+    }
+
+    $r = array();
+    for ($i = 0; $i < $length; $i += $limit) {
+        $r[] = mb_substr($value, $i, $limit, $charset);
+    }
+
+    return $r;
 }
 
 // The '_default' filter is used internally to avoid using the ternary operator
@@ -771,7 +883,7 @@ function twig_get_array_keys_filter($array)
  *
  * @param Twig_Environment         $env          A Twig_Environment instance
  * @param array|Traversable|string $item         An array, a Traversable instance, or a string
- * @param Boolean                  $preserveKeys Whether to preserve key or not
+ * @param bool                     $preserveKeys Whether to preserve key or not
  *
  * @return mixed The reversed input
  */
@@ -809,7 +921,9 @@ function twig_reverse_filter(Twig_Environment $env, $item, $preserveKeys = false
 /**
  * Sorts an array.
  *
- * @param array $array An array
+ * @param array $array
+ *
+ * @return array
  */
 function twig_sort_filter($array)
 {
@@ -822,15 +936,11 @@ function twig_sort_filter($array)
 function twig_in_filter($value, $compare)
 {
     if (is_array($compare)) {
-        return in_array($value, $compare, is_object($value));
-    } elseif (is_string($compare)) {
-        if (!strlen($value)) {
-            return empty($compare);
-        }
-
-        return false !== strpos($compare, (string) $value);
+        return in_array($value, $compare, is_object($value) || is_resource($value));
+    } elseif (is_string($compare) && (is_string($value) || is_int($value) || is_float($value))) {
+        return '' === $value || false !== strpos($compare, (string) $value);
     } elseif ($compare instanceof Traversable) {
-        return in_array($value, iterator_to_array($compare, false), is_object($value));
+        return in_array($value, iterator_to_array($compare, false), is_object($value) || is_resource($value));
     }
 
     return false;
@@ -843,7 +953,9 @@ function twig_in_filter($value, $compare)
  * @param string           $string     The value to be escaped
  * @param string           $strategy   The escaping strategy
  * @param string           $charset    The charset
- * @param Boolean          $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
+ * @param bool             $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
+ *
+ * @return string
  */
 function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
 {
@@ -870,22 +982,30 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
             // Using a static variable to avoid initializing the array
             // each time the function is called. Moving the declaration on the
             // top of the function slow downs other escaping strategies.
-            static $htmlspecialcharsCharsets = array(
-                'ISO-8859-1' => true, 'ISO8859-1' => true,
-                'ISO-8859-15' => true, 'ISO8859-15' => true,
-                'utf-8' => true, 'UTF-8' => true,
-                'CP866' => true, 'IBM866' => true, '866' => true,
-                'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
-                '1251' => true,
-                'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
-                'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
-                'BIG5' => true, '950' => true,
-                'GB2312' => true, '936' => true,
-                'BIG5-HKSCS' => true,
-                'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
-                'EUC-JP' => true, 'EUCJP' => true,
-                'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
-            );
+            static $htmlspecialcharsCharsets;
+
+            if (null === $htmlspecialcharsCharsets) {
+                if (defined('HHVM_VERSION')) {
+                    $htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
+                } else {
+                    $htmlspecialcharsCharsets = array(
+                        'ISO-8859-1' => true, 'ISO8859-1' => true,
+                        'ISO-8859-15' => true, 'ISO8859-15' => true,
+                        'utf-8' => true, 'UTF-8' => true,
+                        'CP866' => true, 'IBM866' => true, '866' => true,
+                        'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
+                        '1251' => true,
+                        'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
+                        'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
+                        'BIG5' => true, '950' => true,
+                        'GB2312' => true, '936' => true,
+                        'BIG5-HKSCS' => true,
+                        'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
+                        'EUC-JP' => true, 'EUCJP' => true,
+                        'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
+                    );
+                }
+            }
 
             if (isset($htmlspecialcharsCharsets[$charset])) {
                 return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
@@ -957,16 +1077,26 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
             return $string;
 
         case 'url':
-            // hackish test to avoid version_compare that is much slower, this works unless PHP releases a 5.10.*
-            // at that point however PHP 5.2.* support can be removed
-            if (PHP_VERSION < '5.3.0') {
+            if (PHP_VERSION_ID < 50300) {
                 return str_replace('%7E', '~', rawurlencode($string));
             }
 
             return rawurlencode($string);
 
         default:
-            throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy));
+            static $escapers;
+
+            if (null === $escapers) {
+                $escapers = $env->getExtension('core')->getEscapers();
+            }
+
+            if (isset($escapers[$strategy])) {
+                return call_user_func($escapers[$strategy], $env, $string, $charset);
+            }
+
+            $validStrategies = implode(', ', array_merge(array('html', 'js', 'url', 'css', 'html_attr'), array_keys($escapers)));
+
+            throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
     }
 }
 
@@ -1060,7 +1190,7 @@ function _twig_escape_html_attr_callback($matches)
     $chr = $matches[0];
     $ord = ord($chr);
 
-    /**
+    /*
      * The following replaces characters undefined in HTML with the
      * hex entity for the Unicode replacement character.
      */
@@ -1068,7 +1198,7 @@ function _twig_escape_html_attr_callback($matches)
         return '&#xFFFD;';
     }
 
-    /**
+    /*
      * Check if the current character to escape has a name entity we should
      * replace it with while grabbing the hex value of the character.
      */
@@ -1084,11 +1214,10 @@ function _twig_escape_html_attr_callback($matches)
         return sprintf('&%s;', $entityMap[$int]);
     }
 
-    /**
+    /*
      * Per OWASP recommendations, we'll use hex entities for any other
      * characters where a named entity does not exist.
      */
-
     return sprintf('&#x%s;', $hex);
 }
 
@@ -1100,7 +1229,7 @@ if (function_exists('mb_get_info')) {
      * @param Twig_Environment $env   A Twig_Environment instance
      * @param mixed            $thing A variable
      *
-     * @return integer The length of the value
+     * @return int The length of the value
      */
     function twig_length_filter(Twig_Environment $env, $thing)
     {
@@ -1184,7 +1313,7 @@ else {
      * @param Twig_Environment $env   A Twig_Environment instance
      * @param mixed            $thing A variable
      *
-     * @return integer The length of the value
+     * @return int The length of the value
      */
     function twig_length_filter(Twig_Environment $env, $thing)
     {
@@ -1240,7 +1369,7 @@ function twig_ensure_traversable($seq)
  *
  * @param mixed $value A variable
  *
- * @return Boolean true if the value is empty, false otherwise
+ * @return bool    true if the value is empty, false otherwise
  */
 function twig_test_empty($value)
 {
@@ -1263,7 +1392,7 @@ function twig_test_empty($value)
  *
  * @param mixed $value A variable
  *
- * @return Boolean true if the value is traversable
+ * @return bool    true if the value is traversable
  */
 function twig_test_iterable($value)
 {
@@ -1273,16 +1402,20 @@ function twig_test_iterable($value)
 /**
  * Renders a template.
  *
- * @param string  $template       The template to render
- * @param array   $variables      The variables to pass to the template
- * @param Boolean $with_context   Whether to pass the current context variables or not
- * @param Boolean $ignore_missing Whether to ignore missing templates or not
- * @param Boolean $sandboxed      Whether to sandbox the template or not
+ * @param Twig_Environment $env
+ * @param array            $context
+ * @param string|array     $template      The template to render or an array of templates to try consecutively
+ * @param array            $variables     The variables to pass to the template
+ * @param bool             $withContext
+ * @param bool             $ignoreMissing Whether to ignore missing templates or not
+ * @param bool             $sandboxed     Whether to sandbox the template or not
  *
  * @return string The rendered template
  */
 function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false)
 {
+    $alreadySandboxed = false;
+    $sandbox = null;
     if ($withContext) {
         $variables = array_merge($context, $variables);
     }
@@ -1294,10 +1427,15 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
         }
     }
 
+    $result = null;
     try {
-        return $env->resolveTemplate($template)->render($variables);
+        $result = $env->resolveTemplate($template)->render($variables);
     } catch (Twig_Error_Loader $e) {
         if (!$ignoreMissing) {
+            if ($isSandboxed && !$alreadySandboxed) {
+                $sandbox->disableSandbox();
+            }
+
             throw $e;
         }
     }
@@ -1305,6 +1443,27 @@ function twig_include(Twig_Environment $env, $context, $template, $variables = a
     if ($isSandboxed && !$alreadySandboxed) {
         $sandbox->disableSandbox();
     }
+
+    return $result;
+}
+
+/**
+ * Returns a template content without rendering it.
+ *
+ * @param string $name          The template name
+ * @param bool   $ignoreMissing Whether to ignore missing templates or not
+ *
+ * @return string The template source
+ */
+function twig_source(Twig_Environment $env, $name, $ignoreMissing = false)
+{
+    try {
+        return $env->getLoader()->getSource($name);
+    } catch (Twig_Error_Loader $e) {
+        if (!$ignoreMissing) {
+            throw $e;
+        }
+    }
 }
 
 /**
@@ -1328,8 +1487,8 @@ function twig_constant($constant, $object = null)
  * Batches item.
  *
  * @param array   $items An array of items
- * @param integer $size  The size of the batch
- * @param string  $fill  A string to fill missing items
+ * @param int     $size  The size of the batch
+ * @param mixed   $fill  A value used to fill missing items
  *
  * @return array
  */
@@ -1343,12 +1502,14 @@ function twig_array_batch($items, $size, $fill = null)
 
     $result = array_chunk($items, $size, true);
 
-    if (null !== $fill) {
+    if (null !== $fill && !empty($result)) {
         $last = count($result) - 1;
-        $result[$last] = array_merge(
-            $result[$last],
-            array_fill(0, $size - count($result[$last]), $fill)
-        );
+        if ($fillCount = $size - count($result[$last])) {
+            $result[$last] = array_merge(
+                $result[$last],
+                array_fill(0, $fillCount, $fill)
+            );
+        }
     }
 
     return $result;
--- a/vendor/twig/twig/lib/Twig/Extension/Debug.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Debug.php
@@ -62,7 +62,7 @@ function twig_var_dump(Twig_Environment $env, $context)
 
         var_dump($vars);
     } else {
-        for ($i = 2; $i < $count; $i++) {
+        for ($i = 2; $i < $count; ++$i) {
             var_dump(func_get_arg($i));
         }
     }
--- a/vendor/twig/twig/lib/Twig/Extension/Escaper.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Escaper.php
@@ -30,7 +30,7 @@ class Twig_Extension_Escaper extends Twig_Extension
     /**
      * Returns the node visitor instances to add to the existing list.
      *
-     * @return array An array of Twig_NodeVisitorInterface instances
+     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
      */
     public function getNodeVisitors()
     {
@@ -64,6 +64,10 @@ class Twig_Extension_Escaper extends Twig_Extension
             $defaultStrategy = 'html';
         }
 
+        if ('filename' === $defaultStrategy) {
+            $defaultStrategy = array('Twig_FileExtensionEscapingStrategy', 'guess');
+        }
+
         $this->defaultStrategy = $defaultStrategy;
     }
 
@@ -100,6 +104,8 @@ class Twig_Extension_Escaper extends Twig_Extension
  * Marks a variable as being safe.
  *
  * @param string $string A PHP variable
+ *
+ * @return string
  */
 function twig_raw_filter($string)
 {
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Extension/Profiler.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Twig_Extension_Profiler extends Twig_Extension
+{
+    private $actives;
+
+    public function __construct(Twig_Profiler_Profile $profile)
+    {
+        $this->actives = array($profile);
+    }
+
+    public function enter(Twig_Profiler_Profile $profile)
+    {
+        $this->actives[0]->addProfile($profile);
+        array_unshift($this->actives, $profile);
+    }
+
+    public function leave(Twig_Profiler_Profile $profile)
+    {
+        $profile->leave();
+        array_shift($this->actives);
+
+        if (1 === count($this->actives)) {
+            $this->actives[0]->leave();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getNodeVisitors()
+    {
+        return array(new Twig_Profiler_NodeVisitor_Profiler($this->getName()));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'profiler';
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Extension/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php
@@ -16,7 +16,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
 
     public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
     {
-        $this->policy            = $policy;
+        $this->policy = $policy;
         $this->sandboxedGlobally = $sandboxed;
     }
 
@@ -33,7 +33,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
     /**
      * Returns the node visitor instances to add to the existing list.
      *
-     * @return array An array of Twig_NodeVisitorInterface instances
+     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
      */
     public function getNodeVisitors()
     {
@@ -93,7 +93,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
 
     public function ensureToStringAllowed($obj)
     {
-        if (is_object($obj)) {
+        if ($this->isSandboxed() && is_object($obj)) {
             $this->policy->checkMethodAllowed($obj, '__toString');
         }
 
--- a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php
+++ b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php
@@ -43,22 +43,5 @@ class Twig_Extension_StringLoader extends Twig_Extension
  */
 function twig_template_from_string(Twig_Environment $env, $template)
 {
-    static $loader;
-
-    if (null === $loader) {
-        $loader = new Twig_Loader_String();
-    }
-
-    $current = $env->getLoader();
-    $env->setLoader($loader);
-    try {
-        $template = $env->loadTemplate($template);
-    } catch (Exception $e) {
-        $env->setLoader($current);
-
-        throw $e;
-    }
-    $env->setLoader($current);
-
-    return $template;
+    return $env->createTemplate($template);
 }
--- a/vendor/twig/twig/lib/Twig/ExtensionInterface.php
+++ b/vendor/twig/twig/lib/Twig/ExtensionInterface.php
@@ -35,7 +35,7 @@ interface Twig_ExtensionInterface
     /**
      * Returns the node visitor instances to add to the existing list.
      *
-     * @return array An array of Twig_NodeVisitorInterface instances
+     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
      */
     public function getNodeVisitors();
 
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Default autoescaping strategy based on file names.
+ *
+ * This strategy sets the HTML as the default autoescaping strategy,
+ * but changes it based on the filename.
+ *
+ * Note that there is no runtime performance impact as the
+ * default autoescaping strategy is set at compilation time.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_FileExtensionEscapingStrategy
+{
+    /**
+     * Guesses the best autoescaping strategy based on the file name.
+     *
+     * @param string $filename The template file name
+     *
+     * @return string The escaping strategy name to use
+     */
+    public static function guess($filename)
+    {
+        if (!preg_match('{\.(js|css|txt)(?:\.[^/\\\\]+)?$}', $filename, $match)) {
+            return 'html';
+        }
+
+        switch ($match[1]) {
+            case 'js':
+                return 'js';
+
+            case 'css':
+                return 'css';
+
+            case 'txt':
+                return false;
+        }
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Filter.php
+++ b/vendor/twig/twig/lib/Twig/Filter.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface
@@ -26,10 +27,10 @@ abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableI
     {
         $this->options = array_merge(array(
             'needs_environment' => false,
-            'needs_context'     => false,
-            'pre_escape'        => null,
-            'preserves_safety'  => null,
-            'callable'          => null,
+            'needs_context' => false,
+            'pre_escape' => null,
+            'preserves_safety' => null,
+            'callable' => null,
         ), $options);
     }
 
--- a/vendor/twig/twig/lib/Twig/Filter/Function.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Function.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Filter_Function extends Twig_Filter
--- a/vendor/twig/twig/lib/Twig/Filter/Method.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Method.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Filter_Method extends Twig_Filter
--- a/vendor/twig/twig/lib/Twig/Filter/Node.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Node.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Filter_Node extends Twig_Filter
--- a/vendor/twig/twig/lib/Twig/FilterCallableInterface.php
+++ b/vendor/twig/twig/lib/Twig/FilterCallableInterface.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_FilterCallableInterface
--- a/vendor/twig/twig/lib/Twig/FilterInterface.php
+++ b/vendor/twig/twig/lib/Twig/FilterInterface.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFilter instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_FilterInterface
--- a/vendor/twig/twig/lib/Twig/Function.php
+++ b/vendor/twig/twig/lib/Twig/Function.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface
@@ -26,8 +27,8 @@ abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCal
     {
         $this->options = array_merge(array(
             'needs_environment' => false,
-            'needs_context'     => false,
-            'callable'          => null,
+            'needs_context' => false,
+            'callable' => null,
         ), $options);
     }
 
--- a/vendor/twig/twig/lib/Twig/Function/Function.php
+++ b/vendor/twig/twig/lib/Twig/Function/Function.php
@@ -16,6 +16,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Function_Function extends Twig_Function
--- a/vendor/twig/twig/lib/Twig/Function/Method.php
+++ b/vendor/twig/twig/lib/Twig/Function/Method.php
@@ -16,6 +16,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Function_Method extends Twig_Function
--- a/vendor/twig/twig/lib/Twig/Function/Node.php
+++ b/vendor/twig/twig/lib/Twig/Function/Node.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Function_Node extends Twig_Function
--- a/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php
+++ b/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php
@@ -15,6 +15,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_FunctionCallableInterface
--- a/vendor/twig/twig/lib/Twig/FunctionInterface.php
+++ b/vendor/twig/twig/lib/Twig/FunctionInterface.php
@@ -16,6 +16,7 @@
  * Use Twig_SimpleFunction instead.
  *
  * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_FunctionInterface
--- a/vendor/twig/twig/lib/Twig/Lexer.php
+++ b/vendor/twig/twig/lib/Twig/Lexer.php
@@ -33,58 +33,55 @@ class Twig_Lexer implements Twig_LexerInterface
     protected $positions;
     protected $currentVarBlockLine;
 
-    const STATE_DATA            = 0;
-    const STATE_BLOCK           = 1;
-    const STATE_VAR             = 2;
-    const STATE_STRING          = 3;
-    const STATE_INTERPOLATION   = 4;
-
-    const REGEX_NAME            = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
-    const REGEX_NUMBER          = '/[0-9]+(?:\.[0-9]+)?/A';
-    const REGEX_STRING          = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
+    const STATE_DATA = 0;
+    const STATE_BLOCK = 1;
+    const STATE_VAR = 2;
+    const STATE_STRING = 3;
+    const STATE_INTERPOLATION = 4;
+
+    const REGEX_NAME = '/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A';
+    const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
+    const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
     const REGEX_DQ_STRING_DELIM = '/"/A';
-    const REGEX_DQ_STRING_PART  = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
-    const PUNCTUATION           = '()[]{}?:.,|';
+    const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\{))[^#"\\\\]*)*/As';
+    const PUNCTUATION = '()[]{}?:.,|';
 
     public function __construct(Twig_Environment $env, array $options = array())
     {
         $this->env = $env;
 
         $this->options = array_merge(array(
-            'tag_comment'     => array('{#', '#}'),
-            'tag_block'       => array('{%', '%}'),
-            'tag_variable'    => array('{{', '}}'),
+            'tag_comment' => array('{#', '#}'),
+            'tag_block' => array('{%', '%}'),
+            'tag_variable' => array('{{', '}}'),
             'whitespace_trim' => '-',
-            'interpolation'   => array('#{', '}'),
+            'interpolation' => array('#{', '}'),
         ), $options);
 
         $this->regexes = array(
-            'lex_var'             => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A',
-            'lex_block'           => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A',
-            'lex_raw_data'        => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',
-            'operator'            => $this->getOperatorRegex(),
-            'lex_comment'         => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s',
-            'lex_block_raw'       => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',
-            'lex_block_line'      => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As',
-            'lex_tokens_start'    => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s',
+            'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A',
+            'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A',
+            'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',
+            'operator' => $this->getOperatorRegex(),
+            'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s',
+            'lex_block_raw' => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',
+            'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As',
+            'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s',
             'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A',
-            'interpolation_end'   => '/\s*'.preg_quote($this->options['interpolation'][1], '/').'/A',
+            'interpolation_end' => '/\s*'.preg_quote($this->options['interpolation'][1], '/').'/A',
         );
     }
 
     /**
-     * Tokenizes a source code.
-     *
-     * @param string $code     The source code
-     * @param string $filename A unique identifier for the source code
-     *
-     * @return Twig_TokenStream A token stream instance
+     * {@inheritdoc}
      */
     public function tokenize($code, $filename = null)
     {
         if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
             $mbEncoding = mb_internal_encoding();
             mb_internal_encoding('ASCII');
+        } else {
+            $mbEncoding = null;
         }
 
         $this->code = str_replace(array("\r\n", "\r"), "\n", $code);
@@ -135,7 +132,7 @@ class Twig_Lexer implements Twig_LexerInterface
             throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
         }
 
-        if (isset($mbEncoding)) {
+        if ($mbEncoding) {
             mb_internal_encoding($mbEncoding);
         }
 
@@ -233,7 +230,7 @@ class Twig_Lexer implements Twig_LexerInterface
 
         // operators
         if (preg_match($this->regexes['operator'], $this->code, $match, null, $this->cursor)) {
-            $this->pushToken(Twig_Token::OPERATOR_TYPE, $match[0]);
+            $this->pushToken(Twig_Token::OPERATOR_TYPE, preg_replace('/\s+/', ' ', $match[0]));
             $this->moveCursor($match[0]);
         }
         // names
@@ -320,13 +317,10 @@ class Twig_Lexer implements Twig_LexerInterface
             $this->pushToken(Twig_Token::INTERPOLATION_START_TYPE);
             $this->moveCursor($match[0]);
             $this->pushState(self::STATE_INTERPOLATION);
-
         } elseif (preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, null, $this->cursor) && strlen($match[0]) > 0) {
             $this->pushToken(Twig_Token::STRING_TYPE, stripcslashes($match[0]));
             $this->moveCursor($match[0]);
-
         } elseif (preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, null, $this->cursor)) {
-
             list($expect, $lineno) = array_pop($this->brackets);
             if ($this->code[$this->cursor] != '"') {
                 throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $expect), $lineno, $this->filename);
@@ -382,10 +376,15 @@ class Twig_Lexer implements Twig_LexerInterface
             // an operator that ends with a character must be followed by
             // a whitespace or a parenthesis
             if (ctype_alpha($operator[$length - 1])) {
-                $regex[] = preg_quote($operator, '/').'(?=[\s()])';
+                $r = preg_quote($operator, '/').'(?=[\s()])';
             } else {
-                $regex[] = preg_quote($operator, '/');
+                $r = preg_quote($operator, '/');
             }
+
+            // an operator with a space can be any amount of whitespaces
+            $r = preg_replace('/\s+/', '\s+', $r);
+
+            $regex[] = $r;
         }
 
         return '/'.implode('|', $regex).'/A';
--- a/vendor/twig/twig/lib/Twig/LexerInterface.php
+++ b/vendor/twig/twig/lib/Twig/LexerInterface.php
@@ -13,7 +13,8 @@
  * Interface implemented by lexer classes.
  *
  * @author Fabien Potencier <fabien@symfony.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_LexerInterface
 {
@@ -24,6 +25,8 @@ interface Twig_LexerInterface
      * @param string $filename A unique identifier for the source code
      *
      * @return Twig_TokenStream A token stream instance
+     *
+     * @throws Twig_Error_Syntax When the code is syntactically wrong
      */
     public function tokenize($code, $filename = null);
 }
--- a/vendor/twig/twig/lib/Twig/Loader/Array.php
+++ b/vendor/twig/twig/lib/Twig/Loader/Array.php
@@ -17,11 +17,13 @@
  * source code of the template). If you don't want to see your cache grows out of
  * control, you need to take care of clearing the old cache file by yourself.
  *
+ * This loader should only be used for unit testing.
+ *
  * @author Fabien Potencier <fabien@symfony.com>
  */
 class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
 {
-    protected $templates;
+    protected $templates = array();
 
     /**
      * Constructor.
@@ -32,10 +34,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
      */
     public function __construct(array $templates)
     {
-        $this->templates = array();
-        foreach ($templates as $name => $template) {
-            $this->templates[$name] = $template;
-        }
+        $this->templates = $templates;
     }
 
     /**
--- a/vendor/twig/twig/lib/Twig/Loader/Chain.php
+++ b/vendor/twig/twig/lib/Twig/Loader/Chain.php
@@ -17,7 +17,7 @@
 class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
 {
     private $hasSourceCache = array();
-    protected $loaders;
+    protected $loaders = array();
 
     /**
      * Constructor.
@@ -26,7 +26,6 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
      */
     public function __construct(array $loaders = array())
     {
-        $this->loaders = array();
         foreach ($loaders as $loader) {
             $this->addLoader($loader);
         }
--- a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php
+++ b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php
@@ -19,8 +19,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
     /** Identifier of the main namespace. */
     const MAIN_NAMESPACE = '__main__';
 
-    protected $paths;
-    protected $cache;
+    protected $paths = array();
+    protected $cache = array();
 
     /**
      * Constructor.
@@ -143,7 +143,8 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
      */
     public function exists($name)
     {
-        $name = (string) $name;
+        $name = $this->normalizeName($name);
+
         if (isset($this->cache[$name])) {
             return true;
         }
@@ -167,10 +168,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
 
     protected function findTemplate($name)
     {
-        $name = (string) $name;
-
-        // normalize name
-        $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'));
+        $name = $this->normalizeName($name);
 
         if (isset($this->cache[$name])) {
             return $this->cache[$name];
@@ -178,30 +176,46 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
 
         $this->validateName($name);
 
-        $namespace = self::MAIN_NAMESPACE;
-        if (isset($name[0]) && '@' == $name[0]) {
-            if (false === $pos = strpos($name, '/')) {
-                throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
-            }
-
-            $namespace = substr($name, 1, $pos - 1);
-
-            $name = substr($name, $pos + 1);
-        }
+        list($namespace, $shortname) = $this->parseName($name);
 
         if (!isset($this->paths[$namespace])) {
             throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace));
         }
 
         foreach ($this->paths[$namespace] as $path) {
-            if (is_file($path.'/'.$name)) {
-                return $this->cache[$name] = $path.'/'.$name;
+            if (is_file($path.'/'.$shortname)) {
+                if (false !== $realpath = realpath($path.'/'.$shortname)) {
+                    return $this->cache[$name] = $realpath;
+                }
+
+                return $this->cache[$name] = $path.'/'.$shortname;
             }
         }
 
         throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
     }
 
+    protected function parseName($name, $default = self::MAIN_NAMESPACE)
+    {
+        if (isset($name[0]) && '@' == $name[0]) {
+            if (false === $pos = strpos($name, '/')) {
+                throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
+            }
+
+            $namespace = substr($name, 1, $pos - 1);
+            $shortname = substr($name, $pos + 1);
+
+            return array($namespace, $shortname);
+        }
+
+        return array($default, $name);
+    }
+
+    protected function normalizeName($name)
+    {
+        return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
+    }
+
     protected function validateName($name)
     {
         if (false !== strpos($name, "\0")) {
--- a/vendor/twig/twig/lib/Twig/Loader/String.php
+++ b/vendor/twig/twig/lib/Twig/Loader/String.php
@@ -12,15 +12,15 @@
 /**
  * Loads a template from a string.
  *
- * This loader should only be used for unit testing as it has many limitations
- * (for instance, the include or extends tag does not make any sense for a string
- * loader).
+ * This loader should NEVER be used. It only exists for Twig internal purposes.
  *
  * When using this loader with a cache mechanism, you should know that a new cache
  * key is generated each time a template content "changes" (the cache key being the
  * source code of the template). If you don't want to see your cache grows out of
  * control, you need to take care of clearing the old cache file by yourself.
  *
+ * @deprecated since 1.18.1 (to be removed in 2.0)
+ *
  * @author Fabien Potencier <fabien@symfony.com>
  */
 class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
--- a/vendor/twig/twig/lib/Twig/LoaderInterface.php
+++ b/vendor/twig/twig/lib/Twig/LoaderInterface.php
@@ -41,10 +41,11 @@ interface Twig_LoaderInterface
     /**
      * Returns true if the template is still fresh.
      *
-     * @param string    $name The template name
-     * @param timestamp $time The last modification time of the cached template
+     * @param string $name The template name
+     * @param int    $time Timestamp of the last modification time of the
+     *                     cached template
      *
-     * @return Boolean true if the template is fresh, false otherwise
+     * @return bool true if the template is fresh, false otherwise
      *
      * @throws Twig_Error_Loader When $name is not found
      */
--- a/vendor/twig/twig/lib/Twig/Node.php
+++ b/vendor/twig/twig/lib/Twig/Node.php
@@ -28,10 +28,10 @@ class Twig_Node implements Twig_NodeInterface
      * The nodes are automatically made available as properties ($this->node).
      * The attributes are automatically made available as array items ($this['name']).
      *
-     * @param array   $nodes      An array of named nodes
-     * @param array   $attributes An array of attributes (should not be nodes)
-     * @param integer $lineno     The line number
-     * @param string  $tag        The tag name associated with the Node
+     * @param array  $nodes      An array of named nodes
+     * @param array  $attributes An array of attributes (should not be nodes)
+     * @param int    $lineno     The line number
+     * @param string $tag        The tag name associated with the Node
      */
     public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
     {
@@ -69,6 +69,9 @@ class Twig_Node implements Twig_NodeInterface
         return implode("\n", $repr);
     }
 
+    /**
+     * @deprecated since 1.16.1 (to be removed in 2.0)
+     */
     public function toXml($asDom = false)
     {
         $dom = new DOMDocument('1.0', 'UTF-8');
@@ -119,9 +122,9 @@ class Twig_Node implements Twig_NodeInterface
     /**
      * Returns true if the attribute is defined.
      *
-     * @param  string  The attribute name
+     * @param string $name The attribute name
      *
-     * @return Boolean true if the attribute is defined, false otherwise
+     * @return bool true if the attribute is defined, false otherwise
      */
     public function hasAttribute($name)
     {
@@ -129,11 +132,11 @@ class Twig_Node implements Twig_NodeInterface
     }
 
     /**
-     * Gets an attribute.
+     * Gets an attribute value by name.
      *
-     * @param  string The attribute name
+     * @param string $name
      *
-     * @return mixed The attribute value
+     * @return mixed
      */
     public function getAttribute($name)
     {
@@ -145,10 +148,10 @@ class Twig_Node implements Twig_NodeInterface
     }
 
     /**
-     * Sets an attribute.
+     * Sets an attribute by name to a value.
      *
-     * @param string The attribute name
-     * @param mixed  The attribute value
+     * @param string $name
+     * @param mixed  $value
      */
     public function setAttribute($name, $value)
     {
@@ -156,9 +159,9 @@ class Twig_Node implements Twig_NodeInterface
     }
 
     /**
-     * Removes an attribute.
+     * Removes an attribute by name.
      *
-     * @param string The attribute name
+     * @param string $name
      */
     public function removeAttribute($name)
     {
@@ -166,11 +169,11 @@ class Twig_Node implements Twig_NodeInterface
     }
 
     /**
-     * Returns true if the node with the given identifier exists.
+     * Returns true if the node with the given name exists.
      *
-     * @param  string  The node name
+     * @param string $name
      *
-     * @return Boolean true if the node with the given name exists, false otherwise
+     * @return bool
      */
     public function hasNode($name)
     {
@@ -180,9 +183,9 @@ class Twig_Node implements Twig_NodeInterface
     /**
      * Gets a node by name.
      *
-     * @param  string The node name
+     * @param string $name
      *
-     * @return Twig_Node A Twig_Node instance
+     * @return Twig_Node
      */
     public function getNode($name)
     {
@@ -196,8 +199,8 @@ class Twig_Node implements Twig_NodeInterface
     /**
      * Sets a node.
      *
-     * @param string    The node name
-     * @param Twig_Node A Twig_Node instance
+     * @param string    $name
+     * @param Twig_Node $node
      */
     public function setNode($name, $node = null)
     {
@@ -207,7 +210,7 @@ class Twig_Node implements Twig_NodeInterface
     /**
      * Removes a node by name.
      *
-     * @param string The node name
+     * @param string $name
      */
     public function removeNode($name)
     {
--- a/vendor/twig/twig/lib/Twig/Node/AutoEscape.php
+++ b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php
@@ -30,7 +30,7 @@ class Twig_Node_AutoEscape extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Block.php
+++ b/vendor/twig/twig/lib/Twig/Node/Block.php
@@ -25,7 +25,7 @@ class Twig_Node_Block extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/BlockReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/BlockReference.php
@@ -25,7 +25,7 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/CheckSecurity.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Node_CheckSecurity extends Twig_Node
+{
+    protected $usedFilters;
+    protected $usedTags;
+    protected $usedFunctions;
+
+    public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
+    {
+        $this->usedFilters = $usedFilters;
+        $this->usedTags = $usedTags;
+        $this->usedFunctions = $usedFunctions;
+
+        parent::__construct();
+    }
+
+    public function compile(Twig_Compiler $compiler)
+    {
+        $tags = $filters = $functions = array();
+        foreach (array('tags', 'filters', 'functions') as $type) {
+            foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
+                if ($node instanceof Twig_Node) {
+                    ${$type}[$name] = $node->getLine();
+                } else {
+                    ${$type}[$node] = null;
+                }
+            }
+        }
+
+        $compiler
+            ->write('$tags = ')->repr(array_filter($tags))->raw(";\n")
+            ->write('$filters = ')->repr(array_filter($filters))->raw(";\n")
+            ->write('$functions = ')->repr(array_filter($functions))->raw(";\n\n")
+            ->write("try {\n")
+            ->indent()
+            ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
+            ->indent()
+            ->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
+            ->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
+            ->write(!$functions ? "array()\n" : "array('".implode("', '", array_keys($functions))."')\n")
+            ->outdent()
+            ->write(");\n")
+            ->outdent()
+            ->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
+            ->indent()
+            ->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n")
+            ->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
+            ->indent()
+            ->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
+            ->outdent()
+            ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
+            ->indent()
+            ->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
+            ->outdent()
+            ->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
+            ->indent()
+            ->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
+            ->outdent()
+            ->write("}\n\n")
+            ->write("throw \$e;\n")
+            ->outdent()
+            ->write("}\n\n")
+        ;
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Node/Do.php
+++ b/vendor/twig/twig/lib/Twig/Node/Do.php
@@ -24,7 +24,7 @@ class Twig_Node_Do extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Embed.php
+++ b/vendor/twig/twig/lib/Twig/Node/Embed.php
@@ -28,11 +28,15 @@ class Twig_Node_Embed extends Twig_Node_Include
     protected function addGetTemplate(Twig_Compiler $compiler)
     {
         $compiler
-            ->write("\$this->env->loadTemplate(")
+            ->write('$this->loadTemplate(')
             ->string($this->getAttribute('filename'))
             ->raw(', ')
+            ->repr($compiler->getFilename())
+            ->raw(', ')
+            ->repr($this->getLine())
+            ->raw(', ')
             ->string($this->getAttribute('index'))
-            ->raw(")")
+            ->raw(')')
         ;
     }
 }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Array.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php
@@ -63,7 +63,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php
@@ -15,7 +15,7 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php
@@ -19,7 +19,7 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2013 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
+{
+    public function compile(Twig_Compiler $compiler)
+    {
+        $left = $compiler->getVarName();
+        $right = $compiler->getVarName();
+        $compiler
+            ->raw(sprintf('(is_string($%s = ', $left))
+            ->subcompile($this->getNode('left'))
+            ->raw(sprintf(') && is_string($%s = ', $right))
+            ->subcompile($this->getNode('right'))
+            ->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right))
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('');
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php
@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2013 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
+{
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->raw('preg_match(')
+            ->subcompile($this->getNode('right'))
+            ->raw(', ')
+            ->subcompile($this->getNode('left'))
+            ->raw(')')
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('');
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php
@@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php
@@ -0,0 +1,30 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2013 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
+{
+    public function compile(Twig_Compiler $compiler)
+    {
+        $left = $compiler->getVarName();
+        $right = $compiler->getVarName();
+        $compiler
+            ->raw(sprintf('(is_string($%s = ', $left))
+            ->subcompile($this->getNode('left'))
+            ->raw(sprintf(') && is_string($%s = ', $right))
+            ->subcompile($this->getNode('right'))
+            ->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right))
+        ;
+    }
+
+    public function operator(Twig_Compiler $compiler)
+    {
+        return $compiler->raw('');
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php
@@ -25,7 +25,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -36,15 +36,15 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
         if ($this->getAttribute('output')) {
             $compiler
                 ->addDebugInfo($this)
-                ->write("\$this->displayBlock(")
+                ->write('$this->displayBlock(')
                 ->subcompile($this->getNode('name'))
                 ->raw(", \$context, \$blocks);\n")
             ;
         } else {
             $compiler
-                ->raw("\$this->renderBlock(")
+                ->raw('$this->renderBlock(')
                 ->subcompile($this->getNode('name'))
-                ->raw(", \$context, \$blocks)")
+                ->raw(', $context, $blocks)')
             ;
         }
     }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php
@@ -12,10 +12,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
 {
     protected function compileCallable(Twig_Compiler $compiler)
     {
-        $callable = $this->getAttribute('callable');
-
         $closingParenthesis = false;
-        if ($callable) {
+        if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
             if (is_string($callable)) {
                 $compiler->raw($callable);
             } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
@@ -92,6 +90,9 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
 
     protected function getArguments($callable, $arguments)
     {
+        $callType = $this->getAttribute('type');
+        $callName = $this->getAttribute('name');
+
         $parameters = array();
         $named = false;
         foreach ($arguments as $name => $node) {
@@ -99,18 +100,25 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
                 $named = true;
                 $name = $this->normalizeName($name);
             } elseif ($named) {
-                throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
+                throw new Twig_Error_Syntax(sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName));
             }
 
             $parameters[$name] = $node;
         }
 
-        if (!$named) {
+        $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
+        if (!$named && !$isVariadic) {
             return $parameters;
         }
 
         if (!$callable) {
-            throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
+            if ($named) {
+                $message = sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
+            } else {
+                $message = sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
+            }
+
+            throw new LogicException($message);
         }
 
         // manage named arguments
@@ -119,6 +127,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
         } elseif (is_object($callable) && !$callable instanceof Closure) {
             $r = new ReflectionObject($callable);
             $r = $r->getMethod('__invoke');
+        } elseif (is_string($callable) && false !== strpos($callable, '::')) {
+            $r = new ReflectionMethod($callable);
         } else {
             $r = new ReflectionFunction($callable);
         }
@@ -138,34 +148,93 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
                 array_shift($definition);
             }
         }
+        if ($isVariadic) {
+            $argument = end($definition);
+            if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && array() === $argument->getDefaultValue()) {
+                array_pop($definition);
+            } else {
+                $callableName = $r->name;
+                if ($r->getDeclaringClass()) {
+                    $callableName = $r->getDeclaringClass()->name.'::'.$callableName;
+                }
+
+                throw new LogicException(sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = array()".', $callableName, $callType, $callName));
+            }
+        }
 
         $arguments = array();
+        $names = array();
+        $missingArguments = array();
+        $optionalArguments = array();
         $pos = 0;
         foreach ($definition as $param) {
-            $name = $this->normalizeName($param->name);
+            $names[] = $name = $this->normalizeName($param->name);
 
             if (array_key_exists($name, $parameters)) {
                 if (array_key_exists($pos, $parameters)) {
-                    throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
+                    throw new Twig_Error_Syntax(sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName));
+                }
+
+                if (!empty($missingArguments)) {
+                    throw new Twig_Error_Syntax(sprintf(
+                        'Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".',
+                        $name, $callType, $callName, implode(', ', $names), count($missingArguments) > 1 ? 's' : '', implode('", "', $missingArguments))
+                    );
                 }
 
+                $arguments = array_merge($arguments, $optionalArguments);
                 $arguments[] = $parameters[$name];
                 unset($parameters[$name]);
+                $optionalArguments = array();
             } elseif (array_key_exists($pos, $parameters)) {
+                $arguments = array_merge($arguments, $optionalArguments);
                 $arguments[] = $parameters[$pos];
                 unset($parameters[$pos]);
+                $optionalArguments = array();
                 ++$pos;
             } elseif ($param->isDefaultValueAvailable()) {
-                $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
+                $optionalArguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
             } elseif ($param->isOptional()) {
-                break;
+                if (empty($parameters)) {
+                    break;
+                } else {
+                    $missingArguments[] = $name;
+                }
             } else {
-                throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
+                throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName));
+            }
+        }
+
+        if ($isVariadic) {
+            $arbitraryArguments = new Twig_Node_Expression_Array(array(), -1);
+            foreach ($parameters as $key => $value) {
+                if (is_int($key)) {
+                    $arbitraryArguments->addElement($value);
+                } else {
+                    $arbitraryArguments->addElement($value, new Twig_Node_Expression_Constant($key, -1));
+                }
+                unset($parameters[$key]);
+            }
+
+            if ($arbitraryArguments->count()) {
+                $arguments = array_merge($arguments, $optionalArguments);
+                $arguments[] = $arbitraryArguments;
             }
         }
 
         if (!empty($parameters)) {
-            throw new Twig_Error_Syntax(sprintf('Unknown argument%s "%s" for %s "%s".', count($parameters) > 1 ? 's' : '' , implode('", "', array_keys($parameters)), $this->getAttribute('type'), $this->getAttribute('name')));
+            $unknownParameter = null;
+            foreach ($parameters as $parameter) {
+                if ($parameter instanceof Twig_Node) {
+                    $unknownParameter = $parameter;
+                    break;
+                }
+            }
+
+            throw new Twig_Error_Syntax(sprintf(
+                'Unknown argument%s "%s" for %s "%s(%s)".',
+                count($parameters) > 1 ? 's' : '', implode('", "', array_keys($parameters)), $callType, $callName, implode(', ', $names)
+            ), $unknownParameter ? $unknownParameter->getLine() : -1);
         }
 
         return $arguments;
--- a/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php
@@ -24,7 +24,7 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php
@@ -30,6 +30,9 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
         if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) {
             $this->setAttribute('callable', $filter->getCallable());
         }
+        if ($filter instanceof Twig_SimpleFilter) {
+            $this->setAttribute('is_variadic', $filter->isVariadic());
+        }
 
         $this->compileCallable($compiler);
     }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php
@@ -29,6 +29,9 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
         if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) {
             $this->setAttribute('callable', $function->getCallable());
         }
+        if ($function instanceof Twig_SimpleFunction) {
+            $this->setAttribute('is_variadic', $function->isVariadic());
+        }
 
         $this->compileCallable($compiler);
     }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
@@ -11,7 +11,7 @@
  */
 class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
 {
-    public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno)
+    public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $lineno)
     {
         parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
     }
@@ -32,20 +32,30 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
 
         $compiler->raw(', ')->subcompile($this->getNode('attribute'));
 
-        if (count($this->getNode('arguments')) || Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
-            $compiler->raw(', ')->subcompile($this->getNode('arguments'));
-
-            if (Twig_TemplateInterface::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
-                $compiler->raw(', ')->repr($this->getAttribute('type'));
+        // only generate optional arguments when needed (to make generated code more readable)
+        $needFourth = $this->getAttribute('ignore_strict_check');
+        $needThird = $needFourth || $this->getAttribute('is_defined_test');
+        $needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
+        $needFirst = $needSecond || null !== $this->getNode('arguments');
+
+        if ($needFirst) {
+            if (null !== $this->getNode('arguments')) {
+                $compiler->raw(', ')->subcompile($this->getNode('arguments'));
+            } else {
+                $compiler->raw(', array()');
             }
+        }
 
-            if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
-                $compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false'));
-            }
+        if ($needSecond) {
+            $compiler->raw(', ')->repr($this->getAttribute('type'));
+        }
 
-            if ($this->getAttribute('ignore_strict_check')) {
-                $compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false'));
-            }
+        if ($needThird) {
+            $compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
+        }
+
+        if ($needFourth) {
+            $compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
         }
 
         $compiler->raw(')');
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Name.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php
@@ -12,7 +12,7 @@
 class Twig_Node_Expression_Name extends Twig_Node_Expression
 {
     protected $specialVars = array(
-        '_self'    => '$this',
+        '_self' => '$this',
         '_context' => '$context',
         '_charset' => '$this->env->getCharset()',
     );
@@ -26,6 +26,8 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
     {
         $name = $this->getAttribute('name');
 
+        $compiler->addDebugInfo($this);
+
         if ($this->getAttribute('is_defined_test')) {
             if ($this->isSpecial()) {
                 $compiler->repr(true);
@@ -44,7 +46,7 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
             // remove the non-PHP 5.4 version when PHP 5.3 support is dropped
             // as the non-optimized version is just a workaround for slow ternary operator
             // when the context has a lot of variables
-            if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
+            if (PHP_VERSION_ID >= 50400) {
                 // PHP 5.4 ternary operator performance was optimized
                 $compiler
                     ->raw('(isset($context[')
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php
@@ -25,22 +25,22 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
         if ($this->getAttribute('output')) {
             $compiler
                 ->addDebugInfo($this)
-                ->write("\$this->displayParentBlock(")
+                ->write('$this->displayParentBlock(')
                 ->string($this->getAttribute('name'))
                 ->raw(", \$context, \$blocks);\n")
             ;
         } else {
             $compiler
-                ->raw("\$this->renderParentBlock(")
+                ->raw('$this->renderParentBlock(')
                 ->string($this->getAttribute('name'))
-                ->raw(", \$context, \$blocks)")
+                ->raw(', $context, $blocks)')
             ;
         }
     }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php
@@ -26,6 +26,9 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
         if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) {
             $this->setAttribute('callable', $test->getCallable());
         }
+        if ($test instanceof Twig_SimpleTest) {
+            $this->setAttribute('is_variadic', $test->isVariadic());
+        }
 
         $this->compileCallable($compiler);
     }
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
@@ -13,7 +13,7 @@
  * Checks if a variable is divisible by a number.
  *
  * <pre>
- *  {% if loop.index is divisibleby(3) %}
+ *  {% if loop.index is divisible by(3) %}
  * </pre>
  *
  * @author Fabien Potencier <fabien@symfony.com>
--- a/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php
@@ -18,12 +18,9 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
 
     public function compile(Twig_Compiler $compiler)
     {
-        $compiler->raw('(');
+        $compiler->raw(' ');
         $this->operator($compiler);
-        $compiler
-            ->subcompile($this->getNode('node'))
-            ->raw(')')
-        ;
+        $compiler->subcompile($this->getNode('node'));
     }
 
     abstract public function operator(Twig_Compiler $compiler);
--- a/vendor/twig/twig/lib/Twig/Node/Flush.php
+++ b/vendor/twig/twig/lib/Twig/Node/Flush.php
@@ -24,7 +24,7 @@ class Twig_Node_Flush extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/For.php
+++ b/vendor/twig/twig/lib/Twig/Node/For.php
@@ -33,7 +33,7 @@ class Twig_Node_For extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -82,7 +82,7 @@ class Twig_Node_For extends Twig_Node
         $compiler
             ->write("foreach (\$context['_seq'] as ")
             ->subcompile($this->getNode('key_target'))
-            ->raw(" => ")
+            ->raw(' => ')
             ->subcompile($this->getNode('value_target'))
             ->raw(") {\n")
             ->indent()
--- a/vendor/twig/twig/lib/Twig/Node/ForLoop.php
+++ b/vendor/twig/twig/lib/Twig/Node/ForLoop.php
@@ -24,7 +24,7 @@ class Twig_Node_ForLoop extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/If.php
+++ b/vendor/twig/twig/lib/Twig/Node/If.php
@@ -25,16 +25,16 @@ class Twig_Node_If extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
         $compiler->addDebugInfo($this);
-        for ($i = 0; $i < count($this->getNode('tests')); $i += 2) {
+        for ($i = 0, $count = count($this->getNode('tests')); $i < $count; $i += 2) {
             if ($i > 0) {
                 $compiler
                     ->outdent()
-                    ->write("} elseif (")
+                    ->write('} elseif (')
                 ;
             } else {
                 $compiler
--- a/vendor/twig/twig/lib/Twig/Node/Import.php
+++ b/vendor/twig/twig/lib/Twig/Node/Import.php
@@ -24,7 +24,7 @@ class Twig_Node_Import extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -36,12 +36,16 @@ class Twig_Node_Import extends Twig_Node
         ;
 
         if ($this->getNode('expr') instanceof Twig_Node_Expression_Name && '_self' === $this->getNode('expr')->getAttribute('name')) {
-            $compiler->raw("\$this");
+            $compiler->raw('$this');
         } else {
             $compiler
-                ->raw('$this->env->loadTemplate(')
+                ->raw('$this->loadTemplate(')
                 ->subcompile($this->getNode('expr'))
-                ->raw(")")
+                ->raw(', ')
+                ->repr($compiler->getFilename())
+                ->raw(', ')
+                ->repr($this->getLine())
+                ->raw(')')
             ;
         }
 
--- a/vendor/twig/twig/lib/Twig/Node/Include.php
+++ b/vendor/twig/twig/lib/Twig/Node/Include.php
@@ -19,13 +19,13 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
 {
     public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
     {
-        parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag);
+        parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
     }
 
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -60,40 +60,29 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
 
     protected function addGetTemplate(Twig_Compiler $compiler)
     {
-        if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) {
-            $compiler
-                ->write("\$this->env->loadTemplate(")
-                ->subcompile($this->getNode('expr'))
-                ->raw(")")
-            ;
-        } else {
-            $compiler
-                ->write("\$template = \$this->env->resolveTemplate(")
-                ->subcompile($this->getNode('expr'))
-                ->raw(");\n")
-                ->write('$template')
-            ;
-        }
+        $compiler
+             ->write('$this->loadTemplate(')
+             ->subcompile($this->getNode('expr'))
+             ->raw(', ')
+             ->repr($compiler->getFilename())
+             ->raw(', ')
+             ->repr($this->getLine())
+             ->raw(')')
+         ;
     }
 
     protected function addTemplateArguments(Twig_Compiler $compiler)
     {
-        if (false === $this->getAttribute('only')) {
-            if (null === $this->getNode('variables')) {
-                $compiler->raw('$context');
-            } else {
-                $compiler
-                    ->raw('array_merge($context, ')
-                    ->subcompile($this->getNode('variables'))
-                    ->raw(')')
-                ;
-            }
+        if (null === $this->getNode('variables')) {
+            $compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
+        } elseif (false === $this->getAttribute('only')) {
+            $compiler
+                ->raw('array_merge($context, ')
+                ->subcompile($this->getNode('variables'))
+                ->raw(')')
+            ;
         } else {
-            if (null === $this->getNode('variables')) {
-                $compiler->raw('array()');
-            } else {
-                $compiler->subcompile($this->getNode('variables'));
-            }
+            $compiler->subcompile($this->getNode('variables'));
         }
     }
 }
--- a/vendor/twig/twig/lib/Twig/Node/Macro.php
+++ b/vendor/twig/twig/lib/Twig/Node/Macro.php
@@ -16,28 +16,36 @@
  */
 class Twig_Node_Macro extends Twig_Node
 {
+    const VARARGS_NAME = 'varargs';
+
     public function __construct($name, Twig_NodeInterface $body, Twig_NodeInterface $arguments, $lineno, $tag = null)
     {
+        foreach ($arguments as $argumentName => $argument) {
+            if (self::VARARGS_NAME === $argumentName) {
+                throw new Twig_Error_Syntax(sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getLine());
+            }
+        }
+
         parent::__construct(array('body' => $body, 'arguments' => $arguments), array('name' => $name), $lineno, $tag);
     }
 
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
         $compiler
             ->addDebugInfo($this)
-            ->write(sprintf("public function get%s(", $this->getAttribute('name')))
+            ->write(sprintf('public function get%s(', $this->getAttribute('name')))
         ;
 
         $count = count($this->getNode('arguments'));
         $pos = 0;
         foreach ($this->getNode('arguments') as $name => $default) {
             $compiler
-                ->raw('$_'.$name.' = ')
+                ->raw('$__'.$name.'__ = ')
                 ->subcompile($default)
             ;
 
@@ -46,36 +54,55 @@ class Twig_Node_Macro extends Twig_Node
             }
         }
 
+        if (PHP_VERSION_ID >= 50600) {
+            if ($count) {
+                $compiler->raw(', ');
+            }
+
+            $compiler->raw('...$__varargs__');
+        }
+
         $compiler
             ->raw(")\n")
             ->write("{\n")
             ->indent()
         ;
 
-        if (!count($this->getNode('arguments'))) {
-            $compiler->write("\$context = \$this->env->getGlobals();\n\n");
-        } else {
+        $compiler
+            ->write("\$context = \$this->env->mergeGlobals(array(\n")
+            ->indent()
+        ;
+
+        foreach ($this->getNode('arguments') as $name => $default) {
             $compiler
-                ->write("\$context = \$this->env->mergeGlobals(array(\n")
-                ->indent()
+                ->addIndentation()
+                ->string($name)
+                ->raw(' => $__'.$name.'__')
+                ->raw(",\n")
             ;
+        }
 
-            foreach ($this->getNode('arguments') as $name => $default) {
-                $compiler
-                    ->write('')
-                    ->string($name)
-                    ->raw(' => $_'.$name)
-                    ->raw(",\n")
-                ;
-            }
+        $compiler
+            ->addIndentation()
+            ->string(self::VARARGS_NAME)
+            ->raw(' => ')
+        ;
 
+        if (PHP_VERSION_ID >= 50600) {
+            $compiler->raw("\$__varargs__,\n");
+        } else {
             $compiler
-                ->outdent()
-                ->write("));\n\n")
+                ->raw('func_num_args() > ')
+                ->repr($count)
+                ->raw(' ? array_slice(func_get_args(), ')
+                ->repr($count)
+                ->raw(") : array(),\n")
             ;
         }
 
         $compiler
+            ->outdent()
+            ->write("));\n\n")
             ->write("\$blocks = array();\n\n")
             ->write("ob_start();\n")
             ->write("try {\n")
--- a/vendor/twig/twig/lib/Twig/Node/Module.php
+++ b/vendor/twig/twig/lib/Twig/Node/Module.php
@@ -13,6 +13,10 @@
 /**
  * Represents a module node.
  *
+ * Consider this class as being final. If you need to customize the behavior of
+ * the generated class, consider adding nodes to the following nodes: display_start,
+ * display_end, constructor_start, constructor_end, and class_end.
+ *
  * @author Fabien Potencier <fabien@symfony.com>
  */
 class Twig_Node_Module extends Twig_Node
@@ -20,7 +24,22 @@ class Twig_Node_Module extends Twig_Node
     public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename)
     {
         // embedded templates are set as attributes so that they are only visited once by the visitors
-        parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1);
+        parent::__construct(array(
+            'parent' => $parent,
+            'body' => $body,
+            'blocks' => $blocks,
+            'macros' => $macros,
+            'traits' => $traits,
+            'display_start' => new Twig_Node(),
+            'display_end' => new Twig_Node(),
+            'constructor_start' => new Twig_Node(),
+            'constructor_end' => new Twig_Node(),
+            'class_end' => new Twig_Node(),
+        ), array(
+            'filename' => $filename,
+            'index' => null,
+            'embedded_templates' => $embeddedTemplates,
+        ), 1);
     }
 
     public function setIndex($index)
@@ -31,7 +50,7 @@ class Twig_Node_Module extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -50,17 +69,20 @@ class Twig_Node_Module extends Twig_Node
 
         $this->compileClassHeader($compiler);
 
-        if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
+        if (
+            count($this->getNode('blocks'))
+            || count($this->getNode('traits'))
+            || null === $this->getNode('parent')
+            || $this->getNode('parent') instanceof Twig_Node_Expression_Constant
+            || count($this->getNode('constructor_start'))
+            || count($this->getNode('constructor_end'))
+        ) {
             $this->compileConstructor($compiler);
         }
 
         $this->compileGetParent($compiler);
 
-        $this->compileDisplayHeader($compiler);
-
-        $this->compileDisplayBody($compiler);
-
-        $this->compileDisplayFooter($compiler);
+        $this->compileDisplay($compiler);
 
         $compiler->subcompile($this->getNode('blocks'));
 
@@ -77,23 +99,28 @@ class Twig_Node_Module extends Twig_Node
 
     protected function compileGetParent(Twig_Compiler $compiler)
     {
-        if (null === $this->getNode('parent')) {
+        if (null === $parent = $this->getNode('parent')) {
             return;
         }
 
         $compiler
             ->write("protected function doGetParent(array \$context)\n", "{\n")
             ->indent()
-            ->write("return ")
+            ->addDebugInfo($parent)
+            ->write('return ')
         ;
 
-        if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
-            $compiler->subcompile($this->getNode('parent'));
+        if ($parent instanceof Twig_Node_Expression_Constant) {
+            $compiler->subcompile($parent);
         } else {
             $compiler
-                ->raw("\$this->env->resolveTemplate(")
-                ->subcompile($this->getNode('parent'))
-                ->raw(")")
+                ->raw('$this->loadTemplate(')
+                ->subcompile($parent)
+                ->raw(', ')
+                ->repr($compiler->getFilename())
+                ->raw(', ')
+                ->repr($this->getNode('parent')->getLine())
+                ->raw(')')
             ;
         }
 
@@ -104,26 +131,12 @@ class Twig_Node_Module extends Twig_Node
         ;
     }
 
-    protected function compileDisplayBody(Twig_Compiler $compiler)
-    {
-        $compiler->subcompile($this->getNode('body'));
-
-        if (null !== $this->getNode('parent')) {
-            if ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
-                $compiler->write("\$this->parent");
-            } else {
-                $compiler->write("\$this->getParent(\$context)");
-            }
-            $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
-        }
-    }
-
     protected function compileClassHeader(Twig_Compiler $compiler)
     {
         $compiler
             ->write("\n\n")
             // if the filename contains */, add a blank to avoid a PHP parse error
-            ->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
+            ->write('/* '.str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
             ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
             ->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
             ->write("{\n")
@@ -136,17 +149,23 @@ class Twig_Node_Module extends Twig_Node
         $compiler
             ->write("public function __construct(Twig_Environment \$env)\n", "{\n")
             ->indent()
+            ->subcompile($this->getNode('constructor_start'))
             ->write("parent::__construct(\$env);\n\n")
         ;
 
         // parent
-        if (null === $this->getNode('parent')) {
+        if (null === $parent = $this->getNode('parent')) {
             $compiler->write("\$this->parent = false;\n\n");
-        } elseif ($this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
+        } elseif ($parent instanceof Twig_Node_Expression_Constant) {
             $compiler
-                ->write("\$this->parent = \$this->env->loadTemplate(")
-                ->subcompile($this->getNode('parent'))
-                ->raw(");\n\n")
+                ->addDebugInfo($parent)
+                ->write('$this->parent = $this->loadTemplate(')
+                ->subcompile($parent)
+                ->raw(', ')
+                ->repr($compiler->getFilename())
+                ->raw(', ')
+                ->repr($this->getNode('parent')->getLine())
+                ->raw(");\n")
             ;
         }
 
@@ -170,11 +189,23 @@ class Twig_Node_Module extends Twig_Node
 
                 foreach ($trait->getNode('targets') as $key => $value) {
                     $compiler
-                        ->write(sprintf("\$_trait_%s_blocks[", $i))
+                        ->write(sprintf('if (!isset($_trait_%s_blocks[', $i))
+                        ->string($key)
+                        ->raw("])) {\n")
+                        ->indent()
+                        ->write("throw new Twig_Error_Runtime(sprintf('Block ")
+                        ->string($key)
+                        ->raw(' is not defined in trait ')
+                        ->subcompile($trait->getNode('template'))
+                        ->raw(".'));\n")
+                        ->outdent()
+                        ->write("}\n\n")
+
+                        ->write(sprintf('$_trait_%s_blocks[', $i))
                         ->subcompile($value)
-                        ->raw(sprintf("] = \$_trait_%s_blocks[", $i))
+                        ->raw(sprintf('] = $_trait_%s_blocks[', $i))
                         ->string($key)
-                        ->raw(sprintf("]; unset(\$_trait_%s_blocks[", $i))
+                        ->raw(sprintf(']; unset($_trait_%s_blocks[', $i))
                         ->string($key)
                         ->raw("]);\n\n")
                     ;
@@ -187,9 +218,9 @@ class Twig_Node_Module extends Twig_Node
                     ->indent()
                 ;
 
-                for ($i = 0; $i < $countTraits; $i++) {
+                for ($i = 0; $i < $countTraits; ++$i) {
                     $compiler
-                        ->write(sprintf("\$_trait_%s_blocks".($i == $countTraits - 1 ? '' : ',')."\n", $i))
+                        ->write(sprintf('$_trait_%s_blocks'.($i == $countTraits - 1 ? '' : ',')."\n", $i))
                     ;
                 }
 
@@ -237,21 +268,32 @@ class Twig_Node_Module extends Twig_Node
             ->outdent()
             ->write(");\n")
             ->outdent()
-            ->write("}\n\n");
+            ->subcompile($this->getNode('constructor_end'))
+            ->write("}\n\n")
         ;
     }
 
-    protected function compileDisplayHeader(Twig_Compiler $compiler)
+    protected function compileDisplay(Twig_Compiler $compiler)
     {
         $compiler
             ->write("protected function doDisplay(array \$context, array \$blocks = array())\n", "{\n")
             ->indent()
+            ->subcompile($this->getNode('display_start'))
+            ->subcompile($this->getNode('body'))
         ;
-    }
 
-    protected function compileDisplayFooter(Twig_Compiler $compiler)
-    {
+        if (null !== $parent = $this->getNode('parent')) {
+            $compiler->addDebugInfo($parent);
+            if ($parent instanceof Twig_Node_Expression_Constant) {
+                $compiler->write('$this->parent');
+            } else {
+                $compiler->write('$this->getParent($context)');
+            }
+            $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
+        }
+
         $compiler
+            ->subcompile($this->getNode('display_end'))
             ->outdent()
             ->write("}\n\n")
         ;
@@ -260,6 +302,7 @@ class Twig_Node_Module extends Twig_Node
     protected function compileClassFooter(Twig_Compiler $compiler)
     {
         $compiler
+            ->subcompile($this->getNode('class_end'))
             ->outdent()
             ->write("}\n")
         ;
@@ -350,19 +393,28 @@ class Twig_Node_Module extends Twig_Node
     {
         if ($node instanceof Twig_Node_Expression_Constant) {
             $compiler
-                ->write(sprintf("%s = \$this->env->loadTemplate(", $var))
+                ->write(sprintf('%s = $this->loadTemplate(', $var))
                 ->subcompile($node)
+                ->raw(', ')
+                ->repr($compiler->getFilename())
+                ->raw(', ')
+                ->repr($node->getLine())
                 ->raw(");\n")
             ;
         } else {
             $compiler
-                ->write(sprintf("%s = ", $var))
+                ->write(sprintf('%s = ', $var))
                 ->subcompile($node)
                 ->raw(";\n")
-                ->write(sprintf("if (!%s", $var))
+                ->write(sprintf('if (!%s', $var))
                 ->raw(" instanceof Twig_Template) {\n")
                 ->indent()
-                ->write(sprintf("%s = \$this->env->loadTemplate(%s);\n", $var, $var))
+                ->write(sprintf('%s = $this->loadTemplate(%s')
+                ->raw(', ')
+                ->repr($compiler->getFilename())
+                ->raw(', ')
+                ->repr($node->getLine())
+                ->raw(");\n", $var, $var))
                 ->outdent()
                 ->write("}\n")
             ;
--- a/vendor/twig/twig/lib/Twig/Node/Print.php
+++ b/vendor/twig/twig/lib/Twig/Node/Print.php
@@ -25,7 +25,7 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/Node/Sandbox.php
@@ -24,7 +24,7 @@ class Twig_Node_Sandbox extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
+++ b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
@@ -29,7 +29,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
@@ -47,6 +47,8 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
      * This is mostly needed when another visitor adds filters (like the escaper one).
      *
      * @param Twig_Node $node A Node
+     *
+     * @return Twig_Node
      */
     protected function removeNodeFilter($node)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Set.php
+++ b/vendor/twig/twig/lib/Twig/Node/Set.php
@@ -39,7 +39,7 @@ class Twig_Node_Set extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Spaceless.php
+++ b/vendor/twig/twig/lib/Twig/Node/Spaceless.php
@@ -26,7 +26,7 @@ class Twig_Node_Spaceless extends Twig_Node
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/Node/Text.php
+++ b/vendor/twig/twig/lib/Twig/Node/Text.php
@@ -25,7 +25,7 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler)
     {
--- a/vendor/twig/twig/lib/Twig/NodeInterface.php
+++ b/vendor/twig/twig/lib/Twig/NodeInterface.php
@@ -13,14 +13,15 @@
  * Represents a node in the AST.
  *
  * @author Fabien Potencier <fabien@symfony.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_NodeInterface extends Countable, IteratorAggregate
 {
     /**
      * Compiles the node to PHP.
      *
-     * @param Twig_Compiler A Twig_Compiler instance
+     * @param Twig_Compiler $compiler A Twig_Compiler instance
      */
     public function compile(Twig_Compiler $compiler);
 
--- a/vendor/twig/twig/lib/Twig/NodeTraverser.php
+++ b/vendor/twig/twig/lib/Twig/NodeTraverser.php
@@ -12,7 +12,7 @@
 /**
  * Twig_NodeTraverser is a node traverser.
  *
- * It visits all nodes and their children and call the given visitor for each.
+ * It visits all nodes and their children and calls the given visitor for each.
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */
@@ -24,8 +24,8 @@ class Twig_NodeTraverser
     /**
      * Constructor.
      *
-     * @param Twig_Environment $env      A Twig_Environment instance
-     * @param array            $visitors An array of Twig_NodeVisitorInterface instances
+     * @param Twig_Environment            $env      A Twig_Environment instance
+     * @param Twig_NodeVisitorInterface[] $visitors An array of Twig_NodeVisitorInterface instances
      */
     public function __construct(Twig_Environment $env, array $visitors = array())
     {
@@ -54,6 +54,8 @@ class Twig_NodeTraverser
      * Traverses a node and calls the registered visitors.
      *
      * @param Twig_NodeInterface $node A Twig_NodeInterface instance
+     *
+     * @return Twig_NodeInterface
      */
     public function traverse(Twig_NodeInterface $node)
     {
@@ -70,7 +72,7 @@ class Twig_NodeTraverser
     protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null)
     {
         if (null === $node) {
-            return null;
+            return;
         }
 
         $node = $visitor->enterNode($node, $this->env);
--- a/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
@@ -14,7 +14,7 @@
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */
-class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
+class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
 {
     protected $statusStack = array();
     protected $blocks = array();
@@ -29,14 +29,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
     }
 
     /**
-     * Called before child nodes are visited.
-     *
-     * @param Twig_NodeInterface $node The node to visit
-     * @param Twig_Environment   $env  The Twig environment instance
-     *
-     * @return Twig_NodeInterface The modified node
+     * {@inheritdoc}
      */
-    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Module) {
             if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) {
@@ -55,14 +50,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
     }
 
     /**
-     * Called after child nodes are visited.
-     *
-     * @param Twig_NodeInterface $node The node to visit
-     * @param Twig_Environment   $env  The Twig environment instance
-     *
-     * @return Twig_NodeInterface The modified node
+     * {@inheritdoc}
      */
-    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Module) {
             $this->defaultStrategy = false;
--- a/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
@@ -19,15 +19,16 @@
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */
-class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
+class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
 {
-    const OPTIMIZE_ALL         = -1;
-    const OPTIMIZE_NONE        = 0;
-    const OPTIMIZE_FOR         = 2;
-    const OPTIMIZE_RAW_FILTER  = 4;
-    const OPTIMIZE_VAR_ACCESS  = 8;
+    const OPTIMIZE_ALL = -1;
+    const OPTIMIZE_NONE = 0;
+    const OPTIMIZE_FOR = 2;
+    const OPTIMIZE_RAW_FILTER = 4;
+    const OPTIMIZE_VAR_ACCESS = 8;
 
     protected $loops = array();
+    protected $loopsTargets = array();
     protected $optimizers;
     protected $prependedNodes = array();
     protected $inABody = false;
@@ -35,11 +36,11 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
     /**
      * Constructor.
      *
-     * @param integer $optimizers The optimizer mode
+     * @param int $optimizers The optimizer mode
      */
     public function __construct($optimizers = -1)
     {
-        if (!is_int($optimizers) || $optimizers > 2) {
+        if (!is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
             throw new InvalidArgumentException(sprintf('Optimizer mode "%s" is not valid.', $optimizers));
         }
 
@@ -49,13 +50,13 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
     /**
      * {@inheritdoc}
      */
-    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
     {
         if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
             $this->enterOptimizeFor($node, $env);
         }
 
-        if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
+        if (PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
             if ($this->inABody) {
                 if (!$node instanceof Twig_Node_Expression) {
                     if (get_class($node) !== 'Twig_Node') {
@@ -75,7 +76,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
     /**
      * {@inheritdoc}
      */
-    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
     {
         $expression = $node instanceof Twig_Node_Expression;
 
@@ -108,7 +109,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
         return $node;
     }
 
-    protected function optimizeVariables($node, $env)
+    protected function optimizeVariables(Twig_NodeInterface $node, Twig_Environment $env)
     {
         if ('Twig_Node_Expression_Name' === get_class($node) && $node->isSimple()) {
             $this->prependedNodes[0][] = $node->getAttribute('name');
@@ -128,8 +129,10 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
      *
      * @param Twig_NodeInterface $node A Node
      * @param Twig_Environment   $env  The current Twig environment
+     *
+     * @return Twig_NodeInterface
      */
-    protected function optimizePrintNode($node, $env)
+    protected function optimizePrintNode(Twig_NodeInterface $node, Twig_Environment $env)
     {
         if (!$node instanceof Twig_Node_Print) {
             return $node;
@@ -152,8 +155,10 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
      *
      * @param Twig_NodeInterface $node A Node
      * @param Twig_Environment   $env  The current Twig environment
+     *
+     * @return Twig_NodeInterface
      */
-    protected function optimizeRawFilter($node, $env)
+    protected function optimizeRawFilter(Twig_NodeInterface $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Expression_Filter && 'raw' == $node->getNode('filter')->getAttribute('value')) {
             return $node->getNode('node');
@@ -168,12 +173,14 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
      * @param Twig_NodeInterface $node A Node
      * @param Twig_Environment   $env  The current Twig environment
      */
-    protected function enterOptimizeFor($node, $env)
+    protected function enterOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_For) {
             // disable the loop variable by default
             $node->setAttribute('with_loop', false);
             array_unshift($this->loops, $node);
+            array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
+            array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
         } elseif (!$this->loops) {
             // we are outside a loop
             return;
@@ -183,9 +190,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
 
         // the loop variable is referenced for the current loop
         elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
+            $node->setAttribute('always_defined', true);
             $this->addLoopToCurrent();
         }
 
+        // optimize access to loop targets
+        elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) {
+            $node->setAttribute('always_defined', true);
+        }
+
         // block reference
         elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
             $this->addLoopToCurrent();
@@ -196,6 +209,16 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
             $this->addLoopToAll();
         }
 
+        // include function without the with_context=false parameter
+        elseif ($node instanceof Twig_Node_Expression_Function
+            && 'include' === $node->getAttribute('name')
+            && (!$node->getNode('arguments')->hasNode('with_context')
+                 || false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value')
+               )
+        ) {
+            $this->addLoopToAll();
+        }
+
         // the loop variable is referenced via an attribute
         elseif ($node instanceof Twig_Node_Expression_GetAttr
             && (!$node->getNode('attribute') instanceof Twig_Node_Expression_Constant
@@ -217,10 +240,12 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
      * @param Twig_NodeInterface $node A Node
      * @param Twig_Environment   $env  The current Twig environment
      */
-    protected function leaveOptimizeFor($node, $env)
+    protected function leaveOptimizeFor(Twig_NodeInterface $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_For) {
             array_shift($this->loops);
+            array_shift($this->loopsTargets);
+            array_shift($this->loopsTargets);
         }
     }
 
--- a/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
@@ -1,6 +1,15 @@
 <?php
 
-class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
+/*
+ * This file is part of Twig.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
 {
     protected $data = array();
     protected $safeVars = array();
@@ -13,12 +22,20 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
     public function getSafe(Twig_NodeInterface $node)
     {
         $hash = spl_object_hash($node);
-        if (isset($this->data[$hash])) {
-            foreach ($this->data[$hash] as $bucket) {
-                if ($bucket['key'] === $node) {
-                    return $bucket['value'];
-                }
+        if (!isset($this->data[$hash])) {
+            return;
+        }
+
+        foreach ($this->data[$hash] as $bucket) {
+            if ($bucket['key'] !== $node) {
+                continue;
+            }
+
+            if (in_array('html_attr', $bucket['value'])) {
+                $bucket['value'][] = 'html';
             }
+
+            return $bucket['value'];
         }
     }
 
@@ -40,12 +57,18 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
         );
     }
 
-    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    /**
+     * {@inheritdoc}
+     */
+    protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
     {
         return $node;
     }
 
-    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    /**
+     * {@inheritdoc}
+     */
+    protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Expression_Constant) {
             // constants are marked safe for all
--- a/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
@@ -14,7 +14,7 @@
  *
  * @author Fabien Potencier <fabien@symfony.com>
  */
-class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
+class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
 {
     protected $inAModule = false;
     protected $tags;
@@ -22,14 +22,9 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
     protected $functions;
 
     /**
-     * Called before child nodes are visited.
-     *
-     * @param Twig_NodeInterface $node The node to visit
-     * @param Twig_Environment   $env  The Twig environment instance
-     *
-     * @return Twig_NodeInterface The modified node
+     * {@inheritdoc}
      */
-    public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Module) {
             $this->inAModule = true;
@@ -40,18 +35,18 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
             return $node;
         } elseif ($this->inAModule) {
             // look for tags
-            if ($node->getNodeTag()) {
-                $this->tags[] = $node->getNodeTag();
+            if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) {
+                $this->tags[$node->getNodeTag()] = $node;
             }
 
             // look for filters
-            if ($node instanceof Twig_Node_Expression_Filter) {
-                $this->filters[] = $node->getNode('filter')->getAttribute('value');
+            if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
+                $this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
             }
 
             // look for functions
-            if ($node instanceof Twig_Node_Expression_Function) {
-                $this->functions[] = $node->getAttribute('name');
+            if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) {
+                $this->functions[$node->getAttribute('name')] = $node;
             }
 
             // wrap print to check __toString() calls
@@ -64,19 +59,14 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
     }
 
     /**
-     * Called after child nodes are visited.
-     *
-     * @param Twig_NodeInterface $node The node to visit
-     * @param Twig_Environment   $env  The Twig environment instance
-     *
-     * @return Twig_NodeInterface The modified node
+     * {@inheritdoc}
      */
-    public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
+    protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
     {
         if ($node instanceof Twig_Node_Module) {
             $this->inAModule = false;
 
-            return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions));
+            $node->setNode('display_start', new Twig_Node(array(new Twig_Node_CheckSecurity($this->filters, $this->tags, $this->functions), $node->getNode('display_start'))));
         }
 
         return $node;
--- a/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php
@@ -41,7 +41,7 @@ interface Twig_NodeVisitorInterface
      *
      * Priority should be between -10 and 10 (0 is the default).
      *
-     * @return integer The priority level
+     * @return int The priority level
      */
     public function getPriority();
 }
--- a/vendor/twig/twig/lib/Twig/Parser.php
+++ b/vendor/twig/twig/lib/Twig/Parser.php
@@ -49,7 +49,7 @@ class Twig_Parser implements Twig_ParserInterface
 
     public function getVarName()
     {
-        return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false));
+        return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
     }
 
     public function getFilename()
@@ -58,11 +58,7 @@ class Twig_Parser implements Twig_ParserInterface
     }
 
     /**
-     * Converts a token stream to a node tree.
-     *
-     * @param Twig_TokenStream $stream A token stream instance
-     *
-     * @return Twig_Node_Module A node tree
+     * {@inheritdoc}
      */
     public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
     {
@@ -246,7 +242,7 @@ class Twig_Parser implements Twig_ParserInterface
         return $this->blocks[$name];
     }
 
-    public function setBlock($name, $value)
+    public function setBlock($name, Twig_Node_Block $value)
     {
         $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
     }
@@ -258,19 +254,28 @@ class Twig_Parser implements Twig_ParserInterface
 
     public function setMacro($name, Twig_Node_Macro $node)
     {
+        if ($this->isReservedMacroName($name)) {
+            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
+        }
+
+        $this->macros[$name] = $node;
+    }
+
+    public function isReservedMacroName($name)
+    {
         if (null === $this->reservedMacroNames) {
             $this->reservedMacroNames = array();
             $r = new ReflectionClass($this->env->getBaseTemplateClass());
             foreach ($r->getMethods() as $method) {
-                $this->reservedMacroNames[] = $method->getName();
-            }
-        }
+                $methodName = strtolower($method->getName());
 
-        if (in_array($name, $this->reservedMacroNames)) {
-            throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
+                if ('get' === substr($methodName, 0, 3) && isset($methodName[3])) {
+                    $this->reservedMacroNames[] = substr($methodName, 3);
+                }
+            }
         }
 
-        $this->macros[$name] = $node;
+        return in_array(strtolower($name), $this->reservedMacroNames);
     }
 
     public function addTrait($trait)
@@ -384,7 +389,7 @@ class Twig_Parser implements Twig_ParserInterface
         }
 
         foreach ($node as $k => $n) {
-            if (null !== $n && null === $n = $this->filterBodyNodes($n)) {
+            if (null !== $n && null === $this->filterBodyNodes($n)) {
                 $node->removeNode($k);
             }
         }
--- a/vendor/twig/twig/lib/Twig/ParserInterface.php
+++ b/vendor/twig/twig/lib/Twig/ParserInterface.php
@@ -13,7 +13,8 @@
  * Interface implemented by parser classes.
  *
  * @author Fabien Potencier <fabien@symfony.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_ParserInterface
 {
@@ -23,6 +24,8 @@ interface Twig_ParserInterface
      * @param Twig_TokenStream $stream A token stream instance
      *
      * @return Twig_Node_Module A node tree
+     *
+     * @throws Twig_Error_Syntax When the token stream is syntactically or semantically wrong
      */
     public function parse(Twig_TokenStream $stream);
 }
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Dumper_Blackfire
+{
+    public function dump(Twig_Profiler_Profile $profile)
+    {
+        $data = array();
+        $this->dumpProfile('main()', $profile, $data);
+        $this->dumpChildren('main()', $profile, $data);
+
+        $start = microtime(true);
+        $str = <<<EOF
+file-format: BlackfireProbe
+cost-dimensions: wt mu pmu
+request-start: {$start}
+
+
+EOF;
+
+        foreach ($data as $name => $values) {
+            $str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n";
+        }
+
+        return $str;
+    }
+
+    private function dumpChildren($parent, Twig_Profiler_Profile $profile, &$data)
+    {
+        foreach ($profile as $p) {
+            if ($p->isTemplate()) {
+                $name = $p->getTemplate();
+            } else {
+                $name = sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName());
+            }
+            $this->dumpProfile(sprintf('%s==>%s', $parent, $name), $p, $data);
+            $this->dumpChildren($name, $p, $data);
+        }
+    }
+
+    private function dumpProfile($edge, Twig_Profiler_Profile $profile, &$data)
+    {
+        if (isset($data[$edge])) {
+            $data[$edge]['ct'] += 1;
+            $data[$edge]['wt'] += floor($profile->getDuration() * 1000000);
+            $data[$edge]['mu'] += $profile->getMemoryUsage();
+            $data[$edge]['pmu'] += $profile->getPeakMemoryUsage();
+        } else {
+            $data[$edge] = array(
+                'ct' => 1,
+                'wt' => floor($profile->getDuration() * 1000000),
+                'mu' => $profile->getMemoryUsage(),
+                'pmu' => $profile->getPeakMemoryUsage(),
+            );
+        }
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text
+{
+    private static $colors = array(
+        'block' => '#dfd',
+        'macro' => '#ddf',
+        'template' => '#ffd',
+        'big' => '#d44',
+    );
+
+    public function dump(Twig_Profiler_Profile $profile)
+    {
+        return '<pre>'.parent::dump($profile).'</pre>';
+    }
+
+    protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
+    {
+        return sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate());
+    }
+
+    protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix)
+    {
+        return sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
+    }
+
+    protected function formatTime(Twig_Profiler_Profile $profile, $percent)
+    {
+        return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Dumper_Text
+{
+    private $root;
+
+    public function dump(Twig_Profiler_Profile $profile)
+    {
+        return $this->dumpProfile($profile);
+    }
+
+    protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
+    {
+        return sprintf('%s└ %s', $prefix, $profile->getTemplate());
+    }
+
+    protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix)
+    {
+        return sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
+    }
+
+    protected function formatTime(Twig_Profiler_Profile $profile, $percent)
+    {
+        return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
+    }
+
+    private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
+    {
+        if ($profile->isRoot()) {
+            $this->root = $profile->getDuration();
+            $start = $profile->getName();
+        } else {
+            if ($profile->isTemplate()) {
+                $start = $this->formatTemplate($profile, $prefix);
+            } else {
+                $start = $this->formatNonTemplate($profile, $prefix);
+            }
+            $prefix .= $sibling ? '│ ' : '  ';
+        }
+
+        $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
+
+        if ($profile->getDuration() * 1000 < 1) {
+            $str = $start."\n";
+        } else {
+            $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
+        }
+
+        $nCount = count($profile->getProfiles());
+        foreach ($profile as $i => $p) {
+            $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
+        }
+
+        return $str;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a profile enter node.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Node_EnterProfile extends Twig_Node
+{
+    public function __construct($extensionName, $type, $name, $varName)
+    {
+        parent::__construct(array(), array('extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write(sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))
+            ->repr($this->getAttribute('extension_name'))
+            ->raw(");\n")
+            ->write(sprintf('$%s->enter($%s = new Twig_Profiler_Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
+            ->repr($this->getAttribute('type'))
+            ->raw(', ')
+            ->repr($this->getAttribute('name'))
+            ->raw("));\n\n")
+        ;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php
@@ -0,0 +1,34 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Represents a profile leave node.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Node_LeaveProfile extends Twig_Node
+{
+    public function __construct($varName)
+    {
+        parent::__construct(array(), array('var_name' => $varName));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function compile(Twig_Compiler $compiler)
+    {
+        $compiler
+            ->write("\n")
+            ->write(sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name').'_prof'))
+        ;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php
@@ -0,0 +1,72 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
+{
+    private $extensionName;
+
+    public function __construct($extensionName)
+    {
+        $this->extensionName = $extensionName;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doEnterNode(Twig_Node $node, Twig_Environment $env)
+    {
+        return $node;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doLeaveNode(Twig_Node $node, Twig_Environment $env)
+    {
+        if ($node instanceof Twig_Node_Module) {
+            $varName = $this->getVarName();
+            $node->setNode('display_start', new Twig_Node(array(new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::TEMPLATE, $node->getAttribute('filename'), $varName), $node->getNode('display_start'))));
+            $node->setNode('display_end', new Twig_Node(array(new Twig_Profiler_Node_LeaveProfile($varName), $node->getNode('display_end'))));
+        } elseif ($node instanceof Twig_Node_Block) {
+            $varName = $this->getVarName();
+            $node->setNode('body', new Twig_Node_Body(array(
+                new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::BLOCK, $node->getAttribute('name'), $varName),
+                $node->getNode('body'),
+                new Twig_Profiler_Node_LeaveProfile($varName),
+            )));
+        } elseif ($node instanceof Twig_Node_Macro) {
+            $varName = $this->getVarName();
+            $node->setNode('body', new Twig_Node_Body(array(
+                new Twig_Profiler_Node_EnterProfile($this->extensionName, Twig_Profiler_Profile::MACRO, $node->getAttribute('name'), $varName),
+                $node->getNode('body'),
+                new Twig_Profiler_Node_LeaveProfile($varName),
+            )));
+        }
+
+        return $node;
+    }
+
+    private function getVarName()
+    {
+        return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPriority()
+    {
+        return 0;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Profiler/Profile.php
@@ -0,0 +1,150 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2015 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Twig_Profiler_Profile implements IteratorAggregate, Serializable
+{
+    const ROOT = 'ROOT';
+    const BLOCK = 'block';
+    const TEMPLATE = 'template';
+    const MACRO = 'macro';
+
+    private $template;
+    private $name;
+    private $type;
+    private $starts = array();
+    private $ends = array();
+    private $profiles = array();
+
+    public function __construct($template = 'main', $type = self::ROOT, $name = 'main')
+    {
+        $this->template = $template;
+        $this->type = $type;
+        $this->name = 0 === strpos($name, '__internal_') ? 'INTERNAL' : $name;
+        $this->enter();
+    }
+
+    public function getTemplate()
+    {
+        return $this->template;
+    }
+
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    public function isRoot()
+    {
+        return self::ROOT === $this->type;
+    }
+
+    public function isTemplate()
+    {
+        return self::TEMPLATE === $this->type;
+    }
+
+    public function isBlock()
+    {
+        return self::BLOCK === $this->type;
+    }
+
+    public function isMacro()
+    {
+        return self::MACRO === $this->type;
+    }
+
+    public function getProfiles()
+    {
+        return $this->profiles;
+    }
+
+    public function addProfile(Twig_Profiler_Profile $profile)
+    {
+        $this->profiles[] = $profile;
+    }
+
+    /**
+     * Returns the duration in microseconds.
+     *
+     * @return int
+     */
+    public function getDuration()
+    {
+        return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0;
+    }
+
+    /**
+     * Returns the memory usage in bytes.
+     *
+     * @return int
+     */
+    public function getMemoryUsage()
+    {
+        return isset($this->ends['mu']) && isset($this->starts['mu']) ? $this->ends['mu'] - $this->starts['mu'] : 0;
+    }
+
+    /**
+     * Returns the peak memory usage in bytes.
+     *
+     * @return int
+     */
+    public function getPeakMemoryUsage()
+    {
+        return isset($this->ends['pmu']) && isset($this->starts['pmu']) ? $this->ends['pmu'] - $this->starts['pmu'] : 0;
+    }
+
+    /**
+     * Starts the profiling.
+     */
+    public function enter()
+    {
+        $this->starts = array(
+            'wt' => microtime(true),
+            'mu' => memory_get_usage(),
+            'pmu' => memory_get_peak_usage(),
+        );
+    }
+
+    /**
+     * Stops the profiling.
+     */
+    public function leave()
+    {
+        $this->ends = array(
+            'wt' => microtime(true),
+            'mu' => memory_get_usage(),
+            'pmu' => memory_get_peak_usage(),
+        );
+    }
+
+    public function getIterator()
+    {
+        return new ArrayIterator($this->profiles);
+    }
+
+    public function serialize()
+    {
+        return serialize(array($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles));
+    }
+
+    public function unserialize($data)
+    {
+        list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = unserialize($data);
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when a not allowed filter is used in a template.
+ *
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityError
+{
+    private $filterName;
+
+    public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null)
+    {
+        parent::__construct($message, $lineno, $filename, $previous);
+        $this->filterName = $functionName;
+    }
+
+    public function getFilterName()
+    {
+        return $this->filterName;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when a not allowed function is used in a template.
+ *
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_SecurityError
+{
+    private $functionName;
+
+    public function __construct($message, $functionName, $lineno = -1, $filename = null, Exception $previous = null)
+    {
+        parent::__construct($message, $lineno, $filename, $previous);
+        $this->functionName = $functionName;
+    }
+
+    public function getFunctionName()
+    {
+        return $this->functionName;
+    }
+}
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of Twig.
+ *
+ * (c) 2009 Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Exception thrown when a not allowed tag is used in a template.
+ *
+ * @author Martin Hasoň <martin.hason@gmail.com>
+ */
+class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError
+{
+    private $tagName;
+
+    public function __construct($message, $tagName, $lineno = -1, $filename = null, Exception $previous = null)
+    {
+        parent::__construct($message, $lineno, $filename, $previous);
+        $this->tagName = $tagName;
+    }
+
+    public function getTagName()
+    {
+        return $this->tagName;
+    }
+}
--- a/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
@@ -63,19 +63,19 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
     {
         foreach ($tags as $tag) {
             if (!in_array($tag, $this->allowedTags)) {
-                throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag));
+                throw new Twig_Sandbox_SecurityNotAllowedTagError(sprintf('Tag "%s" is not allowed.', $tag), $tag);
             }
         }
 
         foreach ($filters as $filter) {
             if (!in_array($filter, $this->allowedFilters)) {
-                throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter));
+                throw new Twig_Sandbox_SecurityNotAllowedFilterError(sprintf('Filter "%s" is not allowed.', $filter), $filter);
             }
         }
 
         foreach ($functions as $function) {
             if (!in_array($function, $this->allowedFunctions)) {
-                throw new Twig_Sandbox_SecurityError(sprintf('Function "%s" is not allowed.', $function));
+                throw new Twig_Sandbox_SecurityNotAllowedFunctionError(sprintf('Function "%s" is not allowed.', $function), $function);
             }
         }
     }
--- a/vendor/twig/twig/lib/Twig/SimpleFilter.php
+++ b/vendor/twig/twig/lib/Twig/SimpleFilter.php
@@ -27,12 +27,13 @@ class Twig_SimpleFilter
         $this->callable = $callable;
         $this->options = array_merge(array(
             'needs_environment' => false,
-            'needs_context'     => false,
-            'is_safe'           => null,
-            'is_safe_callback'  => null,
-            'pre_escape'        => null,
-            'preserves_safety'  => null,
-            'node_class'        => 'Twig_Node_Expression_Filter',
+            'needs_context' => false,
+            'is_variadic' => false,
+            'is_safe' => null,
+            'is_safe_callback' => null,
+            'pre_escape' => null,
+            'preserves_safety' => null,
+            'node_class' => 'Twig_Node_Expression_Filter',
         ), $options);
     }
 
@@ -91,4 +92,9 @@ class Twig_SimpleFilter
     {
         return $this->options['pre_escape'];
     }
+
+    public function isVariadic()
+    {
+        return $this->options['is_variadic'];
+    }
 }
--- a/vendor/twig/twig/lib/Twig/SimpleFunction.php
+++ b/vendor/twig/twig/lib/Twig/SimpleFunction.php
@@ -27,10 +27,11 @@ class Twig_SimpleFunction
         $this->callable = $callable;
         $this->options = array_merge(array(
             'needs_environment' => false,
-            'needs_context'     => false,
-            'is_safe'           => null,
-            'is_safe_callback'  => null,
-            'node_class'        => 'Twig_Node_Expression_Function',
+            'needs_context' => false,
+            'is_variadic' => false,
+            'is_safe' => null,
+            'is_safe_callback' => null,
+            'node_class' => 'Twig_Node_Expression_Function',
         ), $options);
     }
 
@@ -81,4 +82,9 @@ class Twig_SimpleFunction
 
         return array();
     }
+
+    public function isVariadic()
+    {
+        return $this->options['is_variadic'];
+    }
 }
--- a/vendor/twig/twig/lib/Twig/SimpleTest.php
+++ b/vendor/twig/twig/lib/Twig/SimpleTest.php
@@ -25,6 +25,7 @@ class Twig_SimpleTest
         $this->name = $name;
         $this->callable = $callable;
         $this->options = array_merge(array(
+            'is_variadic' => false,
             'node_class' => 'Twig_Node_Expression_Test',
         ), $options);
     }
@@ -43,4 +44,9 @@ class Twig_SimpleTest
     {
         return $this->options['node_class'];
     }
+
+    public function isVariadic()
+    {
+        return $this->options['is_variadic'];
+    }
 }
--- a/vendor/twig/twig/lib/Twig/Template.php
+++ b/vendor/twig/twig/lib/Twig/Template.php
@@ -20,7 +20,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
     protected static $cache = array();
 
     protected $parent;
-    protected $parents;
+    protected $parents = array();
     protected $env;
     protected $blocks;
     protected $traits;
@@ -45,10 +45,12 @@ abstract class Twig_Template implements Twig_TemplateInterface
     abstract public function getTemplateName();
 
     /**
-     * {@inheritdoc}
+     * @deprecated since 1.20 (to be removed in 2.0)
      */
     public function getEnvironment()
     {
+        @trigger_error('The '.__METHOD__.' method is deprecated since version 1.20 and will be removed in 2.0.', E_USER_DEPRECATED);
+
         return $this->env;
     }
 
@@ -58,6 +60,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
      * This method is for internal use only and should never be called
      * directly.
      *
+     * @param array $context
+     *
      * @return Twig_TemplateInterface|false The parent template or false if there is no parent
      */
     public function getParent(array $context)
@@ -66,15 +70,25 @@ abstract class Twig_Template implements Twig_TemplateInterface
             return $this->parent;
         }
 
-        $parent = $this->doGetParent($context);
-        if (false === $parent) {
-            return false;
-        } elseif ($parent instanceof Twig_Template) {
-            $name = $parent->getTemplateName();
-            $this->parents[$name] = $parent;
-            $parent = $name;
-        } elseif (!isset($this->parents[$parent])) {
-            $this->parents[$parent] = $this->env->loadTemplate($parent);
+        try {
+            $parent = $this->doGetParent($context);
+
+            if (false === $parent) {
+                return false;
+            }
+
+            if ($parent instanceof self) {
+                return $this->parents[$parent->getTemplateName()] = $parent;
+            }
+
+            if (!isset($this->parents[$parent])) {
+                $this->parents[$parent] = $this->loadTemplate($parent);
+            }
+        } catch (Twig_Error_Loader $e) {
+            $e->setTemplateFile(null);
+            $e->guess();
+
+            throw $e;
         }
 
         return $this->parents[$parent];
@@ -105,9 +119,9 @@ abstract class Twig_Template implements Twig_TemplateInterface
         $name = (string) $name;
 
         if (isset($this->traits[$name])) {
-            $this->traits[$name][0]->displayBlock($name, $context, $blocks);
+            $this->traits[$name][0]->displayBlock($name, $context, $blocks, false);
         } elseif (false !== $parent = $this->getParent($context)) {
-            $parent->displayBlock($name, $context, $blocks);
+            $parent->displayBlock($name, $context, $blocks, false);
         } else {
             throw new Twig_Error_Runtime(sprintf('The template has no parent and no traits defining the "%s" block', $name), -1, $this->getTemplateName());
         }
@@ -119,22 +133,52 @@ abstract class Twig_Template implements Twig_TemplateInterface
      * This method is for internal use only and should never be called
      * directly.
      *
-     * @param string $name    The block name to display
-     * @param array  $context The context
-     * @param array  $blocks  The current set of blocks
+     * @param string $name      The block name to display
+     * @param array  $context   The context
+     * @param array  $blocks    The current set of blocks
+     * @param bool   $useBlocks Whether to use the current set of blocks
      */
-    public function displayBlock($name, array $context, array $blocks = array())
+    public function displayBlock($name, array $context, array $blocks = array(), $useBlocks = true)
     {
         $name = (string) $name;
 
-        if (isset($blocks[$name])) {
-            $b = $blocks;
-            unset($b[$name]);
-            call_user_func($blocks[$name], $context, $b);
+        if ($useBlocks && isset($blocks[$name])) {
+            $template = $blocks[$name][0];
+            $block = $blocks[$name][1];
         } elseif (isset($this->blocks[$name])) {
-            call_user_func($this->blocks[$name], $context, $blocks);
+            $template = $this->blocks[$name][0];
+            $block = $this->blocks[$name][1];
+        } else {
+            $template = null;
+            $block = null;
+        }
+
+        if (null !== $template) {
+            // avoid RCEs when sandbox is enabled
+            if (!$template instanceof Twig_Template) {
+                throw new \LogicException('A block must be a method on a Twig_Template instance.');
+            }
+
+            try {
+                $template->$block($context, $blocks);
+            } catch (Twig_Error $e) {
+                if (!$e->getTemplateFile()) {
+                    $e->setTemplateFile($template->getTemplateName());
+                }
+
+                // this is mostly useful for Twig_Error_Loader exceptions
+                // see Twig_Error_Loader
+                if (false === $e->getTemplateLine()) {
+                    $e->setTemplateLine(-1);
+                    $e->guess();
+                }
+
+                throw $e;
+            } catch (Exception $e) {
+                throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getTemplateName(), $e);
+            }
         } elseif (false !== $parent = $this->getParent($context)) {
-            $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks));
+            $parent->displayBlock($name, $context, array_merge($this->blocks, $blocks), false);
         }
     }
 
@@ -164,16 +208,17 @@ abstract class Twig_Template implements Twig_TemplateInterface
      * This method is for internal use only and should never be called
      * directly.
      *
-     * @param string $name    The block name to render
-     * @param array  $context The context
-     * @param array  $blocks  The current set of blocks
+     * @param string $name      The block name to render
+     * @param array  $context   The context
+     * @param array  $blocks    The current set of blocks
+     * @param bool   $useBlocks Whether to use the current set of blocks
      *
      * @return string The rendered block
      */
-    public function renderBlock($name, array $context, array $blocks = array())
+    public function renderBlock($name, array $context, array $blocks = array(), $useBlocks = true)
     {
         ob_start();
-        $this->displayBlock($name, $context, $blocks);
+        $this->displayBlock($name, $context, $blocks, $useBlocks);
 
         return ob_get_clean();
     }
@@ -193,7 +238,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
      *
      * @param string $name The block name
      *
-     * @return Boolean true if the block exists, false otherwise
+     * @return bool true if the block exists, false otherwise
      */
     public function hasBlock($name)
     {
@@ -215,6 +260,37 @@ abstract class Twig_Template implements Twig_TemplateInterface
         return array_keys($this->blocks);
     }
 
+    protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
+    {
+        try {
+            if (is_array($template)) {
+                return $this->env->resolveTemplate($template);
+            }
+
+            if ($template instanceof self) {
+                return $template;
+            }
+
+            return $this->env->loadTemplate($template, $index);
+        } catch (Twig_Error $e) {
+            if (!$e->getTemplateFile()) {
+                $e->setTemplateFile($templateName ? $templateName : $this->getTemplateName());
+            }
+
+            if ($e->getTemplateLine()) {
+                throw $e;
+            }
+
+            if (!$line) {
+                $e->guess();
+            } else {
+                $e->setTemplateLine($line);
+            }
+
+            throw $e;
+        }
+    }
+
     /**
      * Returns all blocks.
      *
@@ -235,7 +311,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
      */
     public function display(array $context, array $blocks = array())
     {
-        $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks);
+        $this->displayWithErrorHandling($this->env->mergeGlobals($context), array_merge($this->blocks, $blocks));
     }
 
     /**
@@ -276,7 +352,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
 
             throw $e;
         } catch (Exception $e) {
-            throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e);
+            throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getTemplateName(), $e);
         }
     }
 
@@ -299,11 +375,11 @@ abstract class Twig_Template implements Twig_TemplateInterface
      * access for versions of PHP before 5.4. This is not a way to override
      * the way to get a variable value.
      *
-     * @param array   $context           The context
-     * @param string  $item              The variable to return from the context
-     * @param Boolean $ignoreStrictCheck Whether to ignore the strict variable check or not
+     * @param array  $context           The context
+     * @param string $item              The variable to return from the context
+     * @param bool   $ignoreStrictCheck Whether to ignore the strict variable check or not
      *
-     * @return The content of the context variable
+     * @return mixed The content of the context variable
      *
      * @throws Twig_Error_Runtime if the variable does not exist and Twig is running in strict mode
      */
@@ -311,7 +387,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
     {
         if (!array_key_exists($item, $context)) {
             if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
-                return null;
+                return;
             }
 
             throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
@@ -323,21 +399,21 @@ abstract class Twig_Template implements Twig_TemplateInterface
     /**
      * Returns the attribute value for a given array/object.
      *
-     * @param mixed   $object            The object or array from where to get the item
-     * @param mixed   $item              The item to get from the array or object
-     * @param array   $arguments         An array of arguments to pass if the item is an object method
-     * @param string  $type              The type of attribute (@see Twig_TemplateInterface)
-     * @param Boolean $isDefinedTest     Whether this is only a defined check
-     * @param Boolean $ignoreStrictCheck Whether to ignore the strict attribute check or not
+     * @param mixed  $object            The object or array from where to get the item
+     * @param mixed  $item              The item to get from the array or object
+     * @param array  $arguments         An array of arguments to pass if the item is an object method
+     * @param string $type              The type of attribute (@see Twig_Template constants)
+     * @param bool   $isDefinedTest     Whether this is only a defined check
+     * @param bool   $ignoreStrictCheck Whether to ignore the strict attribute check or not
      *
      * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
      *
      * @throws Twig_Error_Runtime if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
      */
-    protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
+    protected function getAttribute($object, $item, array $arguments = array(), $type = self::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
     {
         // array
-        if (Twig_TemplateInterface::METHOD_CALL !== $type) {
+        if (self::METHOD_CALL !== $type) {
             $arrayItem = is_bool($item) || is_float($item) ? (int) $item : $item;
 
             if ((is_array($object) && array_key_exists($arrayItem, $object))
@@ -350,24 +426,38 @@ abstract class Twig_Template implements Twig_TemplateInterface
                 return $object[$arrayItem];
             }
 
-            if (Twig_TemplateInterface::ARRAY_CALL === $type || !is_object($object)) {
+            if (self::ARRAY_CALL === $type || !is_object($object)) {
                 if ($isDefinedTest) {
                     return false;
                 }
 
                 if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
-                    return null;
+                    return;
                 }
 
-                if (is_object($object)) {
-                    throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $arrayItem, get_class($object)), -1, $this->getTemplateName());
+                if ($object instanceof ArrayAccess) {
+                    $message = sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist', $arrayItem, get_class($object));
+                } elseif (is_object($object)) {
+                    $message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
                 } elseif (is_array($object)) {
-                    throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object))), -1, $this->getTemplateName());
-                } elseif (Twig_TemplateInterface::ARRAY_CALL === $type) {
-                    throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
+                    if (empty($object)) {
+                        $message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
+                    } else {
+                        $message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
+                    }
+                } elseif (self::ARRAY_CALL === $type) {
+                    if (null === $object) {
+                        $message = sprintf('Impossible to access a key ("%s") on a null variable', $item);
+                    } else {
+                        $message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
+                    }
+                } elseif (null === $object) {
+                    $message = sprintf('Impossible to access an attribute ("%s") on a null variable', $item);
                 } else {
-                    throw new Twig_Error_Runtime(sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
+                    $message = sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
                 }
+
+                throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
             }
         }
 
@@ -377,16 +467,20 @@ abstract class Twig_Template implements Twig_TemplateInterface
             }
 
             if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
-                return null;
+                return;
             }
 
-            throw new Twig_Error_Runtime(sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object), -1, $this->getTemplateName());
-        }
+            if (null === $object) {
+                $message = sprintf('Impossible to invoke a method ("%s") on a null variable', $item);
+            } else {
+                $message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
+            }
 
-        $class = get_class($object);
+            throw new Twig_Error_Runtime($message, -1, $this->getTemplateName());
+        }
 
         // object property
-        if (Twig_TemplateInterface::METHOD_CALL !== $type) {
+        if (self::METHOD_CALL !== $type && !$object instanceof self) { // Twig_Template does not have public properties, and we don't want to allow access to internal ones
             if (isset($object->$item) || array_key_exists((string) $item, $object)) {
                 if ($isDefinedTest) {
                     return true;
@@ -400,11 +494,31 @@ abstract class Twig_Template implements Twig_TemplateInterface
             }
         }
 
+        $class = get_class($object);
+
         // object method
         if (!isset(self::$cache[$class]['methods'])) {
-            self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
+            // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
+            if ($object instanceof self) {
+                $ref = new ReflectionClass($class);
+                $methods = array();
+
+                foreach ($ref->getMethods(ReflectionMethod::IS_PUBLIC) as $refMethod) {
+                    $methodName = strtolower($refMethod->name);
+
+                    // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
+                    if ('getenvironment' !== $methodName) {
+                        $methods[$methodName] = true;
+                    }
+                }
+
+                self::$cache[$class]['methods'] = $methods;
+            } else {
+                self::$cache[$class]['methods'] = array_change_key_case(array_flip(get_class_methods($object)));
+            }
         }
 
+        $call = false;
         $lcItem = strtolower($item);
         if (isset(self::$cache[$class]['methods'][$lcItem])) {
             $method = (string) $item;
@@ -414,13 +528,14 @@ abstract class Twig_Template implements Twig_TemplateInterface
             $method = 'is'.$item;
         } elseif (isset(self::$cache[$class]['methods']['__call'])) {
             $method = (string) $item;
+            $call = true;
         } else {
             if ($isDefinedTest) {
                 return false;
             }
 
             if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
-                return null;
+                return;
             }
 
             throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
@@ -434,7 +549,16 @@ abstract class Twig_Template implements Twig_TemplateInterface
             $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
         }
 
-        $ret = call_user_func_array(array($object, $method), $arguments);
+        // Some objects throw exceptions when they have __call, and the method we try
+        // to call is not supported. If ignoreStrictCheck is true, we should return null.
+        try {
+            $ret = call_user_func_array(array($object, $method), $arguments);
+        } catch (BadMethodCallException $e) {
+            if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
+                return;
+            }
+            throw $e;
+        }
 
         // useful when calling a template method from a template
         // this is not supported but unfortunately heavily used in the Symfony profiler
@@ -444,12 +568,4 @@ abstract class Twig_Template implements Twig_TemplateInterface
 
         return $ret;
     }
-
-    /**
-     * This method is only useful when testing Twig. Do not use it.
-     */
-    public static function clearCache()
-    {
-        self::$cache = array();
-    }
 }
--- a/vendor/twig/twig/lib/Twig/TemplateInterface.php
+++ b/vendor/twig/twig/lib/Twig/TemplateInterface.php
@@ -13,12 +13,13 @@
  * Interface implemented by all compiled templates.
  *
  * @author Fabien Potencier <fabien@symfony.com>
- * @deprecated since 1.12 (to be removed in 2.0)
+ *
+ * @deprecated since 1.12 (to be removed in 3.0)
  */
 interface Twig_TemplateInterface
 {
-    const ANY_CALL    = 'any';
-    const ARRAY_CALL  = 'array';
+    const ANY_CALL = 'any';
+    const ARRAY_CALL = 'array';
     const METHOD_CALL = 'method';
 
     /**
--- a/vendor/twig/twig/lib/Twig/Test.php
+++ b/vendor/twig/twig/lib/Twig/Test.php
@@ -13,6 +13,7 @@
  * Represents a template test.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 abstract class Twig_Test implements Twig_TestInterface, Twig_TestCallableInterface
--- a/vendor/twig/twig/lib/Twig/Test/Function.php
+++ b/vendor/twig/twig/lib/Twig/Test/Function.php
@@ -13,6 +13,7 @@
  * Represents a function template test.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Test_Function extends Twig_Test
--- a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
+++ b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
@@ -10,7 +10,7 @@
  */
 
 /**
- * Integration test helper
+ * Integration test helper.
  *
  * @author Fabien Potencier <fabien@symfony.com>
  * @author Karma Dordrak <drak@zikula.org>
@@ -74,7 +74,7 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
 
         $loader = new Twig_Loader_Array($templates);
 
-        foreach ($outputs as $match) {
+        foreach ($outputs as $i => $match) {
             $config = array_merge(array(
                 'cache' => false,
                 'strict_variables' => true,
@@ -85,6 +85,14 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
                 $twig->addExtension($extension);
             }
 
+            // avoid using the same PHP class name for different cases
+            // only for PHP 5.2+
+            if (PHP_VERSION_ID >= 50300) {
+                $p = new ReflectionProperty($twig, 'templateClassPrefix');
+                $p->setAccessible(true);
+                $p->setValue($twig, '__TwigTemplate_'.hash('sha256', uniqid(mt_rand(), true), false).'_');
+            }
+
             try {
                 $template = $twig->loadTemplate('index.twig');
             } catch (Exception $e) {
@@ -122,14 +130,14 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
             }
 
             if (false !== $exception) {
-                list($class, ) = explode(':', $exception);
-                $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class));
+                list($class) = explode(':', $exception);
+                $this->assertThat(null, new PHPUnit_Framework_Constraint_Exception($class));
             }
 
             $expected = trim($match[3], "\n ");
 
             if ($expected != $output) {
-                echo 'Compiled template that failed:';
+                printf("Compiled templates that failed on case %d:\n", $i + 1);
 
                 foreach (array_keys($templates) as $name) {
                     echo "Template: $name\n";
--- a/vendor/twig/twig/lib/Twig/Test/Method.php
+++ b/vendor/twig/twig/lib/Twig/Test/Method.php
@@ -13,6 +13,7 @@
  * Represents a method template test.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Test_Method extends Twig_Test
--- a/vendor/twig/twig/lib/Twig/Test/Node.php
+++ b/vendor/twig/twig/lib/Twig/Test/Node.php
@@ -13,6 +13,7 @@
  * Represents a template test as a Node.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_Test_Node extends Twig_Test
--- a/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php
+++ b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php
@@ -38,13 +38,15 @@ abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
         return new Twig_Environment();
     }
 
-    protected function getVariableGetter($name)
+    protected function getVariableGetter($name, $line = false)
     {
-        if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
-            return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name);
+        $line = $line > 0 ? "// line {$line}\n" : '';
+
+        if (PHP_VERSION_ID >= 50400) {
+            return sprintf('%s(isset($context["%s"]) ? $context["%s"] : null)', $line, $name, $name);
         }
 
-        return sprintf('$this->getContext($context, "%s")', $name);
+        return sprintf('%s$this->getContext($context, "%s")', $line, $name);
     }
 
     protected function getAttributeGetter()
--- a/vendor/twig/twig/lib/Twig/TestCallableInterface.php
+++ b/vendor/twig/twig/lib/Twig/TestCallableInterface.php
@@ -13,6 +13,7 @@
  * Represents a callable template test.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_TestCallableInterface
--- a/vendor/twig/twig/lib/Twig/TestInterface.php
+++ b/vendor/twig/twig/lib/Twig/TestInterface.php
@@ -13,6 +13,7 @@
  * Represents a template test.
  *
  * @author Fabien Potencier <fabien@symfony.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_TestInterface
--- a/vendor/twig/twig/lib/Twig/Token.php
+++ b/vendor/twig/twig/lib/Twig/Token.php
@@ -21,31 +21,31 @@ class Twig_Token
     protected $type;
     protected $lineno;
 
-    const EOF_TYPE                  = -1;
-    const TEXT_TYPE                 = 0;
-    const BLOCK_START_TYPE          = 1;
-    const VAR_START_TYPE            = 2;
-    const BLOCK_END_TYPE            = 3;
-    const VAR_END_TYPE              = 4;
-    const NAME_TYPE                 = 5;
-    const NUMBER_TYPE               = 6;
-    const STRING_TYPE               = 7;
-    const OPERATOR_TYPE             = 8;
-    const PUNCTUATION_TYPE          = 9;
-    const INTERPOLATION_START_TYPE  = 10;
-    const INTERPOLATION_END_TYPE    = 11;
+    const EOF_TYPE = -1;
+    const TEXT_TYPE = 0;
+    const BLOCK_START_TYPE = 1;
+    const VAR_START_TYPE = 2;
+    const BLOCK_END_TYPE = 3;
+    const VAR_END_TYPE = 4;
+    const NAME_TYPE = 5;
+    const NUMBER_TYPE = 6;
+    const STRING_TYPE = 7;
+    const OPERATOR_TYPE = 8;
+    const PUNCTUATION_TYPE = 9;
+    const INTERPOLATION_START_TYPE = 10;
+    const INTERPOLATION_END_TYPE = 11;
 
     /**
      * Constructor.
      *
-     * @param integer $type   The type of the token
-     * @param string  $value  The token value
-     * @param integer $lineno The line position in the source
+     * @param int    $type   The type of the token
+     * @param string $value  The token value
+     * @param int    $lineno The line position in the source
      */
     public function __construct($type, $value, $lineno)
     {
-        $this->type   = $type;
-        $this->value  = $value;
+        $this->type = $type;
+        $this->value = $value;
         $this->lineno = $lineno;
     }
 
@@ -56,7 +56,7 @@ class Twig_Token
      */
     public function __toString()
     {
-        return sprintf('%s(%s)', self::typeToString($this->type, true, $this->lineno), $this->value);
+        return sprintf('%s(%s)', self::typeToString($this->type, true), $this->value);
     }
 
     /**
@@ -67,10 +67,10 @@ class Twig_Token
      * * type and value (or array of possible values)
      * * just value (or array of possible values) (NAME_TYPE is used as type)
      *
-     * @param array|integer     $type   The type to test
+     * @param array|int         $type   The type to test
      * @param array|string|null $values The token value
      *
-     * @return Boolean
+     * @return bool
      */
     public function test($type, $values = null)
     {
@@ -89,7 +89,7 @@ class Twig_Token
     /**
      * Gets the line.
      *
-     * @return integer The source line
+     * @return int The source line
      */
     public function getLine()
     {
@@ -99,7 +99,7 @@ class Twig_Token
     /**
      * Gets the token type.
      *
-     * @return integer The token type
+     * @return int The token type
      */
     public function getType()
     {
@@ -119,13 +119,12 @@ class Twig_Token
     /**
      * Returns the constant representation (internal) of a given type.
      *
-     * @param integer $type  The type as an integer
-     * @param Boolean $short Whether to return a short representation or not
-     * @param integer $line  The code line
+     * @param int  $type  The type as an integer
+     * @param bool $short Whether to return a short representation or not
      *
      * @return string The string representation
      */
-    public static function typeToString($type, $short = false, $line = -1)
+    public static function typeToString($type, $short = false)
     {
         switch ($type) {
             case self::EOF_TYPE:
@@ -177,12 +176,11 @@ class Twig_Token
     /**
      * Returns the english representation of a given type.
      *
-     * @param integer $type The type as an integer
-     * @param integer $line The code line
+     * @param int $type The type as an integer
      *
      * @return string The string representation
      */
-    public static function typeToEnglish($type, $line = -1)
+    public static function typeToEnglish($type)
     {
         switch ($type) {
             case self::EOF_TYPE:
--- a/vendor/twig/twig/lib/Twig/TokenParser.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser.php
@@ -22,9 +22,9 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface
     protected $parser;
 
     /**
-     * Sets the parser associated with this token parser
+     * Sets the parser associated with this token parser.
      *
-     * @param $parser A Twig_Parser instance
+     * @param Twig_Parser $parser A Twig_Parser instance
      */
     public function setParser(Twig_Parser $parser)
     {
--- a/vendor/twig/twig/lib/Twig/TokenParser/Block.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Block.php
@@ -41,15 +41,13 @@ class Twig_TokenParser_Block extends Twig_TokenParser
         $this->parser->pushLocalScope();
         $this->parser->pushBlockStack($name);
 
-        if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
-            $stream->next();
-
+        if ($stream->nextIf(Twig_Token::BLOCK_END_TYPE)) {
             $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
-            if ($stream->test(Twig_Token::NAME_TYPE)) {
-                $value = $stream->next()->getValue();
+            if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) {
+                $value = $token->getValue();
 
                 if ($value != $name) {
-                    throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename());
+                    throw new Twig_Error_Syntax(sprintf('Expected endblock for block "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
                 }
             }
         } else {
--- a/vendor/twig/twig/lib/Twig/TokenParser/For.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/For.php
@@ -39,8 +39,7 @@ class Twig_TokenParser_For extends Twig_TokenParser
         $seq = $this->parser->getExpressionParser()->parseExpression();
 
         $ifexpr = null;
-        if ($stream->test(Twig_Token::NAME_TYPE, 'if')) {
-            $stream->next();
+        if ($stream->nextIf(Twig_Token::NAME_TYPE, 'if')) {
             $ifexpr = $this->parser->getExpressionParser()->parseExpression();
         }
 
--- a/vendor/twig/twig/lib/Twig/TokenParser/From.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/From.php
@@ -36,19 +36,15 @@ class Twig_TokenParser_From extends Twig_TokenParser
             $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
 
             $alias = $name;
-            if ($stream->test('as')) {
-                $stream->next();
-
+            if ($stream->nextIf('as')) {
                 $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
             }
 
             $targets[$name] = $alias;
 
-            if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+            if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
                 break;
             }
-
-            $stream->next();
         } while (true);
 
         $stream->expect(Twig_Token::BLOCK_END_TYPE);
@@ -56,6 +52,10 @@ class Twig_TokenParser_From extends Twig_TokenParser
         $node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
 
         foreach ($targets as $name => $alias) {
+            if ($this->parser->isReservedMacroName($name)) {
+                throw new Twig_Error_Syntax(sprintf('"%s" cannot be an imported macro as it is a reserved keyword', $name), $token->getLine(), $stream->getFilename());
+            }
+
             $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
         }
 
--- a/vendor/twig/twig/lib/Twig/TokenParser/Include.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Include.php
@@ -42,24 +42,19 @@ class Twig_TokenParser_Include extends Twig_TokenParser
         $stream = $this->parser->getStream();
 
         $ignoreMissing = false;
-        if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) {
-            $stream->next();
+        if ($stream->nextIf(Twig_Token::NAME_TYPE, 'ignore')) {
             $stream->expect(Twig_Token::NAME_TYPE, 'missing');
 
             $ignoreMissing = true;
         }
 
         $variables = null;
-        if ($stream->test(Twig_Token::NAME_TYPE, 'with')) {
-            $stream->next();
-
+        if ($stream->nextIf(Twig_Token::NAME_TYPE, 'with')) {
             $variables = $this->parser->getExpressionParser()->parseExpression();
         }
 
         $only = false;
-        if ($stream->test(Twig_Token::NAME_TYPE, 'only')) {
-            $stream->next();
-
+        if ($stream->nextIf(Twig_Token::NAME_TYPE, 'only')) {
             $only = true;
         }
 
--- a/vendor/twig/twig/lib/Twig/TokenParser/Macro.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php
@@ -38,11 +38,11 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
         $stream->expect(Twig_Token::BLOCK_END_TYPE);
         $this->parser->pushLocalScope();
         $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
-        if ($stream->test(Twig_Token::NAME_TYPE)) {
-            $value = $stream->next()->getValue();
+        if ($token = $stream->nextIf(Twig_Token::NAME_TYPE)) {
+            $value = $token->getValue();
 
             if ($value != $name) {
-                throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename());
+                throw new Twig_Error_Syntax(sprintf('Expected endmacro for macro "%s" (but "%s" given)', $name, $value), $stream->getCurrent()->getLine(), $stream->getFilename());
             }
         }
         $this->parser->popLocalScope();
--- a/vendor/twig/twig/lib/Twig/TokenParser/Set.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Set.php
@@ -42,20 +42,19 @@ class Twig_TokenParser_Set extends Twig_TokenParser
         $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
 
         $capture = false;
-        if ($stream->test(Twig_Token::OPERATOR_TYPE, '=')) {
-            $stream->next();
+        if ($stream->nextIf(Twig_Token::OPERATOR_TYPE, '=')) {
             $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
 
             $stream->expect(Twig_Token::BLOCK_END_TYPE);
 
             if (count($names) !== count($values)) {
-                throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignments.", $stream->getCurrent()->getLine(), $stream->getFilename());
+                throw new Twig_Error_Syntax('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getFilename());
             }
         } else {
             $capture = true;
 
             if (count($names) > 1) {
-                throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename());
+                throw new Twig_Error_Syntax('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getFilename());
             }
 
             $stream->expect(Twig_Token::BLOCK_END_TYPE);
--- a/vendor/twig/twig/lib/Twig/TokenParser/Use.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Use.php
@@ -42,26 +42,20 @@ class Twig_TokenParser_Use extends Twig_TokenParser
         }
 
         $targets = array();
-        if ($stream->test('with')) {
-            $stream->next();
-
+        if ($stream->nextIf('with')) {
             do {
                 $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
 
                 $alias = $name;
-                if ($stream->test('as')) {
-                    $stream->next();
-
+                if ($stream->nextIf('as')) {
                     $alias = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
                 }
 
                 $targets[$name] = new Twig_Node_Expression_Constant($alias, -1);
 
-                if (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ',')) {
+                if (!$stream->nextIf(Twig_Token::PUNCTUATION_TYPE, ',')) {
                     break;
                 }
-
-                $stream->next();
             } while (true);
         }
 
--- a/vendor/twig/twig/lib/Twig/TokenParserBroker.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserBroker.php
@@ -14,6 +14,7 @@
  * Default implementation of a token parser broker.
  *
  * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
--- a/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php
@@ -16,6 +16,7 @@
  * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name.
  *
  * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
+ *
  * @deprecated since 1.12 (to be removed in 2.0)
  */
 interface Twig_TokenParserBrokerInterface
--- a/vendor/twig/twig/lib/Twig/TokenParserInterface.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserInterface.php
@@ -17,9 +17,9 @@
 interface Twig_TokenParserInterface
 {
     /**
-     * Sets the parser associated with this token parser
+     * Sets the parser associated with this token parser.
      *
-     * @param $parser A Twig_Parser instance
+     * @param Twig_Parser $parser A Twig_Parser instance
      */
     public function setParser(Twig_Parser $parser);
 
@@ -29,6 +29,8 @@ interface Twig_TokenParserInterface
      * @param Twig_Token $token A Twig_Token instance
      *
      * @return Twig_NodeInterface A Twig_NodeInterface instance
+     *
+     * @throws Twig_Error_Syntax
      */
     public function parse(Twig_Token $token);
 
--- a/vendor/twig/twig/lib/Twig/TokenStream.php
+++ b/vendor/twig/twig/lib/Twig/TokenStream.php
@@ -29,9 +29,9 @@ class Twig_TokenStream
      */
     public function __construct(array $tokens, $filename = null)
     {
-        $this->tokens     = $tokens;
-        $this->current    = 0;
-        $this->filename   = $filename;
+        $this->tokens = $tokens;
+        $this->current = 0;
+        $this->filename = $filename;
     }
 
     /**
@@ -64,6 +64,18 @@ class Twig_TokenStream
     }
 
     /**
+     * Tests a token, sets the pointer to the next one and returns it or throws a syntax error.
+     *
+     * @return Twig_Token|null The next token if the condition is true, null otherwise
+     */
+    public function nextIf($primary, $secondary = null)
+    {
+        if ($this->tokens[$this->current]->test($primary, $secondary)) {
+            return $this->next();
+        }
+    }
+
+    /**
      * Tests a token and returns it or throws a syntax error.
      *
      * @return Twig_Token
@@ -75,8 +87,8 @@ class Twig_TokenStream
             $line = $token->getLine();
             throw new Twig_Error_Syntax(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)',
                 $message ? $message.'. ' : '',
-                Twig_Token::typeToEnglish($token->getType(), $line), $token->getValue(),
-                Twig_Token::typeToEnglish($type, $line), $value ? sprintf(' with value "%s"', $value) : ''),
+                Twig_Token::typeToEnglish($token->getType()), $token->getValue(),
+                Twig_Token::typeToEnglish($type), $value ? sprintf(' with value "%s"', $value) : ''),
                 $line,
                 $this->filename
             );
@@ -89,7 +101,7 @@ class Twig_TokenStream
     /**
      * Looks at the next token.
      *
-     * @param integer $number
+     * @param int $number
      *
      * @return Twig_Token
      */
@@ -103,7 +115,7 @@ class Twig_TokenStream
     }
 
     /**
-     * Tests the current token
+     * Tests the current token.
      *
      * @return bool
      */
@@ -113,7 +125,7 @@ class Twig_TokenStream
     }
 
     /**
-     * Checks if end of stream was reached
+     * Checks if end of stream was reached.
      *
      * @return bool
      */
@@ -123,7 +135,7 @@ class Twig_TokenStream
     }
 
     /**
-     * Gets the current token
+     * Gets the current token.
      *
      * @return Twig_Token
      */
@@ -133,7 +145,7 @@ class Twig_TokenStream
     }
 
     /**
-     * Gets the filename associated with this stream
+     * Gets the filename associated with this stream.
      *
      * @return string
      */
--- a/viewtopic.php
+++ b/viewtopic.php
@@ -588,7 +588,7 @@ $quickmod_array = array(
 	'topic_logs'			=> array('VIEW_TOPIC_LOGS', $auth->acl_get('m_', $forum_id)),
 );
 
-foreach($quickmod_array as $option => $qm_ary)
+foreach ($quickmod_array as $option => $qm_ary)
 {
 	if (!empty($qm_ary[1]))
 	{
