diff options
48 files changed, 4412 insertions, 0 deletions
diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..d9731d27 --- /dev/null +++ b/COPYING | |||
@@ -0,0 +1,21 @@ | |||
1 | Shaarli is distributed under the zlib/libpng License: | ||
2 | |||
3 | Copyright (c) 2011 Sébastien SAUVAGE (sebsauvage.net) | ||
4 | |||
5 | This software is provided 'as-is', without any express or implied warranty. | ||
6 | In no event will the authors be held liable for any damages arising from | ||
7 | the use of this software. | ||
8 | |||
9 | Permission is granted to anyone to use this software for any purpose, | ||
10 | including commercial applications, and to alter it and redistribute it | ||
11 | freely, subject to the following restrictions: | ||
12 | |||
13 | 1. The origin of this software must not be misrepresented; you must not | ||
14 | claim that you wrote the original software. If you use this software | ||
15 | in a product, an acknowledgment in the product documentation would | ||
16 | be appreciated but is not required. | ||
17 | |||
18 | 2. Altered source versions must be plainly marked as such, and must | ||
19 | not be misrepresented as being the original software. | ||
20 | |||
21 | 3. This notice may not be removed or altered from any source distribution. | ||
diff --git a/images/50pc_transparent.png b/images/50pc_transparent.png new file mode 100644 index 00000000..8d8f99de --- /dev/null +++ b/images/50pc_transparent.png | |||
Binary files differ | |||
diff --git a/images/Paper_texture_v5_by_bashcorpo_w1000.jpg b/images/Paper_texture_v5_by_bashcorpo_w1000.jpg new file mode 100644 index 00000000..dd8e67ac --- /dev/null +++ b/images/Paper_texture_v5_by_bashcorpo_w1000.jpg | |||
Binary files differ | |||
diff --git a/images/calendar.png b/images/calendar.png new file mode 100644 index 00000000..65891385 --- /dev/null +++ b/images/calendar.png | |||
Binary files differ | |||
diff --git a/images/delete_icon.png b/images/delete_icon.png new file mode 100644 index 00000000..55e388b4 --- /dev/null +++ b/images/delete_icon.png | |||
Binary files differ | |||
diff --git a/images/edit_icon.png b/images/edit_icon.png new file mode 100644 index 00000000..5cff5743 --- /dev/null +++ b/images/edit_icon.png | |||
Binary files differ | |||
diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 00000000..c8b043b4 --- /dev/null +++ b/images/favicon.ico | |||
Binary files differ | |||
diff --git a/images/feed-icon-14x14.png b/images/feed-icon-14x14.png new file mode 100644 index 00000000..b3c949d2 --- /dev/null +++ b/images/feed-icon-14x14.png | |||
Binary files differ | |||
diff --git a/images/floral_left.png b/images/floral_left.png new file mode 100644 index 00000000..5a4ad89b --- /dev/null +++ b/images/floral_left.png | |||
Binary files differ | |||
diff --git a/images/floral_right.png b/images/floral_right.png new file mode 100644 index 00000000..cb7b201f --- /dev/null +++ b/images/floral_right.png | |||
Binary files differ | |||
diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 00000000..20989288 --- /dev/null +++ b/images/logo.png | |||
Binary files differ | |||
diff --git a/images/private.png b/images/private.png new file mode 100644 index 00000000..5cea272a --- /dev/null +++ b/images/private.png | |||
Binary files differ | |||
diff --git a/images/private_16x16.png b/images/private_16x16.png new file mode 100644 index 00000000..d58c4823 --- /dev/null +++ b/images/private_16x16.png | |||
Binary files differ | |||
diff --git a/images/private_16x16_active.png b/images/private_16x16_active.png new file mode 100644 index 00000000..dd43baf2 --- /dev/null +++ b/images/private_16x16_active.png | |||
Binary files differ | |||
diff --git a/images/qrcode.png b/images/qrcode.png new file mode 100644 index 00000000..99f25267 --- /dev/null +++ b/images/qrcode.png | |||
Binary files differ | |||
diff --git a/images/squiggle.png b/images/squiggle.png new file mode 100644 index 00000000..9fd2129d --- /dev/null +++ b/images/squiggle.png | |||
Binary files differ | |||
diff --git a/images/squiggle2.png b/images/squiggle2.png new file mode 100644 index 00000000..23409ce3 --- /dev/null +++ b/images/squiggle2.png | |||
Binary files differ | |||
diff --git a/images/squiggle_closing.png b/images/squiggle_closing.png new file mode 100644 index 00000000..901fff5f --- /dev/null +++ b/images/squiggle_closing.png | |||
Binary files differ | |||
diff --git a/images/tag_blue.png b/images/tag_blue.png new file mode 100644 index 00000000..9757fc6e --- /dev/null +++ b/images/tag_blue.png | |||
Binary files differ | |||
diff --git a/inc/jquery-MIT-LICENSE.txt b/inc/jquery-MIT-LICENSE.txt new file mode 100644 index 00000000..53270463 --- /dev/null +++ b/inc/jquery-MIT-LICENSE.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | Copyright (c) 2011 John Resig, http://jquery.com/ | ||
2 | |||
3 | Permission is hereby granted, free of charge, to any person obtaining | ||
4 | a copy of this software and associated documentation files (the | ||
5 | "Software"), to deal in the Software without restriction, including | ||
6 | without limitation the rights to use, copy, modify, merge, publish, | ||
7 | distribute, sublicense, and/or sell copies of the Software, and to | ||
8 | permit persons to whom the Software is furnished to do so, subject to | ||
9 | the following conditions: | ||
10 | |||
11 | The above copyright notice and this permission notice shall be | ||
12 | included in all copies or substantial portions of the Software. | ||
13 | |||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
diff --git a/inc/jquery-ui.min.js b/inc/jquery-ui.min.js new file mode 100644 index 00000000..618b8efe --- /dev/null +++ b/inc/jquery-ui.min.js | |||
@@ -0,0 +1,15 @@ | |||
1 | /*! | ||
2 | * jQuery UI 1.8.17 | ||
3 | * | ||
4 | * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) | ||
5 | * Dual licensed under the MIT or GPL Version 2 licenses. | ||
6 | * http://jquery.org/license | ||
7 | * | ||
8 | * http://docs.jquery.com/UI | ||
9 | */(function(a,b){function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;if(!b.href||!g||f.nodeName.toLowerCase()!=="map")return!1;h=a("img[usemap=#"+g+"]")[0];return!!h&&d(h)}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}a.ui=a.ui||{};a.ui.version||(a.extend(a.ui,{version:"1.8.17",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)});return c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){if(c===b)return g["inner"+d].call(this);return this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){if(typeof b!="number")return g["outer"+d].call(this,b);return this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!!d&&!!a.element[0].parentNode)for(var e=0;e<d.length;e++)a.options[d[e][0]]&&d[e][1].apply(a.element,c)}},contains:function(a,b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(b,c){if(a(b).css("overflow")==="hidden")return!1;var d=c&&c==="left"?"scrollLeft":"scrollTop",e=!1;if(b[d]>0)return!0;b[d]=1,e=b[d]>0,b[d]=0;return e},isOverAxis:function(a,b,c){return a>b&&a<b+c},isOver:function(b,c,d,e,f,g){return a.ui.isOverAxis(b,d,f)&&a.ui.isOverAxis(c,e,g)}}))})(jQuery),function(a,b){if(a.cleanData){var c=a.cleanData;a.cleanData=function(b){for(var d=0,e;(e=b[d])!=null;d++)try{a(e).triggerHandler("remove")}catch(f){}c(b)}}else{var d=a.fn.remove;a.fn.remove=function(b,c){return this.each(function(){c||(!b||a.filter(b,[this]).length)&&a("*",this).add([this]).each(function(){try{a(this).triggerHandler("remove")}catch(b){}});return d.call(a(this),b,c)})}}a.widget=function(b,c,d){var e=b.split(".")[0],f;b=b.split(".")[1],f=e+"-"+b,d||(d=c,c=a.Widget),a.expr[":"][f]=function(c){return!!a.data(c,b)},a[e]=a[e]||{},a[e][b]=function(a,b){arguments.length&&this._createWidget(a,b)};var g=new c;g.options=a.extend(!0,{},g.options),a[e][b].prototype=a.extend(!0,g,{namespace:e,widgetName:b,widgetEventPrefix:a[e][b].prototype.widgetEventPrefix||b,widgetBaseClass:f},d),a.widget.bridge(b,a[e][b])},a.widget.bridge=function(c,d){a.fn[c]=function(e){var f=typeof e=="string",g=Array.prototype.slice.call(arguments,1),h=this;e=!f&&g.length?a.extend.apply(null,[!0,e].concat(g)):e;if(f&&e.charAt(0)==="_")return h;f?this.each(function(){var d=a.data(this,c),f=d&&a.isFunction(d[e])?d[e].apply(d,g):d;if(f!==d&&f!==b){h=f;return!1}}):this.each(function(){var b=a.data(this,c);b?b.option(e||{})._init():a.data(this,c,new d(e,this))});return h}},a.Widget=function(a,b){arguments.length&&this._createWidget(a,b)},a.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(b,c){a.data(c,this.widgetName,this),this.element=a(c),this.options=a.extend(!0,{},this.options,this._getCreateOptions(),b);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return a.metadata&&a.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(c,d){var e=c;if(arguments.length===0)return a.extend({},this.options);if(typeof c=="string"){if(d===b)return this.options[c];e={},e[c]=d}this._setOptions(e);return this},_setOptions:function(b){var c=this;a.each(b,function(a,b){c._setOption(a,b)});return this},_setOption:function(a,b){this.options[a]=b,a==="disabled"&&this.widget()[b?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",b);return this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(b,c,d){var e,f,g=this.options[b];d=d||{},c=a.Event(c),c.type=(b===this.widgetEventPrefix?b:this.widgetEventPrefix+b).toLowerCase(),c.target=this.element[0],f=c.originalEvent;if(f)for(e in f)e in c||(c[e]=f[e]);this.element.trigger(c,d);return!(a.isFunction(g)&&g.call(this.element[0],c,d)===!1||c.isDefaultPrevented())}}}(jQuery),function(a,b){var c=!1;a(document).mouseup(function(a){c=!1}),a.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var b=this;this.element.bind("mousedown."+this.widgetName,function(a){return b._mouseDown(a)}).bind("click."+this.widgetName,function(c){if(!0===a.data(c.target,b.widgetName+".preventClickEvent")){a.removeData(c.target,b.widgetName+".preventClickEvent"),c.stopImmediatePropagation();return!1}}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(b){if(!c){this._mouseStarted&&this._mouseUp(b),this._mouseDownEvent=b;var d=this,e=b.which==1,f=typeof this.options.cancel=="string"&&b.target.nodeName?a(b.target).closest(this.options.cancel).length:!1;if(!e||f||!this._mouseCapture(b))return!0;this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){d.mouseDelayMet=!0},this.options.delay));if(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)){this._mouseStarted=this._mouseStart(b)!==!1;if(!this._mouseStarted){b.preventDefault();return!0}}!0===a.data(b.target,this.widgetName+".preventClickEvent")&&a.removeData(b.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(a){return d._mouseMove(a)},this._mouseUpDelegate=function(a){return d._mouseUp(a)},a(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),b.preventDefault(),c=!0;return!0}},_mouseMove:function(b){if(a.browser.msie&&!(document.documentMode>=9)&&!b.button)return this._mouseUp(b);if(this._mouseStarted){this._mouseDrag(b);return b.preventDefault()}this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b));return!this._mouseStarted},_mouseUp:function(b){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b));return!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})}(jQuery),function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!!this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy();return this}},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle"))return!1;this.handle=this._getHandle(b);if(!this.handle)return!1;c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")});return!0},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment();if(this._trigger("start",b)===!1){this._clear();return!1}this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.helper.addClass("ui-draggable-dragging"),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b);return!0},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1){this._mouseUp({});return!1}this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,b);return!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",b)!==!1&&d._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b);return a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)});return c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute");return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.left<h[0]&&(f=h[0]+this.offset.click.left),b.pageY-this.offset.click.top<h[1]&&(g=h[1]+this.offset.click.top),b.pageX-this.offset.click.left>h[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.top<h[1]||j-this.offset.click.top>h[3]?j-this.offset.click.top<h[1]?j+c.grid[1]:j-c.grid[1]:j:j;var k=c.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0]:this.originalPageX;f=h?k-this.offset.click.left<h[0]||k-this.offset.click.left>h[2]?k-this.offset.click.left<h[0]?k+c.grid[0]:k-c.grid[0]:k:k}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(b,c,d){d=d||this._uiHash(),a.ui.plugin.call(this,b,[c,d]),b=="drag"&&(this.positionAbs=this._convertPositionTo("absolute"));return a.Widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(a){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),a.extend(a.ui.draggable,{version:"1.8.17"}),a.ui.plugin.add("draggable","connectToSortable",{start:function(b,c){var d=a(this).data("draggable"),e=d.options,f=a.extend({},c,{item:d.element});d.sortables=[],a(e.connectToSortable).each(function(){var c=a.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",b,f))})},stop:function(b,c){var d=a(this).data("draggable"),e=a.extend({},c,{item:d.element});a.each(d.sortables,function(){this.instance.isOver?(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(b),this.instance.options.helper=this.instance.options._helper,d.options.helper=="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",b,e))})},drag:function(b,c){var d=a(this).data("draggable"),e=this,f=function(b){var c=this.offset.click.top,d=this.offset.click.left,e=this.positionAbs.top,f=this.positionAbs.left,g=b.height,h=b.width,i=b.top,j=b.left;return a.ui.isOver(e+c,f+d,i,j,g,h)};a.each(d.sortables,function(f){this.instance.positionAbs=d.positionAbs,this.instance.helperProportions=d.helperProportions,this.instance.offset.click=d.offset.click,this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=a(e).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},b.target=this.instance.currentItem[0],this.instance._mouseCapture(b,!0),this.instance._mouseStart(b,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",b),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(b)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",b,this.instance._uiHash(this.instance)),this.instance._mouseStop(b,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",b),d.dropped=!1)})}}),a.ui.plugin.add("draggable","cursor",{start:function(b,c){var d=a("body"),e=a(this).data("draggable").options;d.css("cursor")&&(e._cursor=d.css("cursor")),d.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;d._cursor&&a("body").css("cursor",d._cursor)}}),a.ui.plugin.add("draggable","opacity",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("opacity")&&(e._opacity=d.css("opacity")),d.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;d._opacity&&a(c.helper).css("opacity",d._opacity)}}),a.ui.plugin.add("draggable","scroll",{start:function(b,c){var d=a(this).data("draggable");d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"&&(d.overflowOffset=d.scrollParent.offset())},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=!1;if(d.scrollParent[0]!=document&&d.scrollParent[0].tagName!="HTML"){if(!e.axis||e.axis!="x")d.overflowOffset.top+d.scrollParent[0].offsetHeight-b.pageY<e.scrollSensitivity?d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop+e.scrollSpeed:b.pageY-d.overflowOffset.top<e.scrollSensitivity&&(d.scrollParent[0].scrollTop=f=d.scrollParent[0].scrollTop-e.scrollSpeed);if(!e.axis||e.axis!="y")d.overflowOffset.left+d.scrollParent[0].offsetWidth-b.pageX<e.scrollSensitivity?d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft+e.scrollSpeed:b.pageX-d.overflowOffset.left<e.scrollSensitivity&&(d.scrollParent[0].scrollLeft=f=d.scrollParent[0].scrollLeft-e.scrollSpeed)}else{if(!e.axis||e.axis!="x")b.pageY-a(document).scrollTop()<e.scrollSensitivity?f=a(document).scrollTop(a(document).scrollTop()-e.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<e.scrollSensitivity&&(f=a(document).scrollTop(a(document).scrollTop()+e.scrollSpeed));if(!e.axis||e.axis!="y")b.pageX-a(document).scrollLeft()<e.scrollSensitivity?f=a(document).scrollLeft(a(document).scrollLeft()-e.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<e.scrollSensitivity&&(f=a(document).scrollLeft(a(document).scrollLeft()+e.scrollSpeed))}f!==!1&&a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(d,b)}}),a.ui.plugin.add("draggable","snap",{start:function(b,c){var d=a(this).data("draggable"),e=d.options;d.snapElements=[],a(e.snap.constructor!=String?e.snap.items||":data(draggable)":e.snap).each(function(){var b=a(this),c=b.offset();this!=d.element[0]&&d.snapElements.push({item:this,width:b.outerWidth(),height:b.outerHeight(),top:c.top,left:c.left})})},drag:function(b,c){var d=a(this).data("draggable"),e=d.options,f=e.snapTolerance,g=c.offset.left,h=g+d.helperProportions.width,i=c.offset.top,j=i+d.helperProportions.height;for(var k=d.snapElements.length-1;k>=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f<g&&g<m+f&&n-f<i&&i<o+f||l-f<g&&g<m+f&&n-f<j&&j<o+f||l-f<h&&h<m+f&&n-f<i&&i<o+f||l-f<h&&h<m+f&&n-f<j&&j<o+f)){d.snapElements[k].snapping&&d.options.snap.release&&d.options.snap.release.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=!1;continue}if(e.snapMode!="inner"){var p=Math.abs(n-j)<=f,q=Math.abs(o-i)<=f,r=Math.abs(l-h)<=f,s=Math.abs(m-g)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n-d.helperProportions.height,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l-d.helperProportions.width}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m}).left-d.margins.left)}var t=p||q||r||s;if(e.snapMode!="outer"){var p=Math.abs(n-i)<=f,q=Math.abs(o-j)<=f,r=Math.abs(l-g)<=f,s=Math.abs(m-h)<=f;p&&(c.position.top=d._convertPositionTo("relative",{top:n,left:0}).top-d.margins.top),q&&(c.position.top=d._convertPositionTo("relative",{top:o-d.helperProportions.height,left:0}).top-d.margins.top),r&&(c.position.left=d._convertPositionTo("relative",{top:0,left:l}).left-d.margins.left),s&&(c.position.left=d._convertPositionTo("relative",{top:0,left:m-d.helperProportions.width}).left-d.margins.left)}!d.snapElements[k].snapping&&(p||q||r||s||t)&&d.options.snap.snap&&d.options.snap.snap.call(d.element,b,a.extend(d._uiHash(),{snapItem:d.snapElements[k].item})),d.snapElements[k].snapping=p||q||r||s||t}}}),a.ui.plugin.add("draggable","stack",{start:function(b,c){var d=a(this).data("draggable").options,e=a.makeArray(a(d.stack)).sort(function(b,c){return(parseInt(a(b).css("zIndex"),10)||0)-(parseInt(a(c).css("zIndex"),10)||0)});if(!!e.length){var f=parseInt(e[0].style.zIndex)||0;a(e).each(function(a){this.style.zIndex=f+a}),this[0].style.zIndex=f+e.length}}}),a.ui.plugin.add("draggable","zIndex",{start:function(b,c){var d=a(c.helper),e=a(this).data("draggable").options;d.css("zIndex")&&(e._zIndex=d.css("zIndex")),d.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;d._zIndex&&a(c.helper).css("zIndex",d._zIndex)}})}(jQuery),function(a,b){a.widget("ui.droppable",{widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect"},_create:function(){var b=this.options,c=b.accept;this.isover=0,this.isout=1,this.accept=a.isFunction(c)?c:function(a){return a.is(c)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},a.ui.ddmanager.droppables[b.scope]=a.ui.ddmanager.droppables[b.scope]||[],a.ui.ddmanager.droppables[b.scope].push(this),b.addClasses&&this.element.addClass("ui-droppable")},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++)b[c]==this&&b.splice(c,1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this},_setOption:function(b,c){b=="accept"&&(this.accept=a.isFunction(c)?c:function(a){return a.is(c)}),a.Widget.prototype._setOption.apply(this,arguments)},_activate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),c&&this._trigger("activate",b,this.ui(c))},_deactivate:function(b){var c=a.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),c&&this._trigger("deactivate",b,this.ui(c))},_over:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",b,this.ui(c)))},_out:function(b){var c=a.ui.ddmanager.current;!!c&&(c.currentItem||c.element)[0]!=this.element[0]&&this.accept.call(this.element[0],c.currentItem||c.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",b,this.ui(c)))},_drop:function(b,c){var d=c||a.ui.ddmanager.current;if(!d||(d.currentItem||d.element)[0]==this.element[0])return!1;var e=!1;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var b=a.data(this,"droppable");if(b.options.greedy&&!b.options.disabled&&b.options.scope==d.options.scope&&b.accept.call(b.element[0],d.currentItem||d.element)&&a.ui.intersect(d,a.extend(b,{offset:b.element.offset()}),b.options.tolerance)){e=!0;return!1}});if(e)return!1;if(this.accept.call(this.element[0],d.currentItem||d.element)){this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",b,this.ui(d));return this.element}return!1},ui:function(a){return{draggable:a.currentItem||a.element,helper:a.helper,position:a.position,offset:a.positionAbs}}}),a.extend(a.ui.droppable,{version:"1.8.17"}),a.ui.intersect=function(b,c,d){if(!c.offset)return!1;var e=(b.positionAbs||b.position.absolute).left,f=e+b.helperProportions.width,g=(b.positionAbs||b.position.absolute).top,h=g+b.helperProportions.height,i=c.offset.left,j=i+c.proportions.width,k=c.offset.top,l=k+c.proportions.height;switch(d){case"fit":return i<=e&&f<=j&&k<=g&&h<=l;case"intersect":return i<e+b.helperProportions.width/2&&f-b.helperProportions.width/2<j&&k<g+b.helperProportions.height/2&&h-b.helperProportions.height/2<l;case"pointer":var m=(b.positionAbs||b.position.absolute).left+(b.clickOffset||b.offset.click).left,n=(b.positionAbs||b.position.absolute).top+(b.clickOffset||b.offset.click).top,o=a.ui.isOver(n,m,k,i,c.proportions.height,c.proportions.width);return o;case"touch":return(g>=k&&g<=l||h>=k&&h<=l||g<k&&h>l)&&(e>=i&&e<=j||f>=i&&f<=j||e<i&&f>j);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();droppablesLoop:for(var g=0;g<d.length;g++){if(d[g].options.disabled||b&&!d[g].accept.call(d[g].element[0],b.currentItem||b.element))continue;for(var h=0;h<f.length;h++)if(f[h]==d[g].element[0]){d[g].proportions.height=0;continue droppablesLoop}d[g].visible=d[g].element.css("display")!="none";if(!d[g].visible)continue;e=="mousedown"&&d[g]._activate.call(d[g],c),d[g].offset=d[g].element.offset(),d[g].proportions={width:d[g].element[0].offsetWidth,height:d[g].element | ||
10 | [0].offsetHeight}}},drop:function(b,c){var d=!1;a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){!this.options||(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)&&(d=this._drop.call(this,c)||d),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],b.currentItem||b.element)&&(this.isout=1,this.isover=0,this._deactivate.call(this,c)))});return d},dragStart:function(b,c){b.element.parents(":not(body,html)").bind("scroll.droppable",function(){b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)})},drag:function(b,c){b.options.refreshPositions&&a.ui.ddmanager.prepareOffsets(b,c),a.each(a.ui.ddmanager.droppables[b.options.scope]||[],function(){if(!(this.options.disabled||this.greedyChild||!this.visible)){var d=a.ui.intersect(b,this,this.options.tolerance),e=!d&&this.isover==1?"isout":d&&this.isover==0?"isover":null;if(!e)return;var f;if(this.options.greedy){var g=this.element.parents(":data(droppable):eq(0)");g.length&&(f=a.data(g[0],"droppable"),f.greedyChild=e=="isover"?1:0)}f&&e=="isover"&&(f.isover=0,f.isout=1,f._out.call(f,c)),this[e]=1,this[e=="isout"?"isover":"isout"]=0,this[e=="isover"?"_over":"_out"].call(this,c),f&&e=="isout"&&(f.isout=0,f.isover=1,f._over.call(f,c))}})},dragStop:function(b,c){b.element.parents(":not(body,html)").unbind("scroll.droppable"),b.options.refreshPositions||a.ui.ddmanager.prepareOffsets(b,c)}}}(jQuery),function(a,b){a.widget("ui.resizable",a.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1e3},_create:function(){var b=this,c=this.options;this.element.addClass("ui-resizable"),a.extend(this,{_aspectRatio:!!c.aspectRatio,aspectRatio:c.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:c.helper||c.ghost||c.animate?c.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(/relative/.test(this.element.css("position"))&&a.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"}),this.element.wrap(a('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e<d.length;e++){var f=a.trim(d[e]),g="ui-resizable-"+f,h=a('<div class="ui-resizable-handle '+g+'"></div>');/sw|se|ne|nw/.test(f)&&h.css({zIndex:++c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){c.disabled||(a(this).removeClass("ui-resizable-autohide"),b._handles.show())},function(){c.disabled||b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement);return this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),a.browser.opera&&/relative/.test(f.css("position"))&&f.css({position:"relative",top:"auto",left:"auto"}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b);return!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui());return!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),e<h.maxWidth&&(h.maxWidth=e),g<h.maxHeight&&(h.maxHeight=g);this._vBoundaries=h},_updateCache:function(a){var b=this.options;this.offset=this.helper.offset(),d(a.left)&&(this.position.left=a.left),d(a.top)&&(this.position.top=a.top),d(a.height)&&(this.size.height=a.height),d(a.width)&&(this.size.width=a.width)},_updateRatio:function(a,b){var c=this.options,e=this.position,f=this.size,g=this.axis;d(a.height)?a.width=a.height*this.aspectRatio:d(a.width)&&(a.height=a.width/this.aspectRatio),g=="sw"&&(a.left=e.left+(f.width-a.width),a.top=null),g=="nw"&&(a.top=e.top+(f.height-a.height),a.left=e.left+(f.width-a.width));return a},_respectSize:function(a,b){var c=this.helper,e=this._vBoundaries,f=this._aspectRatio||b.shiftKey,g=this.axis,h=d(a.width)&&e.maxWidth&&e.maxWidth<a.width,i=d(a.height)&&e.maxHeight&&e.maxHeight<a.height,j=d(a.width)&&e.minWidth&&e.minWidth>a.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null);return a},_proportionallyResize:function(){var b=this.options;if(!!this._proportionallyResizeElements.length){var c=this.helper||this.element;for(var d=0;d<this._proportionallyResizeElements.length;d++){var e=this._proportionallyResizeElements[d];if(!this.borderDif){var f=[e.css("borderTopWidth"),e.css("borderRightWidth"),e.css("borderBottomWidth"),e.css("borderLeftWidth")],g=[e.css("paddingTop"),e.css("paddingRight"),e.css("paddingBottom"),e.css("paddingLeft")];this.borderDif=a.map(f,function(a,b){var c=parseInt(a,10)||0,d=parseInt(g[b],10)||0;return c+d})}if(a.browser.msie&&(!!a(c).is(":hidden")||!!a(c).parents(":hidden").length))continue;e.css({height:c.height()-this.borderDif[0]-this.borderDif[2]||0,width:c.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var b=this.element,c=this.options;this.elementOffset=b.offset();if(this._helper){this.helper=this.helper||a('<div style="overflow:hidden;"></div>');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.17"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10),position:b.css("position")})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,e){a(b).each(function(){var b=a(this),f=a(this).data("resizable-alsoresize"),g={},i=e&&e.length?e:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(i,function(a,b){var c=(f[b]||0)+(h[b]||0);c&&c>=0&&(g[b]=c||null)}),a.browser.opera&&/relative/.test(b.css("position"))&&(d._revertToRelativePosition=!0,b.css({position:"absolute",top:"auto",left:"auto"})),b.css(g)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};d._revertToRelativePosition&&(d._revertToRelativePosition=!1,typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)),a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!!i){e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/e.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*e.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}}(jQuery),function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("<div class='ui-selectable-helper'></div>")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy();return this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(!this.options.disabled){var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element});return!1}})}},_mouseDrag:function(b){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!!i&&i.element!=c.element[0]){var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.right<e||i.top>h||i.bottom<f):d.tolerance=="fit"&&(j=i.left>e&&i.right<g&&i.top>f&&i.bottom<h),j?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,c._trigger("selecting",b,{selecting:i.element}))):(i.selecting&&((b.metaKey||b.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),c._trigger("unselecting",b,{unselecting:i.element}))),i.selected&&!b.metaKey&&!b.ctrlKey&&!i.startselected&&(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,c._trigger("unselecting",b,{unselecting:i.element})))}});return!1}},_mouseStop:function(b){var c=this;this.dragged=!1;var d=this.options;a(".ui-unselecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-unselecting"),d.unselecting=!1,d.startselected=!1,c._trigger("unselected",b,{unselected:d.element})}),a(".ui-selecting",this.element[0]).each(function(){var d=a.data(this,"selectable-item");d.$element.removeClass("ui-selecting").addClass("ui-selected"),d.selecting=!1,d.selected=!0,d.startselected=!0,c._trigger("selected",b,{selected:d.element})}),this._trigger("stop",b),this.helper.remove();return!1}}),a.extend(a.ui.selectable,{version:"1.8.17"})}(jQuery),function(a,b){a.widget("ui.sortable",a.ui.mouse,{widgetEventPrefix:"sort",options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f){e=a(this);return!1}});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}this.currentItem=e,this._removeCurrentsFromItems();return!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b);return!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY<c.scrollSensitivity?this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop+c.scrollSpeed:b.pageY-this.overflowOffset.top<c.scrollSensitivity&&(this.scrollParent[0].scrollTop=d=this.scrollParent[0].scrollTop-c.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-b.pageX<c.scrollSensitivity?this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft+c.scrollSpeed:b.pageX-this.overflowOffset.left<c.scrollSensitivity&&(this.scrollParent[0].scrollLeft=d=this.scrollParent[0].scrollLeft-c.scrollSpeed)):(b.pageY-a(document).scrollTop()<c.scrollSensitivity?d=a(document).scrollTop(a(document).scrollTop()-c.scrollSpeed):a(window).height()-(b.pageY-a(document).scrollTop())<c.scrollSensitivity&&(d=a(document).scrollTop(a(document).scrollTop()+c.scrollSpeed)),b.pageX-a(document).scrollLeft()<c.scrollSensitivity?d=a(document).scrollLeft(a(document).scrollLeft()-c.scrollSpeed):a(window).width()-(b.pageX-a(document).scrollLeft())<c.scrollSensitivity&&(d=a(document).scrollLeft(a(document).scrollLeft()+c.scrollSpeed))),d!==!1&&a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b)}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";for(var e=this.items.length-1;e>=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs;return!1},_mouseStop:function(b,c){if(!!b){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1}},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem));return this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"=");return d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")});return d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+j<i&&b+k>f&&b+k<g;return this.options.tolerance=="pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>a[this.floating?"width":"height"]?l:f<b+this.helperProportions.width/2&&c-this.helperProportions.width/2<g&&h<d+this.helperProportions.height/2&&e-this.helperProportions.height/2<i},_intersectsWithPointer:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left,b.width),e=c&&d,f=this._getDragVerticalDirection(),g=this._getDragHorizontalDirection();if(!e)return!1;return this.floating?g&&g=="right"||f=="down"?2:1:f&&(f=="down"?2:1)},_intersectsWithSides:function(b){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,b.top+b.height/2,b.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,b.left+b.width/2,b.width),e=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();return this.floating&&f?f=="right"&&d||f=="left"&&!d:e&&(e=="down"&&c||e=="up"&&!c)},_getDragVerticalDirection:function(){var a=this.positionAbs.top-this.lastPositionAbs.top;return a!=0&&(a>0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this | ||
11 | .lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a),this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b<this.items.length;b++)for(var c=0;c<a.length;c++)a[c]==this.items[b].item[0]&&this.items.splice(b,1)},_refreshItems:function(b){this.items=[],this.containers=[this];var c=this.items,d=this,e=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]],f=this._connectWith();if(f)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i<m;i++){var n=a(l[i]);n.data(this.widgetName+"-item",k),c.push({item:n,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());for(var c=this.items.length-1;c>=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];e||(b.style.visibility="hidden");return b},update:function(a,b){if(!e||!!d.forcePlaceholderSize)b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!!c)if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.items[i][this.containers[d].floating?"left":"top"];Math.abs(j-h)<f&&(f=Math.abs(j-h),g=this.items[i])}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[0]==this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height());return d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.left<this.containment[0]&&(f=this.containment[0]+this.offset.click.left),b.pageY-this.offset.click.top<this.containment[1]&&(g=this.containment[1]+this.offset.click.top),b.pageX-this.offset.click.left>this.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.top<this.containment[1]||h-this.offset.click.top>this.containment[3]?h-this.offset.click.top<this.containment[1]?h+c.grid[1]:h-c.grid[1]:h:h;var i=this.originalPageX+Math.round((f-this.originalPageX)/c.grid[0])*c.grid[0];f=this.containment?i-this.offset.click.left<this.containment[0]||i-this.offset.click.left>this.containment[2]?i-this.offset.click.left<this.containment[0]?i+c.grid[0]:i-c.grid[0]:i:i}}return{top:g-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollTop():e?0:d.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():e?0:d.scrollLeft())}},_rearrange:function(a,b,c,d){c?c[0].appendChild(this.placeholder[0]):b.item[0].parentNode.insertBefore(this.placeholder[0],this.direction=="down"?b.item[0]:b.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var e=this,f=this.counter;window.setTimeout(function(){f==e.counter&&e.refreshPositions(!d)},0)},_clear:function(b,c){this.reverting=!1;var d=[],e=this;!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var f in this._storedCSS)if(this._storedCSS[f]=="auto"||this._storedCSS[f]=="static")this._storedCSS[f]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!c&&d.push(function(a){this._trigger("receive",a,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!c&&d.push(function(a){this._trigger("update",a,this._uiHash())});if(!a.ui.contains(this.element[0],this.currentItem[0])){c||d.push(function(a){this._trigger("remove",a,this._uiHash())});for(var f=this.containers.length-1;f>=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}return!1}c||this._trigger("beforeStop",b,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!=this.currentItem[0]&&this.helper.remove(),this.helper=null;if(!c){for(var f=0;f<d.length;f++)d[f].call(this,b);this._trigger("stop",b,this._uiHash())}this.fromOutside=!1;return!0},_trigger:function(){a.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(b){var c=b||this;return{helper:c.helper,placeholder:c.placeholder||a([]),position:c.position,originalPosition:c.originalPosition,offset:c.positionAbs,item:c.currentItem,sender:b?b.element:null}}}),a.extend(a.ui.sortable,{version:"1.8.17"})}(jQuery),jQuery.effects||function(a,b){function l(b){if(!b||typeof b=="number"||a.fx.speeds[b])return!0;if(typeof b=="string"&&!a.effects[b])return!0;return!1}function k(b,c,d,e){typeof b=="object"&&(e=c,d=null,c=b,b=c.effect),a.isFunction(c)&&(e=c,d=null,c={});if(typeof c=="number"||a.fx.speeds[c])e=d,d=c,c={};a.isFunction(d)&&(e=d,d=null),c=c||{},d=d||c.duration,d=a.fx.off?0:typeof d=="number"?d:d in a.fx.speeds?a.fx.speeds[d]:a.fx.speeds._default,e=e||c.complete;return[b,c,d,e]}function j(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function i(b){var c,d;for(c in b)d=b[c],(d==null||a.isFunction(d)||c in g||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete b[c];return b}function h(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]]){var e=a.length;while(e--)c=a[e],typeof a[c]=="string"&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c])}else for(c in a)typeof a[c]=="string"&&(b[c]=a[c]);return b}function d(b,d){var e;do{e=a.curCSS(b,d);if(e!=""&&e!="transparent"||a.nodeName(b,"body"))break;d="backgroundColor"}while(b=b.parentNode);return c(e)}function c(b){var c;if(b&&b.constructor==Array&&b.length==3)return b;if(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(b))return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];if(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(b))return[parseFloat(c[1])*2.55,parseFloat(c[2])*2.55,parseFloat(c[3])*2.55];if(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(b))return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];if(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(b))return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];if(c=/rgba\(0, 0, 0, 0\)/.exec(b))return e.transparent;return e[a.trim(b).toLowerCase()]}a.effects={},a.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(b,e){a.fx.step[e]=function(a){a.colorInit||(a.start=d(a.elem,e),a.end=c(a.end),a.colorInit=!0),a.elem.style[e]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var e={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},f=["add","remove","toggle"],g={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};a.effects.animateClass=function(b,c,d,e){a.isFunction(d)&&(e=d,d=null);return this.queue(function(){var g=a(this),k=g.attr("style")||" ",l=i(h.call(this)),m,n=g.attr("class");a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),m=i(h.call(this)),g.attr("class",n),g.animate(j(l,m),{queue:!1,duration:c,easing:d,complete:function(){a.each(f,function(a,c){b[c]&&g[c+"Class"](b[c])}),typeof g.attr("style")=="object"?(g.attr("style").cssText="",g.attr("style").cssText=k):g.attr("style",k),e&&e.apply(this,arguments),a.dequeue(this)}})})},a.fn.extend({_addClass:a.fn.addClass,addClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{add:b},c,d,e]):this._addClass(b)},_removeClass:a.fn.removeClass,removeClass:function(b,c,d,e){return c?a.effects.animateClass.apply(this,[{remove:b},c,d,e]):this._removeClass(b)},_toggleClass:a.fn.toggleClass,toggleClass:function(c,d,e,f,g){return typeof d=="boolean"||d===b?e?a.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):a.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(b,c,d,e,f){return a.effects.animateClass.apply(this,[{add:c,remove:b},d,e,f])}}),a.extend(a.effects,{version:"1.8.17",save:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.data("ec.storage."+b[c],a[0].style[b[c]])},restore:function(a,b){for(var c=0;c<b.length;c++)b[c]!==null&&a.css(b[c],a.data("ec.storage."+b[c]))},setMode:function(a,b){b=="toggle"&&(b=a.is(":hidden")?"show":"hide");return b},getBaseline:function(a,b){var c,d;switch(a[0]){case"top":c=0;break;case"middle":c=.5;break;case"bottom":c=1;break;default:c=a[0]/b.height}switch(a[1]){case"left":d=0;break;case"center":d=.5;break;case"right":d=1;break;default:d=a[1]/b.width}return{x:d,y:c}},createWrapper:function(b){if(b.parent().is(".ui-effects-wrapper"))return b.parent();var c={width:b.outerWidth(!0),height:b.outerHeight(!0),"float":b.css("float")},d=a("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e=document.activeElement;b.wrap(d),(b[0]===e||a.contains(b[0],e))&&a(e).focus(),d=b.parent(),b.css("position")=="static"?(d.css({position:"relative"}),b.css({position:"relative"})):(a.extend(c,{position:b.css("position"),zIndex:b.css("z-index")}),a.each(["top","left","bottom","right"],function(a,d){c[d]=b.css(d),isNaN(parseInt(c[d],10))&&(c[d]="auto")}),b.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(b){var c,d=document.activeElement;if(b.parent().is(".ui-effects-wrapper")){c=b.parent().replaceWith(b),(b[0]===d||a.contains(b[0],d))&&a(d).focus();return c}return b},setTransition:function(b,c,d,e){e=e||{},a.each(c,function(a,c){unit=b.cssUnit(c),unit[0]>0&&(e[c]=unit[0]*d+unit[1])});return e}}),a.fn.extend({effect:function(b,c,d,e){var f=k.apply(this,arguments),g={options:f[1],duration:f[2],callback:f[3]},h=g.options.mode,i=a.effects[b];if(a.fx.off||!i)return h?this[h](g.duration,g.callback):this.each(function(){g.callback&&g.callback.call(this)});return i.call(this,g)},_show:a.fn.show,show:function(a){if(l(a))return this._show.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="show";return this.effect.apply(this,b)},_hide:a.fn.hide,hide:function(a){if(l(a))return this._hide.apply(this,arguments);var b=k.apply(this,arguments);b[1].mode="hide";return this.effect.apply(this,b)},__toggle:a.fn.toggle,toggle:function(b){if(l(b)||typeof b=="boolean"||a.isFunction(b))return this.__toggle.apply(this,arguments);var c=k.apply(this,arguments);c[1].mode="toggle";return this.effect.apply(this,c)},cssUnit:function(b){var c=this.css(b),d=[];a.each(["em","px","%","pt"],function(a,b){c.indexOf(b)>0&&(d=[parseFloat(c),b])});return d}}),a.easing.jswing=a.easing.swing,a.extend(a.easing,{def:"easeOutQuad",swing:function(b,c,d,e,f){return a.easing[a.easing.def](b,c,d,e,f)},easeInQuad:function(a,b,c,d,e){return d*(b/=e)*b+c},easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c},easeInOutQuad:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b+c;return-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b+c;return d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c},easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b+c;return-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){if((b/=e/2)<1)return d/2*b*b*b*b*b+c;return d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return b==0?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){if(b==0)return c;if(b==e)return c+d;if((b/=e/2)<1)return d/2*Math.pow(2,10*(b-1))+c;return d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)*b)+c},easeInOutCirc:function(a,b,c,d,e){if((b/=e/2)<1)return-d/2*(Math.sqrt(1-b*b)-1)+c;return d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return-(h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g))+c},easeOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e)==1)return c+d;g||(g=e*.3);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);return h*Math.pow(2,-10*b)*Math.sin((b*e-f)*2*Math.PI/g)+d+c},easeInOutElastic:function(a,b,c,d,e){var f=1.70158,g=0,h=d;if(b==0)return c;if((b/=e/2)==2)return c+d;g||(g=e*.3*1.5);if(h<Math.abs(d)){h=d;var f=g/4}else var f=g/(2*Math.PI)*Math.asin(d/h);if(b<1)return-0.5*h*Math.pow(2,10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)+c;return h*Math.pow(2,-10*(b-=1))*Math.sin((b*e-f)*2*Math.PI/g)*.5+d+c},easeInBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(a,c,d,e,f,g){g==b&&(g=1.70158);if((c/=f/2)<1)return e/2*c*c*(((g*=1.525)+1)*c-g)+d;return e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(b,c,d,e,f){return e-a.easing.easeOutBounce(b,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+.984375)+c},easeInOutBounce:function(b,c,d,e,f){if(c<f/2)return a.easing.easeInBounce(b,c*2,0,e,f)*.5+d;return a.easing.easeOutBounce(b,c*2-f,0,e,f)*.5+e*.5+d}})}(jQuery),function(a,b){a.effects.blind=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=f=="vertical"?"height":"width",i=f=="vertical"?g.height():g.width();e=="show"&&g.css(h,0);var j={};j[h]=e=="show"?i:0,g.animate(j,b.duration,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.effects.bounce=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"up",g=b.options.distance||20,h=b.options.times||5,i=b.duration||250;/show|hide/.test(e)&&d.push("opacity"),a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",g=b.options.distance||(j=="top"?c.outerHeight({margin:!0})/3:c.outerWidth({margin:!0})/3);e=="show"&&c.css("opacity",0).css(j,k=="pos"?-g:g),e=="hide"&&(g=g/(h*2)),e!="hide"&&h--;if(e=="show"){var l={opacity:1};l[j]=(k=="pos"?"+=":"-=")+g,c.animate(l,i/2,b.options.easing),g=g/2,h--}for(var m=0;m<h;m++){var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing),g=e=="hide"?g*2:g/2}if(e=="hide"){var l={opacity:0};l[j]=(k=="pos"?"-=":"+=")+g,c.animate(l,i/2,b.options.easing,function(){c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}else{var n={},p={};n[j]=(k=="pos"?"-=":"+=")+g,p[j]=(k=="pos"?"+=":"-=")+g,c.animate(n,i/2,b.options.easing).animate(p,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)})}c.queue("fx",function(){c.dequeue()}),c.dequeue()})}}(jQuery),function(a,b){a.effects.clip=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","height","width"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"vertical";a.effects.save(c,d),c.show();var g=a.effects.createWrapper(c).css({overflow:"hidden"}),h=c[0].tagName=="IMG"?g:c,i={size:f=="vertical"?"height":"width",position:f=="vertical"?"top":"left"},j=f=="vertical"?h.height():h.width();e=="show"&&(h.css(i.size,0),h.css(i.position,j/2));var k={};k[i.size]=e=="show"?j:0,k[i.position]=e=="show"?0:j/2,h.animate(k,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.drop=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","opacity"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0})/2:c.outerWidth({margin:!0})/2);e=="show"&&c.css("opacity",0).css(g,h=="pos"?-i:i);var j={opacity:e=="show"?1:0};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.explode=function(b){return this.queue(function(){var c=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3,d=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?a(this).is(":visible")?"hide":"show":b.options.mode;var e=a(this).show().css("visibility","hidden"),f=e.offset();f.top-=parseInt(e.css("marginTop"),10)||0,f.left-=parseInt(e.css("marginLeft"),10)||0;var g=e.outerWidth(!0),h=e.outerHeight(!0);for(var i=0;i<c;i++)for(var j=0;j<d;j++)e.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-j*(g/d),top:-i*(h/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/d,height:h/c,left:f.left+j*(g/d)+(b.options.mode=="show"?(j-Math.floor(d/2))*(g/d):0),top:f.top+i*(h/c)+(b.options.mode=="show"?(i-Math.floor(c/2))*(h/c):0),opacity:b.options.mode=="show"?0:1}).animate({left:f.left+j*(g/d)+(b.options.mode=="show"?0:(j-Math.floor(d/2))*(g/d)),top:f.top+i*(h/c)+(b.options.mode=="show"?0:(i-Math.floor(c/2))*(h/c)),opacity:b.options.mode=="show"?1:0},b.duration||500);setTimeout(function(){b.options.mode=="show"?e.css({visibility:"visible"}):e.css({visibility:"visible"}).hide(),b.callback&&b.callback.apply(e[0]),e.dequeue(),a("div.ui-effects-explode").remove()},b.duration||500)})}}(jQuery),function(a,b){a.effects.fade=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.fold=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"hide"),f=b.options.size||15,g=!!b.options.horizFirst,h=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(c,d),c.show();var i=a.effects.createWrapper(c).css({overflow:"hidden"}),j=e=="show"!=g,k=j?["width","height"]:["height","width"],l=j?[i.width(),i.height()]:[i.height(),i.width()],m=/([0-9]+)%/.exec(f);m&&(f=parseInt(m[1],10)/100*l[e=="hide"?0:1]),e=="show"&&i.css(g?{height:0,width:f}:{height:f,width:0});var n={},p={};n[k[0]]=e=="show"?l[0]:f,p[k[1]]=e=="show"?l[1]:0,i.animate(n,h,b.options.easing).animate(p,h,b.options.easing,function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.effects.highlight=function(b){return this.queue(function(){var c=a(this),d=["backgroundImage","backgroundColor","opacity"],e=a.effects.setMode(c,b.options.mode||"show"),f={backgroundColor:c.css("backgroundColor")};e=="hide"&&(f.opacity=0),a.effects.save(c,d),c.show().css({backgroundImage:"none",backgroundColor:b.options.color||"#ffff99"}).animate(f,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),e=="show"&&!a.support.opacity&&this.style.removeAttribute("filter"),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.pulsate=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"show");times=(b.options.times||5)*2-1,duration=b.duration?b.duration/2:a.fx.speeds._default/2,isVisible=c.is(":visible"),animateTo=0,isVisible||(c.css("opacity",0).show(),animateTo=1),(d=="hide"&&isVisible||d=="show"&&!isVisible)&×--;for(var e=0;e<times;e++)c.animate({opacity:animateTo},duration,b.options.easing),animateTo=(animateTo+1)%2;c.animate({opacity:animateTo},duration,b.options.easing,function(){animateTo==0&&c.hide(),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}).dequeue()})}}(jQuery),function(a,b){a.effects.puff=function(b){return this.queue(function(){var c=a(this),d=a.effects.setMode(c,b.options.mode||"hide"),e=parseInt(b.options.percent,10)||150,f=e/100,g={height:c.height(),width:c.width()};a.extend(b.options,{fade:!0,mode:d,percent:d=="hide"?e:100,from:d=="hide"?g:{height:g.height*f,width:g.width*f}}),c.effect("scale",b.options,b.duration,b.callback),c.dequeue()})},a.effects.scale=function(b){return this.queue(function(){var c=a(this),d=a.extend(!0,{},b.options | ||
12 | ),e=a.effects.setMode(c,b.options.mode||"effect"),f=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:e=="hide"?0:100),g=b.options.direction||"both",h=b.options.origin;e!="effect"&&(d.origin=h||["middle","center"],d.restore=!0);var i={height:c.height(),width:c.width()};c.from=b.options.from||(e=="show"?{height:0,width:0}:i);var j={y:g!="horizontal"?f/100:1,x:g!="vertical"?f/100:1};c.to={height:i.height*j.y,width:i.width*j.x},b.options.fade&&(e=="show"&&(c.from.opacity=0,c.to.opacity=1),e=="hide"&&(c.from.opacity=1,c.to.opacity=0)),d.from=c.from,d.to=c.to,d.mode=e,c.effect("size",d,b.duration,b.callback),c.dequeue()})},a.effects.size=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right","width","height","overflow","opacity"],e=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],g=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],i=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],j=a.effects.setMode(c,b.options.mode||"effect"),k=b.options.restore||!1,l=b.options.scale||"both",m=b.options.origin,n={height:c.height(),width:c.width()};c.from=b.options.from||n,c.to=b.options.to||n;if(m){var p=a.effects.getBaseline(m,n);c.from.top=(n.height-c.from.height)*p.y,c.from.left=(n.width-c.from.width)*p.x,c.to.top=(n.height-c.to.height)*p.y,c.to.left=(n.width-c.to.width)*p.x}var q={from:{y:c.from.height/n.height,x:c.from.width/n.width},to:{y:c.to.height/n.height,x:c.to.width/n.width}};if(l=="box"||l=="both")q.from.y!=q.to.y&&(d=d.concat(h),c.from=a.effects.setTransition(c,h,q.from.y,c.from),c.to=a.effects.setTransition(c,h,q.to.y,c.to)),q.from.x!=q.to.x&&(d=d.concat(i),c.from=a.effects.setTransition(c,i,q.from.x,c.from),c.to=a.effects.setTransition(c,i,q.to.x,c.to));(l=="content"||l=="both")&&q.from.y!=q.to.y&&(d=d.concat(g),c.from=a.effects.setTransition(c,g,q.from.y,c.from),c.to=a.effects.setTransition(c,g,q.to.y,c.to)),a.effects.save(c,k?d:e),c.show(),a.effects.createWrapper(c),c.css("overflow","hidden").css(c.from);if(l=="content"||l=="both")h=h.concat(["marginTop","marginBottom"]).concat(g),i=i.concat(["marginLeft","marginRight"]),f=d.concat(h).concat(i),c.find("*[width]").each(function(){child=a(this),k&&a.effects.save(child,f);var c={height:child.height(),width:child.width()};child.from={height:c.height*q.from.y,width:c.width*q.from.x},child.to={height:c.height*q.to.y,width:c.width*q.to.x},q.from.y!=q.to.y&&(child.from=a.effects.setTransition(child,h,q.from.y,child.from),child.to=a.effects.setTransition(child,h,q.to.y,child.to)),q.from.x!=q.to.x&&(child.from=a.effects.setTransition(child,i,q.from.x,child.from),child.to=a.effects.setTransition(child,i,q.to.x,child.to)),child.css(child.from),child.animate(child.to,b.duration,b.options.easing,function(){k&&a.effects.restore(child,f)})});c.animate(c.to,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){c.to.opacity===0&&c.css("opacity",c.from.opacity),j=="hide"&&c.hide(),a.effects.restore(c,k?d:e),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.shake=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"effect"),f=b.options.direction||"left",g=b.options.distance||20,h=b.options.times||3,i=b.duration||b.options.duration||140;a.effects.save(c,d),c.show(),a.effects.createWrapper(c);var j=f=="up"||f=="down"?"top":"left",k=f=="up"||f=="left"?"pos":"neg",l={},m={},n={};l[j]=(k=="pos"?"-=":"+=")+g,m[j]=(k=="pos"?"+=":"-=")+g*2,n[j]=(k=="pos"?"-=":"+=")+g*2,c.animate(l,i,b.options.easing);for(var p=1;p<h;p++)c.animate(m,i,b.options.easing).animate(n,i,b.options.easing);c.animate(m,i,b.options.easing).animate(l,i/2,b.options.easing,function(){a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments)}),c.queue("fx",function(){c.dequeue()}),c.dequeue()})}}(jQuery),function(a,b){a.effects.slide=function(b){return this.queue(function(){var c=a(this),d=["position","top","bottom","left","right"],e=a.effects.setMode(c,b.options.mode||"show"),f=b.options.direction||"left";a.effects.save(c,d),c.show(),a.effects.createWrapper(c).css({overflow:"hidden"});var g=f=="up"||f=="down"?"top":"left",h=f=="up"||f=="left"?"pos":"neg",i=b.options.distance||(g=="top"?c.outerHeight({margin:!0}):c.outerWidth({margin:!0}));e=="show"&&c.css(g,h=="pos"?isNaN(i)?"-"+i:-i:i);var j={};j[g]=(e=="show"?h=="pos"?"+=":"-=":h=="pos"?"-=":"+=")+i,c.animate(j,{queue:!1,duration:b.duration,easing:b.options.easing,complete:function(){e=="hide"&&c.hide(),a.effects.restore(c,d),a.effects.removeWrapper(c),b.callback&&b.callback.apply(this,arguments),c.dequeue()}})})}}(jQuery),function(a,b){a.effects.transfer=function(b){return this.queue(function(){var c=a(this),d=a(b.options.to),e=d.offset(),f={top:e.top,left:e.left,height:d.innerHeight(),width:d.innerWidth()},g=c.offset(),h=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(f,b.duration,b.options.easing,function(){h.remove(),b.callback&&b.callback.apply(c[0],arguments),c.dequeue()})})}}(jQuery),function(a,b){a.widget("ui.accordion",{options:{active:0,animated:"slide",autoHeight:!0,clearStyle:!1,collapsible:!1,event:"click",fillSpace:!1,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("<span></span>").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(b.autoHeight||b.fillHeight)&&c.css("height","");return a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(!(this.options.disabled||b.altKey||b.ctrlKey)){var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}if(f){a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus();return!1}return!0}},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];this._clickHandler({target:b},b);return this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(!d.disabled){if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return}},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!!g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}}),a.extend(a.ui.accordion,{version:"1.8.17",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size())b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);else{if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})}},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})}(jQuery),function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!b.options.disabled&&!b.element.propAttr("readOnly")){d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._move("previous",c),c.preventDefault();break;case e.DOWN:b._move("next",c),c.preventDefault();break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){b.options.disabled||(b.selectedItem=null,b.previous=b.element.val())}).bind("blur.autocomplete",function(a){b.options.disabled||(clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150))}),this._initSource(),this.response=function(){return b._response.apply(b,arguments)},this.menu=a("<ul></ul>").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body",c)[0]).mousedown(function(c){var d=b.menu.element[0];a(c.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(c){c.target!==b.element[0]&&c.target!==d&&!a.ui.contains(d,c.target)&&b.close()})},1),setTimeout(function(){clearTimeout(b.closing)},13)}).menu({focus:function(a,c){var d=c.item.data("item.autocomplete");!1!==b._trigger("focus",a,{item:d})&&/^key/.test(a.originalEvent.type)&&b.element.val(d.value)},selected:function(a,d){var e=d.item.data("item.autocomplete"),f=b.previous;b.element[0]!==c.activeElement&&(b.element.focus(),b.previous=f,setTimeout(function(){b.previous=f,b.selectedItem=e},1)),!1!==b._trigger("select",a,{item:e})&&b.element.val(e.value),b.term=b.element.val(),b.close(a),b.selectedItem=e},blur:function(a,c){b.menu.element.is(":visible")&&b.element.val()!==b.term&&b.element.val(b.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"),a.fn.bgiframe&&this.menu.element.bgiframe(),b.beforeunloadHandler=function(){b.element.removeAttr("autocomplete")},a(window).bind("beforeunload",b.beforeunloadHandler)},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"),this.menu.element.remove(),a(window).unbind("beforeunload",this.beforeunloadHandler),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b==="source"&&this._initSource(),b==="appendTo"&&this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]),b==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var b=this,d,e;a.isArray(this.options.source)?(d=this.options.source,this.source=function(b,c){c(a.ui.autocomplete.filter(d,b.term))}):typeof this.options.source=="string"?(e=this.options.source,this.source=function(d,f){b.xhr&&b.xhr.abort(),b.xhr=a.ajax({url:e,data:d,dataType:"json",autocompleteRequest:++c,success:function(a,b){this.autocompleteRequest===c&&f(a)},error:function(){this.autocompleteRequest===c&&f([])}})}):this.source=this.options.source},search:function(a,b){a=a!=null?a:this.element.val(),this.term=this.element.val();if(a.length<this.options.minLength)return this.close(b);clearTimeout(this.closing);if(this._trigger("search",b)!==!1)return this._search(a)},_search:function(a){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.source({term:a},this.response)},_response:function(a){!this.options.disabled&&a&&a.length?(a=this._normalize(a),this._suggest(a),this._trigger("open")):this.close(),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},close:function(a){clearTimeout(this.closing),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.deactivate(),this._trigger("close",a))},_change:function(a){this.previous!==this.element.val()&&this._trigger("change",a,{item:this.selectedItem})},_normalize:function(b){if(b.length&&b[0].label&&b[0].value)return b;return a.map(b,function(b){if(typeof b=="string")return{label:b,value:b};return a.extend({label:b.label||b.value,value:b.value||b.label},b)})},_suggest:function(b){var c=this.menu.element.empty().zIndex(this.element.zIndex()+1);this._renderMenu(c,b),this.menu.deactivate(),this.menu.refresh(),c.show(),this._resizeMenu(),c.position(a.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var a=this.menu.element;a.outerWidth(Math.max(a.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(b,c){var d=this;a.each(c,function(a,c){d._renderItem(b,c)})},_renderItem:function(b,c){return a("<li></li>").data("item.autocomplete",c).append(a("<a></a>").text(c.label)).appendTo(b)},_move:function(a,b){if(!this.menu.element.is(":visible"))this.search(null,b);else{if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term),this.menu.deactivate();return}this.menu[a](b)}},widget:function(){return this.menu.element}}),a.extend(a.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(b,c){var d=new RegExp(a.ui.autocomplete.escapeRegex(c),"i");return a.grep(b,function(a){return d.test(a.label||a.value||a)})}})}(jQuery),function(a){a.widget("ui.menu",{_create:function(){var b=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){!a(c.target).closest(".ui-menu-item a").length||(c.preventDefault(),b.select(c))}),this.refresh()},refresh:function(){var b=this,c=this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem");c.children("a").addClass("ui-corner-all").attr("tabindex",-1).mouseenter(function(c){b.activate(c,a(this).parent())}).mouseleave(function(){b.deactivate()})},activate:function(a,b){this.deactivate();if(this.hasScroll()){var c=b.offset().top-this.element.offset().top,d=this.element.scrollTop(),e=this.element.height();c<0?this.element.scrollTop(d+c):c>=e&&this.element.scrollTop(d+c-e+b.height())}this.active=b.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end(),this._trigger("focus",a,{item:b})},deactivate:function(){!this.active||(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(a,b,c){if(!this.active)this.activate(c,this.element.children(b));else{var d=this.active[a+"All"](".ui-menu-item").eq(0);d.length?this.activate(c,d):this.activate(c,this.element.children(b))}},nextPage:function(b){if(this.hasScroll()){if(!this.active||this.last()){this.activate(b,this.element.children(".ui-menu-item:first"));return}var c=this.active.offset().top,d=this.element.height(),e=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c-d+a(this).height();return b<10&&b>-10});e.length||(e=this.element.children(".ui-menu-item:last")),this.activate(b,e)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.last()?":first":":last"))},previousPage:function(b){if(this.hasScroll()){if(!this.active||this.first()){this.activate(b,this.element.children(".ui-menu-item:last"));return}var c=this.active.offset().top,d=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var b=a(this).offset().top-c+d-a(this).height();return b<10&&b>-10}),result.length||(result=this.element.children(".ui-menu-item:first")),this.activate(b,result)}else this.activate(b,this.element.children(".ui-menu-item").filter(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()<this.element[a.fn.prop?"prop":"attr"]("scrollHeight")},select:function(a){this._trigger("selected",a,{item:this.active})}})}(jQuery),function(a,b){var c,d,e,f,g="ui-button ui-widget ui-state-default ui-corner-all",h="ui-state-hover ui-state-active ",i="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",j=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},k=function(b){var c=b.name,d=b.form,e=a([]);c&&(d?e=a(d).find("[name='"+c+"']"):e=a("[name='"+c+"']",b.ownerDocument).filter(function(){return!this.form}));return e};a.widget("ui.button",{options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset.button").bind("reset.button",j),typeof this.options.disabled!="boolean"&&(this.options.disabled=this.element.propAttr("disabled")),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var b=this,h=this.options,i=this.type==="checkbox"||this.type==="radio",l="ui-state-hover"+(i?"":" ui-state-active"),m="ui-state-focus";h.label===null&&(h.label=this.buttonElement.html()),this.element.is(":disabled")&&(h.disabled=!0),this.buttonElement.addClass(g).attr("role","button").bind("mouseenter.button",function(){h.disabled||(a(this).addClass("ui-state-hover"),this===c&&a(this).addClass("ui-state-active"))}).bind("mouseleave.button",function(){h.disabled||a(this).removeClass(l)}).bind("click.button",function(a){h.disabled&&(a.preventDefault(),a.stopImmediatePropagation())}),this.element.bind("focus.button",function(){b.buttonElement.addClass(m)}).bind("blur.button",function(){b.buttonElement.removeClass(m)}),i&&(this.element.bind("change.button",function(){f||b.refresh()}),this.buttonElement.bind("mousedown.button",function(a){h.disabled||(f=!1,d=a.pageX,e=a.pageY)}).bind("mouseup.button",function(a){!h.disabled&&(d!==a.pageX||e!==a.pageY)&&(f=!0)})),this.type==="checkbox"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).toggleClass("ui-state-active"),b.buttonElement.attr("aria-pressed",b.element[0].checked)}):this.type==="radio"?this.buttonElement.bind("click.button",function(){if(h.disabled||f)return!1;a(this).addClass("ui-state-active"),b.buttonElement.attr("aria-pressed","true");var c=b.element[0];k(c).not(c).map(function(){return a(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown.button",function(){if(h.disabled)return!1;a(this).addClass("ui-state-active"),c=this,a(document).one("mouseup",function(){c=null})}).bind("mouseup.button",function(){if(h.disabled)return!1;a(this).removeClass("ui-state-active")}).bind("keydown.button",function(b){if(h.disabled)return!1;(b.keyCode==a.ui.keyCode.SPACE||b.keyCode==a.ui.keyCode.ENTER)&&a(this).addClass("ui-state-active")}).bind("keyup.button",function(){a(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(b){b.keyCode===a.ui.keyCode.SPACE&&a(this).click()})),this._setOption("disabled",h.disabled),this._resetButton()},_determineButtonType:function(){this.element.is(":checkbox")?this.type="checkbox":this.element.is(":radio")?this.type="radio":this.element.is("input")?this.type="input":this.type="button";if(this.type==="checkbox"||this.type==="radio"){var a=this.element.parents().filter(":last"),b="label[for='"+this.element.attr("id")+"']";this.buttonElement=a.find(b),this.buttonElement.length||(a=a.length?a.siblings():this.element.siblings(),this.buttonElement=a.filter(b),this.buttonElement.length||(this.buttonElement=a.find(b))),this.element.addClass("ui-helper-hidden-accessible");var c=this.element.is(":checked");c&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.attr("aria-pressed",c)}else this.buttonElement=this.element},widget:function(){return this.buttonElement},destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(g+" "+h+" "+i).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title"),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments);b==="disabled"?c?this.element.propAttr("disabled",!0):this.element.propAttr("disabled",!1):this._resetButton()},refresh:function(){var b=this.element.is(":disabled");b!==this.options.disabled&&this._setOption("disabled",b),this.type==="radio"?k(this.element[0]).each(function(){a(this).is(":checked")?a(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):a(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):this.type==="checkbox"&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if(this.type==="input")this.options.label&&this.element.val(this.options.label);else{var b=this.buttonElement.removeClass(i),c=a("<span></span>",this.element[0].ownerDocument).addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary,f=[];d.primary||d.secondary?(this.options.text&&f.push("ui-button-text-icon"+(e?"s":d.primary?"-primary":"-secondary")),d.primary&&b.prepend("<span class='ui-button-icon-primary ui-icon "+d.primary+"'></span>"),d.secondary&&b.append("<span class='ui-button-icon-secondary ui-icon "+d.secondary+"'></span>"),this.options.text||(f.push(e?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||b.attr("title",c))):f.push("ui-button-text-only"),b.addClass(f.join(" "))}}}),a.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c),a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var b=this.element.css("direction")==="rtl";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(b?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(b?"ui-corner-left":"ui-corner-right").end().end()},destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"),a.Widget.prototype.destroy.call(this)}})}(jQuery),function($,undefined){function isArray(a){return a&&($.browser.safari&&typeof a=="object"&&a.length||a.constructor&&a.constructor.toString().match(/\Array\(\)/))}function extendRemove(a,b){$.extend(a,b);for(var c in b)if(b[c]==null||b[c]==undefined)a[c]=b[c];return a}function bindHover(a){var b="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return a.bind("mouseout",function(a){var c=$(a.target).closest(b);!c.length||c.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){var d=$(c.target).closest(b);!$.datepicker._isDisabledDatepicker(instActive.inline?a.parent()[0]:instActive.input[0])&&!!d.length&&(d.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),d.addClass("ui-state-hover"),d.hasClass("ui-datepicker-prev")&&d.addClass("ui-datepicker-prev-hover"),d.hasClass("ui-datepicker-next")&&d.addClass("ui-datepicker-next-hover"))})}function Datepicker(){this.debug=!1,this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},$.extend(this._defaults,this.regional[""]),this.dpDiv=bindHover($('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}$.extend($.ui,{datepicker:{version:"1.8.17"}});var PROP_NAME="datepicker" | ||
13 | ,dpuuid=(new Date).getTime(),instActive;$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(a){extendRemove(this._defaults,a||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase(),inline=nodeName=="div"||nodeName=="span";target.id||(this.uuid+=1,target.id="dp"+this.uuid);var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{}),nodeName=="input"?this._connectDatepicker(target,inst):inline&&this._inlineDatepicker(target,inst)},_newInst:function(a,b){var c=a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1");return{id:c,input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:b?bindHover($('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>')):this.dpDiv}},_connectDatepicker:function(a,b){var c=$(a);b.append=$([]),b.trigger=$([]);c.hasClass(this.markerClassName)||(this._attachments(c,b),c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),this._autoSize(b),$.data(a,PROP_NAME,b),b.settings.disabled&&this._disableDatepicker(a))},_attachments:function(a,b){var c=this._get(b,"appendText"),d=this._get(b,"isRTL");b.append&&b.append.remove(),c&&(b.append=$('<span class="'+this._appendClass+'">'+c+"</span>"),a[d?"before":"after"](b.append)),a.unbind("focus",this._showDatepicker),b.trigger&&b.trigger.remove();var e=this._get(b,"showOn");(e=="focus"||e=="both")&&a.focus(this._showDatepicker);if(e=="button"||e=="both"){var f=this._get(b,"buttonText"),g=this._get(b,"buttonImage");b.trigger=$(this._get(b,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:g,alt:f,title:f}):$('<button type="button"></button>').addClass(this._triggerClass).html(g==""?f:$("<img/>").attr({src:g,alt:f,title:f}))),a[d?"before":"after"](b.trigger),b.trigger.click(function(){$.datepicker._datepickerShowing&&$.datepicker._lastInput==a[0]?$.datepicker._hideDatepicker():$.datepicker._showDatepicker(a[0]);return!1})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var d=function(a){var b=0,c=0;for(var d=0;d<a.length;d++)a[d].length>b&&(b=a[d].length,c=d);return c};b.setMonth(d(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort"))),b.setDate(d(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a,b){var c=$(a);c.hasClass(this.markerClassName)||(c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(a,c,d){b.settings[c]=d}).bind("getData.datepicker",function(a,c){return this._get(b,c)}),$.data(a,PROP_NAME,b),this._setDate(b,this._getDefaultDate(b),!0),this._updateDatepicker(b),this._updateAlternate(b),b.settings.disabled&&this._disableDatepicker(a),b.dpDiv.css("display","block"))},_dialogDatepicker:function(a,b,c,d,e){var f=this._dialogInst;if(!f){this.uuid+=1;var g="dp"+this.uuid;this._dialogInput=$('<input type="text" id="'+g+'" style="position: absolute; top: -100px; width: 0px; z-index: -10;"/>'),this._dialogInput.keydown(this._doKeyDown),$("body").append(this._dialogInput),f=this._dialogInst=this._newInst(this._dialogInput,!1),f.settings={},$.data(this._dialogInput[0],PROP_NAME,f)}extendRemove(f.settings,d||{}),b=b&&b.constructor==Date?this._formatDate(f,b):b,this._dialogInput.val(b),this._pos=e?e.length?e:[e.pageX,e.pageY]:null;if(!this._pos){var h=document.documentElement.clientWidth,i=document.documentElement.clientHeight,j=document.documentElement.scrollLeft||document.body.scrollLeft,k=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[h/2-100+j,i/2-150+k]}this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),f.settings.onSelect=c,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),$.blockUI&&$.blockUI(this.dpDiv),$.data(this._dialogInput[0],PROP_NAME,f);return this},_destroyDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();$.removeData(a,PROP_NAME),d=="input"?(c.append.remove(),c.trigger.remove(),b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):(d=="div"||d=="span")&&b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!1,c.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().removeClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var b=$(a),c=$.data(a,PROP_NAME);if(!!b.hasClass(this.markerClassName)){var d=a.nodeName.toLowerCase();if(d=="input")a.disabled=!0,c.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if(d=="div"||d=="span"){var e=b.children("."+this._inlineClass);e.children().addClass("ui-state-disabled"),e.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=$.map(this._disabledInputs,function(b){return b==a?null:b}),this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return!1;for(var b=0;b<this._disabledInputs.length;b++)if(this._disabledInputs[b]==a)return!0;return!1},_getInst:function(a){try{return $.data(a,PROP_NAME)}catch(b){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(a,b,c){var d=this._getInst(a);if(arguments.length==2&&typeof b=="string")return b=="defaults"?$.extend({},$.datepicker._defaults):d?b=="all"?$.extend({},d.settings):this._get(d,b):null;var e=b||{};typeof b=="string"&&(e={},e[b]=c);if(d){this._curInst==d&&this._hideDatepicker();var f=this._getDateDatepicker(a,!0),g=this._getMinMaxDate(d,"min"),h=this._getMinMaxDate(d,"max");extendRemove(d.settings,e),g!==null&&e.dateFormat!==undefined&&e.minDate===undefined&&(d.settings.minDate=this._formatDate(d,g)),h!==null&&e.dateFormat!==undefined&&e.maxDate===undefined&&(d.settings.maxDate=this._formatDate(d,h)),this._attachments($(a),d),this._autoSize(d),this._setDate(d,f),this._updateAlternate(d),this._updateDatepicker(d)}},_changeDatepicker:function(a,b,c){this._optionDatepicker(a,b,c)},_refreshDatepicker:function(a){var b=this._getInst(a);b&&this._updateDatepicker(b)},_setDateDatepicker:function(a,b){var c=this._getInst(a);c&&(this._setDate(c,b),this._updateDatepicker(c),this._updateAlternate(c))},_getDateDatepicker:function(a,b){var c=this._getInst(a);c&&!c.inline&&this._setDateFromField(c,b);return c?this._getDate(c):null},_doKeyDown:function(a){var b=$.datepicker._getInst(a.target),c=!0,d=b.dpDiv.is(".ui-datepicker-rtl");b._keyEvent=!0;if($.datepicker._datepickerShowing)switch(a.keyCode){case 9:$.datepicker._hideDatepicker(),c=!1;break;case 13:var e=$("td."+$.datepicker._dayOverClass+":not(."+$.datepicker._currentClass+")",b.dpDiv);e[0]&&$.datepicker._selectDay(a.target,b.selectedMonth,b.selectedYear,e[0]);var f=$.datepicker._get(b,"onSelect");if(f){var g=$.datepicker._formatDate(b);f.apply(b.input?b.input[0]:null,[g,b])}else $.datepicker._hideDatepicker();return!1;case 27:$.datepicker._hideDatepicker();break;case 33:$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 34:$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 35:(a.ctrlKey||a.metaKey)&&$.datepicker._clearDate(a.target),c=a.ctrlKey||a.metaKey;break;case 36:(a.ctrlKey||a.metaKey)&&$.datepicker._gotoToday(a.target),c=a.ctrlKey||a.metaKey;break;case 37:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?1:-1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?-$.datepicker._get(b,"stepBigMonths"):-$.datepicker._get(b,"stepMonths"),"M");break;case 38:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,-7,"D"),c=a.ctrlKey||a.metaKey;break;case 39:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,d?-1:1,"D"),c=a.ctrlKey||a.metaKey,a.originalEvent.altKey&&$.datepicker._adjustDate(a.target,a.ctrlKey?+$.datepicker._get(b,"stepBigMonths"):+$.datepicker._get(b,"stepMonths"),"M");break;case 40:(a.ctrlKey||a.metaKey)&&$.datepicker._adjustDate(a.target,7,"D"),c=a.ctrlKey||a.metaKey;break;default:c=!1}else a.keyCode==36&&a.ctrlKey?$.datepicker._showDatepicker(this):c=!1;c&&(a.preventDefault(),a.stopPropagation())},_doKeyPress:function(a){var b=$.datepicker._getInst(a.target);if($.datepicker._get(b,"constrainInput")){var c=$.datepicker._possibleChars($.datepicker._get(b,"dateFormat")),d=String.fromCharCode(a.charCode==undefined?a.keyCode:a.charCode);return a.ctrlKey||a.metaKey||d<" "||!c||c.indexOf(d)>-1}},_doKeyUp:function(a){var b=$.datepicker._getInst(a.target);if(b.input.val()!=b.lastVal)try{var c=$.datepicker.parseDate($.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,$.datepicker._getFormatConfig(b));c&&($.datepicker._setDateFromField(b),$.datepicker._updateAlternate(b),$.datepicker._updateDatepicker(b))}catch(a){$.datepicker.log(a)}return!0},_showDatepicker:function(a){a=a.target||a,a.nodeName.toLowerCase()!="input"&&(a=$("input",a.parentNode)[0]);if(!$.datepicker._isDisabledDatepicker(a)&&$.datepicker._lastInput!=a){var b=$.datepicker._getInst(a);$.datepicker._curInst&&$.datepicker._curInst!=b&&($.datepicker._curInst.dpDiv.stop(!0,!0),b&&$.datepicker._datepickerShowing&&$.datepicker._hideDatepicker($.datepicker._curInst.input[0]));var c=$.datepicker._get(b,"beforeShow"),d=c?c.apply(a,[a,b]):{};if(d===!1)return;extendRemove(b.settings,d),b.lastVal=null,$.datepicker._lastInput=a,$.datepicker._setDateFromField(b),$.datepicker._inDialog&&(a.value=""),$.datepicker._pos||($.datepicker._pos=$.datepicker._findPos(a),$.datepicker._pos[1]+=a.offsetHeight);var e=!1;$(a).parents().each(function(){e|=$(this).css("position")=="fixed";return!e}),e&&$.browser.opera&&($.datepicker._pos[0]-=document.documentElement.scrollLeft,$.datepicker._pos[1]-=document.documentElement.scrollTop);var f={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null,b.dpDiv.empty(),b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),$.datepicker._updateDatepicker(b),f=$.datepicker._checkOffset(b,f,e),b.dpDiv.css({position:$.datepicker._inDialog&&$.blockUI?"static":e?"fixed":"absolute",display:"none",left:f.left+"px",top:f.top+"px"});if(!b.inline){var g=$.datepicker._get(b,"showAnim"),h=$.datepicker._get(b,"duration"),i=function(){var a=b.dpDiv.find("iframe.ui-datepicker-cover");if(!!a.length){var c=$.datepicker._getBorders(b.dpDiv);a.css({left:-c[0],top:-c[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex($(a).zIndex()+1),$.datepicker._datepickerShowing=!0,$.effects&&$.effects[g]?b.dpDiv.show(g,$.datepicker._get(b,"showOptions"),h,i):b.dpDiv[g||"show"](g?h:null,i),(!g||!h)&&i(),b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus(),$.datepicker._curInst=b}}},_updateDatepicker:function(a){var b=this;b.maxRows=4;var c=$.datepicker._getBorders(a.dpDiv);instActive=a,a.dpDiv.empty().append(this._generateHTML(a));var d=a.dpDiv.find("iframe.ui-datepicker-cover");!d.length||d.css({left:-c[0],top:-c[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}),a.dpDiv.find("."+this._dayOverClass+" a").mouseover();var e=this._getNumberOfMonths(a),f=e[1],g=17;a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),f>1&&a.dpDiv.addClass("ui-datepicker-multi-"+f).css("width",g*f+"em"),a.dpDiv[(e[0]!=1||e[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi"),a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),a==$.datepicker._curInst&&$.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&&!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var h=a.yearshtml;setTimeout(function(){h===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml),h=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(a){return{thin:1,medium:2,thick:3}[a]||a};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var d=a.dpDiv.outerWidth(),e=a.dpDiv.outerHeight(),f=a.input?a.input.outerWidth():0,g=a.input?a.input.outerHeight():0,h=document.documentElement.clientWidth+$(document).scrollLeft(),i=document.documentElement.clientHeight+$(document).scrollTop();b.left-=this._get(a,"isRTL")?d-f:0,b.left-=c&&b.left==a.input.offset().left?$(document).scrollLeft():0,b.top-=c&&b.top==a.input.offset().top+g?$(document).scrollTop():0,b.left-=Math.min(b.left,b.left+d>h&&h>d?Math.abs(b.left+d-h):0),b.top-=Math.min(b.top,b.top+e>i&&i>e?Math.abs(e+g):0);return b},_findPos:function(a){var b=this._getInst(a),c=this._get(b,"isRTL");while(a&&(a.type=="hidden"||a.nodeType!=1||$.expr.filters.hidden(a)))a=a[c?"previousSibling":"nextSibling"];var d=$(a).offset();return[d.left,d.top]},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=$.data(a,PROP_NAME))&&this._datepickerShowing){var c=this._get(b,"showAnim"),d=this._get(b,"duration"),e=this,f=function(){$.datepicker._tidyDialog(b),e._curInst=null};$.effects&&$.effects[c]?b.dpDiv.hide(c,$.datepicker._get(b,"showOptions"),d,f):b.dpDiv[c=="slideDown"?"slideUp":c=="fadeIn"?"fadeOut":"hide"](c?d:null,f),c||f(),this._datepickerShowing=!1;var g=this._get(b,"onClose");g&&g.apply(b.input?b.input[0]:null,[b.input?b.input.val():"",b]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),$.blockUI&&($.unblockUI(),$("body").append(this.dpDiv))),this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(a){if(!!$.datepicker._curInst){var b=$(a.target),c=$.datepicker._getInst(b[0]);(b[0].id!=$.datepicker._mainDivId&&b.parents("#"+$.datepicker._mainDivId).length==0&&!b.hasClass($.datepicker.markerClassName)&&!b.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&(!$.datepicker._inDialog||!$.blockUI)||b.hasClass($.datepicker.markerClassName)&&$.datepicker._curInst!=c)&&$.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){var d=$(a),e=this._getInst(d[0]);this._isDisabledDatepicker(d[0])||(this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"):0),c),this._updateDatepicker(e))},_gotoToday:function(a){var b=$(a),c=this._getInst(b[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate(),c.drawMonth=c.selectedMonth=d.getMonth(),c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c),this._adjustDate(b)},_selectMonthYear:function(a,b,c){var d=$(a),e=this._getInst(d[0]);e["selected"+(c=="M"?"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10),this._notifyChange(e),this._adjustDate(d)},_selectDay:function(a,b,c,d){var e=$(a);if(!$(d).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(e[0])){var f=this._getInst(e[0]);f.selectedDay=f.currentDay=$("a",d).html(),f.selectedMonth=f.currentMonth=b,f.selectedYear=f.currentYear=c,this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){var b=$(a),c=this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(a,b){var c=$(a),d=this._getInst(c[0]);b=b!=null?b:this._formatDate(d),d.input&&d.input.val(b),this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[b,d]):d.input&&d.input.trigger("change"),d.inline?this._updateDatepicker(d):(this._hideDatepicker(),this._lastInput=d.input[0],typeof d.input[0]!="object"&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var b=this._get(a,"altField");if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),d=this._getDate(a),e=this.formatDate(c,d,this._getFormatConfig(a));$(b).each(function(){$(this).val(e)})}},noWeekends:function(a){var b=a.getDay();return[b>0&&b<6,""]},iso8601Week:function(a){var b=new Date(a.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();b.setMonth(0),b.setDate(1);return Math.floor(Math.round((c-b)/864e5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"?b.toString():b+"";if(b=="")return null;var d=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;d=typeof d!="string"?d:(new Date).getFullYear()%100+parseInt(d,10);var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,g=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,h=(c?c.monthNames:null)||this._defaults.monthNames,i=-1,j=-1,k=-1,l=-1,m=!1,n=function(b){var c=s+1<a.length&&a.charAt(s+1)==b;c&&s++;return c},o=function(a){var c=n(a),d=a=="@"?14:a=="!"?20:a=="y"&&c?4:a=="o"?3:2,e=new RegExp("^\\d{1,"+d+"}"),f=b.substring(r).match(e);if(!f)throw"Missing number at position "+r;r+=f[0].length;return parseInt(f[0],10)},p=function(a,c,d){var e=$.map(n(a)?d:c,function(a,b){return[[b,a]]}).sort(function(a,b){return-(a[1].length-b[1].length)}),f=-1;$.each(e,function(a,c){var d=c[1];if(b.substr(r,d.length).toLowerCase()==d.toLowerCase()){f=c[0],r+=d.length;return!1}});if(f!=-1)return f+1;throw"Unknown name at position "+r},q=function(){if(b.charAt(r)!=a.charAt(s))throw"Unexpected literal at position "+r;r++},r=0;for(var s=0;s<a.length;s++)if(m)a.charAt(s)=="'"&&!n("'")?m=!1:q();else switch(a.charAt(s)){case"d":k=o("d");break;case"D":p("D",e,f);break;case"o":l=o("o");break;case"m":j=o("m");break;case"M":j=p("M",g,h);break;case"y":i=o("y");break;case"@":var t=new Date(o("@"));i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"!":var t=new Date((o("!")-this._ticksTo1970)/1e4);i=t.getFullYear(),j=t.getMonth()+1,k=t.getDate();break;case"'":n("'")?q():m=!0;break;default:q()}if(r<b.length)throw"Extra/unparsed characters found in date: "+b.substring(r);i==-1?i=(new Date).getFullYear():i<100&&(i+=(new Date).getFullYear()-(new Date).getFullYear()%100+(i<=d?0:-100));if(l>-1){j=1,k=l;for(;;){var u=this._getDaysInMonth(i,j-1);if(k<=u)break;j++,k-=u}}var t=this._daylightSavingAdjust(new Date(i,j-1,k));if(t.getFullYear()!=i||t.getMonth()+1!=j||t.getDate()!=k)throw"Invalid date";return t},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1e7,formatDate:function(a,b,c){if(!b)return"";var d=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,e=(c?c.dayNames:null)||this._defaults.dayNames,f=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,h=function(b){var c=m+1<a.length&&a.charAt(m+1)==b;c&&m++;return c},i=function(a,b,c){var d=""+b;if(h(a))while(d.length<c)d="0"+d;return d},j=function(a,b,c,d){return h(a)?d[b]:c[b]},k="",l=!1;if(b)for(var m=0;m<a.length;m++)if(l)a.charAt(m)=="'"&&!h("'")?l=!1:k+=a.charAt(m);else switch(a.charAt(m)){case"d":k+=i("d",b.getDate(),2);break;case"D":k+=j("D",b.getDay(),d,e);break;case"o":k+=i("o",Math.round(((new Date(b.getFullYear(),b.getMonth(),b.getDate())).getTime()-(new Date(b.getFullYear(),0,0)).getTime())/864e5),3);break;case"m":k+=i("m",b.getMonth()+1,2);break;case"M":k+=j("M",b.getMonth(),f,g);break;case"y":k+=h("y")?b.getFullYear():(b.getYear()%100<10?"0":"")+b.getYear()%100;break;case"@":k+=b.getTime();break;case"!":k+=b.getTime()*1e4+this._ticksTo1970;break;case"'":h("'")?k+="'":l=!0;break;default:k+=a.charAt(m)}return k},_possibleChars:function(a){var b="",c=!1,d=function(b){var c=e+1<a.length&&a.charAt(e+1)==b;c&&e++;return c};for(var e=0;e<a.length;e++)if(c)a.charAt(e)=="'"&&!d("'")?c=!1:b+=a.charAt(e);else switch(a.charAt(e)){case"d":case"m":case"y":case"@":b+="0123456789";break;case"D":case"M":return null;case"'":d("'")?b+="'":c=!0;break;default:b+=a.charAt(e)}return b},_get:function(a,b){return a.settings[b]!==undefined?a.settings[b]:this._defaults[b]},_setDateFromField:function(a,b){if(a.input.val()!=a.lastVal){var c=this._get(a,"dateFormat"),d=a.lastVal=a.input?a.input.val():null,e,f;e=f=this._getDefaultDate(a);var g=this._getFormatConfig(a);try{e=this.parseDate(c,d,g)||f}catch(h){this.log(h),d=b?"":d}a.selectedDay=e.getDate(),a.drawMonth=a.selectedMonth=e.getMonth(),a.drawYear=a.selectedYear=e.getFullYear(),a.currentDay=d?e.getDate():0,a.currentMonth=d?e.getMonth():0,a.currentYear=d?e.getFullYear():0,this._adjustInstDate(a)}},_getDefaultDate:function(a){return this._restrictMinMax(a,this._determineDate(a,this._get(a,"defaultDate"),new Date))},_determineDate:function(a,b,c){var d=function(a){var b=new Date;b.setDate(b.getDate()+a);return b},e=function(b){try{return $.datepicker.parseDate($.datepicker._get(a,"dateFormat"),b,$.datepicker._getFormatConfig(a))}catch(c){}var d=(b.toLowerCase().match(/^c/)?$.datepicker._getDate(a):null)||new Date,e=d.getFullYear(),f=d.getMonth(),g=d.getDate(),h=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,i=h.exec(b);while(i){switch(i[2]||"d"){case"d":case"D":g+=parseInt(i[1],10);break;case"w":case"W":g+=parseInt(i[1],10)*7;break;case"m":case"M":f+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f));break;case"y":case"Y":e+=parseInt(i[1],10),g=Math.min(g,$.datepicker._getDaysInMonth(e,f))}i=h.exec(b)}return new Date(e,f,g)},f=b==null||b===""?c:typeof b=="string"?e(b):typeof b=="number"?isNaN(b)?c:d(b):new Date(b.getTime());f=f&&f.toString()=="Invalid Date"?c:f,f&&(f.setHours(0),f.setMinutes(0),f.setSeconds(0),f.setMilliseconds(0));return this._daylightSavingAdjust(f)},_daylightSavingAdjust:function(a){if(!a)return null;a.setHours(a.getHours()>12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var d=!b,e=a.selectedMonth,f=a.selectedYear,g=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=g.getDate(),a.drawMonth=a.selectedMonth=a.currentMonth=g.getMonth(),a.drawYear=a.selectedYear=a.currentYear=g.getFullYear(),(e!=a.selectedMonth||f!=a.selectedYear)&&!c&&this._notifyChange(a),this._adjustInstDate(a),a.input&&a.input.val(d?"":this._formatDate(a))},_getDate:function(a){var b=!a.currentYear||a.input&&a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return b},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),d=this._get(a,"showButtonPanel"),e=this._get(a,"hideIfNoPrevNext"),f=this._get(a,"navigationAsDateFormat"),g=this._getNumberOfMonths(a),h=this._get(a,"showCurrentAtPos"),i=this._get(a,"stepMonths"),j=g[0]!=1||g[1]!=1,k=this._daylightSavingAdjust(a.currentDay?new Date(a.currentYear,a.currentMonth,a.currentDay):new Date(9999,9,9)),l=this._getMinMaxDate(a,"min"),m=this._getMinMaxDate(a,"max"),n=a.drawMonth-h,o=a.drawYear;n<0&&(n+=12,o--);if(m){var p=this._daylightSavingAdjust(new Date(m.getFullYear(),m.getMonth()-g[0]*g[1]+1,m.getDate()));p=l&&p<l?l:p;while(this._daylightSavingAdjust(new Date(o,n,1))>p)n--,n<0&&(n=11,o--)}a.drawMonth=n,a.drawYear=o;var q=this._get(a,"prevText");q=f?this.formatDate(q,this._daylightSavingAdjust(new Date(o,n-i,1)),this._getFormatConfig(a)):q;var r=this._canAdjustMonth(a,-1,o,n)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', -"+i+", 'M');\""+' title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>":e?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+q+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"e":"w")+'">'+q+"</span></a>",s=this._get(a,"nextText");s=f?this.formatDate(s,this._daylightSavingAdjust(new Date(o,n+i,1)),this._getFormatConfig(a)):s;var t=this._canAdjustMonth(a,1,o,n)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._adjustDate('#"+a.id+"', +"+i+", 'M');\""+' title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>":e?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+s+'"><span class="ui-icon ui-icon-circle-triangle-'+(c?"w":"e")+'">'+s+"</span></a>",u=this._get(a,"currentText"),v=this._get(a,"gotoCurrent")&&a.currentDay?k:b;u=f?this.formatDate(u,v,this._getFormatConfig(a)):u;var w=a.inline?"":'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery_'+dpuuid+'.datepicker._hideDatepicker();">'+this._get(a,"closeText")+"</button>",x=d?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(c?w:"")+(this._isInRange(a,v)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery_'+dpuuid+".datepicker._gotoToday('#"+a.id+"');\""+">"+u+"</button>":"")+(c?"":w)+"</div>":"",y=parseInt(this._get(a,"firstDay"),10);y=isNaN(y)?0:y;var z=this._get(a,"showWeek"),A=this._get(a,"dayNames"),B=this._get(a,"dayNamesShort"),C=this._get(a,"dayNamesMin"),D=this._get(a,"monthNames"),E=this._get(a,"monthNamesShort"),F=this._get(a,"beforeShowDay"),G=this._get(a,"showOtherMonths"),H=this._get(a,"selectOtherMonths"),I=this._get(a,"calculateWeek")||this.iso8601Week,J=this._getDefaultDate(a),K="";for(var L=0;L<g[0];L++){var M="";this.maxRows=4;for(var N=0;N<g[1];N++){var O=this._daylightSavingAdjust(new Date(o,n,a.selectedDay)),P=" ui-corner-all",Q="";if(j){Q+='<div class="ui-datepicker-group';if(g[1]>1)switch(N){case 0:Q+=" ui-datepicker-group-first",P=" ui-corner-"+(c?"right":"left");break;case g[1]-1:Q+=" ui-datepicker-group-last",P=" ui-corner-"+(c?"left":"right");break;default:Q+=" ui-datepicker-group-middle",P=""}Q+='">'}Q+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+P+'">'+(/all|left/.test(P)&&L==0?c?t:r:"")+(/all|right/.test(P)&&L==0?c?r:t:"")+this._generateMonthYearHeader(a,n,o,l,m,L>0||N>0,D,E)+'</div><table class="ui-datepicker-calendar"><thead>'+"<tr>";var R=z?'<th class="ui-datepicker-week-col">'+this._get(a,"weekHeader")+"</th>":"";for(var S=0;S<7;S++){var T=(S+y)%7;R+="<th"+((S+y+6)%7>=5?' class="ui-datepicker-week-end"':"")+">"+'<span title="'+A[T]+'">'+C[T]+"</span></th>"}Q+=R+"</tr></thead><tbody>";var U=this._getDaysInMonth(o,n);o==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay,U));var V=(this._getFirstDayOfMonth(o,n)-y+7)%7,W=Math.ceil((V+U)/7),X=j?this.maxRows>W?this.maxRows:W:W;this.maxRows=X;var Y=this._daylightSavingAdjust(new Date(o,n,1-V));for(var Z=0;Z<X;Z++){Q+="<tr>";var _=z?'<td class="ui-datepicker-week-col">'+this._get(a,"calculateWeek")(Y)+"</td>":"";for(var S=0;S<7;S++){var ba=F?F.apply(a.input?a.input[0]:null,[Y]):[!0,""],bb=Y.getMonth()!=n,bc=bb&&!H||!ba[0]||l&&Y<l||m&&Y>m;_+='<td class="'+((S+y+6)%7>=5?" ui-datepicker-week-end":"")+(bb?" ui-datepicker-other-month":"")+(Y.getTime()==O.getTime()&&n==a.selectedMonth&&a._keyEvent||J.getTime()==Y.getTime()&&J.getTime()==O.getTime()?" "+this._dayOverClass:"")+(bc?" "+this._unselectableClass+" ui-state-disabled":"")+(bb&&!G?"":" "+ba[1]+(Y.getTime()==k.getTime()?" "+this._currentClass:"")+(Y.getTime()==b.getTime()?" ui-datepicker-today":""))+'"'+((!bb||G)&&ba[2]?' title="'+ba[2]+'"':"")+(bc?"":' onclick="DP_jQuery_'+dpuuid+".datepicker._selectDay('#"+a.id+"',"+Y.getMonth()+","+Y.getFullYear()+', this);return false;"')+">"+(bb&&!G?" ":bc?'<span class="ui-state-default">'+Y.getDate()+"</span>":'<a class="ui-state-default'+(Y.getTime()==b.getTime()?" ui-state-highlight":"")+(Y.getTime()==k.getTime()?" ui-state-active":"")+(bb?" ui-priority-secondary":"")+'" href="#">'+Y.getDate()+"</a>")+"</td>",Y.setDate(Y.getDate()+1),Y=this._daylightSavingAdjust(Y)}Q+=_+"</tr>"}n++,n>11&&(n=0,o++),Q+="</tbody></table>"+(j?"</div>"+(g[0]>0&&N==g[1]-1?'<div class="ui-datepicker-row-break"></div>':""):""),M+=Q}K+=M}K+=x+($.browser.msie&&parseInt($.browser.version,10)<7&&!a.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':""),a._keyEvent=!1;return K},_generateMonthYearHeader:function(a,b,c,d,e,f,g,h){var i=this._get(a,"changeMonth"),j=this._get(a,"changeYear"),k=this._get(a,"showMonthAfterYear"),l='<div class="ui-datepicker-title">',m="";if(f||!i)m+='<span class="ui-datepicker-month">'+g[b]+"</span>";else{var n=d&&d.getFullYear()==c,o=e&&e.getFullYear()==c;m+='<select class="ui-datepicker-month" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'M');\" "+">";for(var p=0;p<12;p++)(!n||p>=d.getMonth())&&(!o||p<=e.getMonth())&&(m+='<option value="'+p+'"'+(p==b?' selected="selected"':"")+">"+h[p]+"</option>");m+="</select>"}k||(l+=m+(f||!i||!j?" ":""));if(!a.yearshtml){a.yearshtml="";if(f||!j)l+='<span class="ui-datepicker-year">'+c+"</span>";else{var q=this._get(a,"yearRange").split(":"),r=(new Date).getFullYear(),s=function(a){var b=a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?r+parseInt(a,10):parseInt(a,10);return isNaN(b)?r:b},t=s(q[0]),u=Math.max(t,s(q[1]||""));t=d?Math.max(t,d.getFullYear()):t,u=e?Math.min(u,e.getFullYear()):u,a.yearshtml+='<select class="ui-datepicker-year" onchange="DP_jQuery_'+dpuuid+".datepicker._selectMonthYear('#"+a.id+"', this, 'Y');\" "+">";for(;t<=u;t++)a.yearshtml+='<option value="'+t+'"'+(t==c?' selected="selected"':"")+">"+t+"</option>";a.yearshtml+="</select>",l+=a.yearshtml,a.yearshtml=null}}l+=this._get(a,"yearSuffix"),k&&(l+=(f||!i||!j?" ":"")+m),l+="</div>";return l},_adjustInstDate:function(a,b,c){var d=a.drawYear+(c=="Y"?b:0),e=a.drawMonth+(c=="M"?b:0),f=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+(c=="D"?b:0),g=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,f)));a.selectedDay=g.getDate(),a.drawMonth=a.selectedMonth=g.getMonth(),a.drawYear=a.selectedYear=g.getFullYear(),(c=="M"||c=="Y")&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),e=c&&b<c?c:b;e=d&&e>d?d:e;return e},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){var b=this._get(a,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),f=this._daylightSavingAdjust(new Date(c,d+(b<0?b:e[0]*e[1]),1));b<0&&f.setDate(this._getDaysInMonth(f.getFullYear(),f.getMonth()));return this._isInRange(a,f)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<=d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);var e=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(d,c,b)):this._daylightSavingAdjust(new Date | ||
14 | (a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),e,this._getFormatConfig(a))}}),$.fn.datepicker=function(a){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv),$.datepicker.initialized=!0);var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return $.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this[0]].concat(b));return this.each(function(){typeof a=="string"?$.datepicker["_"+a+"Datepicker"].apply($.datepicker,[this].concat(b)):$.datepicker._attachDatepicker(this,a)})},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.8.17",window["DP_jQuery_"+dpuuid]=$}(jQuery),function(a,b){var c="ui-dialog ui-widget ui-widget-content ui-corner-all ",d={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},e={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},f=a.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};a.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(b){var c=a(this).css(b).offset().top;c<0&&a(this).css("top",b.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.options.title=this.options.title||this.originalTitle;var b=this,d=b.options,e=d.title||" ",f=a.ui.dialog.getTitleId(b.element),g=(b.uiDialog=a("<div></div>")).appendTo(document.body).hide().addClass(c+d.dialogClass).css({zIndex:d.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(c){d.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}).attr({role:"dialog","aria-labelledby":f}).mousedown(function(a){b.moveToTop(!1,a)}),h=b.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g),i=(b.uiDialogTitlebar=a("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g),j=a('<a href="#"></a>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){j.addClass("ui-state-hover")},function(){j.removeClass("ui-state-hover")}).focus(function(){j.addClass("ui-state-focus")}).blur(function(){j.removeClass("ui-state-focus")}).click(function(a){b.close(a);return!1}).appendTo(i),k=(b.uiDialogTitlebarCloseText=a("<span></span>")).addClass("ui-icon ui-icon-closethick").text(d.closeText).appendTo(j),l=a("<span></span>").addClass("ui-dialog-title").attr("id",f).html(e).prependTo(i);a.isFunction(d.beforeclose)&&!a.isFunction(d.beforeClose)&&(d.beforeClose=d.beforeclose),i.find("*").add(i).disableSelection(),d.draggable&&a.fn.draggable&&b._makeDraggable(),d.resizable&&a.fn.resizable&&b._makeResizable(),b._createButtons(d.buttons),b._isOpen=!1,a.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy(),a.uiDialog.hide(),a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),a.uiDialog.remove(),a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(b){var c=this,d,e;if(!1!==c._trigger("beforeClose",b)){c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",b)}):(c.uiDialog.hide(),c._trigger("close",b)),a.ui.dialog.overlay.resize(),c.options.modal&&(d=0,a(".ui-dialog").each(function(){this!==c.uiDialog[0]&&(e=a(this).css("z-index"),isNaN(e)||(d=Math.max(d,e)))}),a.ui.dialog.maxZ=d);return c}},isOpen:function(){return this._isOpen},moveToTop:function(b,c){var d=this,e=d.options,f;if(e.modal&&!b||!e.stack&&!e.modal)return d._trigger("focus",c);e.zIndex>a.ui.dialog.maxZ&&(a.ui.dialog.maxZ=e.zIndex),d.overlay&&(a.ui.dialog.maxZ+=1,d.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ)),f={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()},a.ui.dialog.maxZ+=1,d.uiDialog.css("z-index",a.ui.dialog.maxZ),d.element.attr(f),d._trigger("focus",c);return d},open:function(){if(!this._isOpen){var b=this,c=b.options,d=b.uiDialog;b.overlay=c.modal?new a.ui.dialog.overlay(b):null,b._size(),b._position(c.position),d.show(c.show),b.moveToTop(!0),c.modal&&d.bind("keydown.ui-dialog",function(b){if(b.keyCode===a.ui.keyCode.TAB){var c=a(":tabbable",this),d=c.filter(":first"),e=c.filter(":last");if(b.target===e[0]&&!b.shiftKey){d.focus(1);return!1}if(b.target===d[0]&&b.shiftKey){e.focus(1);return!1}}}),a(b.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(),b._isOpen=!0,b._trigger("open");return b}},_createButtons:function(b){var c=this,d=!1,e=a("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=a("<div></div>").addClass("ui-dialog-buttonset").appendTo(e);c.uiDialog.find(".ui-dialog-buttonpane").remove(),typeof b=="object"&&b!==null&&a.each(b,function(){return!(d=!0)}),d&&(a.each(b,function(b,d){d=a.isFunction(d)?{click:d,text:b}:d;var e=a('<button type="button"></button>').click(function(){d.click.apply(c.element[0],arguments)}).appendTo(g);a.each(d,function(a,b){a!=="click"&&(a in f?e[a](b):e.attr(a,b))}),a.fn.button&&e.button()}),e.appendTo(c.uiDialog))},_makeDraggable:function(){function f(a){return{position:a.position,offset:a.offset}}var b=this,c=b.options,d=a(document),e;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(d,g){e=c.height==="auto"?"auto":a(this).height(),a(this).height(a(this).height()).addClass("ui-dialog-dragging"),b._trigger("dragStart",d,f(g))},drag:function(a,c){b._trigger("drag",a,f(c))},stop:function(g,h){c.position=[h.position.left-d.scrollLeft(),h.position.top-d.scrollTop()],a(this).removeClass("ui-dialog-dragging").height(e),b._trigger("dragStop",g,f(h)),a.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function h(a){return{originalPosition:a.originalPosition,originalSize:a.originalSize,position:a.position,size:a.size}}c=c===b?this.options.resizable:c;var d=this,e=d.options,f=d.uiDialog.css("position"),g=typeof c=="string"?c:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:g,start:function(b,c){a(this).addClass("ui-dialog-resizing"),d._trigger("resizeStart",b,h(c))},resize:function(a,b){d._trigger("resize",a,h(b))},stop:function(b,c){a(this).removeClass("ui-dialog-resizing"),e.height=a(this).height(),e.width=a(this).width(),d._trigger("resizeStop",b,h(c)),a.ui.dialog.overlay.resize()}}).css("position",f).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(b){var c=[],d=[0,0],e;if(b){if(typeof b=="string"||typeof b=="object"&&"0"in b)c=b.split?b.split(" "):[b[0],b[1]],c.length===1&&(c[1]=c[0]),a.each(["left","top"],function(a,b){+c[a]===c[a]&&(d[a]=c[a],c[a]=b)}),b={my:c.join(" "),at:c.join(" "),offset:d.join(" ")};b=a.extend({},a.ui.dialog.prototype.options.position,b)}else b=a.ui.dialog.prototype.options.position;e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.css({top:0,left:0}).position(a.extend({of:window},b)),e||this.uiDialog.hide()},_setOptions:function(b){var c=this,f={},g=!1;a.each(b,function(a,b){c._setOption(a,b),a in d&&(g=!0),a in e&&(f[a]=b)}),g&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(b,d){var e=this,f=e.uiDialog;switch(b){case"beforeclose":b="beforeClose";break;case"buttons":e._createButtons(d);break;case"closeText":e.uiDialogTitlebarCloseText.text(""+d);break;case"dialogClass":f.removeClass(e.options.dialogClass).addClass(c+d);break;case"disabled":d?f.addClass("ui-dialog-disabled"):f.removeClass("ui-dialog-disabled");break;case"draggable":var g=f.is(":data(draggable)");g&&!d&&f.draggable("destroy"),!g&&d&&e._makeDraggable();break;case"position":e._position(d);break;case"resizable":var h=f.is(":data(resizable)");h&&!d&&f.resizable("destroy"),h&&typeof d=="string"&&f.resizable("option","handles",d),!h&&d!==!1&&e._makeResizable(d);break;case"title":a(".ui-dialog-title",e.uiDialogTitlebar).html(""+(d||" "))}a.Widget.prototype._setOption.apply(e,arguments)},_size:function(){var b=this.options,c,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),b.minWidth>b.width&&(b.width=b.minWidth),c=this.uiDialog.css({height:"auto",width:b.width}).height(),d=Math.max(0,b.minHeight-c);if(b.height==="auto")if(a.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();var f=this.element.css("height","auto").height();e||this.uiDialog.hide(),this.element.height(Math.max(f,d))}else this.element.height(Math.max(b.height-c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),a.extend(a.ui.dialog,{version:"1.8.17",uuid:0,maxZ:0,getTitleId:function(a){var b=a.attr("id");b||(this.uuid+=1,b=this.uuid);return"ui-dialog-title-"+b},overlay:function(b){this.$el=a.ui.dialog.overlay.create(b)}}),a.extend(a.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:a.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(b){this.instances.length===0&&(setTimeout(function(){a.ui.dialog.overlay.instances.length&&a(document).bind(a.ui.dialog.overlay.events,function(b){if(a(b.target).zIndex()<a.ui.dialog.overlay.maxZ)return!1})},1),a(document).bind("keydown.dialog-overlay",function(c){b.options.closeOnEscape&&!c.isDefaultPrevented()&&c.keyCode&&c.keyCode===a.ui.keyCode.ESCAPE&&(b.close(c),c.preventDefault())}),a(window).bind("resize.dialog-overlay",a.ui.dialog.overlay.resize));var c=(this.oldInstances.pop()||a("<div></div>").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});a.fn.bgiframe&&c.bgiframe(),this.instances.push(c);return c},destroy:function(b){var c=a.inArray(b,this.instances);c!=-1&&this.oldInstances.push(this.instances.splice(c,1)[0]),this.instances.length===0&&a([document,window]).unbind(".dialog-overlay"),b.remove();var d=0;a.each(this.instances,function(){d=Math.max(d,this.css("z-index"))}),this.maxZ=d},height:function(){var b,c;if(a.browser.msie&&a.browser.version<7){b=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return b<c?a(window).height()+"px":b+"px"}return a(document).height()+"px"},width:function(){var b,c;if(a.browser.msie){b=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth),c=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);return b<c?a(window).width()+"px":b+"px"}return a(document).width()+"px"},resize:function(){var b=a([]);a.each(a.ui.dialog.overlay.instances,function(){b=b.add(this)}),b.css({width:0,height:0}).css({width:a.ui.dialog.overlay.width(),height:a.ui.dialog.overlay.height()})}}),a.extend(a.ui.dialog.overlay.prototype,{destroy:function(){a.ui.dialog.overlay.destroy(this.$el)}})}(jQuery),function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1];return this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]!==e){var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0}},top:function(b,c){if(c.at[1]!==e){var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];if(!c||!c.ownerDocument)return null;if(b)return this.each(function(){a.offset.setOffset(this,b)});return h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&jQuery.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()}(jQuery),function(a,b){a.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()}),this.valueDiv=a("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove(),a.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===b)return this._value();this._setOption("value",a);return this},_setOption:function(b,c){b==="value"&&(this.options.value=c,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),a.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;typeof a!="number"&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change")),this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%"),this.element.attr("aria-valuenow",a)}}),a.extend(a.ui.progressbar,{version:"1.8.17"})}(jQuery),function(a,b){var c=5;a.widget("ui.slider",a.ui.mouse,{widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var b=this,d=this.options,e=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),f="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",g=d.values&&d.values.length||1,h=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":"")),this.range=a([]),d.range&&(d.range===!0&&(d.values||(d.values=[this._valueMin(),this._valueMin()]),d.values.length&&d.values.length!==2&&(d.values=[d.values[0],d.values[0]])),this.range=a("<div></div>").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:"")));for(var i=e.length;i<g;i+=1)h.push(f);this.handles=e.add(a(h.join("")).appendTo(b.element)),this.handle=this.handles.eq(0),this.handles.add(this.range).filter("a").click(function(a){a.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){d.disabled?a(this).blur():(a(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),a(this).addClass("ui-state-focus"))}).blur(function(){a(this).removeClass("ui-state-focus")}),this.handles.each(function(b){a(this).data("index.ui-slider-handle",b)}),this.handles.keydown(function(d){var e=!0,f=a(this).data("index.ui-slider-handle"),g,h,i,j;if(!b.options.disabled){switch(d.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:e=!1;if(!b._keySliding){b._keySliding=!0,a(this).addClass("ui-state-active"),g=b._start(d,f);if(g===!1)return}}j=b.options.step,b.options.values&&b.options.values.length?h=i=b.values(f):h=i=b.value();switch(d.keyCode){case a.ui.keyCode.HOME:i=b._valueMin();break;case a.ui.keyCode.END:i=b._valueMax();break;case a.ui.keyCode.PAGE_UP:i=b._trimAlignValue(h+(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.PAGE_DOWN:i=b._trimAlignValue(h-(b._valueMax()-b._valueMin())/c);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(h===b._valueMax())return;i=b._trimAlignValue(h+j);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(h===b._valueMin())return;i=b._trimAlignValue(h-j)}b._slide(d,f,i);return e}}).keyup(function(c){var d=a(this).data("index.ui-slider-handle");b._keySliding&&(b._keySliding=!1,b._stop(c,d),b._change(c,d),a(this).removeClass("ui-state-active"))}),this._refreshValue(),this._animateOff=!1},destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider"),this._mouseDestroy();return this},_mouseCapture:function(b){var c=this.options,d,e,f,g,h,i,j,k,l;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),d={x:b.pageX,y:b.pageY},e=this._normValueFromMouse(d),f=this._valueMax()-this._valueMin()+1,h=this,this.handles.each(function(b){var c=Math.abs(e-h.values(b));f>c&&(f=c,g=a(this),i=b)}),c.range===!0&&this.values(1)===c.min&&(i+=1,g=a(this.handles[i])),j=this._start(b,i);if(j===!1)return!1;this._mouseSliding=!0,h._handleIndex=i,g.addClass("ui-state-active").focus(),k=g.offset(),l=!a(b.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:b.pageX-k.left-g.width()/2,top:b.pageY-k.top-g.height()/2-(parseInt(g.css("borderTopWidth"),10)||0)-(parseInt(g.css("borderBottomWidth"),10)||0)+(parseInt(g.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(b,i,e),this._animateOff=!0;return!0},_mouseStart:function(a){return!0},_mouseDrag:function(a){var b={x:a.pageX,y:a.pageY},c=this._normValueFromMouse(b);this._slide(a,this._handleIndex,c);return!1},_mouseStop:function(a){this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(a,this._handleIndex),this._change(a,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1;return!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b,c,d,e,f;this.orientation==="horizontal"?(b=this.elementSize.width,c=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(b=this.elementSize.height,c=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),d=c/b,d>1&&(d=1),d<0&&(d=0),this.orientation==="vertical"&&(d=1-d),e=this._valueMax()-this._valueMin(),f=this._valueMin()+d*e;return this._trimAlignValue(f)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values());return this._trigger("start",a,c)},_slide:function(a,b,c){var d,e,f;this.options.values&&this.options.values.length?(d=this.values(b?0:1),this.options.values.length===2&&this.options.range===!0&&(b===0&&c>d||b===1&&c<d)&&(c=d),c!==this.values(b)&&(e=this.values(),e[b]=c,f=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e}),d=this.values(b?0:1),f!==!1&&this.values(b,c,!0))):c!==this.value()&&(f=this._trigger("slide",a,{handle:this.handles[b],value:c}),f!==!1&&this.value(c))},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};this.options.values&&this.options.values.length&&(c.value=this.values(b),c.values=this.values()),this._trigger("change",a,c)}},value:function(a){if(arguments.length)this.options.value=this._trimAlignValue(a),this._refreshValue(),this._change(null,0);else return this._value()},values:function(b,c){var d,e,f;if(arguments.length>1)this.options.values[b]=this._trimAlignValue(c),this._refreshValue(),this._change(null,b);else{if(!arguments.length)return this._values();if(!a.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(b):this.value();d=this.options.values,e=arguments[0];for(f=0;f<d.length;f+=1)d[f]=this._trimAlignValue(e[f]),this._change(null,f);this._refreshValue()}},_setOption:function(b,c){var d,e=0;a.isArray(this.options.values)&&(e=this.options.values.length),a.Widget.prototype._setOption.apply(this,arguments);switch(b){case"disabled":c?(this.handles.filter(".ui-state-focus").blur(),this.handles.removeClass("ui-state-hover"),this.handles.propAttr("disabled",!0),this.element.addClass("ui-disabled")):(this.handles.propAttr("disabled",!1),this.element.removeClass("ui-disabled"));break;case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":this._animateOff=!0,this._refreshValue();for(d=0;d<e;d+=1)this._change(null,d);this._animateOff=!1}},_value:function(){var a=this.options.value;a=this._trimAlignValue(a);return a},_values:function(a){var b,c,d;if(arguments.length){b=this.options.values[a],b=this._trimAlignValue(b);return b}c=this.options.values.slice();for(d=0;d<c.length;d+=1)c[d]=this._trimAlignValue(c[d]);return c},_trimAlignValue:function(a){if(a<=this._valueMin())return this._valueMin();if(a>=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b,d=a-c;Math.abs(c)*2>=b&&(d+=c>0?b:-b);return parseFloat(d.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var b=this.options.range,c=this.options,d=this,e=this._animateOff?!1:c.animate,f,g={},h,i,j,k;this.options.values&&this.options.values.length?this.handles.each(function(b,i){f=(d.values(b)-d._valueMin())/(d._valueMax()-d._valueMin())*100,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",a(this).stop(1,1)[e?"animate":"css"](g,c.animate),d.options.range===!0&&(d.orientation==="horizontal"?(b===0&&d.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({width:f-h+"%"},{queue:!1,duration:c.animate})):(b===0&&d.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},c.animate),b===1&&d.range[e?"animate":"css"]({height:f-h+"%"},{queue:!1,duration:c.animate}))),h=f}):(i=this.value(),j=this._valueMin(),k=this._valueMax(),f=k!==j?(i-j)/(k-j)*100:0,g[d.orientation==="horizontal"?"left":"bottom"]=f+"%",this.handle.stop(1,1)[e?"animate":"css"](g,c.animate),b==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},c.animate),b==="max"&&this.orientation==="horizontal"&&this.range[e?"animate":"css"]({width:100-f+"%"},{queue:!1,duration:c.animate}),b==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},c.animate),b==="max"&&this.orientation==="vertical"&&this.range[e?"animate":"css"]({height:100-f+"%"},{queue:!1,duration:c.animate}))}}),a.extend(a.ui.slider,{version:"1.8.17"})}(jQuery),function(a,b){function f(){return++d}function e(){return++c}var c=0,d=0;a.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:!1,cookie:null,collapsible:!1,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"<div></div>",remove:null,select:null,show:null,spinner:"<em>Loading…</em>",tabTemplate:"<li><a href='#{href}'><span>#{label}</span></a></li>"},_create:function(){this._tabify(!0)},_setOption:function(a,b){if(a=="selected"){if(this.options.collapsible&&b==this.options.selected)return;this.select(b)}else this.options[a]=b,this._tabify()},_tabId:function(a){return a.title&&a.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+e()},_sanitizeSelector:function(a){return a.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+f());return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(a,b){return{tab:a,panel:b,index:this.anchors.index(a)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function m(b,c){b.css("display",""),!a.support.opacity&&c.opacity&&b[0].style.removeAttribute("filter")}var d=this,e=this.options,f=/^#.+/;this.list=this.element.find("ol,ul").eq(0),this.lis=a(" > li:has(a[href])",this.list),this.anchors=this.lis.map(function(){return a("a",this)[0]}),this.panels=a([]),this.anchors.each(function(b,c){var g=a(c).attr("href"),h=g.split("#")[0],i;h&&(h===location.toString().split("#")[0]||(i=a("base")[0])&&h===i.href)&&(g=c.hash,c.href=g);if(f.test(g))d.panels=d.panels.add(d.element.find(d._sanitizeSelector(g)));else if(g&&g!=="#"){a.data(c,"href.tabs",g),a.data(c,"load.tabs",g.replace(/#.*$/,""));var j=d._tabId(c);c.href="#"+j;var k=d.element.find("#"+j);k.length||(k=a(e.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(d.panels[b-1]||d.list),k.data("destroy.tabs",!0)),d.panels=d.panels.add(k)}else e.disabled.push(b)}),c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"),this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),e.selected===b?(location.hash&&this.anchors.each(function(a,b){if(b.hash==location.hash){e.selected=a;return!1}}),typeof e.selected!="number"&&e.cookie&&(e.selected=parseInt(d._cookie(),10)),typeof e.selected!="number"&&this.lis.filter(".ui-tabs-selected").length&&(e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))),e.selected=e.selected||(this.lis.length?0:-1)):e.selected===null&&(e.selected=-1),e.selected=e.selected>=0&&this.anchors[e.selected]||e.selected<0?e.selected:0,e.disabled=a.unique(e.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(a,b){return d.lis.index(a)}))).sort(),a.inArray(e.selected,e.disabled)!=-1&&e.disabled.splice(a.inArray(e.selected,e.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"),e.selected>=0&&this.anchors.length&&(d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(e.selected).addClass("ui-tabs-selected ui-state-active"),d.element.queue("tabs",function(){d._trigger("show",null,d._ui(d.anchors[e.selected],d.element.find(d._sanitizeSelector(d.anchors[e.selected].hash))[0]))}),this.load(e.selected)),a(window).bind("unload",function(){d.lis.add(d.anchors).unbind(".tabs"),d.lis=d.anchors=d.panels=null})):e.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")),this.element[e.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible"),e.cookie&&this._cookie(e.selected,e.cookie);for(var g=0,h;h=this.lis[g];g++)a(h)[a.inArray(g,e.disabled)!=-1&&!a(h).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");e.cache===!1&&this.anchors.removeData("cache.tabs"),this.lis.add(this.anchors).unbind(".tabs");if(e.event!=="mouseover"){var i=function(a,b){b.is(":not(.ui-state-disabled)")&&b.addClass("ui-state-"+a)},j=function(a,b){b.removeClass("ui-state-"+a)};this.lis.bind("mouseover.tabs",function(){i("hover",a(this))}),this.lis.bind("mouseout.tabs",function(){j("hover",a(this))}),this.anchors.bind("focus.tabs",function(){i("focus",a(this).closest("li"))}),this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var k,l;e.fx&&(a.isArray(e.fx)?(k=e.fx[0],l=e.fx[1]):k=l=e.fx);var n=l?function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.hide().removeClass("ui-tabs-hide").animate(l,l.duration||"normal",function(){m(c,l),d._trigger("show",null,d._ui(b,c[0]))})}:function(b,c){a(b).closest("li").addClass("ui-tabs-selected ui-state-active"),c.removeClass("ui-tabs-hide"),d._trigger("show",null,d._ui(b,c[0]))},o=k?function(a,b){b.animate(k,k.duration||"normal",function(){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),m(b,k),d.element.dequeue("tabs")})}:function(a,b,c){d.lis.removeClass("ui-tabs-selected ui-state-active"),b.addClass("ui-tabs-hide"),d.element.dequeue("tabs")};this.anchors.bind(e.event+".tabs",function(){var b=this,c=a(b).closest("li"),f=d.panels.filter(":not(.ui-tabs-hide)"),g=d.element.find(d._sanitizeSelector(b.hash));if(c.hasClass("ui-tabs-selected")&&!e.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing" | ||
15 | )||d.panels.filter(":animated").length||d._trigger("select",null,d._ui(this,g[0]))===!1){this.blur();return!1}e.selected=d.anchors.index(this),d.abort();if(e.collapsible){if(c.hasClass("ui-tabs-selected")){e.selected=-1,e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){o(b,f)}).dequeue("tabs"),this.blur();return!1}if(!f.length){e.cookie&&d._cookie(e.selected,e.cookie),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this)),this.blur();return!1}}e.cookie&&d._cookie(e.selected,e.cookie);if(g.length)f.length&&d.element.queue("tabs",function(){o(b,f)}),d.element.queue("tabs",function(){n(b,g)}),d.load(d.anchors.index(this));else throw"jQuery UI Tabs: Mismatching fragment identifier.";a.browser.msie&&this.blur()}),this.anchors.bind("click.tabs",function(){return!1})},_getIndex:function(a){typeof a=="string"&&(a=this.anchors.index(this.anchors.filter("[href$="+a+"]")));return a},destroy:function(){var b=this.options;this.abort(),this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs"),this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.anchors.each(function(){var b=a.data(this,"href.tabs");b&&(this.href=b);var c=a(this).unbind(".tabs");a.each(["href","load","cache"],function(a,b){c.removeData(b+".tabs")})}),this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}),b.cookie&&this._cookie(null,b.cookie);return this},add:function(c,d,e){e===b&&(e=this.anchors.length);var f=this,g=this.options,h=a(g.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),i=c.indexOf("#")?this._tabId(a("a",h)[0]):c.replace("#","");h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+i);j.length||(j=a(g.panelTemplate).attr("id",i).data("destroy.tabs",!0)),j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide"),e>=this.lis.length?(h.appendTo(this.list),j.appendTo(this.list[0].parentNode)):(h.insertBefore(this.lis[e]),j.insertBefore(this.panels[e])),g.disabled=a.map(g.disabled,function(a,b){return a>=e?++a:a}),this._tabify(),this.anchors.length==1&&(g.selected=0,h.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0)),this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(b){b=this._getIndex(b);var c=this.options,d=this.lis.eq(b).remove(),e=this.panels.eq(b).remove();d.hasClass("ui-tabs-selected")&&this.anchors.length>1&&this.select(b+(b+1<this.anchors.length?1:-1)),c.disabled=a.map(a.grep(c.disabled,function(a,c){return a!=b}),function(a,c){return a>=b?--a:a}),this._tabify(),this._trigger("remove",null,this._ui(d.find("a")[0],e[0]));return this},enable:function(b){b=this._getIndex(b);var c=this.options;if(a.inArray(b,c.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled"),c.disabled=a.grep(c.disabled,function(a,c){return a!=b}),this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(a){a=this._getIndex(a);var b=this,c=this.options;a!=c.selected&&(this.lis.eq(a).addClass("ui-state-disabled"),c.disabled.push(a),c.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[a],this.panels[a])));return this},select:function(a){a=this._getIndex(a);if(a==-1)if(this.options.collapsible&&this.options.selected!=-1)a=this.options.selected;else return this;this.anchors.eq(a).trigger(this.options.event+".tabs");return this},load:function(b){b=this._getIndex(b);var c=this,d=this.options,e=this.anchors.eq(b)[0],f=a.data(e,"load.tabs");this.abort();if(!f||this.element.queue("tabs").length!==0&&a.data(e,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(d.spinner){var g=a("span",e);g.data("label.tabs",g.html()).html(d.spinner)}this.xhr=a.ajax(a.extend({},d.ajaxOptions,{url:f,success:function(f,g){c.element.find(c._sanitizeSelector(e.hash)).html(f),c._cleanup(),d.cache&&a.data(e,"cache.tabs",!0),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.success(f,g)}catch(h){}},error:function(a,f,g){c._cleanup(),c._trigger("load",null,c._ui(c.anchors[b],c.panels[b]));try{d.ajaxOptions.error(a,f,b,e)}catch(g){}}})),c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]),this.panels.stop(!1,!0),this.element.queue("tabs",this.element.queue("tabs").splice(-2,2)),this.xhr&&(this.xhr.abort(),delete this.xhr),this._cleanup();return this},url:function(a,b){this.anchors.eq(a).removeData("cache.tabs").data("load.tabs",b);return this},length:function(){return this.anchors.length}}),a.extend(a.ui.tabs,{version:"1.8.17"}),a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(a,b){var c=this,d=this.options,e=c._rotate||(c._rotate=function(b){clearTimeout(c.rotation),c.rotation=setTimeout(function(){var a=d.selected;c.select(++a<c.anchors.length?a:0)},a),b&&b.stopPropagation()}),f=c._unrotate||(c._unrotate=b?function(a){t=d.selected,e()}:function(a){a.clientX&&c.rotate(null)});a?(this.element.bind("tabsshow",e),this.anchors.bind(d.event+".tabs",f),e()):(clearTimeout(c.rotation),this.element.unbind("tabsshow",e),this.anchors.unbind(d.event+".tabs",f),delete this._rotate,delete this._unrotate);return this}})}(jQuery) \ No newline at end of file | ||
diff --git a/inc/jquery.lazyload.min.js b/inc/jquery.lazyload.min.js new file mode 100644 index 00000000..2364d8d9 --- /dev/null +++ b/inc/jquery.lazyload.min.js | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Lazy Load - jQuery plugin for lazy loading images | ||
3 | * | ||
4 | * Copyright (c) 2007-2012 Mika Tuupola | ||
5 | * | ||
6 | * Licensed under the MIT license: | ||
7 | * http://www.opensource.org/licenses/mit-license.php | ||
8 | * | ||
9 | * Project home: | ||
10 | * http://www.appelsiini.net/projects/lazyload | ||
11 | * | ||
12 | * Version: 1.7.0 | ||
13 | * | ||
14 | */ | ||
15 | (function(a,b){$window=a(b),a.fn.lazyload=function(c){var d={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null};c&&(undefined!==c.failurelimit&&(c.failure_limit=c.failurelimit,delete c.failurelimit),undefined!==c.effectspeed&&(c.effect_speed=c.effectspeed,delete c.effectspeed),a.extend(d,c));var e=this;return 0==d.event.indexOf("scroll")&&a(d.container).bind(d.event,function(b){var c=0;e.each(function(){$this=a(this);if(d.skip_invisible&&!$this.is(":visible"))return;if(!a.abovethetop(this,d)&&!a.leftofbegin(this,d))if(!a.belowthefold(this,d)&&!a.rightoffold(this,d))$this.trigger("appear");else if(++c>d.failure_limit)return!1})}),this.each(function(){var b=this,c=a(b);b.loaded=!1,c.one("appear",function(){if(!this.loaded){if(d.appear){var f=e.length;d.appear.call(b,f,d)}a("<img />").bind("load",function(){c.hide().attr("src",c.data(d.data_attribute))[d.effect](d.effect_speed),b.loaded=!0;var f=a.grep(e,function(a){return!a.loaded});e=a(f);if(d.load){var g=e.length;d.load.call(b,g,d)}}).attr("src",c.data(d.data_attribute))}}),0!=d.event.indexOf("scroll")&&c.bind(d.event,function(a){b.loaded||c.trigger("appear")})}),$window.bind("resize",function(b){a(d.container).trigger(d.event)}),a(d.container).trigger(d.event),this},a.belowthefold=function(c,d){if(d.container===undefined||d.container===b)var e=$window.height()+$window.scrollTop();else var e=a(d.container).offset().top+a(d.container).height();return e<=a(c).offset().top-d.threshold},a.rightoffold=function(c,d){if(d.container===undefined||d.container===b)var e=$window.width()+$window.scrollLeft();else var e=a(d.container).offset().left+a(d.container).width();return e<=a(c).offset().left-d.threshold},a.abovethetop=function(c,d){if(d.container===undefined||d.container===b)var e=$window.scrollTop();else var e=a(d.container).offset().top;return e>=a(c).offset().top+d.threshold+a(c).height()},a.leftofbegin=function(c,d){if(d.container===undefined||d.container===b)var e=$window.scrollLeft();else var e=a(d.container).offset().left;return e>=a(c).offset().left+d.threshold+a(c).width()},a.inviewport=function(b,c){return!a.rightofscreen(b,c)&&!a.leftofscreen(b,c)&&!a.belowthefold(b,c)&&!a.abovethetop(b,c)},a.extend(a.expr[":"],{"below-the-fold":function(c){return a.belowthefold(c,{threshold:0,container:b})},"above-the-top":function(c){return!a.belowthefold(c,{threshold:0,container:b})},"right-of-screen":function(c){return a.rightoffold(c,{threshold:0,container:b})},"left-of-screen":function(c){return!a.rightoffold(c,{threshold:0,container:b})},"in-viewport":function(c){return!a.inviewport(c,{threshold:0,container:b})},"above-the-fold":function(c){return!a.belowthefold(c,{threshold:0,container:b})},"right-of-fold":function(c){return a.rightoffold(c,{threshold:0,container:b})},"left-of-fold":function(c){return!a.rightoffold(c,{threshold:0,container:b})}})})(jQuery,window) | ||
diff --git a/inc/jquery.min.js b/inc/jquery.min.js new file mode 100644 index 00000000..198b3ff0 --- /dev/null +++ b/inc/jquery.min.js | |||
@@ -0,0 +1,4 @@ | |||
1 | /*! jQuery v1.7.1 jquery.com | jquery.org/license */ | ||
2 | (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test("Â ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; | ||
3 | f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() | ||
4 | {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file | ||
diff --git a/inc/rain.tpl.class.php b/inc/rain.tpl.class.php new file mode 100644 index 00000000..e9f3bd29 --- /dev/null +++ b/inc/rain.tpl.class.php | |||
@@ -0,0 +1,1037 @@ | |||
1 | <?php | ||
2 | |||
3 | /** | ||
4 | * RainTPL | ||
5 | * ------- | ||
6 | * Realized by Federico Ulfo & maintained by the Rain Team | ||
7 | * Distributed under GNU/LGPL 3 License | ||
8 | * | ||
9 | * @version 2.7 | ||
10 | */ | ||
11 | |||
12 | |||
13 | class RainTPL{ | ||
14 | |||
15 | // ------------------------- | ||
16 | // CONFIGURATION | ||
17 | // ------------------------- | ||
18 | |||
19 | /** | ||
20 | * Template directory | ||
21 | * | ||
22 | * @var string | ||
23 | */ | ||
24 | static $tpl_dir = "tpl/"; | ||
25 | |||
26 | |||
27 | /** | ||
28 | * Cache directory. Is the directory where RainTPL will compile the template and save the cache | ||
29 | * | ||
30 | * @var string | ||
31 | */ | ||
32 | static $cache_dir = "tmp/"; | ||
33 | |||
34 | |||
35 | /** | ||
36 | * Template base URL. RainTPL will add this URL to the relative paths of element selected in $path_replace_list. | ||
37 | * | ||
38 | * @var string | ||
39 | */ | ||
40 | static $base_url = null; | ||
41 | |||
42 | |||
43 | /** | ||
44 | * Template extension. | ||
45 | * | ||
46 | * @var string | ||
47 | */ | ||
48 | static $tpl_ext = "html"; | ||
49 | |||
50 | |||
51 | /** | ||
52 | * Path replace is a cool features that replace all relative paths of images (<img src="...">), stylesheet (<link href="...">), script (<script src="...">) and link (<a href="...">) | ||
53 | * Set true to enable the path replace. | ||
54 | * | ||
55 | * @var unknown_type | ||
56 | */ | ||
57 | static $path_replace = true; | ||
58 | |||
59 | |||
60 | /** | ||
61 | * You can set what the path_replace method will replace. | ||
62 | * Avaible options: a, img, link, script, input | ||
63 | * | ||
64 | * @var array | ||
65 | */ | ||
66 | static $path_replace_list = array( 'a', 'img', 'link', 'script', 'input' ); | ||
67 | |||
68 | |||
69 | /** | ||
70 | * You can define in the black list what string are disabled into the template tags | ||
71 | * | ||
72 | * @var unknown_type | ||
73 | */ | ||
74 | static $black_list = array( '\$this', 'raintpl::', 'self::', '_SESSION', '_SERVER', '_ENV', 'eval', 'exec', 'unlink', 'rmdir' ); | ||
75 | |||
76 | |||
77 | /** | ||
78 | * Check template. | ||
79 | * true: checks template update time, if changed it compile them | ||
80 | * false: loads the compiled template. Set false if server doesn't have write permission for cache_directory. | ||
81 | * | ||
82 | */ | ||
83 | static $check_template_update = true; | ||
84 | |||
85 | |||
86 | /** | ||
87 | * PHP tags <? ?> | ||
88 | * True: php tags are enabled into the template | ||
89 | * False: php tags are disabled into the template and rendered as html | ||
90 | * | ||
91 | * @var bool | ||
92 | */ | ||
93 | static $php_enabled = false; | ||
94 | |||
95 | |||
96 | /** | ||
97 | * Debug mode flag. | ||
98 | * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated. | ||
99 | * False: exception is thrown on found error. | ||
100 | * | ||
101 | * @var bool | ||
102 | */ | ||
103 | static $debug = false; | ||
104 | |||
105 | // ------------------------- | ||
106 | |||
107 | |||
108 | // ------------------------- | ||
109 | // RAINTPL VARIABLES | ||
110 | // ------------------------- | ||
111 | |||
112 | /** | ||
113 | * Is the array where RainTPL keep the variables assigned | ||
114 | * | ||
115 | * @var array | ||
116 | */ | ||
117 | public $var = array(); | ||
118 | |||
119 | protected $tpl = array(), // variables to keep the template directories and info | ||
120 | $cache = false, // static cache enabled / disabled | ||
121 | $cache_id = null; // identify only one cache | ||
122 | |||
123 | protected static $config_name_sum = array(); // takes all the config to create the md5 of the file | ||
124 | |||
125 | // ------------------------- | ||
126 | |||
127 | |||
128 | |||
129 | const CACHE_EXPIRE_TIME = 3600; // default cache expire time = hour | ||
130 | |||
131 | |||
132 | |||
133 | /** | ||
134 | * Assign variable | ||
135 | * eg. $t->assign('name','mickey'); | ||
136 | * | ||
137 | * @param mixed $variable_name Name of template variable or associative array name/value | ||
138 | * @param mixed $value value assigned to this variable. Not set if variable_name is an associative array | ||
139 | */ | ||
140 | |||
141 | function assign( $variable, $value = null ){ | ||
142 | if( is_array( $variable ) ) | ||
143 | $this->var += $variable; | ||
144 | else | ||
145 | $this->var[ $variable ] = $value; | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | /** | ||
151 | * Draw the template | ||
152 | * eg. $html = $tpl->draw( 'demo', TRUE ); // return template in string | ||
153 | * or $tpl->draw( $tpl_name ); // echo the template | ||
154 | * | ||
155 | * @param string $tpl_name template to load | ||
156 | * @param boolean $return_string true=return a string, false=echo the template | ||
157 | * @return string | ||
158 | */ | ||
159 | |||
160 | function draw( $tpl_name, $return_string = false ){ | ||
161 | |||
162 | try { | ||
163 | // compile the template if necessary and set the template filepath | ||
164 | $this->check_template( $tpl_name ); | ||
165 | } catch (RainTpl_Exception $e) { | ||
166 | $output = $this->printDebug($e); | ||
167 | die($output); | ||
168 | } | ||
169 | |||
170 | // Cache is off and, return_string is false | ||
171 | // Rain just echo the template | ||
172 | |||
173 | if( !$this->cache && !$return_string ){ | ||
174 | extract( $this->var ); | ||
175 | include $this->tpl['compiled_filename']; | ||
176 | unset( $this->tpl ); | ||
177 | } | ||
178 | |||
179 | |||
180 | // cache or return_string are enabled | ||
181 | // rain get the output buffer to save the output in the cache or to return it as string | ||
182 | |||
183 | else{ | ||
184 | |||
185 | //---------------------- | ||
186 | // get the output buffer | ||
187 | //---------------------- | ||
188 | ob_start(); | ||
189 | extract( $this->var ); | ||
190 | include $this->tpl['compiled_filename']; | ||
191 | $raintpl_contents = ob_get_clean(); | ||
192 | //---------------------- | ||
193 | |||
194 | |||
195 | // save the output in the cache | ||
196 | if( $this->cache ) | ||
197 | file_put_contents( $this->tpl['cache_filename'], "<?php if(!class_exists('raintpl')){exit;}?>" . $raintpl_contents ); | ||
198 | |||
199 | // free memory | ||
200 | unset( $this->tpl ); | ||
201 | |||
202 | // return or print the template | ||
203 | if( $return_string ) return $raintpl_contents; else echo $raintpl_contents; | ||
204 | |||
205 | } | ||
206 | |||
207 | } | ||
208 | |||
209 | |||
210 | |||
211 | /** | ||
212 | * If exists a valid cache for this template it returns the cache | ||
213 | * | ||
214 | * @param string $tpl_name Name of template (set the same of draw) | ||
215 | * @param int $expiration_time Set after how many seconds the cache expire and must be regenerated | ||
216 | * @return string it return the HTML or null if the cache must be recreated | ||
217 | */ | ||
218 | |||
219 | function cache( $tpl_name, $expire_time = self::CACHE_EXPIRE_TIME, $cache_id = null ){ | ||
220 | |||
221 | // set the cache_id | ||
222 | $this->cache_id = $cache_id; | ||
223 | |||
224 | if( !$this->check_template( $tpl_name ) && file_exists( $this->tpl['cache_filename'] ) && ( time() - filemtime( $this->tpl['cache_filename'] ) < $expire_time ) ) | ||
225 | return substr( file_get_contents( $this->tpl['cache_filename'] ), 43 ); | ||
226 | else{ | ||
227 | //delete the cache of the selected template | ||
228 | if (file_exists($this->tpl['cache_filename'])) | ||
229 | unlink($this->tpl['cache_filename'] ); | ||
230 | $this->cache = true; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | |||
235 | |||
236 | /** | ||
237 | * Configure the settings of RainTPL | ||
238 | * | ||
239 | */ | ||
240 | static function configure( $setting, $value = null ){ | ||
241 | if( is_array( $setting ) ) | ||
242 | foreach( $setting as $key => $value ) | ||
243 | self::configure( $key, $value ); | ||
244 | else if( property_exists( __CLASS__, $setting ) ){ | ||
245 | self::$$setting = $value; | ||
246 | self::$config_name_sum[$key] = $value; // take trace of all config | ||
247 | } | ||
248 | } | ||
249 | |||
250 | |||
251 | |||
252 | // check if has to compile the template | ||
253 | // return true if the template has changed | ||
254 | protected function check_template( $tpl_name ){ | ||
255 | |||
256 | if( !isset($this->tpl['checked']) ){ | ||
257 | |||
258 | $tpl_basename = basename( $tpl_name ); // template basename | ||
259 | $tpl_basedir = strpos($tpl_name,"/") ? dirname($tpl_name) . '/' : null; // template basedirectory | ||
260 | $tpl_dir = self::$tpl_dir . $tpl_basedir; // template directory | ||
261 | $this->tpl['tpl_filename'] = $tpl_dir . $tpl_basename . '.' . self::$tpl_ext; // template filename | ||
262 | $temp_compiled_filename = self::$cache_dir . $tpl_basename . "." . md5( $tpl_dir . implode('', self::$config_name_sum)); | ||
263 | $this->tpl['compiled_filename'] = $temp_compiled_filename . '.rtpl.php'; // cache filename | ||
264 | $this->tpl['cache_filename'] = $temp_compiled_filename . '.s_' . $this->cache_id . '.rtpl.php'; // static cache filename | ||
265 | |||
266 | // if the template doesn't exsist throw an error | ||
267 | if( self::$check_template_update && !file_exists( $this->tpl['tpl_filename'] ) ){ | ||
268 | $e = new RainTpl_NotFoundException( 'Template '. $tpl_basename .' not found!' ); | ||
269 | throw $e->setTemplateFile($this->tpl['tpl_filename']); | ||
270 | } | ||
271 | |||
272 | // file doesn't exsist, or the template was updated, Rain will compile the template | ||
273 | if( !file_exists( $this->tpl['compiled_filename'] ) || ( self::$check_template_update && filemtime($this->tpl['compiled_filename']) < filemtime( $this->tpl['tpl_filename'] ) ) ){ | ||
274 | $this->compileFile( $tpl_basename, $tpl_basedir, $this->tpl['tpl_filename'], self::$cache_dir, $this->tpl['compiled_filename'] ); | ||
275 | return true; | ||
276 | } | ||
277 | $this->tpl['checked'] = true; | ||
278 | } | ||
279 | } | ||
280 | |||
281 | |||
282 | /** | ||
283 | * execute stripslaches() on the xml block. Invoqued by preg_replace_callback function below | ||
284 | * @access protected | ||
285 | */ | ||
286 | protected function xml_reSubstitution($capture) { | ||
287 | return "<?php echo '<?xml ".stripslashes($capture[1])." ?>'; ?>"; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * Compile and write the compiled template file | ||
292 | * @access protected | ||
293 | */ | ||
294 | protected function compileFile( $tpl_basename, $tpl_basedir, $tpl_filename, $cache_dir, $compiled_filename ){ | ||
295 | |||
296 | //read template file | ||
297 | $this->tpl['source'] = $template_code = file_get_contents( $tpl_filename ); | ||
298 | |||
299 | //xml substitution | ||
300 | $template_code = preg_replace( "/<\?xml(.*?)\?>/s", "##XML\\1XML##", $template_code ); | ||
301 | |||
302 | //disable php tag | ||
303 | if( !self::$php_enabled ) | ||
304 | $template_code = str_replace( array("<?","?>"), array("<?","?>"), $template_code ); | ||
305 | |||
306 | //xml re-substitution | ||
307 | $template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code ); | ||
308 | |||
309 | //compile template | ||
310 | $template_compiled = "<?php if(!class_exists('raintpl')){exit;}?>" . $this->compileTemplate( $template_code, $tpl_basedir ); | ||
311 | |||
312 | |||
313 | // fix the php-eating-newline-after-closing-tag-problem | ||
314 | $template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled ); | ||
315 | |||
316 | // create directories | ||
317 | if( !is_dir( $cache_dir ) ) | ||
318 | mkdir( $cache_dir, 0755, true ); | ||
319 | |||
320 | if( !is_writable( $cache_dir ) ) | ||
321 | throw new RainTpl_Exception ('Cache directory ' . $cache_dir . 'doesn\'t have write permission. Set write permission or set RAINTPL_CHECK_TEMPLATE_UPDATE to false. More details on http://www.raintpl.com/Documentation/Documentation-for-PHP-developers/Configuration/'); | ||
322 | |||
323 | //write compiled file | ||
324 | file_put_contents( $compiled_filename, $template_compiled ); | ||
325 | } | ||
326 | |||
327 | |||
328 | |||
329 | /** | ||
330 | * Compile template | ||
331 | * @access protected | ||
332 | */ | ||
333 | protected function compileTemplate( $template_code, $tpl_basedir ){ | ||
334 | |||
335 | //tag list | ||
336 | $tag_regexp = array( 'loop' => '(\{loop(?: name){0,1}="\${0,1}[^"]*"\})', | ||
337 | 'loop_close' => '(\{\/loop\})', | ||
338 | 'if' => '(\{if(?: condition){0,1}="[^"]*"\})', | ||
339 | 'elseif' => '(\{elseif(?: condition){0,1}="[^"]*"\})', | ||
340 | 'else' => '(\{else\})', | ||
341 | 'if_close' => '(\{\/if\})', | ||
342 | 'function' => '(\{function="[^"]*"\})', | ||
343 | 'noparse' => '(\{noparse\})', | ||
344 | 'noparse_close'=> '(\{\/noparse\})', | ||
345 | 'ignore' => '(\{ignore\})', | ||
346 | 'ignore_close' => '(\{\/ignore\})', | ||
347 | 'include' => '(\{include="[^"]*"(?: cache="[^"]*")?\})', | ||
348 | 'template_info'=> '(\{\$template_info\})', | ||
349 | 'function' => '(\{function="(\w*?)(?:.*?)"\})' | ||
350 | ); | ||
351 | |||
352 | $tag_regexp = "/" . join( "|", $tag_regexp ) . "/"; | ||
353 | |||
354 | //split the code with the tags regexp | ||
355 | $template_code = preg_split ( $tag_regexp, $template_code, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); | ||
356 | |||
357 | //path replace (src of img, background and href of link) | ||
358 | $template_code = $this->path_replace( $template_code, $tpl_basedir ); | ||
359 | |||
360 | //compile the code | ||
361 | $compiled_code = $this->compileCode( $template_code ); | ||
362 | |||
363 | //return the compiled code | ||
364 | return $compiled_code; | ||
365 | |||
366 | } | ||
367 | |||
368 | |||
369 | |||
370 | /** | ||
371 | * Compile the code | ||
372 | * @access protected | ||
373 | */ | ||
374 | protected function compileCode( $parsed_code ){ | ||
375 | |||
376 | //variables initialization | ||
377 | $compiled_code = $open_if = $comment_is_open = $ignore_is_open = null; | ||
378 | $loop_level = 0; | ||
379 | |||
380 | //read all parsed code | ||
381 | while( $html = array_shift( $parsed_code ) ){ | ||
382 | |||
383 | //close ignore tag | ||
384 | if( !$comment_is_open && strpos( $html, '{/ignore}' ) !== FALSE ) | ||
385 | $ignore_is_open = false; | ||
386 | |||
387 | //code between tag ignore id deleted | ||
388 | elseif( $ignore_is_open ){ | ||
389 | //ignore the code | ||
390 | } | ||
391 | |||
392 | //close no parse tag | ||
393 | elseif( strpos( $html, '{/noparse}' ) !== FALSE ) | ||
394 | $comment_is_open = false; | ||
395 | |||
396 | //code between tag noparse is not compiled | ||
397 | elseif( $comment_is_open ) | ||
398 | $compiled_code .= $html; | ||
399 | |||
400 | //ignore | ||
401 | elseif( strpos( $html, '{ignore}' ) !== FALSE ) | ||
402 | $ignore_is_open = true; | ||
403 | |||
404 | //noparse | ||
405 | elseif( strpos( $html, '{noparse}' ) !== FALSE ) | ||
406 | $comment_is_open = true; | ||
407 | |||
408 | //include tag | ||
409 | elseif( preg_match( '/\{include="([^"]*)"(?: cache="([^"]*)"){0,1}\}/', $html, $code ) ){ | ||
410 | |||
411 | //variables substitution | ||
412 | $include_var = $this->var_replace( $code[ 1 ], $left_delimiter = null, $right_delimiter = null, $php_left_delimiter = '".' , $php_right_delimiter = '."', $loop_level ); | ||
413 | |||
414 | // if the cache is active | ||
415 | if( isset($code[ 2 ]) ){ | ||
416 | |||
417 | //dynamic include | ||
418 | $compiled_code .= '<?php $tpl = new RainTpl;' . | ||
419 | 'if( $cache = $tpl->cache( $template = basename("'.$include_var.'") ) )' . | ||
420 | ' echo $cache;' . | ||
421 | 'else{' . | ||
422 | ' $tpl_dir_temp = self::$tpl_dir;' . | ||
423 | ' $tpl->assign( $this->var );' . | ||
424 | ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ). | ||
425 | ' $tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'. | ||
426 | '} ?>'; | ||
427 | } | ||
428 | else{ | ||
429 | |||
430 | //dynamic include | ||
431 | $compiled_code .= '<?php $tpl = new RainTpl;' . | ||
432 | '$tpl_dir_temp = self::$tpl_dir;' . | ||
433 | '$tpl->assign( $this->var );' . | ||
434 | ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ). | ||
435 | '$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'. | ||
436 | '?>'; | ||
437 | |||
438 | |||
439 | } | ||
440 | |||
441 | } | ||
442 | |||
443 | //loop | ||
444 | elseif( preg_match( '/\{loop(?: name){0,1}="\${0,1}([^"]*)"\}/', $html, $code ) ){ | ||
445 | |||
446 | //increase the loop counter | ||
447 | $loop_level++; | ||
448 | |||
449 | //replace the variable in the loop | ||
450 | $var = $this->var_replace( '$' . $code[ 1 ], $tag_left_delimiter=null, $tag_right_delimiter=null, $php_left_delimiter=null, $php_right_delimiter=null, $loop_level-1 ); | ||
451 | |||
452 | //loop variables | ||
453 | $counter = "\$counter$loop_level"; // count iteration | ||
454 | $key = "\$key$loop_level"; // key | ||
455 | $value = "\$value$loop_level"; // value | ||
456 | |||
457 | //loop code | ||
458 | $compiled_code .= "<?php $counter=-1; if( isset($var) && is_array($var) && sizeof($var) ) foreach( $var as $key => $value ){ $counter++; ?>"; | ||
459 | |||
460 | } | ||
461 | |||
462 | //close loop tag | ||
463 | elseif( strpos( $html, '{/loop}' ) !== FALSE ) { | ||
464 | |||
465 | //iterator | ||
466 | $counter = "\$counter$loop_level"; | ||
467 | |||
468 | //decrease the loop counter | ||
469 | $loop_level--; | ||
470 | |||
471 | //close loop code | ||
472 | $compiled_code .= "<?php } ?>"; | ||
473 | |||
474 | } | ||
475 | |||
476 | //if | ||
477 | elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){ | ||
478 | |||
479 | //increase open if counter (for intendation) | ||
480 | $open_if++; | ||
481 | |||
482 | //tag | ||
483 | $tag = $code[ 0 ]; | ||
484 | |||
485 | //condition attribute | ||
486 | $condition = $code[ 1 ]; | ||
487 | |||
488 | // check if there's any function disabled by black_list | ||
489 | $this->function_check( $tag ); | ||
490 | |||
491 | //variable substitution into condition (no delimiter into the condition) | ||
492 | $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); | ||
493 | |||
494 | //if code | ||
495 | $compiled_code .= "<?php if( $parsed_condition ){ ?>"; | ||
496 | |||
497 | } | ||
498 | |||
499 | //elseif | ||
500 | elseif( preg_match( '/\{elseif(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){ | ||
501 | |||
502 | //tag | ||
503 | $tag = $code[ 0 ]; | ||
504 | |||
505 | //condition attribute | ||
506 | $condition = $code[ 1 ]; | ||
507 | |||
508 | //variable substitution into condition (no delimiter into the condition) | ||
509 | $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); | ||
510 | |||
511 | //elseif code | ||
512 | $compiled_code .= "<?php }elseif( $parsed_condition ){ ?>"; | ||
513 | } | ||
514 | |||
515 | //else | ||
516 | elseif( strpos( $html, '{else}' ) !== FALSE ) { | ||
517 | |||
518 | //else code | ||
519 | $compiled_code .= '<?php }else{ ?>'; | ||
520 | |||
521 | } | ||
522 | |||
523 | //close if tag | ||
524 | elseif( strpos( $html, '{/if}' ) !== FALSE ) { | ||
525 | |||
526 | //decrease if counter | ||
527 | $open_if--; | ||
528 | |||
529 | // close if code | ||
530 | $compiled_code .= '<?php } ?>'; | ||
531 | |||
532 | } | ||
533 | |||
534 | //function | ||
535 | elseif( preg_match( '/\{function="(\w*)(.*?)"\}/', $html, $code ) ){ | ||
536 | |||
537 | //tag | ||
538 | $tag = $code[ 0 ]; | ||
539 | |||
540 | //function | ||
541 | $function = $code[ 1 ]; | ||
542 | |||
543 | // check if there's any function disabled by black_list | ||
544 | $this->function_check( $tag ); | ||
545 | |||
546 | if( empty( $code[ 2 ] ) ) | ||
547 | $parsed_function = $function . "()"; | ||
548 | else | ||
549 | // parse the function | ||
550 | $parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); | ||
551 | |||
552 | //if code | ||
553 | $compiled_code .= "<?php echo $parsed_function; ?>"; | ||
554 | } | ||
555 | |||
556 | // show all vars | ||
557 | elseif ( strpos( $html, '{$template_info}' ) !== FALSE ) { | ||
558 | |||
559 | //tag | ||
560 | $tag = '{$template_info}'; | ||
561 | |||
562 | //if code | ||
563 | $compiled_code .= '<?php echo "<pre>"; print_r( $this->var ); echo "</pre>"; ?>'; | ||
564 | } | ||
565 | |||
566 | |||
567 | //all html code | ||
568 | else{ | ||
569 | |||
570 | //variables substitution (es. {$title}) | ||
571 | $html = $this->var_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true ); | ||
572 | //const substitution (es. {#CONST#}) | ||
573 | $html = $this->const_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true ); | ||
574 | //functions substitution (es. {"string"|functions}) | ||
575 | $compiled_code .= $this->func_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '<?php ', $php_right_delimiter = ';?>', $loop_level, $echo = true ); | ||
576 | } | ||
577 | } | ||
578 | |||
579 | if( $open_if > 0 ) { | ||
580 | $e = new RainTpl_SyntaxException('Error! You need to close an {if} tag in ' . $this->tpl['tpl_filename'] . ' template'); | ||
581 | throw $e->setTemplateFile($this->tpl['tpl_filename']); | ||
582 | } | ||
583 | return $compiled_code; | ||
584 | } | ||
585 | |||
586 | |||
587 | |||
588 | protected function reduce_path( $path ){ | ||
589 | $path = str_replace( "//", "/", $path ); | ||
590 | return preg_replace('/\w+\/\.\.\//', '', $path ); | ||
591 | } | ||
592 | |||
593 | |||
594 | |||
595 | /** | ||
596 | * replace the path of image src, link href and a href. | ||
597 | * url => template_dir/url | ||
598 | * url# => url | ||
599 | * http://url => http://url | ||
600 | * | ||
601 | * @param string $html | ||
602 | * @return string html sostituito | ||
603 | */ | ||
604 | protected function path_replace( $html, $tpl_basedir ){ | ||
605 | |||
606 | if( self::$path_replace ){ | ||
607 | |||
608 | $tpl_dir = self::$base_url . self::$tpl_dir . $tpl_basedir; | ||
609 | |||
610 | // reduce the path | ||
611 | $path = $this->reduce_path($tpl_dir); | ||
612 | |||
613 | $exp = $sub = array(); | ||
614 | |||
615 | if( in_array( "img", self::$path_replace_list ) ){ | ||
616 | $exp = array( '/<img(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<img(.*?)src=(?:")([^"]+?)#(?:")/i', '/<img(.*?)src="(.*?)"/', '/<img(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ); | ||
617 | $sub = array( '<img$1src=@$2://$3@', '<img$1src=@$2@', '<img$1src="' . $path . '$2"', '<img$1src="$2"' ); | ||
618 | } | ||
619 | |||
620 | if( in_array( "script", self::$path_replace_list ) ){ | ||
621 | $exp = array_merge( $exp , array( '/<script(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<script(.*?)src=(?:")([^"]+?)#(?:")/i', '/<script(.*?)src="(.*?)"/', '/<script(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) ); | ||
622 | $sub = array_merge( $sub , array( '<script$1src=@$2://$3@', '<script$1src=@$2@', '<script$1src="' . $path . '$2"', '<script$1src="$2"' ) ); | ||
623 | } | ||
624 | |||
625 | if( in_array( "link", self::$path_replace_list ) ){ | ||
626 | $exp = array_merge( $exp , array( '/<link(.*?)href=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<link(.*?)href=(?:")([^"]+?)#(?:")/i', '/<link(.*?)href="(.*?)"/', '/<link(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) ); | ||
627 | $sub = array_merge( $sub , array( '<link$1href=@$2://$3@', '<link$1href=@$2@' , '<link$1href="' . $path . '$2"', '<link$1href="$2"' ) ); | ||
628 | } | ||
629 | |||
630 | if( in_array( "a", self::$path_replace_list ) ){ | ||
631 | $exp = array_merge( $exp , array( '/<a(.*?)href=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<a(.*?)href="(.*?)"/', '/<a(.*?)href=(?:\@)([^"]+?)(?:\@)/i' ) ); | ||
632 | $sub = array_merge( $sub , array( '<a$1href=@$2://$3@', '<a$1href="' . self::$base_url . '$2"', '<a$1href="$2"' ) ); | ||
633 | } | ||
634 | |||
635 | if( in_array( "input", self::$path_replace_list ) ){ | ||
636 | $exp = array_merge( $exp , array( '/<input(.*?)src=(?:")(http|https)\:\/\/([^"]+?)(?:")/i', '/<input(.*?)src=(?:")([^"]+?)#(?:")/i', '/<input(.*?)src="(.*?)"/', '/<input(.*?)src=(?:\@)([^"]+?)(?:\@)/i' ) ); | ||
637 | $sub = array_merge( $sub , array( '<input$1src=@$2://$3@', '<input$1src=@$2@', '<input$1src="' . $path . '$2"', '<input$1src="$2"' ) ); | ||
638 | } | ||
639 | |||
640 | return preg_replace( $exp, $sub, $html ); | ||
641 | |||
642 | } | ||
643 | else | ||
644 | return $html; | ||
645 | |||
646 | } | ||
647 | |||
648 | |||
649 | |||
650 | |||
651 | |||
652 | // replace const | ||
653 | function const_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){ | ||
654 | // const | ||
655 | return preg_replace( '/\{\#(\w+)\#{0,1}\}/', $php_left_delimiter . ( $echo ? " echo " : null ) . '\\1' . $php_right_delimiter, $html ); | ||
656 | } | ||
657 | |||
658 | |||
659 | |||
660 | // replace functions/modifiers on constants and strings | ||
661 | function func_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){ | ||
662 | |||
663 | preg_match_all( '/' . '\{\#{0,1}(\"{0,1}.*?\"{0,1})(\|\w.*?)\#{0,1}\}' . '/', $html, $matches ); | ||
664 | |||
665 | for( $i=0, $n=count($matches[0]); $i<$n; $i++ ){ | ||
666 | |||
667 | //complete tag ex: {$news.title|substr:0,100} | ||
668 | $tag = $matches[ 0 ][ $i ]; | ||
669 | |||
670 | //variable name ex: news.title | ||
671 | $var = $matches[ 1 ][ $i ]; | ||
672 | |||
673 | //function and parameters associate to the variable ex: substr:0,100 | ||
674 | $extra_var = $matches[ 2 ][ $i ]; | ||
675 | |||
676 | // check if there's any function disabled by black_list | ||
677 | $this->function_check( $tag ); | ||
678 | |||
679 | $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level ); | ||
680 | |||
681 | |||
682 | // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value | ||
683 | $is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var ); | ||
684 | |||
685 | //function associate to variable | ||
686 | $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null; | ||
687 | |||
688 | //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title) | ||
689 | $temp = preg_split( "/\.|\[|\-\>/", $var ); | ||
690 | |||
691 | //variable name | ||
692 | $var_name = $temp[ 0 ]; | ||
693 | |||
694 | //variable path | ||
695 | $variable_path = substr( $var, strlen( $var_name ) ); | ||
696 | |||
697 | //parentesis transform [ e ] in [" e in "] | ||
698 | $variable_path = str_replace( '[', '["', $variable_path ); | ||
699 | $variable_path = str_replace( ']', '"]', $variable_path ); | ||
700 | |||
701 | //transform .$variable in ["$variable"] | ||
702 | $variable_path = preg_replace('/\.\$(\w+)/', '["$\\1"]', $variable_path ); | ||
703 | |||
704 | //transform [variable] in ["variable"] | ||
705 | $variable_path = preg_replace('/\.(\w+)/', '["\\1"]', $variable_path ); | ||
706 | |||
707 | //if there's a function | ||
708 | if( $function_var ){ | ||
709 | |||
710 | // check if there's a function or a static method and separate, function by parameters | ||
711 | $function_var = str_replace("::", "@double_dot@", $function_var ); | ||
712 | |||
713 | // get the position of the first : | ||
714 | if( $dot_position = strpos( $function_var, ":" ) ){ | ||
715 | |||
716 | // get the function and the parameters | ||
717 | $function = substr( $function_var, 0, $dot_position ); | ||
718 | $params = substr( $function_var, $dot_position+1 ); | ||
719 | |||
720 | } | ||
721 | else{ | ||
722 | |||
723 | //get the function | ||
724 | $function = str_replace( "@double_dot@", "::", $function_var ); | ||
725 | $params = null; | ||
726 | |||
727 | } | ||
728 | |||
729 | // replace back the @double_dot@ with :: | ||
730 | $function = str_replace( "@double_dot@", "::", $function ); | ||
731 | $params = str_replace( "@double_dot@", "::", $params ); | ||
732 | |||
733 | |||
734 | } | ||
735 | else | ||
736 | $function = $params = null; | ||
737 | |||
738 | $php_var = $var_name . $variable_path; | ||
739 | |||
740 | // compile the variable for php | ||
741 | if( isset( $function ) ){ | ||
742 | if( $php_var ) | ||
743 | $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter; | ||
744 | else | ||
745 | $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $params ) )" : "$function()" ) . $php_right_delimiter; | ||
746 | } | ||
747 | else | ||
748 | $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter; | ||
749 | |||
750 | $html = str_replace( $tag, $php_var, $html ); | ||
751 | |||
752 | } | ||
753 | |||
754 | return $html; | ||
755 | |||
756 | } | ||
757 | |||
758 | |||
759 | |||
760 | function var_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){ | ||
761 | |||
762 | //all variables | ||
763 | if( preg_match_all( '/' . $tag_left_delimiter . '\$(\w+(?:\.\${0,1}[A-Za-z0-9_]+)*(?:(?:\[\${0,1}[A-Za-z0-9_]+\])|(?:\-\>\${0,1}[A-Za-z0-9_]+))*)(.*?)' . $tag_right_delimiter . '/', $html, $matches ) ){ | ||
764 | |||
765 | for( $parsed=array(), $i=0, $n=count($matches[0]); $i<$n; $i++ ) | ||
766 | $parsed[$matches[0][$i]] = array('var'=>$matches[1][$i],'extra_var'=>$matches[2][$i]); | ||
767 | |||
768 | foreach( $parsed as $tag => $array ){ | ||
769 | |||
770 | //variable name ex: news.title | ||
771 | $var = $array['var']; | ||
772 | |||
773 | //function and parameters associate to the variable ex: substr:0,100 | ||
774 | $extra_var = $array['extra_var']; | ||
775 | |||
776 | // check if there's any function disabled by black_list | ||
777 | $this->function_check( $tag ); | ||
778 | |||
779 | $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level ); | ||
780 | |||
781 | // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value | ||
782 | $is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var ); | ||
783 | |||
784 | //function associate to variable | ||
785 | $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null; | ||
786 | |||
787 | //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title) | ||
788 | $temp = preg_split( "/\.|\[|\-\>/", $var ); | ||
789 | |||
790 | //variable name | ||
791 | $var_name = $temp[ 0 ]; | ||
792 | |||
793 | //variable path | ||
794 | $variable_path = substr( $var, strlen( $var_name ) ); | ||
795 | |||
796 | //parentesis transform [ e ] in [" e in "] | ||
797 | $variable_path = str_replace( '[', '["', $variable_path ); | ||
798 | $variable_path = str_replace( ']', '"]', $variable_path ); | ||
799 | |||
800 | //transform .$variable in ["$variable"] and .variable in ["variable"] | ||
801 | $variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path ); | ||
802 | |||
803 | // if is an assignment also assign the variable to $this->var['value'] | ||
804 | if( $is_init_variable ) | ||
805 | $extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var; | ||
806 | |||
807 | |||
808 | |||
809 | //if there's a function | ||
810 | if( $function_var ){ | ||
811 | |||
812 | // check if there's a function or a static method and separate, function by parameters | ||
813 | $function_var = str_replace("::", "@double_dot@", $function_var ); | ||
814 | |||
815 | |||
816 | // get the position of the first : | ||
817 | if( $dot_position = strpos( $function_var, ":" ) ){ | ||
818 | |||
819 | // get the function and the parameters | ||
820 | $function = substr( $function_var, 0, $dot_position ); | ||
821 | $params = substr( $function_var, $dot_position+1 ); | ||
822 | |||
823 | } | ||
824 | else{ | ||
825 | |||
826 | //get the function | ||
827 | $function = str_replace( "@double_dot@", "::", $function_var ); | ||
828 | $params = null; | ||
829 | |||
830 | } | ||
831 | |||
832 | // replace back the @double_dot@ with :: | ||
833 | $function = str_replace( "@double_dot@", "::", $function ); | ||
834 | $params = str_replace( "@double_dot@", "::", $params ); | ||
835 | } | ||
836 | else | ||
837 | $function = $params = null; | ||
838 | |||
839 | //if it is inside a loop | ||
840 | if( $loop_level ){ | ||
841 | //verify the variable name | ||
842 | if( $var_name == 'key' ) | ||
843 | $php_var = '$key' . $loop_level; | ||
844 | elseif( $var_name == 'value' ) | ||
845 | $php_var = '$value' . $loop_level . $variable_path; | ||
846 | elseif( $var_name == 'counter' ) | ||
847 | $php_var = '$counter' . $loop_level; | ||
848 | else | ||
849 | $php_var = '$' . $var_name . $variable_path; | ||
850 | }else | ||
851 | $php_var = '$' . $var_name . $variable_path; | ||
852 | |||
853 | // compile the variable for php | ||
854 | if( isset( $function ) ) | ||
855 | $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter; | ||
856 | else | ||
857 | $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter; | ||
858 | |||
859 | $html = str_replace( $tag, $php_var, $html ); | ||
860 | |||
861 | |||
862 | } | ||
863 | } | ||
864 | |||
865 | return $html; | ||
866 | } | ||
867 | |||
868 | |||
869 | |||
870 | /** | ||
871 | * Check if function is in black list (sandbox) | ||
872 | * | ||
873 | * @param string $code | ||
874 | * @param string $tag | ||
875 | */ | ||
876 | protected function function_check( $code ){ | ||
877 | |||
878 | $preg = '#(\W|\s)' . implode( '(\W|\s)|(\W|\s)', self::$black_list ) . '(\W|\s)#'; | ||
879 | |||
880 | // check if the function is in the black list (or not in white list) | ||
881 | if( count(self::$black_list) && preg_match( $preg, $code, $match ) ){ | ||
882 | |||
883 | // find the line of the error | ||
884 | $line = 0; | ||
885 | $rows=explode("\n",$this->tpl['source']); | ||
886 | while( !strpos($rows[$line],$code) ) | ||
887 | $line++; | ||
888 | |||
889 | // stop the execution of the script | ||
890 | $e = new RainTpl_SyntaxException('Unallowed syntax in ' . $this->tpl['tpl_filename'] . ' template'); | ||
891 | throw $e->setTemplateFile($this->tpl['tpl_filename']) | ||
892 | ->setTag($code) | ||
893 | ->setTemplateLine($line); | ||
894 | } | ||
895 | |||
896 | } | ||
897 | |||
898 | /** | ||
899 | * Prints debug info about exception or passes it further if debug is disabled. | ||
900 | * | ||
901 | * @param RainTpl_Exception $e | ||
902 | * @return string | ||
903 | */ | ||
904 | protected function printDebug(RainTpl_Exception $e){ | ||
905 | if (!self::$debug) { | ||
906 | throw $e; | ||
907 | } | ||
908 | $output = sprintf('<h2>Exception: %s</h2><h3>%s</h3><p>template: %s</p>', | ||
909 | get_class($e), | ||
910 | $e->getMessage(), | ||
911 | $e->getTemplateFile() | ||
912 | ); | ||
913 | if ($e instanceof RainTpl_SyntaxException) { | ||
914 | if (null != $e->getTemplateLine()) { | ||
915 | $output .= '<p>line: ' . $e->getTemplateLine() . '</p>'; | ||
916 | } | ||
917 | if (null != $e->getTag()) { | ||
918 | $output .= '<p>in tag: ' . htmlspecialchars($e->getTag()) . '</p>'; | ||
919 | } | ||
920 | if (null != $e->getTemplateLine() && null != $e->getTag()) { | ||
921 | $rows=explode("\n", htmlspecialchars($this->tpl['source'])); | ||
922 | $rows[$e->getTemplateLine()] = '<font color=red>' . $rows[$e->getTemplateLine()] . '</font>'; | ||
923 | $output .= '<h3>template code</h3>' . implode('<br />', $rows) . '</pre>'; | ||
924 | } | ||
925 | } | ||
926 | $output .= sprintf('<h3>trace</h3><p>In %s on line %d</p><pre>%s</pre>', | ||
927 | $e->getFile(), $e->getLine(), | ||
928 | nl2br(htmlspecialchars($e->getTraceAsString())) | ||
929 | ); | ||
930 | return $output; | ||
931 | } | ||
932 | } | ||
933 | |||
934 | |||
935 | /** | ||
936 | * Basic Rain tpl exception. | ||
937 | */ | ||
938 | class RainTpl_Exception extends Exception{ | ||
939 | /** | ||
940 | * Path of template file with error. | ||
941 | */ | ||
942 | protected $templateFile = ''; | ||
943 | |||
944 | /** | ||
945 | * Returns path of template file with error. | ||
946 | * | ||
947 | * @return string | ||
948 | */ | ||
949 | public function getTemplateFile() | ||
950 | { | ||
951 | return $this->templateFile; | ||
952 | } | ||
953 | |||
954 | /** | ||
955 | * Sets path of template file with error. | ||
956 | * | ||
957 | * @param string $templateFile | ||
958 | * @return RainTpl_Exception | ||
959 | */ | ||
960 | public function setTemplateFile($templateFile) | ||
961 | { | ||
962 | $this->templateFile = (string) $templateFile; | ||
963 | return $this; | ||
964 | } | ||
965 | } | ||
966 | |||
967 | /** | ||
968 | * Exception thrown when template file does not exists. | ||
969 | */ | ||
970 | class RainTpl_NotFoundException extends RainTpl_Exception{ | ||
971 | } | ||
972 | |||
973 | /** | ||
974 | * Exception thrown when syntax error occurs. | ||
975 | */ | ||
976 | class RainTpl_SyntaxException extends RainTpl_Exception{ | ||
977 | /** | ||
978 | * Line in template file where error has occured. | ||
979 | * | ||
980 | * @var int | null | ||
981 | */ | ||
982 | protected $templateLine = null; | ||
983 | |||
984 | /** | ||
985 | * Tag which caused an error. | ||
986 | * | ||
987 | * @var string | null | ||
988 | */ | ||
989 | protected $tag = null; | ||
990 | |||
991 | /** | ||
992 | * Returns line in template file where error has occured | ||
993 | * or null if line is not defined. | ||
994 | * | ||
995 | * @return int | null | ||
996 | */ | ||
997 | public function getTemplateLine() | ||
998 | { | ||
999 | return $this->templateLine; | ||
1000 | } | ||
1001 | |||
1002 | /** | ||
1003 | * Sets line in template file where error has occured. | ||
1004 | * | ||
1005 | * @param int $templateLine | ||
1006 | * @return RainTpl_SyntaxException | ||
1007 | */ | ||
1008 | public function setTemplateLine($templateLine) | ||
1009 | { | ||
1010 | $this->templateLine = (int) $templateLine; | ||
1011 | return $this; | ||
1012 | } | ||
1013 | |||
1014 | /** | ||
1015 | * Returns tag which caused an error. | ||
1016 | * | ||
1017 | * @return string | ||
1018 | */ | ||
1019 | public function getTag() | ||
1020 | { | ||
1021 | return $this->tag; | ||
1022 | } | ||
1023 | |||
1024 | /** | ||
1025 | * Sets tag which caused an error. | ||
1026 | * | ||
1027 | * @param string $tag | ||
1028 | * @return RainTpl_SyntaxException | ||
1029 | */ | ||
1030 | public function setTag($tag) | ||
1031 | { | ||
1032 | $this->tag = (string) $tag; | ||
1033 | return $this; | ||
1034 | } | ||
1035 | } | ||
1036 | |||
1037 | // -- end | ||
diff --git a/inc/shaarli.css b/inc/shaarli.css new file mode 100644 index 00000000..b4d0414c --- /dev/null +++ b/inc/shaarli.css | |||
@@ -0,0 +1,449 @@ | |||
1 | /* CSS Stylsheet for Shaarli - http://sebsauvage.net/wiki/doku.php?id=php:shaarli */ | ||
2 | |||
3 | /* CSS Reset from Yahoo to cope with browsers CSS inconsistencies. */ | ||
4 | /* | ||
5 | Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html | ||
6 | version: 2.8.2r1 | ||
7 | */ | ||
8 | html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var,optgroup{font-style:inherit;font-weight:inherit;}del,ins{text-decoration:none;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:baseline;}sub{vertical-align:baseline;}legend{color:#000;}input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} | ||
9 | |||
10 | body { font-family: "Trebuchet MS",Verdana,Arial,Helvetica,sans-serif; font-size:10pt; background-color: #ffffff; } | ||
11 | input, textarea { | ||
12 | background-color: #dedede; | ||
13 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
14 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
15 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
16 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
17 | background: -o-linear-gradient(#dedede, #ffffff); | ||
18 | background: linear-gradient(#dedede, #ffffff); | ||
19 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
20 | padding:5px; | ||
21 | border-radius: 5px 5px 5px 5px; | ||
22 | border: none; | ||
23 | color:#000; | ||
24 | |||
25 | } | ||
26 | |||
27 | h1 { font-size:20pt; font-weight:bold; font-style:italic; margin-bottom:20px; } | ||
28 | /* I don't give a shit about IE. He can't understand selectors such as input[type='submit']. */ | ||
29 | |||
30 | /* Buttons */ | ||
31 | .bigbutton { | ||
32 | background-color: #c0c0c0; | ||
33 | background: -moz-linear-gradient(#c0c0c0, #ffffff) repeat scroll 0 0 transparent; | ||
34 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#c0c0c0), to(#ffffff)); | ||
35 | background: -webkit-linear-gradient(#c0c0c0, #ffffff); | ||
36 | background: -ms-linear-gradient(#c0c0c0, #ffffff); | ||
37 | background: -o-linear-gradient(#c0c0c0, #ffffff); | ||
38 | background: linear-gradient(#c0c0c0, #ffffff); | ||
39 | border-radius: 3px 3px 3px 3px; | ||
40 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); | ||
41 | cursor: pointer; | ||
42 | height: 24px; | ||
43 | margin-left: 5px; | ||
44 | padding: 0 5px; | ||
45 | color: #606060; | ||
46 | border-style:outset; | ||
47 | border-width:1px; | ||
48 | |||
49 | } | ||
50 | .smallbutton { | ||
51 | background-color: #c0c0c0; | ||
52 | background: -moz-linear-gradient(#c0c0c0, #ffffff) repeat scroll 0 0 transparent; | ||
53 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#c0c0c0), to(#ffffff)); | ||
54 | background: -webkit-linear-gradient(#c0c0c0, #ffffff); | ||
55 | background: -ms-linear-gradient(#c0c0c0, #ffffff); | ||
56 | background: -o-linear-gradient(#c0c0c0, #ffffff); | ||
57 | background: linear-gradient(#c0c0c0, #ffffff); | ||
58 | border-radius: 3px 3px 3px 3px; | ||
59 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); | ||
60 | cursor: pointer; | ||
61 | height: 20px; | ||
62 | margin-left: 5px; | ||
63 | padding: 0 5px; | ||
64 | color: #606060; | ||
65 | border-style:outset; | ||
66 | border-width:1px; | ||
67 | |||
68 | } | ||
69 | |||
70 | /* Edit/Delete buttons on links */ | ||
71 | .button_edit, .button_delete { border-radius:0; box-shadow:none; border-style:none; border-width:0; padding:0; background:none; } | ||
72 | .button_edit { margin-left:10px; } | ||
73 | |||
74 | |||
75 | #pageheader #logo{ | ||
76 | background-image: url('../images/logo.png'); | ||
77 | background-repeat: no-repeat; | ||
78 | float:left; | ||
79 | margin:0 10px 0 10px; | ||
80 | width:105px; | ||
81 | height:55px; | ||
82 | cursor:pointer; | ||
83 | |||
84 | } | ||
85 | |||
86 | #pageheader | ||
87 | { | ||
88 | background-color: #333333; | ||
89 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#333333), to(#111111)); | ||
90 | background: -webkit-linear-gradient(#333333, #111111); | ||
91 | background: -moz-linear-gradient(#333333, #111111); | ||
92 | background: -ms-linear-gradient(#333333, #111111); | ||
93 | background: -o-linear-gradient(#333333, #111111); | ||
94 | background: linear-gradient(#333333, #111111); | ||
95 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
96 | width:auto; | ||
97 | padding:0 10px 5px 10px; | ||
98 | margin: auto; | ||
99 | } | ||
100 | |||
101 | #pageheader a | ||
102 | { | ||
103 | background-color: #333333; | ||
104 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#333333), to(#000000)); | ||
105 | background: -webkit-linear-gradient(#333333, #000000); | ||
106 | background: -moz-linear-gradient(#333333, #000000); | ||
107 | background: -ms-linear-gradient(#333333, #000000); | ||
108 | background: -o-linear-gradient(#333333, #000000); | ||
109 | background: linear-gradient(#333333, #000000); | ||
110 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
111 | padding:5px; | ||
112 | border-radius: 5px 5px 5px 5px; | ||
113 | margin:10px 3px 3px 3px; | ||
114 | color:#A2DD42; | ||
115 | float:left; | ||
116 | text-decoration:none; | ||
117 | } | ||
118 | |||
119 | #toolsdiv a{ | ||
120 | clear:both; | ||
121 | } | ||
122 | #toolsdiv a span{ | ||
123 | color:#ffffff; | ||
124 | } | ||
125 | .linksperpage,.tagfilter,.searchform,.addform { | ||
126 | background-color: #dedede; | ||
127 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
128 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
129 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
130 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
131 | background: -o-linear-gradient(#dedede, #ffffff); | ||
132 | background: linear-gradient(#dedede, #ffffff); | ||
133 | display:inline; | ||
134 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
135 | padding:5px; | ||
136 | border: none; | ||
137 | border-radius: 5px 5px 5px 5px; | ||
138 | margin:10px 3px 3px 3px; | ||
139 | color:#cecece; | ||
140 | } | ||
141 | |||
142 | .linksperpage{ | ||
143 | box-shadow: 0 0 0 rgba(0, 0, 0, 0.5); | ||
144 | padding:3px; | ||
145 | } | ||
146 | |||
147 | .linksperpage input,.tagfilter input, .searchform input, .addform input{ | ||
148 | border:none; | ||
149 | color:#606060; | ||
150 | background:none; | ||
151 | box-shadow:none; | ||
152 | padding:5px; | ||
153 | } | ||
154 | |||
155 | .linksperpage input{ | ||
156 | padding:0; | ||
157 | } | ||
158 | |||
159 | .tagfilter input.bigbutton,.searchform input.bigbutton,.addform input.bigbutton{ | ||
160 | background-color: #dedede; | ||
161 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#dedede), to(#ffffff)); | ||
162 | background: -webkit-linear-gradient(#dedede, #ffffff); | ||
163 | background: -moz-linear-gradient(#dedede, #ffffff); | ||
164 | background: -ms-linear-gradient(#dedede, #ffffff); | ||
165 | background: -o-linear-gradient(#dedede, #ffffff); | ||
166 | background: linear-gradient(#dedede, #ffffff); | ||
167 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | ||
168 | padding:0 5px 0 5px; | ||
169 | margin:5px 0 5px 0; | ||
170 | height:20px; | ||
171 | border-radius: 5px 5px 5px 5px; | ||
172 | cursor:pointer; | ||
173 | } | ||
174 | |||
175 | #shaarli_title { font-weight:bold; font-style:italic; margin-top:0;} | ||
176 | #shaarli_title a { color: #fff !important; } | ||
177 | |||
178 | #pageheader a:visited { color:#98C943; text-decoration:none;} | ||
179 | #pageheader a:hover { color:#FFFFC9; text-decoration:none;} | ||
180 | #pageheader a:active { color:#bbb; text-decoration:none;} | ||
181 | #searchcriteria { padding: 4px 0px 5px 5px; font-weight:bold;} | ||
182 | .paging { padding:5px;background-color:#777; color:#ccc; text-align:center; clear:both;} | ||
183 | .paging a:link { color:#ccc; text-decoration:none;} | ||
184 | .paging a:visited { color:#ccc; } | ||
185 | .paging a:hover { color:#FFFFC9; } | ||
186 | .paging a:active { color:#fff; } | ||
187 | #paging_privatelinks { float:left; } | ||
188 | #paging_linksperpage { float:right; padding-right:5px; } | ||
189 | #paging_current { display:inline; color:#fff; padding:0 20 0 20; } | ||
190 | #paging_older { margin-right:15px; } | ||
191 | #paging_newer { margin-left:15px; } | ||
192 | |||
193 | #headerform { color:#ffffff; padding:5px 5px 5px 5px; clear: both;} | ||
194 | #toolsdiv { color:#ffffff; padding:5px 5px 5px 5px; clear:left; } | ||
195 | #uploaddiv { color:#ffffff; padding:5px 5px 5px 5px; clear:left; } | ||
196 | #editlinkform { height:100%;color:#ffffff; padding:5px 5px 5px 15px; width:80%; clear:left; } | ||
197 | #linklist li { | ||
198 | padding:4px 10px 15px 20px; border-top: 1px solid #bbb; clear:both; | ||
199 | background-color: #F2F2F2; | ||
200 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#F2F2F2), to(#ffffff)); | ||
201 | background: -webkit-linear-gradient(#F2F2F2, #ffffff); | ||
202 | background: -moz-linear-gradient(#F2F2F2, #ffffff); | ||
203 | background: -ms-linear-gradient(#F2F2F2, #ffffff); | ||
204 | background: -o-linear-gradient(#F2F2F2, #ffffff); | ||
205 | background: linear-gradient(#F2F2F2, #ffffff); | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | #linklist li.publicLinkHightLight:hover,#linklist li:hover{ | ||
210 | background: #E9FFCE; | ||
211 | } | ||
212 | */ | ||
213 | #linklist li.private { background: url('../images/private.png') no-repeat 10px center; padding-left:60px; } | ||
214 | .private .linktitle a {color:#969696;} | ||
215 | .linktitle { font-size:14pt; font-weight:bold; } | ||
216 | .linktitle a { text-decoration: none; color:#80AD48; } | ||
217 | .linktitle a:hover { color:#F57900; } | ||
218 | .linkdate { font-size:8pt; color:#888; } | ||
219 | .linkdate a { background-image:url('../images/calendar.png');padding:2px 0 3px 20px;background-repeat:no-repeat;text-decoration: none; color:#E28E3F; } | ||
220 | .linkdate a:hover { color: #F57900 } | ||
221 | .linkurl { font-size:8pt; color:#4BAA74; } | ||
222 | .linkdescription { color:#000; margin-top:0; margin-bottom:12px; font-weight:normal; max-height:400px; overflow:auto; } | ||
223 | .linkdescription a { text-decoration: none; color:#3465A4; } | ||
224 | .linkdescription a:hover { color:#F57900; } | ||
225 | .linktaglist { padding-top:10px;} | ||
226 | .linktag { | ||
227 | |||
228 | font-size:9pt; | ||
229 | background-color: #F2F2F2; | ||
230 | background: -webkit-gradient(linear, 0 0, 0 bottom, from(#F2F2F2), to(#ffffff)); | ||
231 | background: -webkit-linear-gradient(#F2F2F2, #ffffff); | ||
232 | background: -moz-linear-gradient(#F2F2F2, #ffffff); | ||
233 | background: -ms-linear-gradient(#F2F2F2, #ffffff); | ||
234 | background: -o-linear-gradient(#F2F2F2, #ffffff); | ||
235 | background: linear-gradient(#F2F2F2, #ffffff); | ||
236 | box-shadow: 0 0 2px rgba(0, 0, 0, 0.5); | ||
237 | padding:3px 3px 3px 20px; | ||
238 | height:20px; | ||
239 | border-radius: 3px 3px 3px 3px; | ||
240 | cursor:pointer; | ||
241 | background-image:url('../images/tag_blue.png'); | ||
242 | background-repeat:no-repeat; | ||
243 | background-position:3px center; | ||
244 | background-color:#ffffff; | ||
245 | } | ||
246 | .linktag:hover { border-color: #555573; color:#000; } | ||
247 | .linktag a { color:#777; text-decoration:none; } | ||
248 | .linkshort { font-size:8pt; color:#888; } | ||
249 | .linkshort a { text-decoration: none; color:#393964; } | ||
250 | .linkshort a:hover { text-decoration: underline; } | ||
251 | .buttoneditform { display:inline; } | ||
252 | #footer { font-size:8pt; text-align:center; border-top:1px solid #ddd; color: #888; clear:both; } | ||
253 | #footer a{ color:#486D08;} | ||
254 | #footer a:hover{ color:#000000;} | ||
255 | #newversion { background-color: #FFFFA0; color:#000; position:absolute; top:0;right:0; padding:2 7 2 7; font-size:9pt;} | ||
256 | #cloudtag { padding-left:10%; padding-right:10%; } | ||
257 | #cloudtag a { color:black; text-decoration:none; } | ||
258 | #installform td { font-size: 10pt; color:black; padding:10px 5px 10px 5px; clear:left; } | ||
259 | #changepasswordform { color:#ccc; padding:10px 5px 10px 5px; clear:left; } | ||
260 | #changetag { color:#ccc; padding:10px 5px 10px 5px; clear:left; } | ||
261 | #configform td { color:#ccc; font-size: 10pt; padding:10px 5px 10px 5px; } | ||
262 | #configform { color:#ccc; padding:10px 5px 10px 5px; clear:left; } | ||
263 | .thumbnail { float:right; margin-left: 10px; } | ||
264 | /* If you want thumbnails on the left: | ||
265 | .thumbnail { float:left; margin-right: 10px; } | ||
266 | .linkcontainer { position: static; margin-left:130px; } | ||
267 | */ | ||
268 | |||
269 | |||
270 | |||
271 | |||
272 | /* --- Picture wall CSS --- */ | ||
273 | #picwall_container { color:#fff; background-color:#000; clear:both; } | ||
274 | .picwall_pictureframe { background-color:#000; z-index:5; position:relative; display:table-cell; vertical-align:middle;width:90px; height:90px; overflow:hidden; text-align:center; float:left; } | ||
275 | .picwall_pictureframe img { max-width: 100%;height: auto; } /* Adapt the width of the image */ | ||
276 | .picwall_pictureframe a {text-decoration:none;} | ||
277 | |||
278 | /* CSS to show title when hovering an image - no javascript required. */ | ||
279 | .picwall_pictureframe span.info {display: none;} | ||
280 | .picwall_pictureframe:hover span.info { | ||
281 | display:block; | ||
282 | position:absolute; | ||
283 | top:0; left:0; width:90px; | ||
284 | font-weight:bold; | ||
285 | font-size:8pt; | ||
286 | color:#fff; | ||
287 | text-align: left; | ||
288 | background-color: transparent; | ||
289 | background-color: rgba(0, 0, 0, 0.4); /* FF3+, Saf3+, Opera 10.10+, Chrome, IE9 */ | ||
290 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000); /* IE6ÂIE9 */ | ||
291 | text-shadow:2px 2px 1px #000000; | ||
292 | } | ||
293 | |||
294 | /* Minimal customisation for jQuery widgets */ | ||
295 | .ui-autocomplete { background-color:#fff; padding-left:5px;} | ||
296 | .ui-state-hover { background-color: #604dff; color:#fff; } | ||
297 | |||
298 | #linklist li.publicLinkHightLight{ | ||
299 | background: #ffffff; | ||
300 | } | ||
301 | |||
302 | div.qrcode { | ||
303 | width:220px; | ||
304 | height:220px; | ||
305 | background-color: #ffffff; | ||
306 | border: 1px solid black; | ||
307 | position: absolute; | ||
308 | top:-100px; | ||
309 | left:-100px; | ||
310 | text-align:center; | ||
311 | font-size: 8pt; | ||
312 | z-index:50; | ||
313 | -webkit-box-shadow:2px 2px 20px 2px #333333; | ||
314 | -moz-box-shadow:2px 2px 20px 2px #333333; | ||
315 | -o-box-shadow:2px 2px 20px 2px #333333; | ||
316 | -ms-box-shadow:2px 2px 20px 2px #333333; | ||
317 | box-shadow:2px 2px 20px 2px #333333; | ||
318 | } | ||
319 | |||
320 | div.daily | ||
321 | { | ||
322 | font-family: Georgia, 'DejaVu Serif', Norasi, serif; | ||
323 | background-color: #E6D6BE; | ||
324 | /* Background paper texture by BashCorpo: | ||
325 | http://www.bashcorpo.dk/textures.php | ||
326 | http://bashcorpo.deviantart.com/art/Grungy-paper-texture-v-5-22966998 */ | ||
327 | background-image: url("../images/Paper_texture_v5_by_bashcorpo_w1000.jpg"); | ||
328 | -webkit-background-size: cover; | ||
329 | -moz-background-size: cover; | ||
330 | -o-background-size: cover; | ||
331 | background-size: cover; | ||
332 | position:relative; | ||
333 | border-bottom: 2px solid black; | ||
334 | } | ||
335 | |||
336 | #daily_col1 { float:left;position:relative; width:33%; padding-left:1%; } | ||
337 | #daily_col2 { float:left;position:relative; width:33%; } | ||
338 | #daily_col3 { float:left;position:relative; width:33%;} | ||
339 | |||
340 | div.dailyAbout | ||
341 | { | ||
342 | float:left; | ||
343 | border: 1px solid black; | ||
344 | font-size: 8pt; | ||
345 | position:absolute; | ||
346 | left:10px; | ||
347 | top: 15px; | ||
348 | padding: 5px 5px 5px 5px; | ||
349 | text-align:center; | ||
350 | } | ||
351 | div.dailyAbout a { color: #890500; } | ||
352 | div.dailyTitle | ||
353 | { | ||
354 | font-weight: bold; | ||
355 | font-size: 44pt; | ||
356 | text-align:center; | ||
357 | padding:10px 20px 0px 20px; | ||
358 | } | ||
359 | div.dailyDate | ||
360 | { | ||
361 | font-size: 12pt; | ||
362 | font-weight:bold; | ||
363 | text-align:center; | ||
364 | padding:0px 20px 30px 20px; | ||
365 | } | ||
366 | |||
367 | /* Individual entries in "Daily": */ | ||
368 | div.dailyEntry | ||
369 | { | ||
370 | margin: 5px 10px 2px 5px; | ||
371 | font-size: 11pt; | ||
372 | border-top: 1px solid #555; | ||
373 | } | ||
374 | div.dailyEntry a { text-decoration:none; color: #890500; } | ||
375 | div.dailyEntryTags { font-size:7.75pt; } | ||
376 | div.dailyEntryTitle { font-size:18pt; font-weight:bold;} | ||
377 | div.dailyEntryThumbnail | ||
378 | { | ||
379 | width:100%; | ||
380 | text-align:center; | ||
381 | background-color:rgb(128,128,128); | ||
382 | background:url(../images/50pc_transparent.png); | ||
383 | padding:4px 0px 2px 0px; | ||
384 | } | ||
385 | div.dailyEntryDescription | ||
386 | { | ||
387 | margin-top: 10px; | ||
388 | margin-bottom: 30px; | ||
389 | text-align:justify; | ||
390 | overflow:auto; | ||
391 | } | ||
392 | |||
393 | /* Common css screwdriver */ | ||
394 | .clear{ | ||
395 | clear:both; | ||
396 | } | ||
397 | |||
398 | /* For lazy images loading in picture wall. | ||
399 | using http://www.appelsiini.net/projects/lazyload | ||
400 | */ | ||
401 | .lazyimage { display:none; } | ||
402 | |||
403 | @media print { | ||
404 | html {border:none;background:#fff!important;color:#000!important;} | ||
405 | body {font-size:12pt;width:auto!important;margin:auto!important;} | ||
406 | p {orphans:3; /*pas de ligne seule en bas */widows:3;/*pas de ligne seule en haut*/} | ||
407 | a {color:#000!important;text-decoration:none!important;} | ||
408 | #pageheader, .paging, #linklist li form, #footer {display:none;} | ||
409 | #linklist li { padding:2 0 10 0; border-top: 2px solid #000; clear:both; } | ||
410 | #linklist li.private { background-color: none; border-left:0; } | ||
411 | .linkdate { line-height:2; } | ||
412 | .linkurl { color:#000; } | ||
413 | .linkdescription { font-size:10pt;} | ||
414 | .linktag { border: 1px solid black; font-style:italic; font-size:8pt;} | ||
415 | |||
416 | } | ||
417 | |||
418 | |||
419 | @media handheld, only screen and (max-width: 480px), only screen and (max-device-width: 854px) | ||
420 | { | ||
421 | /* A few fixes for mobile devices (far from perfect). */ | ||
422 | .nomobile { display:none; } | ||
423 | #logo { display:none; } | ||
424 | #pageheader a | ||
425 | { | ||
426 | padding:5px; | ||
427 | border-radius: 5px 5px 5px 5px; | ||
428 | margin:3px; | ||
429 | } | ||
430 | .searchform,.tagfilter { display:block !important; margin:0px !important; padding:0px !important; width:100% !important; } | ||
431 | .searchform input,.tagfilter input { margin:0px !important; padding:0px !important; display:inline !important; } | ||
432 | .tagfilter input.bigbutton,.searchform input.bigbutton,.addform input.bigbutton{ width:30%; font-size:smaller;} | ||
433 | #searchform_value { width:70% !important; } | ||
434 | #tagfilter_value { width:70% !important; } | ||
435 | div.qrcode { position:relative; float:left; top:-10px; left:0px; } | ||
436 | #paging_privatelinks { float;none; } | ||
437 | #paging_linksperpage { float:none; margin-bottom:10px; font-size:smaller;} | ||
438 | #paging_older,#paging_newer,#paging_linksperpage a { border: 1px solid black; padding:3px 5px 3px 5px; background-color:#666; color:#fff; border-radius: 5px 5px 5px 5px;} | ||
439 | .thumbnail { float:none; height:auto; margin: 0px; text-align:center;} | ||
440 | #cloudtag { padding:0px; } | ||
441 | div.dailyAbout { float:none; position:relative; width:100%; clear:both; padding:0px; top:0px; left:0px; } | ||
442 | #daily_col1,#daily_col2,#daily_col3 { float:none; width:100%; padding:0px;} | ||
443 | div.dailyTitle { font-size: 18pt; margin-top:5px; padding:0px;} | ||
444 | div.dailyDate { font-size: 11pt;padding:0px; display:block; } | ||
445 | div.dailyEntryTitle { font-size:16pt; font-weight:bold;} | ||
446 | div.dailyEntryDescription { font-size:10pt; } | ||
447 | |||
448 | } | ||
449 | |||
diff --git a/index.php b/index.php new file mode 100644 index 00000000..8436f8ac --- /dev/null +++ b/index.php | |||
@@ -0,0 +1,2321 @@ | |||
1 | <?php | ||
2 | // Shaarli 0.0.40 beta - Shaare your links... | ||
3 | // The personal, minimalist, super-fast, no-database delicious clone. By sebsauvage.net | ||
4 | // http://sebsauvage.net/wiki/doku.php?id=php:shaarli | ||
5 | // Licence: http://www.opensource.org/licenses/zlib-license.php | ||
6 | // Requires: php 5.1.x (but autocomplete fields will only work if you have php 5.2.x) | ||
7 | // ----------------------------------------------------------------------------------------------- | ||
8 | // Hardcoded parameter (These parameters can be overwritten by creating the file /config/options.php) | ||
9 | $GLOBALS['config']['DATADIR'] = 'data'; // Data subdirectory | ||
10 | $GLOBALS['config']['CONFIG_FILE'] = $GLOBALS['config']['DATADIR'].'/config.php'; // Configuration file (user login/password) | ||
11 | $GLOBALS['config']['DATASTORE'] = $GLOBALS['config']['DATADIR'].'/datastore.php'; // Data storage file. | ||
12 | $GLOBALS['config']['LINKS_PER_PAGE'] = 20; // Default links per page. | ||
13 | $GLOBALS['config']['IPBANS_FILENAME'] = $GLOBALS['config']['DATADIR'].'/ipbans.php'; // File storage for failures and bans. | ||
14 | $GLOBALS['config']['BAN_AFTER'] = 4; // Ban IP after this many failures. | ||
15 | $GLOBALS['config']['BAN_DURATION'] = 1800; // Ban duration for IP address after login failures (in seconds) (1800 sec. = 30 minutes) | ||
16 | $GLOBALS['config']['OPEN_SHAARLI'] = false; // If true, anyone can add/edit/delete links without having to login | ||
17 | $GLOBALS['config']['HIDE_TIMESTAMPS'] = false; // If true, the moment when links were saved are not shown to users that are not logged in. | ||
18 | $GLOBALS['config']['ENABLE_THUMBNAILS'] = true; // Enable thumbnails in links. | ||
19 | $GLOBALS['config']['CACHEDIR'] = 'cache'; // Cache directory for thumbnails for SLOW services (like flickr) | ||
20 | $GLOBALS['config']['PAGECACHE'] = 'pagecache'; // Page cache directory. | ||
21 | $GLOBALS['config']['ENABLE_LOCALCACHE'] = true; // Enable Shaarli to store thumbnail in a local cache. Disable to reduce webspace usage. | ||
22 | $GLOBALS['config']['PUBSUBHUB_URL'] = ''; // PubSubHubbub support. Put an empty string to disable, or put your hub url here to enable. | ||
23 | $GLOBALS['config']['UPDATECHECK_FILENAME'] = $GLOBALS['config']['DATADIR'].'/lastupdatecheck.txt'; // For updates check of Shaarli. | ||
24 | $GLOBALS['config']['UPDATECHECK_INTERVAL'] = 86400 ; // Updates check frequency for Shaarli. 86400 seconds=24 hours | ||
25 | // Note: You must have publisher.php in the same directory as Shaarli index.php | ||
26 | // ----------------------------------------------------------------------------------------------- | ||
27 | // You should not touch below (or at your own risks !) | ||
28 | // Optionnal config file. | ||
29 | if (is_file($GLOBALS['config']['DATADIR'].'/options.php')) require($GLOBALS['config']['DATADIR'].'/options.php'); | ||
30 | |||
31 | define('shaarli_version','0.0.40 beta'); | ||
32 | define('PHPPREFIX','<?php /* '); // Prefix to encapsulate data in php code. | ||
33 | define('PHPSUFFIX',' */ ?>'); // Suffix to encapsulate data in php code. | ||
34 | |||
35 | // Force cookie path (but do not change lifetime) | ||
36 | $cookie=session_get_cookie_params(); | ||
37 | session_set_cookie_params($cookie['lifetime'],dirname($_SERVER["SCRIPT_NAME"]).'/'); // Default cookie expiration and path. | ||
38 | |||
39 | // PHP Settings | ||
40 | ini_set('max_input_time','60'); // High execution time in case of problematic imports/exports. | ||
41 | ini_set('memory_limit', '128M'); // Try to set max upload file size and read (May not work on some hosts). | ||
42 | ini_set('post_max_size', '16M'); | ||
43 | ini_set('upload_max_filesize', '16M'); | ||
44 | checkphpversion(); | ||
45 | error_reporting(E_ALL^E_WARNING); // See all error except warnings. | ||
46 | //error_reporting(-1); // See all errors (for debugging only) | ||
47 | |||
48 | include "inc/rain.tpl.class.php"; //include Rain TPL | ||
49 | raintpl::$tpl_dir = "tpl/"; // template directory | ||
50 | if (!is_dir('tmp')) { mkdir('tmp',0705); chmod('tmp',0705); } | ||
51 | raintpl::$cache_dir = "tmp/"; // cache directory | ||
52 | |||
53 | ob_start(); // Output buffering for the page cache. | ||
54 | |||
55 | |||
56 | // In case stupid admin has left magic_quotes enabled in php.ini: | ||
57 | if (get_magic_quotes_gpc()) | ||
58 | { | ||
59 | function stripslashes_deep($value) { $value = is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value); return $value; } | ||
60 | $_POST = array_map('stripslashes_deep', $_POST); | ||
61 | $_GET = array_map('stripslashes_deep', $_GET); | ||
62 | $_COOKIE = array_map('stripslashes_deep', $_COOKIE); | ||
63 | } | ||
64 | |||
65 | // Prevent caching on client side or proxy: (yes, it's ugly) | ||
66 | header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | ||
67 | header("Cache-Control: no-store, no-cache, must-revalidate"); | ||
68 | header("Cache-Control: post-check=0, pre-check=0", false); | ||
69 | header("Pragma: no-cache"); | ||
70 | |||
71 | // Directories creations (Note that your web host may require differents rights than 705.) | ||
72 | if (!is_dir($GLOBALS['config']['DATADIR'])) { mkdir($GLOBALS['config']['DATADIR'],0705); chmod($GLOBALS['config']['DATADIR'],0705); } | ||
73 | if (!is_dir('tmp')) { mkdir('tmp',0705); chmod('tmp',0705); } // For RainTPL temporary files. | ||
74 | if (!is_file($GLOBALS['config']['DATADIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['DATADIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | ||
75 | if ($GLOBALS['config']['ENABLE_LOCALCACHE']) | ||
76 | { | ||
77 | if (!is_dir($GLOBALS['config']['CACHEDIR'])) { mkdir($GLOBALS['config']['CACHEDIR'],0705); chmod($GLOBALS['config']['CACHEDIR'],0705); } | ||
78 | if (!is_file($GLOBALS['config']['CACHEDIR'].'/.htaccess')) { file_put_contents($GLOBALS['config']['CACHEDIR'].'/.htaccess',"Allow from none\nDeny from all\n"); } // Protect data files. | ||
79 | } | ||
80 | |||
81 | // Run config screen if first run: | ||
82 | if (!is_file($GLOBALS['config']['CONFIG_FILE'])) install(); | ||
83 | |||
84 | require $GLOBALS['config']['CONFIG_FILE']; // Read login/password hash into $GLOBALS. | ||
85 | |||
86 | // Handling of old config file which do not have the new parameters. | ||
87 | if (empty($GLOBALS['title'])) $GLOBALS['title']='Shared links on '.htmlspecialchars(indexUrl()); | ||
88 | if (empty($GLOBALS['timezone'])) $GLOBALS['timezone']=date_default_timezone_get(); | ||
89 | if (empty($GLOBALS['disablesessionprotection'])) $GLOBALS['disablesessionprotection']=false; | ||
90 | |||
91 | |||
92 | autoLocale(); // Sniff browser language and set date format accordingly. | ||
93 | header('Content-Type: text/html; charset=utf-8'); // We use UTF-8 for proper international characters handling. | ||
94 | |||
95 | // Check php version | ||
96 | function checkphpversion() | ||
97 | { | ||
98 | if (version_compare(PHP_VERSION, '5.1.0') < 0) | ||
99 | { | ||
100 | header('Content-Type: text/plain; charset=utf-8'); | ||
101 | echo 'Your server supports php '.PHP_VERSION.'. Shaarli requires at last php 5.1.0, and thus cannot run. Sorry.'; | ||
102 | exit; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | // Checks if an update is available for Shaarli. | ||
107 | // (at most once a day, and only for registered user.) | ||
108 | // Output: '' = no new version. | ||
109 | // other= the available version. | ||
110 | function checkUpdate() | ||
111 | { | ||
112 | if (!isLoggedIn()) return ''; // Do not check versions for visitors. | ||
113 | |||
114 | // Get latest version number at most once a day. | ||
115 | if (!is_file($GLOBALS['config']['UPDATECHECK_FILENAME']) || (filemtime($GLOBALS['config']['UPDATECHECK_FILENAME'])<time()-($GLOBALS['config']['UPDATECHECK_INTERVAL']))) | ||
116 | { | ||
117 | $version=shaarli_version; | ||
118 | list($httpstatus,$headers,$data) = getHTTP('http://sebsauvage.net/files/shaarli_version.txt',2); | ||
119 | if (strpos($httpstatus,'200 OK')!==false) $version=$data; | ||
120 | // If failed, nevermind. We don't want to bother the user with that. | ||
121 | file_put_contents($GLOBALS['config']['UPDATECHECK_FILENAME'],$version); // touch file date | ||
122 | } | ||
123 | // Compare versions: | ||
124 | $newestversion=file_get_contents($GLOBALS['config']['UPDATECHECK_FILENAME']); | ||
125 | if (version_compare($newestversion,shaarli_version)==1) return $newestversion; | ||
126 | return ''; | ||
127 | } | ||
128 | |||
129 | |||
130 | // ----------------------------------------------------------------------------------------------- | ||
131 | // Simple cache system (mainly for the RSS/ATOM feeds). | ||
132 | |||
133 | class pageCache | ||
134 | { | ||
135 | private $url; // Full URL of the page to cache (typically the value returned by pageUrl()) | ||
136 | private $shouldBeCached; // boolean: Should this url be cached ? | ||
137 | private $filename; // Name of the cache file for this url | ||
138 | |||
139 | /* | ||
140 | $url = url (typically the value returned by pageUrl()) | ||
141 | $shouldBeCached = boolean. If false, the cache will be disabled. | ||
142 | */ | ||
143 | public function __construct($url,$shouldBeCached) | ||
144 | { | ||
145 | $this->url = $url; | ||
146 | $this->filename = $GLOBALS['config']['PAGECACHE'].'/'.sha1($url).'.cache'; | ||
147 | $this->shouldBeCached = $shouldBeCached; | ||
148 | } | ||
149 | |||
150 | // If the page should be cached and a cached version exists, | ||
151 | // returns the cached version (otherwise, return null). | ||
152 | public function cachedVersion() | ||
153 | { | ||
154 | if (!$this->shouldBeCached) return null; | ||
155 | if (is_file($this->filename)) { return file_get_contents($this->filename); exit; } | ||
156 | return null; | ||
157 | } | ||
158 | |||
159 | // Put a page in the cache. | ||
160 | public function cache($page) | ||
161 | { | ||
162 | if (!$this->shouldBeCached) return; | ||
163 | if (!is_dir($GLOBALS['config']['PAGECACHE'])) { mkdir($GLOBALS['config']['PAGECACHE'],0705); chmod($GLOBALS['config']['PAGECACHE'],0705); } | ||
164 | file_put_contents($this->filename,$page); | ||
165 | } | ||
166 | |||
167 | // Purge the whole cache. | ||
168 | // (call with pageCache::purgeCache()) | ||
169 | public static function purgeCache() | ||
170 | { | ||
171 | if (is_dir($GLOBALS['config']['PAGECACHE'])) | ||
172 | { | ||
173 | $handler = opendir($GLOBALS['config']['PAGECACHE']); | ||
174 | if ($handle!==false) | ||
175 | { | ||
176 | while (($filename = readdir($handler))!==false) | ||
177 | { | ||
178 | if (endsWith($filename,'.cache')) { unlink($GLOBALS['config']['PAGECACHE'].'/'.$filename); } | ||
179 | } | ||
180 | closedir($handler); | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | } | ||
186 | |||
187 | |||
188 | // ----------------------------------------------------------------------------------------------- | ||
189 | // Log to text file | ||
190 | function logm($message) | ||
191 | { | ||
192 | $t = strval(date('Y/m/d_H:i:s')).' - '.$_SERVER["REMOTE_ADDR"].' - '.strval($message)."\n"; | ||
193 | file_put_contents($GLOBALS['config']['DATADIR'].'/log.txt',$t,FILE_APPEND); | ||
194 | } | ||
195 | |||
196 | // Same as nl2br(), but escapes < and > | ||
197 | function nl2br_escaped($html) | ||
198 | { | ||
199 | return str_replace('>','>',str_replace('<','<',nl2br($html))); | ||
200 | } | ||
201 | |||
202 | /* Returns the small hash of a string | ||
203 | eg. smallHash('20111006_131924') --> yZH23w | ||
204 | Small hashes: | ||
205 | - are unique (well, as unique as crc32, at last) | ||
206 | - are always 6 characters long. | ||
207 | - only use the following characters: a-z A-Z 0-9 - _ @ | ||
208 | - are NOT cryptographically secure (they CAN be forged) | ||
209 | In Shaarli, they are used as a tinyurl-like link to individual entries. | ||
210 | */ | ||
211 | function smallHash($text) | ||
212 | { | ||
213 | $t = rtrim(base64_encode(hash('crc32',$text,true)),'='); | ||
214 | $t = str_replace('+','-',$t); // Get rid of characters which need encoding in URLs. | ||
215 | $t = str_replace('/','_',$t); | ||
216 | $t = str_replace('=','@',$t); | ||
217 | return $t; | ||
218 | } | ||
219 | |||
220 | // In a string, converts urls to clickable links. | ||
221 | // Function inspired from http://www.php.net/manual/en/function.preg-replace.php#85722 | ||
222 | function text2clickable($url) | ||
223 | { | ||
224 | $redir = empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']; | ||
225 | return preg_replace('!(((?:https?|ftp|file)://|apt:)\S+[[:alnum:]]/?)!si','<a href="'.$redir.'$1" rel="nofollow">$1</a>',$url); | ||
226 | } | ||
227 | |||
228 | // This function inserts where relevant so that multiple spaces are properly displayed in HTML | ||
229 | // even in the absence of <pre> (This is used in description to keep text formatting) | ||
230 | function keepMultipleSpaces($text) | ||
231 | { | ||
232 | return str_replace(' ',' ',$text); | ||
233 | |||
234 | } | ||
235 | // ------------------------------------------------------------------------------------------ | ||
236 | // Sniff browser language to display dates in the right format automatically. | ||
237 | // (Note that is may not work on your server if the corresponding local is not installed.) | ||
238 | function autoLocale() | ||
239 | { | ||
240 | $loc='en_US'; // Default if browser does not send HTTP_ACCEPT_LANGUAGE | ||
241 | if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) // eg. "fr,fr-fr;q=0.8,en;q=0.5,en-us;q=0.3" | ||
242 | { // (It's a bit crude, but it works very well. Prefered language is always presented first.) | ||
243 | if (preg_match('/([a-z]{2}(-[a-z]{2})?)/i',$_SERVER['HTTP_ACCEPT_LANGUAGE'],$matches)) $loc=$matches[1]; | ||
244 | } | ||
245 | setlocale(LC_TIME,$loc); // LC_TIME = Set local for date/time format only. | ||
246 | } | ||
247 | |||
248 | // ------------------------------------------------------------------------------------------ | ||
249 | // PubSubHubbub protocol support (if enabled) [UNTESTED] | ||
250 | // (Source: http://aldarone.fr/les-flux-rss-shaarli-et-pubsubhubbub/ ) | ||
251 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) include './publisher.php'; | ||
252 | function pubsubhub() | ||
253 | { | ||
254 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
255 | { | ||
256 | $p = new Publisher($GLOBALS['config']['PUBSUBHUB_URL']); | ||
257 | $topic_url = array ( | ||
258 | indexUrl().'?do=atom', | ||
259 | indexUrl().'?do=rss' | ||
260 | ); | ||
261 | $p->publish_update($topic_url); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | // ------------------------------------------------------------------------------------------ | ||
266 | // Session management | ||
267 | define('INACTIVITY_TIMEOUT',3600); // (in seconds). If the user does not access any page within this time, his/her session is considered expired. | ||
268 | ini_set('session.use_cookies', 1); // Use cookies to store session. | ||
269 | ini_set('session.use_only_cookies', 1); // Force cookies for session (phpsessionID forbidden in URL) | ||
270 | ini_set('session.use_trans_sid', false); // Prevent php to use sessionID in URL if cookies are disabled. | ||
271 | session_name('shaarli'); | ||
272 | session_start(); | ||
273 | |||
274 | // Returns the IP address of the client (Used to prevent session cookie hijacking.) | ||
275 | function allIPs() | ||
276 | { | ||
277 | $ip = $_SERVER["REMOTE_ADDR"]; | ||
278 | // Then we use more HTTP headers to prevent session hijacking from users behind the same proxy. | ||
279 | if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$ip.'_'.$_SERVER['HTTP_X_FORWARDED_FOR']; } | ||
280 | if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip=$ip.'_'.$_SERVER['HTTP_CLIENT_IP']; } | ||
281 | return $ip; | ||
282 | } | ||
283 | |||
284 | // Check that user/password is correct. | ||
285 | function check_auth($login,$password) | ||
286 | { | ||
287 | $hash = sha1($password.$login.$GLOBALS['salt']); | ||
288 | if ($login==$GLOBALS['login'] && $hash==$GLOBALS['hash']) | ||
289 | { // Login/password is correct. | ||
290 | $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // generate unique random number (different than phpsessionid) | ||
291 | $_SESSION['ip']=allIPs(); // We store IP address(es) of the client to make sure session is not hijacked. | ||
292 | $_SESSION['username']=$login; | ||
293 | $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. | ||
294 | logm('Login successful'); | ||
295 | return True; | ||
296 | } | ||
297 | logm('Login failed for user '.$login); | ||
298 | return False; | ||
299 | } | ||
300 | |||
301 | // Returns true if the user is logged in. | ||
302 | function isLoggedIn() | ||
303 | { | ||
304 | if ($GLOBALS['config']['OPEN_SHAARLI']) return true; | ||
305 | |||
306 | // If session does not exist on server side, or IP address has changed, or session has expired, logout. | ||
307 | if (empty($_SESSION['uid']) || ($GLOBALS['disablesessionprotection']==false && $_SESSION['ip']!=allIPs()) || time()>=$_SESSION['expires_on']) | ||
308 | { | ||
309 | logout(); | ||
310 | return false; | ||
311 | } | ||
312 | if (!empty($_SESSION['longlastingsession'])) $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // In case of "Stay signed in" checked. | ||
313 | else $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Standard session expiration date. | ||
314 | |||
315 | return true; | ||
316 | } | ||
317 | |||
318 | // Force logout. | ||
319 | function logout() { if (isset($_SESSION)) { unset($_SESSION['uid']); unset($_SESSION['ip']); unset($_SESSION['username']);} } | ||
320 | |||
321 | |||
322 | // ------------------------------------------------------------------------------------------ | ||
323 | // Brute force protection system | ||
324 | // Several consecutive failed logins will ban the IP address for 30 minutes. | ||
325 | if (!is_file($GLOBALS['config']['IPBANS_FILENAME'])) file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export(array('FAILURES'=>array(),'BANS'=>array()),true).";\n?>"); | ||
326 | include $GLOBALS['config']['IPBANS_FILENAME']; | ||
327 | // Signal a failed login. Will ban the IP if too many failures: | ||
328 | function ban_loginFailed() | ||
329 | { | ||
330 | $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; | ||
331 | if (!isset($gb['FAILURES'][$ip])) $gb['FAILURES'][$ip]=0; | ||
332 | $gb['FAILURES'][$ip]++; | ||
333 | if ($gb['FAILURES'][$ip]>($GLOBALS['config']['BAN_AFTER']-1)) | ||
334 | { | ||
335 | $gb['BANS'][$ip]=time()+$GLOBALS['config']['BAN_DURATION']; | ||
336 | logm('IP address banned from login'); | ||
337 | } | ||
338 | $GLOBALS['IPBANS'] = $gb; | ||
339 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); | ||
340 | } | ||
341 | |||
342 | // Signals a successful login. Resets failed login counter. | ||
343 | function ban_loginOk() | ||
344 | { | ||
345 | $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; | ||
346 | unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); | ||
347 | $GLOBALS['IPBANS'] = $gb; | ||
348 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); | ||
349 | } | ||
350 | |||
351 | // Checks if the user CAN login. If 'true', the user can try to login. | ||
352 | function ban_canLogin() | ||
353 | { | ||
354 | $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; | ||
355 | if (isset($gb['BANS'][$ip])) | ||
356 | { | ||
357 | // User is banned. Check if the ban has expired: | ||
358 | if ($gb['BANS'][$ip]<=time()) | ||
359 | { // Ban expired, user can try to login again. | ||
360 | logm('Ban lifted.'); | ||
361 | unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); | ||
362 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); | ||
363 | return true; // Ban has expired, user can login. | ||
364 | } | ||
365 | return false; // User is banned. | ||
366 | } | ||
367 | return true; // User is not banned. | ||
368 | } | ||
369 | |||
370 | // ------------------------------------------------------------------------------------------ | ||
371 | // Process login form: Check if login/password is correct. | ||
372 | if (isset($_POST['login'])) | ||
373 | { | ||
374 | if (!ban_canLogin()) die('I said: NO. You are banned for the moment. Go away.'); | ||
375 | if (isset($_POST['password']) && tokenOk($_POST['token']) && (check_auth($_POST['login'], $_POST['password']))) | ||
376 | { // Login/password is ok. | ||
377 | ban_loginOk(); | ||
378 | // If user wants to keep the session cookie even after the browser closes: | ||
379 | if (!empty($_POST['longlastingsession'])) | ||
380 | { | ||
381 | $_SESSION['longlastingsession']=31536000; // (31536000 seconds = 1 year) | ||
382 | $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // Set session expiration on server-side. | ||
383 | session_set_cookie_params($_SESSION['longlastingsession'],dirname($_SERVER["SCRIPT_NAME"]).'/'); // Set session cookie expiration on client side | ||
384 | // Note: Never forget the trailing slash on the cookie path ! | ||
385 | session_regenerate_id(true); // Send cookie with new expiration date to browser. | ||
386 | } | ||
387 | else // Standard session expiration (=when browser closes) | ||
388 | { | ||
389 | session_set_cookie_params(0,dirname($_SERVER["SCRIPT_NAME"]).'/'); // 0 means "When browser closes" | ||
390 | session_regenerate_id(true); | ||
391 | } | ||
392 | // Optional redirect after login: | ||
393 | if (isset($_GET['post'])) { header('Location: ?post='.urlencode($_GET['post']).(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):'')); exit; } | ||
394 | if (isset($_POST['returnurl'])) | ||
395 | { | ||
396 | if (endsWith($_POST['returnurl'],'?do=login')) { header('Location: ?'); exit; } // Prevent loops over login screen. | ||
397 | header('Location: '.$_POST['returnurl']); exit; | ||
398 | } | ||
399 | header('Location: ?'); exit; | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | ban_loginFailed(); | ||
404 | echo '<script language="JavaScript">alert("Wrong login/password.");document.location=\'?do=login\';</script>'; // Redirect to login screen. | ||
405 | exit; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | // ------------------------------------------------------------------------------------------ | ||
410 | // Misc utility functions: | ||
411 | |||
412 | // Returns the server URL (including port and http/https), without path. | ||
413 | // eg. "http://myserver.com:8080" | ||
414 | // You can append $_SERVER['SCRIPT_NAME'] to get the current script URL. | ||
415 | function serverUrl() | ||
416 | { | ||
417 | $https = (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS'])=='on')) || $_SERVER["SERVER_PORT"]=='443'; // HTTPS detection. | ||
418 | $serverport = ($_SERVER["SERVER_PORT"]=='80' || ($https && $_SERVER["SERVER_PORT"]=='443') ? '' : ':'.$_SERVER["SERVER_PORT"]); | ||
419 | return 'http'.($https?'s':'').'://'.$_SERVER["SERVER_NAME"].$serverport; | ||
420 | } | ||
421 | |||
422 | // Returns the absolute URL of current script, without the query. | ||
423 | // (eg. http://sebsauvage.net/links/) | ||
424 | function indexUrl() | ||
425 | { | ||
426 | return serverUrl() . ($_SERVER["SCRIPT_NAME"] == '/index.php' ? '/' : $_SERVER["SCRIPT_NAME"]); | ||
427 | } | ||
428 | |||
429 | // Returns the absolute URL of current script, WITH the query. | ||
430 | // (eg. http://sebsauvage.net/links/?toto=titi&spamspamspam=humbug) | ||
431 | function pageUrl() | ||
432 | { | ||
433 | return indexUrl().(!empty($_SERVER["QUERY_STRING"]) ? '?'.$_SERVER["QUERY_STRING"] : ''); | ||
434 | } | ||
435 | |||
436 | // Convert post_max_size/upload_max_filesize (eg.'16M') parameters to bytes. | ||
437 | function return_bytes($val) | ||
438 | { | ||
439 | $val = trim($val); $last=strtolower($val[strlen($val)-1]); | ||
440 | switch($last) | ||
441 | { | ||
442 | case 'g': $val *= 1024; | ||
443 | case 'm': $val *= 1024; | ||
444 | case 'k': $val *= 1024; | ||
445 | } | ||
446 | return $val; | ||
447 | } | ||
448 | |||
449 | // Try to determine max file size for uploads (POST). | ||
450 | // Returns an integer (in bytes) | ||
451 | function getMaxFileSize() | ||
452 | { | ||
453 | $size1 = return_bytes(ini_get('post_max_size')); | ||
454 | $size2 = return_bytes(ini_get('upload_max_filesize')); | ||
455 | // Return the smaller of two: | ||
456 | $maxsize = min($size1,$size2); | ||
457 | // FIXME: Then convert back to readable notations ? (eg. 2M instead of 2000000) | ||
458 | return $maxsize; | ||
459 | } | ||
460 | |||
461 | // Tells if a string start with a substring or not. | ||
462 | function startsWith($haystack,$needle,$case=true) | ||
463 | { | ||
464 | if($case){return (strcmp(substr($haystack, 0, strlen($needle)),$needle)===0);} | ||
465 | return (strcasecmp(substr($haystack, 0, strlen($needle)),$needle)===0); | ||
466 | } | ||
467 | |||
468 | // Tells if a string ends with a substring or not. | ||
469 | function endsWith($haystack,$needle,$case=true) | ||
470 | { | ||
471 | if($case){return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0);} | ||
472 | return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)),$needle)===0); | ||
473 | } | ||
474 | |||
475 | /* Converts a linkdate time (YYYYMMDD_HHMMSS) of an article to a timestamp (Unix epoch) | ||
476 | (used to build the ADD_DATE attribute in Netscape-bookmarks file) | ||
477 | PS: I could have used strptime(), but it does not exist on Windows. I'm too kind. */ | ||
478 | function linkdate2timestamp($linkdate) | ||
479 | { | ||
480 | $Y=$M=$D=$h=$m=$s=0; | ||
481 | $r = sscanf($linkdate,'%4d%2d%2d_%2d%2d%2d',$Y,$M,$D,$h,$m,$s); | ||
482 | return mktime($h,$m,$s,$M,$D,$Y); | ||
483 | } | ||
484 | |||
485 | /* Converts a linkdate time (YYYYMMDD_HHMMSS) of an article to a RFC822 date. | ||
486 | (used to build the pubDate attribute in RSS feed.) */ | ||
487 | function linkdate2rfc822($linkdate) | ||
488 | { | ||
489 | return date('r',linkdate2timestamp($linkdate)); // 'r' is for RFC822 date format. | ||
490 | } | ||
491 | |||
492 | /* Converts a linkdate time (YYYYMMDD_HHMMSS) of an article to a ISO 8601 date. | ||
493 | (used to build the updated tags in ATOM feed.) */ | ||
494 | function linkdate2iso8601($linkdate) | ||
495 | { | ||
496 | return date('c',linkdate2timestamp($linkdate)); // 'c' is for ISO 8601 date format. | ||
497 | } | ||
498 | |||
499 | /* Converts a linkdate time (YYYYMMDD_HHMMSS) of an article to a localized date format. | ||
500 | (used to display link date on screen) | ||
501 | The date format is automatically chosen according to locale/languages sniffed from browser headers (see autoLocale()). */ | ||
502 | function linkdate2locale($linkdate) | ||
503 | { | ||
504 | return utf8_encode(strftime('%c',linkdate2timestamp($linkdate))); // %c is for automatic date format according to locale. | ||
505 | // Note that if you use a local which is not installed on your webserver, | ||
506 | // the date will not be displayed in the chosen locale, but probably in US notation. | ||
507 | } | ||
508 | |||
509 | // Parse HTTP response headers and return an associative array. | ||
510 | function http_parse_headers_shaarli( $headers ) | ||
511 | { | ||
512 | $res=array(); | ||
513 | foreach($headers as $header) | ||
514 | { | ||
515 | $i = strpos($header,': '); | ||
516 | if ($i!==false) | ||
517 | { | ||
518 | $key=substr($header,0,$i); | ||
519 | $value=substr($header,$i+2,strlen($header)-$i-2); | ||
520 | $res[$key]=$value; | ||
521 | } | ||
522 | } | ||
523 | return $res; | ||
524 | } | ||
525 | |||
526 | /* GET an URL. | ||
527 | Input: $url : url to get (http://...) | ||
528 | $timeout : Network timeout (will wait this many seconds for an anwser before giving up). | ||
529 | Output: An array. [0] = HTTP status message (eg. "HTTP/1.1 200 OK") or error message | ||
530 | [1] = associative array containing HTTP response headers (eg. echo getHTTP($url)[1]['Content-Type']) | ||
531 | [2] = data | ||
532 | Example: list($httpstatus,$headers,$data) = getHTTP('http://sebauvage.net/'); | ||
533 | if (strpos($httpstatus,'200 OK')!==false) | ||
534 | echo 'Data type: '.htmlspecialchars($headers['Content-Type']); | ||
535 | else | ||
536 | echo 'There was an error: '.htmlspecialchars($httpstatus) | ||
537 | */ | ||
538 | function getHTTP($url,$timeout=30) | ||
539 | { | ||
540 | try | ||
541 | { | ||
542 | $options = array('http'=>array('method'=>'GET','timeout' => $timeout)); // Force network timeout | ||
543 | $context = stream_context_create($options); | ||
544 | $data=file_get_contents($url,false,$context,-1, 4000000); // We download at most 4 Mb from source. | ||
545 | if (!$data) { return array('HTTP Error',array(),''); } | ||
546 | $httpStatus=$http_response_header[0]; // eg. "HTTP/1.1 200 OK" | ||
547 | $responseHeaders=http_parse_headers_shaarli($http_response_header); | ||
548 | return array($httpStatus,$responseHeaders,$data); | ||
549 | } | ||
550 | catch (Exception $e) // getHTTP *can* fail silentely (we don't care if the title cannot be fetched) | ||
551 | { | ||
552 | return array($e->getMessage(),'',''); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | // Extract title from an HTML document. | ||
557 | // (Returns an empty string if not found.) | ||
558 | function html_extract_title($html) | ||
559 | { | ||
560 | return preg_match('!<title>(.*?)</title>!is', $html, $matches) ? trim(str_replace("\n",' ', $matches[1])) : '' ; | ||
561 | } | ||
562 | |||
563 | // ------------------------------------------------------------------------------------------ | ||
564 | // Token management for XSRF protection | ||
565 | // Token should be used in any form which acts on data (create,update,delete,import...). | ||
566 | if (!isset($_SESSION['tokens'])) $_SESSION['tokens']=array(); // Token are attached to the session. | ||
567 | |||
568 | // Returns a token. | ||
569 | function getToken() | ||
570 | { | ||
571 | $rnd = sha1(uniqid('',true).'_'.mt_rand()); // We generate a random string. | ||
572 | $_SESSION['tokens'][$rnd]=1; // Store it on the server side. | ||
573 | return $rnd; | ||
574 | } | ||
575 | |||
576 | // Tells if a token is ok. Using this function will destroy the token. | ||
577 | // true=token is ok. | ||
578 | function tokenOk($token) | ||
579 | { | ||
580 | if (isset($_SESSION['tokens'][$token])) | ||
581 | { | ||
582 | unset($_SESSION['tokens'][$token]); // Token is used: destroy it. | ||
583 | return true; // Token is ok. | ||
584 | } | ||
585 | return false; // Wrong token, or already used. | ||
586 | } | ||
587 | |||
588 | // ------------------------------------------------------------------------------------------ | ||
589 | /* This class is in charge of building the final page. | ||
590 | (This is basically a wrapper around RainTPL which pre-fills some fields.) | ||
591 | p = new pageBuilder; | ||
592 | p.assign('myfield','myvalue'); | ||
593 | p.renderPage('mytemplate'); | ||
594 | |||
595 | */ | ||
596 | class pageBuilder | ||
597 | { | ||
598 | private $tpl; // RainTPL template | ||
599 | |||
600 | function __construct() | ||
601 | { | ||
602 | $this->tpl=false; | ||
603 | } | ||
604 | |||
605 | private function initialize() | ||
606 | { | ||
607 | $this->tpl = new RainTPL; | ||
608 | $this->tpl->assign('newversion',checkUpdate()); | ||
609 | $this->tpl->assign('feedurl',htmlspecialchars(indexUrl())); | ||
610 | $searchcrits=''; // Search criteria | ||
611 | if (!empty($_GET['searchtags'])) $searchcrits.='&searchtags='.urlencode($_GET['searchtags']); | ||
612 | elseif (!empty($_GET['searchterm'])) $searchcrits.='&searchterm='.urlencode($_GET['searchterm']); | ||
613 | $this->tpl->assign('searchcrits',$searchcrits); | ||
614 | $this->tpl->assign('source',indexUrl()); | ||
615 | $this->tpl->assign('version',shaarli_version); | ||
616 | $this->tpl->assign('scripturl',indexUrl()); | ||
617 | $this->tpl->assign('pagetitle','Shaarli'); | ||
618 | $this->tpl->assign('privateonly',!empty($_SESSION['privateonly'])); // Show only private links ? | ||
619 | if (!empty($GLOBALS['title'])) $this->tpl->assign('pagetitle',$GLOBALS['title']); | ||
620 | if (!empty($GLOBALS['pagetitle'])) $this->tpl->assign('pagetitle',$GLOBALS['pagetitle']); | ||
621 | $this->tpl->assign('shaarlititle',empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title'] ); | ||
622 | return; | ||
623 | } | ||
624 | |||
625 | // The following assign() method is basically the same as RainTPL (except that it's lazy) | ||
626 | public function assign($what,$where) | ||
627 | { | ||
628 | if ($this->tpl===false) $this->initialize(); // Lazy initialization | ||
629 | $this->tpl->assign($what,$where); | ||
630 | } | ||
631 | |||
632 | // Render a specific page (using a template). | ||
633 | // eg. pb.renderPage('picwall') | ||
634 | public function renderPage($page) | ||
635 | { | ||
636 | if ($this->tpl===false) $this->initialize(); // Lazy initialization | ||
637 | $this->tpl->draw($page); | ||
638 | } | ||
639 | } | ||
640 | |||
641 | // ------------------------------------------------------------------------------------------ | ||
642 | /* Data storage for links. | ||
643 | This object behaves like an associative array. | ||
644 | Example: | ||
645 | $mylinks = new linkdb(); | ||
646 | echo $mylinks['20110826_161819']['title']; | ||
647 | foreach($mylinks as $link) | ||
648 | echo $link['title'].' at url '.$link['url'].' ; description:'.$link['description']; | ||
649 | |||
650 | Available keys: | ||
651 | title : Title of the link | ||
652 | url : URL of the link. Can be absolute or relative. Relative URLs are permalinks (eg.'?m-ukcw') | ||
653 | description : description of the entry | ||
654 | private : Is this link private ? 0=no, other value=yes | ||
655 | linkdate : date of the creation of this entry, in the form YYYYMMDD_HHMMSS (eg.'20110914_192317') | ||
656 | tags : tags attached to this entry (separated by spaces) | ||
657 | |||
658 | We implement 3 interfaces: | ||
659 | - ArrayAccess so that this object behaves like an associative array. | ||
660 | - Iterator so that this object can be used in foreach() loops. | ||
661 | - Countable interface so that we can do a count() on this object. | ||
662 | */ | ||
663 | class linkdb implements Iterator, Countable, ArrayAccess | ||
664 | { | ||
665 | private $links; // List of links (associative array. Key=linkdate (eg. "20110823_124546"), value= associative array (keys:title,description...) | ||
666 | private $urls; // List of all recorded URLs (key=url, value=linkdate) for fast reserve search (url-->linkdate) | ||
667 | private $keys; // List of linkdate keys (for the Iterator interface implementation) | ||
668 | private $position; // Position in the $this->keys array. (for the Iterator interface implementation.) | ||
669 | private $loggedin; // Is the used logged in ? (used to filter private links) | ||
670 | |||
671 | // Constructor: | ||
672 | function __construct($isLoggedIn) | ||
673 | // Input : $isLoggedIn : is the used logged in ? | ||
674 | { | ||
675 | $this->loggedin = $isLoggedIn; | ||
676 | $this->checkdb(); // Make sure data file exists. | ||
677 | $this->readdb(); // Then read it. | ||
678 | } | ||
679 | |||
680 | // ---- Countable interface implementation | ||
681 | public function count() { return count($this->links); } | ||
682 | |||
683 | // ---- ArrayAccess interface implementation | ||
684 | public function offsetSet($offset, $value) | ||
685 | { | ||
686 | if (!$this->loggedin) die('You are not authorized to add a link.'); | ||
687 | if (empty($value['linkdate']) || empty($value['url'])) die('Internal Error: A link should always have a linkdate and url.'); | ||
688 | if (empty($offset)) die('You must specify a key.'); | ||
689 | $this->links[$offset] = $value; | ||
690 | $this->urls[$value['url']]=$offset; | ||
691 | } | ||
692 | public function offsetExists($offset) { return array_key_exists($offset,$this->links); } | ||
693 | public function offsetUnset($offset) | ||
694 | { | ||
695 | if (!$this->loggedin) die('You are not authorized to delete a link.'); | ||
696 | $url = $this->links[$offset]['url']; unset($this->urls[$url]); | ||
697 | unset($this->links[$offset]); | ||
698 | } | ||
699 | public function offsetGet($offset) { return isset($this->links[$offset]) ? $this->links[$offset] : null; } | ||
700 | |||
701 | // ---- Iterator interface implementation | ||
702 | function rewind() { $this->keys=array_keys($this->links); rsort($this->keys); $this->position=0; } // Start over for iteration, ordered by date (latest first). | ||
703 | function key() { return $this->keys[$this->position]; } // current key | ||
704 | function current() { return $this->links[$this->keys[$this->position]]; } // current value | ||
705 | function next() { ++$this->position; } // go to next item | ||
706 | function valid() { return isset($this->keys[$this->position]); } // Check if current position is valid. | ||
707 | |||
708 | // ---- Misc methods | ||
709 | private function checkdb() // Check if db directory and file exists. | ||
710 | { | ||
711 | if (!file_exists($GLOBALS['config']['DATASTORE'])) // Create a dummy database for example. | ||
712 | { | ||
713 | $this->links = array(); | ||
714 | $link = array('title'=>'Shaarli - sebsauvage.net','url'=>'http://sebsauvage.net/wiki/doku.php?id=php:shaarli','description'=>'Welcome to Shaarli ! This is a bookmark. To edit or delete me, you must first login.','private'=>0,'linkdate'=>'20110914_190000','tags'=>'opensource software'); | ||
715 | $this->links[$link['linkdate']] = $link; | ||
716 | $link = array('title'=>'My secret stuff... - Pastebin.com','url'=>'http://pastebin.com/smCEEeSn','description'=>'SShhhh!! I\'m a private link only YOU can see. You can delete me too.','private'=>1,'linkdate'=>'20110914_074522','tags'=>'secretstuff'); | ||
717 | $this->links[$link['linkdate']] = $link; | ||
718 | file_put_contents($GLOBALS['config']['DATASTORE'], PHPPREFIX.base64_encode(gzdeflate(serialize($this->links))).PHPSUFFIX); // Write database to disk | ||
719 | } | ||
720 | } | ||
721 | |||
722 | // Read database from disk to memory | ||
723 | private function readdb() | ||
724 | { | ||
725 | // Read data | ||
726 | $this->links=(file_exists($GLOBALS['config']['DATASTORE']) ? unserialize(gzinflate(base64_decode(substr(file_get_contents($GLOBALS['config']['DATASTORE']),strlen(PHPPREFIX),-strlen(PHPSUFFIX))))) : array() ); | ||
727 | // Note that gzinflate is faster than gzuncompress. See: http://www.php.net/manual/en/function.gzdeflate.php#96439 | ||
728 | |||
729 | // If user is not logged in, filter private links. | ||
730 | if (!$this->loggedin) | ||
731 | { | ||
732 | $toremove=array(); | ||
733 | foreach($this->links as $link) { if ($link['private']!=0) $toremove[]=$link['linkdate']; } | ||
734 | foreach($toremove as $linkdate) { unset($this->links[$linkdate]); } | ||
735 | } | ||
736 | |||
737 | // Keep the list of the mapping URLs-->linkdate up-to-date. | ||
738 | $this->urls=array(); | ||
739 | foreach($this->links as $link) { $this->urls[$link['url']]=$link['linkdate']; } | ||
740 | } | ||
741 | |||
742 | // Save database from memory to disk. | ||
743 | public function savedb() | ||
744 | { | ||
745 | if (!$this->loggedin) die('You are not authorized to change the database.'); | ||
746 | file_put_contents($GLOBALS['config']['DATASTORE'], PHPPREFIX.base64_encode(gzdeflate(serialize($this->links))).PHPSUFFIX); | ||
747 | invalidateCaches(); | ||
748 | } | ||
749 | |||
750 | // Returns the link for a given URL (if it exists). false it does not exist. | ||
751 | public function getLinkFromUrl($url) | ||
752 | { | ||
753 | if (isset($this->urls[$url])) return $this->links[$this->urls[$url]]; | ||
754 | return false; | ||
755 | } | ||
756 | |||
757 | // Case insentitive search among links (in url, title and description). Returns filtered list of links. | ||
758 | // eg. print_r($mydb->filterFulltext('hollandais')); | ||
759 | public function filterFulltext($searchterms) | ||
760 | { | ||
761 | // FIXME: explode(' ',$searchterms) and perform a AND search. | ||
762 | // FIXME: accept double-quotes to search for a string "as is" ? | ||
763 | $filtered=array(); | ||
764 | $s = strtolower($searchterms); | ||
765 | foreach($this->links as $l) | ||
766 | { | ||
767 | $found= (strpos(strtolower($l['title']),$s)!==false) | ||
768 | || (strpos(strtolower($l['description']),$s)!==false) | ||
769 | || (strpos(strtolower($l['url']),$s)!==false) | ||
770 | || (strpos(strtolower($l['tags']),$s)!==false); | ||
771 | if ($found) $filtered[$l['linkdate']] = $l; | ||
772 | } | ||
773 | krsort($filtered); | ||
774 | return $filtered; | ||
775 | } | ||
776 | |||
777 | // Filter by tag. | ||
778 | // You can specify one or more tags (tags can be separated by space or comma). | ||
779 | // eg. print_r($mydb->filterTags('linux programming')); | ||
780 | public function filterTags($tags,$casesensitive=false) | ||
781 | { | ||
782 | $t = str_replace(',',' ',($casesensitive?$tags:strtolower($tags))); | ||
783 | $searchtags=explode(' ',$t); | ||
784 | $filtered=array(); | ||
785 | foreach($this->links as $l) | ||
786 | { | ||
787 | $linktags = explode(' ',($casesensitive?$l['tags']:strtolower($l['tags']))); | ||
788 | if (count(array_intersect($linktags,$searchtags)) == count($searchtags)) | ||
789 | $filtered[$l['linkdate']] = $l; | ||
790 | } | ||
791 | krsort($filtered); | ||
792 | return $filtered; | ||
793 | } | ||
794 | |||
795 | // Filter by day. Day must be in the form 'YYYYMMDD' (eg. '20120125') | ||
796 | // Sort order is: older articles first. | ||
797 | // eg. print_r($mydb->filterDay('20120125')); | ||
798 | public function filterDay($day) | ||
799 | { | ||
800 | $filtered=array(); | ||
801 | foreach($this->links as $l) | ||
802 | { | ||
803 | if (startsWith($l['linkdate'],$day)) $filtered[$l['linkdate']] = $l; | ||
804 | } | ||
805 | ksort($filtered); | ||
806 | return $filtered; | ||
807 | } | ||
808 | // Filter by smallHash. | ||
809 | // Only 1 article is returned. | ||
810 | public function filterSmallHash($smallHash) | ||
811 | { | ||
812 | $filtered=array(); | ||
813 | foreach($this->links as $l) | ||
814 | { | ||
815 | if ($smallHash==smallHash($l['linkdate'])) // Yes, this is ugly and slow | ||
816 | { | ||
817 | $filtered[$l['linkdate']] = $l; | ||
818 | return $filtered; | ||
819 | } | ||
820 | } | ||
821 | return $filtered; | ||
822 | } | ||
823 | |||
824 | // Returns the list of all tags | ||
825 | // Output: associative array key=tags, value=0 | ||
826 | public function allTags() | ||
827 | { | ||
828 | $tags=array(); | ||
829 | foreach($this->links as $link) | ||
830 | foreach(explode(' ',$link['tags']) as $tag) | ||
831 | if (!empty($tag)) $tags[$tag]=(empty($tags[$tag]) ? 1 : $tags[$tag]+1); | ||
832 | arsort($tags); // Sort tags by usage (most used tag first) | ||
833 | return $tags; | ||
834 | } | ||
835 | |||
836 | // Returns the list of days containing articles (oldest first) | ||
837 | // Output: An array containing days (in format YYYYMMDD). | ||
838 | public function days() | ||
839 | { | ||
840 | $linkdays=array(); | ||
841 | foreach(array_keys($this->links) as $day) | ||
842 | { | ||
843 | $linkdays[substr($day,0,8)]=0; | ||
844 | } | ||
845 | $linkdays=array_keys($linkdays); | ||
846 | sort($linkdays); | ||
847 | return $linkdays; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | // ------------------------------------------------------------------------------------------ | ||
852 | // Ouput the last 50 links in RSS 2.0 format. | ||
853 | function showRSS() | ||
854 | { | ||
855 | header('Content-Type: application/rss+xml; charset=utf-8'); | ||
856 | |||
857 | // Cache system | ||
858 | $query = $_SERVER["QUERY_STRING"]; | ||
859 | $cache = new pageCache(pageUrl(),startsWith($query,'do=rss') && !isLoggedIn()); | ||
860 | $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } | ||
861 | |||
862 | // If cached was not found (or not usable), then read the database and build the response: | ||
863 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
864 | |||
865 | // Optionnaly filter the results: | ||
866 | $linksToDisplay=array(); | ||
867 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); | ||
868 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | ||
869 | else $linksToDisplay = $LINKSDB; | ||
870 | |||
871 | $pageaddr=htmlspecialchars(indexUrl()); | ||
872 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">'; | ||
873 | echo '<channel><title>'.htmlspecialchars($GLOBALS['title']).'</title><link>'.$pageaddr.'</link>'; | ||
874 | echo '<description>Shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n\n"; | ||
875 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
876 | { | ||
877 | echo '<!-- PubSubHubbub Discovery -->'; | ||
878 | echo '<link rel="hub" href="'.htmlspecialchars($GLOBALS['config']['PUBSUBHUB_URL']).'" xmlns="http://www.w3.org/2005/Atom" />'; | ||
879 | echo '<link rel="self" href="'.htmlspecialchars($pageaddr).'?do=rss" xmlns="http://www.w3.org/2005/Atom" />'; | ||
880 | echo '<!-- End Of PubSubHubbub Discovery -->'; | ||
881 | } | ||
882 | $i=0; | ||
883 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | ||
884 | while ($i<50 && $i<count($keys)) | ||
885 | { | ||
886 | $link = $linksToDisplay[$keys[$i]]; | ||
887 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); | ||
888 | $rfc822date = linkdate2rfc822($link['linkdate']); | ||
889 | $absurl = htmlspecialchars($link['url']); | ||
890 | if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute | ||
891 | echo '<item><title>'.htmlspecialchars($link['title']).'</title><guid>'.$guid.'</guid><link>'.$absurl.'</link>'; | ||
892 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) echo '<pubDate>'.htmlspecialchars($rfc822date)."</pubDate>\n"; | ||
893 | if ($link['tags']!='') // Adding tags to each RSS entry (as mentioned in RSS specification) | ||
894 | { | ||
895 | foreach(explode(' ',$link['tags']) as $tag) { echo '<category domain="'.htmlspecialchars($pageaddr).'">'.htmlspecialchars($tag).'</category>'."\n"; } | ||
896 | } | ||
897 | echo '<description><![CDATA['.nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))).']]></description>'."\n</item>\n"; | ||
898 | $i++; | ||
899 | } | ||
900 | echo '</channel></rss>'; | ||
901 | |||
902 | $cache->cache(ob_get_contents()); | ||
903 | ob_end_flush(); | ||
904 | exit; | ||
905 | } | ||
906 | |||
907 | // ------------------------------------------------------------------------------------------ | ||
908 | // Ouput the last 50 links in ATOM format. | ||
909 | function showATOM() | ||
910 | { | ||
911 | header('Content-Type: application/atom+xml; charset=utf-8'); | ||
912 | |||
913 | // Cache system | ||
914 | $query = $_SERVER["QUERY_STRING"]; | ||
915 | $cache = new pageCache(pageUrl(),startsWith($query,'do=atom') && !isLoggedIn()); | ||
916 | $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } | ||
917 | // If cached was not found (or not usable), then read the database and build the response: | ||
918 | |||
919 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
920 | |||
921 | |||
922 | // Optionnaly filter the results: | ||
923 | $linksToDisplay=array(); | ||
924 | if (!empty($_GET['searchterm'])) $linksToDisplay = $LINKSDB->filterFulltext($_GET['searchterm']); | ||
925 | elseif (!empty($_GET['searchtags'])) $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | ||
926 | else $linksToDisplay = $LINKSDB; | ||
927 | |||
928 | $pageaddr=htmlspecialchars(indexUrl()); | ||
929 | $latestDate = ''; | ||
930 | $entries=''; | ||
931 | $i=0; | ||
932 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // No, I can't use array_keys(). | ||
933 | while ($i<50 && $i<count($keys)) | ||
934 | { | ||
935 | $link = $linksToDisplay[$keys[$i]]; | ||
936 | $guid = $pageaddr.'?'.smallHash($link['linkdate']); | ||
937 | $iso8601date = linkdate2iso8601($link['linkdate']); | ||
938 | $latestDate = max($latestDate,$iso8601date); | ||
939 | $absurl = htmlspecialchars($link['url']); | ||
940 | if (startsWith($absurl,'?')) $absurl=$pageaddr.$absurl; // make permalink URL absolute | ||
941 | $entries.='<entry><title>'.htmlspecialchars($link['title']).'</title><link href="'.$absurl.'" /><id>'.$guid.'</id>'; | ||
942 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $entries.='<updated>'.htmlspecialchars($iso8601date).'</updated>'; | ||
943 | $entries.='<content type="html">'.htmlspecialchars(nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))))."</content>\n"; | ||
944 | if ($link['tags']!='') // Adding tags to each ATOM entry (as mentioned in ATOM specification) | ||
945 | { | ||
946 | foreach(explode(' ',$link['tags']) as $tag) | ||
947 | { $entries.='<category scheme="'.htmlspecialchars($pageaddr,ENT_QUOTES).'" term="'.htmlspecialchars($tag,ENT_QUOTES).'" />'."\n"; } | ||
948 | } | ||
949 | $entries.="</entry>\n"; | ||
950 | $i++; | ||
951 | } | ||
952 | $feed='<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">'; | ||
953 | $feed.='<title>'.htmlspecialchars($GLOBALS['title']).'</title>'; | ||
954 | if (!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()) $feed.='<updated>'.htmlspecialchars($latestDate).'</updated>'; | ||
955 | $feed.='<link rel="self" href="'.htmlspecialchars(serverUrl().$_SERVER["REQUEST_URI"]).'" />'; | ||
956 | if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) | ||
957 | { | ||
958 | $feed.='<!-- PubSubHubbub Discovery -->'; | ||
959 | $feed.='<link rel="hub" href="'.htmlspecialchars($GLOBALS['config']['PUBSUBHUB_URL']).'" />'; | ||
960 | $feed.='<!-- End Of PubSubHubbub Discovery -->'; | ||
961 | } | ||
962 | $feed.='<author><name>'.htmlspecialchars($pageaddr).'</name><uri>'.htmlspecialchars($pageaddr).'</uri></author>'; | ||
963 | $feed.='<id>'.htmlspecialchars($pageaddr).'</id>'."\n\n"; // Yes, I know I should use a real IRI (RFC3987), but the site URL will do. | ||
964 | $feed.=$entries; | ||
965 | $feed.='</feed>'; | ||
966 | echo $feed; | ||
967 | |||
968 | $cache->cache(ob_get_contents()); | ||
969 | ob_end_flush(); | ||
970 | exit; | ||
971 | } | ||
972 | |||
973 | // ------------------------------------------------------------------------------------------ | ||
974 | // Daily RSS feed: 1 RSS entry per day giving all the links on that day. | ||
975 | // Gives the last 7 days (which have links). | ||
976 | // This RSS feed cannot be filtered. | ||
977 | function showDailyRSS() | ||
978 | { | ||
979 | // Cache system | ||
980 | $query = $_SERVER["QUERY_STRING"]; | ||
981 | $cache = new pageCache(pageUrl(),startsWith($query,'do=dailyrss') && !isLoggedIn()); | ||
982 | $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } | ||
983 | // If cached was not found (or not usable), then read the database and build the response: | ||
984 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
985 | |||
986 | /* Some Shaarlies may have very few links, so we need to look | ||
987 | back in time (rsort()) until we have enough days ($nb_of_days). | ||
988 | */ | ||
989 | $linkdates=array(); foreach($LINKSDB as $linkdate=>$value) { $linkdates[]=$linkdate; } | ||
990 | rsort($linkdates); | ||
991 | $nb_of_days=7; // We take 7 days. | ||
992 | $today=Date('Ymd'); | ||
993 | $days=array(); | ||
994 | foreach($linkdates as $linkdate) | ||
995 | { | ||
996 | $day=substr($linkdate,0,8); // Extract day (without time) | ||
997 | if (strcmp($day,$today)<0) | ||
998 | { | ||
999 | if (empty($days[$day])) $days[$day]=array(); | ||
1000 | $days[$day][]=$linkdate; | ||
1001 | } | ||
1002 | if (count($days)>$nb_of_days) break; // Have we collected enough days ? | ||
1003 | } | ||
1004 | |||
1005 | // Build the RSS feed. | ||
1006 | header('Content-Type: application/rss+xml; charset=utf-8'); | ||
1007 | $pageaddr=htmlspecialchars(indexUrl()); | ||
1008 | echo '<?xml version="1.0" encoding="UTF-8"?><rss version="2.0">'; | ||
1009 | echo '<channel><title>Daily - '.htmlspecialchars($GLOBALS['title']).'</title><link>'.$pageaddr.'</link>'; | ||
1010 | echo '<description>Daily shared links</description><language>en-en</language><copyright>'.$pageaddr.'</copyright>'."\n"; | ||
1011 | |||
1012 | foreach($days as $day=>$linkdates) // For each day. | ||
1013 | { | ||
1014 | $daydate = utf8_encode(strftime('%A %d, %B %Y',linkdate2timestamp($day.'_000000'))); // Full text date | ||
1015 | $rfc822date = linkdate2rfc822($day.'_000000'); | ||
1016 | $absurl=htmlspecialchars(indexUrl().'?do=daily&day='.$day); // Absolute URL of the corresponding "Daily" page. | ||
1017 | echo '<item><title>'.htmlspecialchars($GLOBALS['title'].' - '.$daydate).'</title><guid>'.$absurl.'</guid><link>'.$absurl.'</link>'; | ||
1018 | echo '<pubDate>'.htmlspecialchars($rfc822date)."</pubDate>"; | ||
1019 | |||
1020 | // Build the HTML body of this RSS entry. | ||
1021 | $html=''; | ||
1022 | $href=''; | ||
1023 | $links=array(); | ||
1024 | // We pre-format some fields for proper output. | ||
1025 | foreach($linkdates as $linkdate) | ||
1026 | { | ||
1027 | $l = $LINKSDB[$linkdate]; | ||
1028 | $l['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($l['description'])))); | ||
1029 | $l['thumbnail'] = thumbnail($l['url']); | ||
1030 | $l['localdate']=linkdate2locale($l['linkdate']); | ||
1031 | if (startsWith($l['url'],'?')) $l['url']=indexUrl().$l['url']; // make permalink URL absolute | ||
1032 | $links[$linkdate]=$l; | ||
1033 | } | ||
1034 | // Then build the HTML for this day: | ||
1035 | $tpl = new RainTPL; | ||
1036 | $tpl->assign('links',$links); | ||
1037 | $html = $tpl->draw('dailyrss',$return_string=true); | ||
1038 | echo "\n"; | ||
1039 | echo '<description><![CDATA['.$html.']]></description>'."\n</item>\n\n"; | ||
1040 | |||
1041 | } | ||
1042 | echo '</channel></rss>'; | ||
1043 | |||
1044 | $cache->cache(ob_get_contents()); | ||
1045 | ob_end_flush(); | ||
1046 | exit; | ||
1047 | } | ||
1048 | |||
1049 | // "Daily" page. | ||
1050 | function showDaily() | ||
1051 | { | ||
1052 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
1053 | |||
1054 | |||
1055 | $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. | ||
1056 | if (isset($_GET['day'])) $day=$_GET['day']; | ||
1057 | |||
1058 | $days = $LINKSDB->days(); | ||
1059 | $i = array_search($day,$days); | ||
1060 | if ($i==false) { $i=count($days)-1; $day=$days[$i]; } | ||
1061 | $previousday=''; | ||
1062 | $nextday=''; | ||
1063 | if ($i!==false) | ||
1064 | { | ||
1065 | if ($i>1) $previousday=$days[$i-1]; | ||
1066 | if ($i<count($days)-1) $nextday=$days[$i+1]; | ||
1067 | } | ||
1068 | |||
1069 | $linksToDisplay=$LINKSDB->filterDay($day); | ||
1070 | // We pre-format some fields for proper output. | ||
1071 | foreach($linksToDisplay as $key=>$link) | ||
1072 | { | ||
1073 | $linksToDisplay[$key]['taglist']=explode(' ',$link['tags']); | ||
1074 | $linksToDisplay[$key]['formatedDescription']=nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))); | ||
1075 | $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); | ||
1076 | } | ||
1077 | |||
1078 | /* We need to spread the articles on 3 columns. | ||
1079 | I did not want to use a javascript lib like http://masonry.desandro.com/ | ||
1080 | so I manually spread entries with a simple method: I roughly evaluate the | ||
1081 | height of a div according to title and description length. | ||
1082 | */ | ||
1083 | $columns=array(array(),array(),array()); // Entries to display, for each column. | ||
1084 | $fill=array(0,0,0); // Rough estimate of columns fill. | ||
1085 | foreach($linksToDisplay as $key=>$link) | ||
1086 | { | ||
1087 | // Roughly estimate length of entry (by counting characters) | ||
1088 | // Title: 30 chars = 1 line. 1 line is 30 pixels height. | ||
1089 | // Description: 836 characters gives roughly 342 pixel height. | ||
1090 | // This is not perfect, but it's usually ok. | ||
1091 | $length=strlen($link['title'])+(342*strlen($link['description']))/836; | ||
1092 | if ($link['thumbnail']) $length +=100; // 1 thumbnails roughly takes 100 pixels height. | ||
1093 | // Then put in column which is the less filled: | ||
1094 | $smallest=min($fill); // find smallest value in array. | ||
1095 | $index=array_search($smallest,$fill); // find index of this smallest value. | ||
1096 | array_push($columns[$index],$link); // Put entry in this column. | ||
1097 | $fill[$index]+=$length; | ||
1098 | } | ||
1099 | $PAGE = new pageBuilder; | ||
1100 | $PAGE->assign('linksToDisplay',$linksToDisplay); | ||
1101 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1102 | $PAGE->assign('col1',$columns[0]); | ||
1103 | $PAGE->assign('col1',$columns[0]); | ||
1104 | $PAGE->assign('col2',$columns[1]); | ||
1105 | $PAGE->assign('col3',$columns[2]); | ||
1106 | $PAGE->assign('day',utf8_encode(strftime('%A %d, %B %Y',linkdate2timestamp($day.'_000000')))); | ||
1107 | $PAGE->assign('previousday',$previousday); | ||
1108 | $PAGE->assign('nextday',$nextday); | ||
1109 | $PAGE->renderPage('daily'); | ||
1110 | exit; | ||
1111 | } | ||
1112 | |||
1113 | |||
1114 | // ------------------------------------------------------------------------------------------ | ||
1115 | // Render HTML page (according to URL parameters and user rights) | ||
1116 | function renderPage() | ||
1117 | { | ||
1118 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
1119 | |||
1120 | // -------- Display login form. | ||
1121 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=login')) | ||
1122 | { | ||
1123 | if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli | ||
1124 | $token=''; if (ban_canLogin()) $token=getToken(); // Do not waste token generation if not useful. | ||
1125 | $PAGE = new pageBuilder; | ||
1126 | $PAGE->assign('token',$token); | ||
1127 | $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER']:'')); | ||
1128 | $PAGE->renderPage('loginform'); | ||
1129 | exit; | ||
1130 | } | ||
1131 | // -------- User wants to logout. | ||
1132 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=logout')) | ||
1133 | { | ||
1134 | invalidateCaches(); | ||
1135 | logout(); | ||
1136 | header('Location: ?'); | ||
1137 | exit; | ||
1138 | } | ||
1139 | |||
1140 | // -------- Picture wall | ||
1141 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=picwall')) | ||
1142 | { | ||
1143 | // Optionnaly filter the results: | ||
1144 | $links=array(); | ||
1145 | if (!empty($_GET['searchterm'])) $links = $LINKSDB->filterFulltext($_GET['searchterm']); | ||
1146 | elseif (!empty($_GET['searchtags'])) $links = $LINKSDB->filterTags(trim($_GET['searchtags'])); | ||
1147 | else $links = $LINKSDB; | ||
1148 | $body=''; | ||
1149 | $linksToDisplay=array(); | ||
1150 | |||
1151 | // Get only links which have a thumbnail. | ||
1152 | foreach($links as $link) | ||
1153 | { | ||
1154 | $permalink='?'.htmlspecialchars(smallhash($link['linkdate']),ENT_QUOTES); | ||
1155 | $thumb=lazyThumbnail($link['url'],$permalink); | ||
1156 | if ($thumb!='') // Only output links which have a thumbnail. | ||
1157 | { | ||
1158 | $link['thumbnail']=$thumb; // Thumbnail HTML code. | ||
1159 | $link['permalink']=$permalink; | ||
1160 | $linksToDisplay[]=$link; // Add to array. | ||
1161 | } | ||
1162 | } | ||
1163 | $PAGE = new pageBuilder; | ||
1164 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1165 | $PAGE->assign('linksToDisplay',$linksToDisplay); | ||
1166 | $PAGE->renderPage('picwall'); | ||
1167 | exit; | ||
1168 | } | ||
1169 | |||
1170 | // -------- Tag cloud | ||
1171 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=tagcloud')) | ||
1172 | { | ||
1173 | $tags= $LINKSDB->allTags(); | ||
1174 | // We sort tags alphabetically, then choose a font size according to count. | ||
1175 | // First, find max value. | ||
1176 | $maxcount=0; foreach($tags as $key=>$value) $maxcount=max($maxcount,$value); | ||
1177 | ksort($tags); | ||
1178 | $tagList=array(); | ||
1179 | foreach($tags as $key=>$value) | ||
1180 | { | ||
1181 | $tagList[$key] = array('count'=>$value,'size'=>max(40*$value/$maxcount,8)); | ||
1182 | } | ||
1183 | $PAGE = new pageBuilder; | ||
1184 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1185 | $PAGE->assign('tags',$tagList); | ||
1186 | $PAGE->renderPage('tagcloud'); | ||
1187 | exit; | ||
1188 | } | ||
1189 | |||
1190 | // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) | ||
1191 | if (isset($_GET['addtag'])) | ||
1192 | { | ||
1193 | // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. | ||
1194 | if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags='.urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER | ||
1195 | parse_str(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_QUERY), $params); | ||
1196 | $params['searchtags'] = (empty($params['searchtags']) ? trim($_GET['addtag']) : trim($params['searchtags']).' '.trim($_GET['addtag'])); | ||
1197 | unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) | ||
1198 | header('Location: ?'.http_build_query($params)); | ||
1199 | exit; | ||
1200 | } | ||
1201 | |||
1202 | // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) | ||
1203 | if (isset($_GET['removetag'])) | ||
1204 | { | ||
1205 | // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. | ||
1206 | if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER | ||
1207 | parse_str(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_QUERY), $params); | ||
1208 | if (isset($params['searchtags'])) | ||
1209 | { | ||
1210 | $tags = explode(' ',$params['searchtags']); | ||
1211 | $tags=array_diff($tags, array($_GET['removetag'])); // Remove value from array $tags. | ||
1212 | if (count($tags)==0) unset($params['searchtags']); else $params['searchtags'] = implode(' ',$tags); | ||
1213 | unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) | ||
1214 | } | ||
1215 | header('Location: ?'.http_build_query($params)); | ||
1216 | exit; | ||
1217 | } | ||
1218 | |||
1219 | // -------- User wants to change the number of links per page (linksperpage=...) | ||
1220 | if (isset($_GET['linksperpage'])) | ||
1221 | { | ||
1222 | if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE']=abs(intval($_GET['linksperpage'])); } | ||
1223 | header('Location: '.(empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER'])); | ||
1224 | exit; | ||
1225 | } | ||
1226 | |||
1227 | // -------- User wants to see only private links (toggle) | ||
1228 | if (isset($_GET['privateonly'])) | ||
1229 | { | ||
1230 | if (empty($_SESSION['privateonly'])) | ||
1231 | { | ||
1232 | $_SESSION['privateonly']=1; // See only private links | ||
1233 | } | ||
1234 | else | ||
1235 | { | ||
1236 | unset($_SESSION['privateonly']); // See all links | ||
1237 | } | ||
1238 | header('Location: '.(empty($_SERVER['HTTP_REFERER'])?'?':$_SERVER['HTTP_REFERER'])); | ||
1239 | exit; | ||
1240 | } | ||
1241 | |||
1242 | // -------- Handle other actions allowed for non-logged in users: | ||
1243 | if (!isLoggedIn()) | ||
1244 | { | ||
1245 | // User tries to post new link but is not loggedin: | ||
1246 | // Show login screen, then redirect to ?post=... | ||
1247 | if (isset($_GET['post'])) | ||
1248 | { | ||
1249 | header('Location: ?do=login&post='.urlencode($_GET['post']).(!empty($_GET['title'])?'&title='.urlencode($_GET['title']):'').(!empty($_GET['source'])?'&source='.urlencode($_GET['source']):'')); // Redirect to login page, then back to post link. | ||
1250 | exit; | ||
1251 | } | ||
1252 | $PAGE = new pageBuilder; | ||
1253 | buildLinkList($PAGE,$LINKSDB); // Compute list of links to display | ||
1254 | $PAGE->renderPage('linklist'); | ||
1255 | exit; // Never remove this one ! All operations below are reserved for logged in user. | ||
1256 | } | ||
1257 | |||
1258 | // -------- All other functions are reserved for the registered user: | ||
1259 | |||
1260 | // -------- Display the Tools menu if requested (import/export/bookmarklet...) | ||
1261 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=tools')) | ||
1262 | { | ||
1263 | $PAGE = new pageBuilder; | ||
1264 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1265 | $PAGE->assign('pageabsaddr',indexUrl()); | ||
1266 | $PAGE->renderPage('tools'); | ||
1267 | exit; | ||
1268 | } | ||
1269 | |||
1270 | // -------- User wants to change his/her password. | ||
1271 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=changepasswd')) | ||
1272 | { | ||
1273 | if ($GLOBALS['config']['OPEN_SHAARLI']) die('You are not supposed to change a password on an Open Shaarli.'); | ||
1274 | if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) | ||
1275 | { | ||
1276 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! | ||
1277 | |||
1278 | // Make sure old password is correct. | ||
1279 | $oldhash = sha1($_POST['oldpassword'].$GLOBALS['login'].$GLOBALS['salt']); | ||
1280 | if ($oldhash!=$GLOBALS['hash']) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } | ||
1281 | // Save new password | ||
1282 | $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. | ||
1283 | $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); | ||
1284 | writeConfig(); | ||
1285 | echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; | ||
1286 | exit; | ||
1287 | } | ||
1288 | else // show the change password form. | ||
1289 | { | ||
1290 | $PAGE = new pageBuilder; | ||
1291 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1292 | $PAGE->assign('token',getToken()); | ||
1293 | $PAGE->renderPage('changepassword'); | ||
1294 | exit; | ||
1295 | } | ||
1296 | } | ||
1297 | |||
1298 | // -------- User wants to change configuration | ||
1299 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=configure')) | ||
1300 | { | ||
1301 | if (!empty($_POST['title']) ) | ||
1302 | { | ||
1303 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! | ||
1304 | $tz = 'UTC'; | ||
1305 | if (!empty($_POST['continent']) && !empty($_POST['city'])) | ||
1306 | if (isTZvalid($_POST['continent'],$_POST['city'])) | ||
1307 | $tz = $_POST['continent'].'/'.$_POST['city']; | ||
1308 | $GLOBALS['timezone'] = $tz; | ||
1309 | $GLOBALS['title']=$_POST['title']; | ||
1310 | $GLOBALS['redirector']=$_POST['redirector']; | ||
1311 | $GLOBALS['disablesessionprotection']=!empty($_POST['disablesessionprotection']); | ||
1312 | writeConfig(); | ||
1313 | echo '<script language="JavaScript">alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; | ||
1314 | exit; | ||
1315 | } | ||
1316 | else // Show the configuration form. | ||
1317 | { | ||
1318 | $PAGE = new pageBuilder; | ||
1319 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1320 | $PAGE->assign('token',getToken()); | ||
1321 | $PAGE->assign('title',htmlspecialchars( empty($GLOBALS['title']) ? '' : $GLOBALS['title'] , ENT_QUOTES)); | ||
1322 | $PAGE->assign('redirector',htmlspecialchars( empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'] , ENT_QUOTES)); | ||
1323 | list($timezone_form,$timezone_js) = templateTZform($GLOBALS['timezone']); | ||
1324 | $PAGE->assign('timezone_form',$timezone_form); // FIXME: put entire tz form generation in template ? | ||
1325 | $PAGE->assign('timezone_js',$timezone_js); | ||
1326 | $PAGE->renderPage('configure'); | ||
1327 | exit; | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | // -------- User wants to rename a tag or delete it | ||
1332 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=changetag')) | ||
1333 | { | ||
1334 | if (empty($_POST['fromtag'])) | ||
1335 | { | ||
1336 | $PAGE = new pageBuilder; | ||
1337 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1338 | $PAGE->assign('token',getToken()); | ||
1339 | $PAGE->renderPage('changetag'); | ||
1340 | exit; | ||
1341 | } | ||
1342 | if (!tokenOk($_POST['token'])) die('Wrong token.'); | ||
1343 | |||
1344 | // Delete a tag: | ||
1345 | if (!empty($_POST['deletetag']) && !empty($_POST['fromtag'])) | ||
1346 | { | ||
1347 | $needle=trim($_POST['fromtag']); | ||
1348 | $linksToAlter = $LINKSDB->filterTags($needle,true); // true for case-sensitive tag search. | ||
1349 | foreach($linksToAlter as $key=>$value) | ||
1350 | { | ||
1351 | $tags = explode(' ',trim($value['tags'])); | ||
1352 | unset($tags[array_search($needle,$tags)]); // Remove tag. | ||
1353 | $value['tags']=trim(implode(' ',$tags)); | ||
1354 | $LINKSDB[$key]=$value; | ||
1355 | } | ||
1356 | $LINKSDB->savedb(); // save to disk | ||
1357 | echo '<script language="JavaScript">alert("Tag was removed from '.count($linksToAlter).' links.");document.location=\'?\';</script>'; | ||
1358 | exit; | ||
1359 | } | ||
1360 | |||
1361 | // Rename a tag: | ||
1362 | if (!empty($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) | ||
1363 | { | ||
1364 | $needle=trim($_POST['fromtag']); | ||
1365 | $linksToAlter = $LINKSDB->filterTags($needle,true); // true for case-sensitive tag search. | ||
1366 | foreach($linksToAlter as $key=>$value) | ||
1367 | { | ||
1368 | $tags = explode(' ',trim($value['tags'])); | ||
1369 | $tags[array_search($needle,$tags)] = trim($_POST['totag']); // Remplace tags value. | ||
1370 | $value['tags']=trim(implode(' ',$tags)); | ||
1371 | $LINKSDB[$key]=$value; | ||
1372 | } | ||
1373 | $LINKSDB->savedb(); // save to disk | ||
1374 | echo '<script language="JavaScript">alert("Tag was renamed in '.count($linksToAlter).' links.");document.location=\'?searchtags='.urlencode($_POST['totag']).'\';</script>'; | ||
1375 | exit; | ||
1376 | } | ||
1377 | } | ||
1378 | |||
1379 | // -------- User wants to add a link without using the bookmarklet: show form. | ||
1380 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=addlink')) | ||
1381 | { | ||
1382 | $PAGE = new pageBuilder; | ||
1383 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1384 | $PAGE->renderPage('addlink'); | ||
1385 | exit; | ||
1386 | } | ||
1387 | |||
1388 | // -------- User clicked the "Save" button when editing a link: Save link to database. | ||
1389 | if (isset($_POST['save_edit'])) | ||
1390 | { | ||
1391 | if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away ! | ||
1392 | $tags = trim(preg_replace('/\s\s+/',' ', $_POST['lf_tags'])); // Remove multiple spaces. | ||
1393 | $linkdate=$_POST['lf_linkdate']; | ||
1394 | $link = array('title'=>trim($_POST['lf_title']),'url'=>trim($_POST['lf_url']),'description'=>trim($_POST['lf_description']),'private'=>(isset($_POST['lf_private']) ? 1 : 0), | ||
1395 | 'linkdate'=>$linkdate,'tags'=>str_replace(',',' ',$tags)); | ||
1396 | if ($link['title']=='') $link['title']=$link['url']; // If title is empty, use the URL as title. | ||
1397 | $LINKSDB[$linkdate] = $link; | ||
1398 | $LINKSDB->savedb(); // save to disk | ||
1399 | pubsubhub(); | ||
1400 | |||
1401 | // If we are called from the bookmarklet, we must close the popup: | ||
1402 | if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } | ||
1403 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); | ||
1404 | header('Location: '.$returnurl); // After saving the link, redirect to the page the user was on. | ||
1405 | exit; | ||
1406 | } | ||
1407 | |||
1408 | // -------- User clicked the "Cancel" button when editing a link. | ||
1409 | if (isset($_POST['cancel_edit'])) | ||
1410 | { | ||
1411 | // If we are called from the bookmarklet, we must close the popup; | ||
1412 | if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } | ||
1413 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); | ||
1414 | header('Location: '.$returnurl); // After canceling, redirect to the page the user was on. | ||
1415 | exit; | ||
1416 | } | ||
1417 | |||
1418 | // -------- User clicked the "Delete" button when editing a link : Delete link from database. | ||
1419 | if (isset($_POST['delete_link'])) | ||
1420 | { | ||
1421 | if (!tokenOk($_POST['token'])) die('Wrong token.'); | ||
1422 | // We do not need to ask for confirmation: | ||
1423 | // - confirmation is handled by javascript | ||
1424 | // - we are protected from XSRF by the token. | ||
1425 | $linkdate=$_POST['lf_linkdate']; | ||
1426 | unset($LINKSDB[$linkdate]); | ||
1427 | $LINKSDB->savedb(); // save to disk | ||
1428 | |||
1429 | // If we are called from the bookmarklet, we must close the popup: | ||
1430 | if (isset($_GET['source']) && $_GET['source']=='bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } | ||
1431 | $returnurl = ( isset($_POST['returnurl']) ? $_POST['returnurl'] : '?' ); | ||
1432 | if ($returnurl=='?') { $returnurl = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '?'); } | ||
1433 | header('Location: '.$returnurl); // After deleting the link, redirect to the page the user was on. | ||
1434 | exit; | ||
1435 | } | ||
1436 | |||
1437 | // -------- User clicked the "EDIT" button on a link: Display link edit form. | ||
1438 | if (isset($_GET['edit_link'])) | ||
1439 | { | ||
1440 | $link = $LINKSDB[$_GET['edit_link']]; // Read database | ||
1441 | if (!$link) { header('Location: ?'); exit; } // Link not found in database. | ||
1442 | $PAGE = new pageBuilder; | ||
1443 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1444 | $PAGE->assign('link',$link); | ||
1445 | $PAGE->assign('link_is_new',false); | ||
1446 | $PAGE->assign('token',getToken()); // XSRF protection. | ||
1447 | $PAGE->assign('http_referer',(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '')); | ||
1448 | $PAGE->renderPage('editlink'); | ||
1449 | exit; | ||
1450 | } | ||
1451 | |||
1452 | // -------- User want to post a new link: Display link edit form. | ||
1453 | if (isset($_GET['post'])) | ||
1454 | { | ||
1455 | $url=$_GET['post']; | ||
1456 | |||
1457 | // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) | ||
1458 | $i=strpos($url,'&utm_source='); if ($i!==false) $url=substr($url,0,$i); | ||
1459 | $i=strpos($url,'?utm_source='); if ($i!==false) $url=substr($url,0,$i); | ||
1460 | $i=strpos($url,'#xtor=RSS-'); if ($i!==false) $url=substr($url,0,$i); | ||
1461 | |||
1462 | $link_is_new = false; | ||
1463 | $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) | ||
1464 | if (!$link) | ||
1465 | { | ||
1466 | $link_is_new = true; // This is a new link | ||
1467 | $linkdate = strval(date('Ymd_His')); | ||
1468 | $title = (empty($_GET['title']) ? '' : $_GET['title'] ); // Get title if it was provided in URL (by the bookmarklet). | ||
1469 | $description=''; $tags=''; $private=0; | ||
1470 | if (($url!='') && parse_url($url,PHP_URL_SCHEME)=='') $url = 'http://'.$url; | ||
1471 | // If this is an HTTP link, we try go get the page to extact the title (otherwise we will to straight to the edit form.) | ||
1472 | if (empty($title) && parse_url($url,PHP_URL_SCHEME)=='http') | ||
1473 | { | ||
1474 | list($status,$headers,$data) = getHTTP($url,4); // Short timeout to keep the application responsive. | ||
1475 | // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html | ||
1476 | if (strpos($status,'200 OK')!==false) $title=html_entity_decode(html_extract_title($data),ENT_QUOTES,'UTF-8'); | ||
1477 | |||
1478 | } | ||
1479 | if ($url=='') $url='?'.smallHash($linkdate); // In case of empty URL, this is just a text (with a link that point to itself) | ||
1480 | $link = array('linkdate'=>$linkdate,'title'=>$title,'url'=>$url,'description'=>$description,'tags'=>$tags,'private'=>0); | ||
1481 | } | ||
1482 | |||
1483 | $PAGE = new pageBuilder; | ||
1484 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1485 | $PAGE->assign('link',$link); | ||
1486 | $PAGE->assign('link_is_new',$link_is_new); | ||
1487 | $PAGE->assign('token',getToken()); // XSRF protection. | ||
1488 | $PAGE->assign('http_referer',(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '')); | ||
1489 | $PAGE->renderPage('editlink'); | ||
1490 | exit; | ||
1491 | } | ||
1492 | |||
1493 | // -------- Export as Netscape Bookmarks HTML file. | ||
1494 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=export')) | ||
1495 | { | ||
1496 | if (empty($_GET['what'])) | ||
1497 | { | ||
1498 | $PAGE = new pageBuilder; | ||
1499 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1500 | $PAGE->renderPage('export'); | ||
1501 | exit; | ||
1502 | } | ||
1503 | $exportWhat=$_GET['what']; | ||
1504 | if (!array_intersect(array('all','public','private'),array($exportWhat))) die('What are you trying to export ???'); | ||
1505 | |||
1506 | header('Content-Type: text/html; charset=utf-8'); | ||
1507 | header('Content-disposition: attachment; filename=bookmarks_'.$exportWhat.'_'.strval(date('Ymd_His')).'.html'); | ||
1508 | $currentdate=date('Y/m/d H:i:s'); | ||
1509 | echo <<<HTML | ||
1510 | <!DOCTYPE NETSCAPE-Bookmark-file-1> | ||
1511 | <!-- This is an automatically generated file. | ||
1512 | It will be read and overwritten. | ||
1513 | DO NOT EDIT! --> | ||
1514 | <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> | ||
1515 | <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> | ||
1516 | <TITLE>Bookmarks</TITLE> | ||
1517 | <H1>Bookmarks</H1> | ||
1518 | HTML; | ||
1519 | foreach($LINKSDB as $link) | ||
1520 | { | ||
1521 | if ($exportWhat=='all' || | ||
1522 | ($exportWhat=='private' && $link['private']!=0) || | ||
1523 | ($exportWhat=='public' && $link['private']==0)) | ||
1524 | { | ||
1525 | echo '<DT><A HREF="'.htmlspecialchars($link['url']).'" ADD_DATE="'.linkdate2timestamp($link['linkdate']).'" PRIVATE="'.$link['private'].'"'; | ||
1526 | if ($link['tags']!='') echo ' TAGS="'.htmlspecialchars(str_replace(' ',',',$link['tags'])).'"'; | ||
1527 | echo '>'.htmlspecialchars($link['title'])."</A>\n"; | ||
1528 | if ($link['description']!='') echo '<DD>'.htmlspecialchars($link['description'])."\n"; | ||
1529 | } | ||
1530 | } | ||
1531 | exit; | ||
1532 | } | ||
1533 | |||
1534 | // -------- User is uploading a file for import | ||
1535 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=upload')) | ||
1536 | { | ||
1537 | // If file is too big, some form field may be missing. | ||
1538 | if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0)) | ||
1539 | { | ||
1540 | $returnurl = ( empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'] ); | ||
1541 | echo '<script language="JavaScript">alert("The file you are trying to upload is probably bigger than what this webserver can accept ('.getMaxFileSize().' bytes). Please upload in smaller chunks.");document.location=\''.htmlspecialchars($returnurl).'\';</script>'; | ||
1542 | exit; | ||
1543 | } | ||
1544 | if (!tokenOk($_POST['token'])) die('Wrong token.'); | ||
1545 | importFile(); | ||
1546 | exit; | ||
1547 | } | ||
1548 | |||
1549 | // -------- Show upload/import dialog: | ||
1550 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=import')) | ||
1551 | { | ||
1552 | $PAGE = new pageBuilder; | ||
1553 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1554 | $PAGE->assign('token',getToken()); | ||
1555 | $PAGE->assign('maxfilesize',getMaxFileSize()); | ||
1556 | $PAGE->renderPage('import'); | ||
1557 | exit; | ||
1558 | } | ||
1559 | |||
1560 | // -------- Otherwise, simply display search form and links: | ||
1561 | $PAGE = new pageBuilder; | ||
1562 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1563 | buildLinkList($PAGE,$LINKSDB); // Compute list of links to display | ||
1564 | $PAGE->renderPage('linklist'); | ||
1565 | exit; | ||
1566 | } | ||
1567 | |||
1568 | // ----------------------------------------------------------------------------------------------- | ||
1569 | // Process the import file form. | ||
1570 | function importFile() | ||
1571 | { | ||
1572 | if (!(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI'])) { die('Not allowed.'); } | ||
1573 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
1574 | $filename=$_FILES['filetoupload']['name']; | ||
1575 | $filesize=$_FILES['filetoupload']['size']; | ||
1576 | $data=file_get_contents($_FILES['filetoupload']['tmp_name']); | ||
1577 | $private = (empty($_POST['private']) ? 0 : 1); // Should the links be imported as private ? | ||
1578 | $overwrite = !empty($_POST['overwrite']) ; // Should the imported links overwrite existing ones ? | ||
1579 | $import_count=0; | ||
1580 | |||
1581 | // Sniff file type: | ||
1582 | $type='unknown'; | ||
1583 | if (startsWith($data,'<!DOCTYPE NETSCAPE-Bookmark-file-1>')) $type='netscape'; // Netscape bookmark file (aka Firefox). | ||
1584 | |||
1585 | // Then import the bookmarks. | ||
1586 | if ($type=='netscape') | ||
1587 | { | ||
1588 | // This is a standard Netscape-style bookmark file. | ||
1589 | // This format is supported by all browsers (except IE, of course), also delicious, diigo and others. | ||
1590 | foreach(explode('<DT>',$data) as $html) // explode is very fast | ||
1591 | { | ||
1592 | $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); | ||
1593 | $d = explode('<DD>',$html); | ||
1594 | if (startswith($d[0],'<A ')) | ||
1595 | { | ||
1596 | $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional) | ||
1597 | preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title | ||
1598 | $link['title'] = html_entity_decode($link['title'],ENT_QUOTES,'UTF-8'); | ||
1599 | preg_match_all('! ([A-Z_]+)=\"(.*?)"!i',$html,$matches,PREG_SET_ORDER); // Get all other attributes | ||
1600 | $raw_add_date=0; | ||
1601 | foreach($matches as $m) | ||
1602 | { | ||
1603 | $attr=$m[1]; $value=$m[2]; | ||
1604 | if ($attr=='HREF') $link['url']=html_entity_decode($value,ENT_QUOTES,'UTF-8'); | ||
1605 | elseif ($attr=='ADD_DATE') $raw_add_date=intval($value); | ||
1606 | elseif ($attr=='PRIVATE') $link['private']=($value=='0'?0:1); | ||
1607 | elseif ($attr=='TAGS') $link['tags']=html_entity_decode(str_replace(',',' ',$value),ENT_QUOTES,'UTF-8'); | ||
1608 | } | ||
1609 | if ($link['url']!='') | ||
1610 | { | ||
1611 | if ($private==1) $link['private']=1; | ||
1612 | $dblink = $LINKSDB->getLinkFromUrl($link['url']); // See if the link is already in database. | ||
1613 | if ($dblink==false) | ||
1614 | { // Link not in database, let's import it... | ||
1615 | if (empty($raw_add_date)) $raw_add_date=time(); // In case of shitty bookmark file with no ADD_DATE | ||
1616 | |||
1617 | // Make sure date/time is not already used by another link. | ||
1618 | // (Some bookmark files have several different links with the same ADD_DATE) | ||
1619 | // We increment date by 1 second until we find a date which is not used in db. | ||
1620 | // (so that links that have the same date/time are more or less kept grouped by date, but do not conflict.) | ||
1621 | while (!empty($LINKSDB[date('Ymd_His',$raw_add_date)])) { $raw_add_date++; }// Yes, I know it's ugly. | ||
1622 | $link['linkdate']=date('Ymd_His',$raw_add_date); | ||
1623 | $LINKSDB[$link['linkdate']] = $link; | ||
1624 | $import_count++; | ||
1625 | } | ||
1626 | else // link already present in database. | ||
1627 | { | ||
1628 | if ($overwrite) | ||
1629 | { // If overwrite is required, we import link data, except date/time. | ||
1630 | $link['linkdate']=$dblink['linkdate']; | ||
1631 | $LINKSDB[$link['linkdate']] = $link; | ||
1632 | $import_count++; | ||
1633 | } | ||
1634 | } | ||
1635 | |||
1636 | } | ||
1637 | } | ||
1638 | } | ||
1639 | $LINKSDB->savedb(); | ||
1640 | |||
1641 | echo '<script language="JavaScript">alert("File '.$filename.' ('.$filesize.' bytes) was successfully processed: '.$import_count.' links imported.");document.location=\'?\';</script>'; | ||
1642 | } | ||
1643 | else | ||
1644 | { | ||
1645 | echo '<script language="JavaScript">alert("File '.$filename.' ('.$filesize.' bytes) has an unknown file format. Nothing was imported.");document.location=\'?\';</script>'; | ||
1646 | } | ||
1647 | } | ||
1648 | |||
1649 | // ----------------------------------------------------------------------------------------------- | ||
1650 | // Template for the list of links (<div id="linklist">) | ||
1651 | // This function fills all the necessary fields in the $PAGE for the template 'linklist.html' | ||
1652 | function buildLinkList($PAGE,$LINKSDB) | ||
1653 | { | ||
1654 | // ---- Filter link database according to parameters | ||
1655 | $linksToDisplay=array(); | ||
1656 | $search_type=''; | ||
1657 | $search_crits=''; | ||
1658 | if (isset($_GET['searchterm'])) // Fulltext search | ||
1659 | { | ||
1660 | $linksToDisplay = $LINKSDB->filterFulltext(trim($_GET['searchterm'])); | ||
1661 | $search_crits=htmlspecialchars(trim($_GET['searchterm'])); | ||
1662 | $search_type='fulltext'; | ||
1663 | } | ||
1664 | elseif (isset($_GET['searchtags'])) // Search by tag | ||
1665 | { | ||
1666 | $linksToDisplay = $LINKSDB->filterTags(trim($_GET['searchtags'])); | ||
1667 | $search_crits=explode(' ',trim($_GET['searchtags'])); | ||
1668 | $search_type='tags'; | ||
1669 | } | ||
1670 | elseif (isset($_SERVER['QUERY_STRING']) && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/',$_SERVER['QUERY_STRING'])) // Detect smallHashes in URL | ||
1671 | { | ||
1672 | $linksToDisplay = $LINKSDB->filterSmallHash(substr(trim($_SERVER["QUERY_STRING"], '/'),0,6)); | ||
1673 | if (count($linksToDisplay)==0) | ||
1674 | { | ||
1675 | header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); | ||
1676 | echo '<h1>404 Not found.</h1>Oh crap. The link you are trying to reach does not exist or has been deleted.'; | ||
1677 | echo '<br>You would mind <a href="?">clicking here</a> ?'; | ||
1678 | exit; | ||
1679 | } | ||
1680 | $search_type='permalink'; | ||
1681 | } | ||
1682 | else | ||
1683 | $linksToDisplay = $LINKSDB; // otherwise, display without filtering. | ||
1684 | |||
1685 | // Option: Show only private links | ||
1686 | if (!empty($_SESSION['privateonly'])) | ||
1687 | { | ||
1688 | $tmp = array(); | ||
1689 | foreach($linksToDisplay as $linkdate=>$link) | ||
1690 | { | ||
1691 | if ($link['private']!=0) $tmp[$linkdate]=$link; | ||
1692 | } | ||
1693 | $linksToDisplay=$tmp; | ||
1694 | } | ||
1695 | |||
1696 | // ---- Handle paging. | ||
1697 | /* Can someone explain to me why you get the following error when using array_keys() on an object which implements the interface ArrayAccess ??? | ||
1698 | "Warning: array_keys() expects parameter 1 to be array, object given in ... " | ||
1699 | If my class implements ArrayAccess, why won't array_keys() accept it ? ( $keys=array_keys($linksToDisplay); ) | ||
1700 | */ | ||
1701 | $keys=array(); foreach($linksToDisplay as $key=>$value) { $keys[]=$key; } // Stupid and ugly. Thanks php. | ||
1702 | |||
1703 | // If there is only a single link, we change on-the-fly the title of the page. | ||
1704 | if (count($linksToDisplay)==1) $GLOBALS['pagetitle'] = $linksToDisplay[$keys[0]]['title'].' - '.$GLOBALS['title']; | ||
1705 | |||
1706 | // Select articles according to paging. | ||
1707 | $pagecount = ceil(count($keys)/$_SESSION['LINKS_PER_PAGE']); | ||
1708 | $pagecount = ($pagecount==0 ? 1 : $pagecount); | ||
1709 | $page=( empty($_GET['page']) ? 1 : intval($_GET['page'])); | ||
1710 | $page = ( $page<1 ? 1 : $page ); | ||
1711 | $page = ( $page>$pagecount ? $pagecount : $page ); | ||
1712 | $i = ($page-1)*$_SESSION['LINKS_PER_PAGE']; // Start index. | ||
1713 | $end = $i+$_SESSION['LINKS_PER_PAGE']; | ||
1714 | $linkDisp=array(); // Links to display | ||
1715 | while ($i<$end && $i<count($keys)) | ||
1716 | { | ||
1717 | $link = $linksToDisplay[$keys[$i]]; | ||
1718 | $link['description']=nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))); | ||
1719 | $title=$link['title']; | ||
1720 | $classLi = $i%2!=0 ? '' : 'publicLinkHightLight'; | ||
1721 | $link['class'] = ($link['private']==0 ? $classLi : 'private'); | ||
1722 | $link['localdate']=linkdate2locale($link['linkdate']); | ||
1723 | $link['taglist']=explode(' ',$link['tags']); | ||
1724 | $linkDisp[$keys[$i]] = $link; | ||
1725 | $i++; | ||
1726 | } | ||
1727 | |||
1728 | // Compute paging navigation | ||
1729 | $searchterm= ( empty($_GET['searchterm']) ? '' : '&searchterm='.$_GET['searchterm'] ); | ||
1730 | $searchtags= ( empty($_GET['searchtags']) ? '' : '&searchtags='.$_GET['searchtags'] ); | ||
1731 | $paging=''; | ||
1732 | $previous_page_url=''; if ($i!=count($keys)) $previous_page_url='?page='.($page+1).$searchterm.$searchtags; | ||
1733 | $next_page_url='';if ($page>1) $next_page_url='?page='.($page-1).$searchterm.$searchtags; | ||
1734 | |||
1735 | $token = ''; if (isLoggedIn()) $token=getToken(); | ||
1736 | |||
1737 | // Fill all template fields. | ||
1738 | $PAGE->assign('linkcount',count($LINKSDB)); | ||
1739 | $PAGE->assign('previous_page_url',$previous_page_url); | ||
1740 | $PAGE->assign('next_page_url',$next_page_url); | ||
1741 | $PAGE->assign('page_current',$page); | ||
1742 | $PAGE->assign('page_max',$pagecount); | ||
1743 | $PAGE->assign('result_count',count($linksToDisplay)); | ||
1744 | $PAGE->assign('search_type',$search_type); | ||
1745 | $PAGE->assign('search_crits',$search_crits); | ||
1746 | $PAGE->assign('redirector',empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); // optional redirector URL | ||
1747 | $PAGE->assign('token',$token); | ||
1748 | $PAGE->assign('links',$linkDisp); | ||
1749 | return; | ||
1750 | } | ||
1751 | |||
1752 | // Compute the thumbnail for a link. | ||
1753 | // | ||
1754 | // with a link to the original URL. | ||
1755 | // Understands various services (youtube.com...) | ||
1756 | // Input: $url = url for which the thumbnail must be found. | ||
1757 | // $href = if provided, this URL will be followed instead of $url | ||
1758 | // Returns an associative array with thumbnail attributes (src,href,width,height,style,alt) | ||
1759 | // Some of them may be missing. | ||
1760 | // Return an empty array if no thumbnail available. | ||
1761 | function computeThumbnail($url,$href=false) | ||
1762 | { | ||
1763 | if (!$GLOBALS['config']['ENABLE_THUMBNAILS']) return array(); | ||
1764 | if ($href==false) $href=$url; | ||
1765 | |||
1766 | // For most hosts, the URL of the thumbnail can be easily deduced from the URL of the link. | ||
1767 | // (eg. http://www.youtube.com/watch?v=spVypYk4kto ---> http://img.youtube.com/vi/spVypYk4kto/default.jpg ) | ||
1768 | // ^^^^^^^^^^^ ^^^^^^^^^^^ | ||
1769 | $domain = parse_url($url,PHP_URL_HOST); | ||
1770 | if ($domain=='youtube.com' || $domain=='www.youtube.com') | ||
1771 | { | ||
1772 | parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract video ID and get thumbnail | ||
1773 | if (!empty($params['v'])) return array('src'=>'http://img.youtube.com/vi/'.$params['v'].'/default.jpg', | ||
1774 | 'href'=>$href,'width'=>'120','height'=>'90','alt'=>'YouTube thumbnail'); | ||
1775 | } | ||
1776 | if ($domain=='youtu.be') // Youtube short links | ||
1777 | { | ||
1778 | $path = parse_url($url,PHP_URL_PATH); | ||
1779 | return array('src'=>'http://img.youtube.com/vi'.$path.'/default.jpg', | ||
1780 | 'href'=>$href,'width'=>'120','height'=>'90','alt'=>'YouTube thumbnail'); | ||
1781 | } | ||
1782 | if ($domain=='pix.toile-libre.org') // pix.toile-libre.org image hosting | ||
1783 | { | ||
1784 | parse_str(parse_url($url,PHP_URL_QUERY), $params); // Extract image filename. | ||
1785 | if (!empty($params) && !empty($params['img'])) return array('src'=>'http://pix.toile-libre.org/upload/thumb/'.urlencode($params['img']), | ||
1786 | 'href'=>$href,'style'=>'max-width:120px; max-height:150px','alt'=>'pix.toile-libre.org thumbnail'); | ||
1787 | } | ||
1788 | |||
1789 | if ($domain=='imgur.com') | ||
1790 | { | ||
1791 | $path = parse_url($url,PHP_URL_PATH); | ||
1792 | if (startsWith($path,'/a/')) return array(); // Thumbnails for albums are not available. | ||
1793 | if (startsWith($path,'/r/')) return array('src'=>'http://i.imgur.com/'.basename($path).'s.jpg', | ||
1794 | 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); | ||
1795 | if (startsWith($path,'/gallery/')) return array('src'=>'http://i.imgur.com'.substr($path,8).'s.jpg', | ||
1796 | 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); | ||
1797 | |||
1798 | if (substr_count($path,'/')==1) return array('src'=>'http://i.imgur.com/'.substr($path,1).'s.jpg', | ||
1799 | 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); | ||
1800 | } | ||
1801 | if ($domain=='i.imgur.com') | ||
1802 | { | ||
1803 | $pi = pathinfo(parse_url($url,PHP_URL_PATH)); | ||
1804 | if (!empty($pi['filename'])) return array('src'=>'http://i.imgur.com/'.$pi['filename'].'s.jpg', | ||
1805 | 'href'=>$href,'width'=>'90','height'=>'90','alt'=>'imgur.com thumbnail'); | ||
1806 | } | ||
1807 | if ($domain=='dailymotion.com' || $domain=='www.dailymotion.com') | ||
1808 | { | ||
1809 | if (strpos($url,'dailymotion.com/video/')!==false) | ||
1810 | { | ||
1811 | $thumburl=str_replace('dailymotion.com/video/','dailymotion.com/thumbnail/video/',$url); | ||
1812 | return array('src'=>$thumburl, | ||
1813 | 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'DailyMotion thumbnail'); | ||
1814 | } | ||
1815 | } | ||
1816 | if (endsWith($domain,'.imageshack.us')) | ||
1817 | { | ||
1818 | $ext=strtolower(pathinfo($url,PATHINFO_EXTENSION)); | ||
1819 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') | ||
1820 | { | ||
1821 | $thumburl = substr($url,0,strlen($url)-strlen($ext)).'th.'.$ext; | ||
1822 | return array('src'=>$thumburl, | ||
1823 | 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'imageshack.us thumbnail'); | ||
1824 | } | ||
1825 | } | ||
1826 | |||
1827 | // Some other hosts are SLOW AS HELL and usually require an extra HTTP request to get the thumbnail URL. | ||
1828 | // So we deport the thumbnail generation in order not to slow down page generation | ||
1829 | // (and we also cache the thumbnail) | ||
1830 | |||
1831 | if (!$GLOBALS['config']['ENABLE_LOCALCACHE']) return array(); // If local cache is disabled, no thumbnails for services which require the use a local cache. | ||
1832 | |||
1833 | if ($domain=='flickr.com' || endsWith($domain,'.flickr.com') | ||
1834 | || $domain=='vimeo.com' | ||
1835 | || $domain=='ted.com' || endsWith($domain,'.ted.com') | ||
1836 | || $domain=='xkcd.com' || endsWith($domain,'.xkcd.com') | ||
1837 | ) | ||
1838 | { | ||
1839 | if ($domain=='vimeo.com') | ||
1840 | { // Make sure this vimeo url points to a video (/xxx... where xxx is numeric) | ||
1841 | $path = parse_url($url,PHP_URL_PATH); | ||
1842 | if (!preg_match('!/\d+.+?!',$path)) return array(); // This is not a single video URL. | ||
1843 | } | ||
1844 | if ($domain=='xkcd.com' || endsWith($domain,'.xkcd.com')) | ||
1845 | { // Make sure this url points to a single comic (/xxx... where xxx is numeric) | ||
1846 | $path = parse_url($url,PHP_URL_PATH); | ||
1847 | if (!preg_match('!/\d+.+?!',$path)) return array(); | ||
1848 | } | ||
1849 | if ($domain=='ted.com' || endsWith($domain,'.ted.com')) | ||
1850 | { // Make sure this TED url points to a video (/talks/...) | ||
1851 | $path = parse_url($url,PHP_URL_PATH); | ||
1852 | if ("/talks/" !== substr($path,0,7)) return array(); // This is not a single video URL. | ||
1853 | } | ||
1854 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) | ||
1855 | return array('src'=>indexUrl().'?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url), | ||
1856 | 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); | ||
1857 | } | ||
1858 | |||
1859 | // For all other, we try to make a thumbnail of links ending with .jpg/jpeg/png/gif | ||
1860 | // Technically speaking, we should download ALL links and check their Content-Type to see if they are images. | ||
1861 | // But using the extension will do. | ||
1862 | $ext=strtolower(pathinfo($url,PATHINFO_EXTENSION)); | ||
1863 | if ($ext=='jpg' || $ext=='jpeg' || $ext=='png' || $ext=='gif') | ||
1864 | { | ||
1865 | $sign = hash_hmac('sha256', $url, $GLOBALS['salt']); // We use the salt to sign data (it's random, secret, and specific to each installation) | ||
1866 | return array('src'=>indexUrl().'?do=genthumbnail&hmac='.htmlspecialchars($sign).'&url='.urlencode($url), | ||
1867 | 'href'=>$href,'width'=>'120','style'=>'height:auto;','alt'=>'thumbnail'); | ||
1868 | } | ||
1869 | return array(); // No thumbnail. | ||
1870 | |||
1871 | } | ||
1872 | |||
1873 | |||
1874 | // Returns the HTML code to display a thumbnail for a link | ||
1875 | // with a link to the original URL. | ||
1876 | // Understands various services (youtube.com...) | ||
1877 | // Input: $url = url for which the thumbnail must be found. | ||
1878 | // $href = if provided, this URL will be followed instead of $url | ||
1879 | // Returns '' if no thumbnail available. | ||
1880 | function thumbnail($url,$href=false) | ||
1881 | { | ||
1882 | $t = computeThumbnail($url,$href); | ||
1883 | if (count($t)==0) return ''; // Empty array = no thumbnail for this URL. | ||
1884 | |||
1885 | $html='<a href="'.htmlspecialchars($t['href']).'"><img src="'.htmlspecialchars($t['src']).'"'; | ||
1886 | if (!empty($t['width'])) $html.=' width="'.htmlspecialchars($t['width']).'"'; | ||
1887 | if (!empty($t['height'])) $html.=' height="'.htmlspecialchars($t['height']).'"'; | ||
1888 | if (!empty($t['style'])) $html.=' style="'.htmlspecialchars($t['style']).'"'; | ||
1889 | if (!empty($t['alt'])) $html.=' alt="'.htmlspecialchars($t['alt']).'"'; | ||
1890 | $html.='></a>'; | ||
1891 | return $html; | ||
1892 | } | ||
1893 | |||
1894 | |||
1895 | // Returns the HTML code to display a thumbnail for a link | ||
1896 | // for the picture wall (using lazy image loading) | ||
1897 | // Understands various services (youtube.com...) | ||
1898 | // Input: $url = url for which the thumbnail must be found. | ||
1899 | // $href = if provided, this URL will be followed instead of $url | ||
1900 | // Returns '' if no thumbnail available. | ||
1901 | function lazyThumbnail($url,$href=false) | ||
1902 | { | ||
1903 | $t = computeThumbnail($url,$href); | ||
1904 | if (count($t)==0) return ''; // Empty array = no thumbnail for this URL. | ||
1905 | |||
1906 | $html='<a href="'.htmlspecialchars($t['href']).'">'; | ||
1907 | |||
1908 | // Lazy image (only loaded by javascript when in the viewport). | ||
1909 | $html.='<img class="lazyimage" src="#" data-original="'.htmlspecialchars($t['src']).'"'; | ||
1910 | if (!empty($t['width'])) $html.=' width="'.htmlspecialchars($t['width']).'"'; | ||
1911 | if (!empty($t['height'])) $html.=' height="'.htmlspecialchars($t['height']).'"'; | ||
1912 | if (!empty($t['style'])) $html.=' style="'.htmlspecialchars($t['style']).'"'; | ||
1913 | if (!empty($t['alt'])) $html.=' alt="'.htmlspecialchars($t['alt']).'"'; | ||
1914 | $html.='>'; | ||
1915 | |||
1916 | // No-javascript fallback: | ||
1917 | $html.='<noscript><img src="'.htmlspecialchars($t['src']).'"'; | ||
1918 | if (!empty($t['width'])) $html.=' width="'.htmlspecialchars($t['width']).'"'; | ||
1919 | if (!empty($t['height'])) $html.=' height="'.htmlspecialchars($t['height']).'"'; | ||
1920 | if (!empty($t['style'])) $html.=' style="'.htmlspecialchars($t['style']).'"'; | ||
1921 | if (!empty($t['alt'])) $html.=' alt="'.htmlspecialchars($t['alt']).'"'; | ||
1922 | $html.='></noscript></a>'; | ||
1923 | |||
1924 | return $html; | ||
1925 | } | ||
1926 | |||
1927 | |||
1928 | // ----------------------------------------------------------------------------------------------- | ||
1929 | // Installation | ||
1930 | // This function should NEVER be called if the file data/config.php exists. | ||
1931 | function install() | ||
1932 | { | ||
1933 | // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. | ||
1934 | if (endsWith($_SERVER['SERVER_NAME'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); | ||
1935 | |||
1936 | if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) | ||
1937 | { | ||
1938 | $tz = 'UTC'; | ||
1939 | if (!empty($_POST['continent']) && !empty($_POST['city'])) | ||
1940 | if (isTZvalid($_POST['continent'],$_POST['city'])) | ||
1941 | $tz = $_POST['continent'].'/'.$_POST['city']; | ||
1942 | $GLOBALS['timezone'] = $tz; | ||
1943 | // Everything is ok, let's create config file. | ||
1944 | $GLOBALS['login'] = $_POST['setlogin']; | ||
1945 | $GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. | ||
1946 | $GLOBALS['hash'] = sha1($_POST['setpassword'].$GLOBALS['login'].$GLOBALS['salt']); | ||
1947 | $GLOBALS['title'] = (empty($_POST['title']) ? 'Shared links on '.htmlspecialchars(indexUrl()) : $_POST['title'] ); | ||
1948 | writeConfig(); | ||
1949 | echo '<script language="JavaScript">alert("Shaarli is now configured. Please enter your login/password and start shaaring your links !");document.location=\'?do=login\';</script>'; | ||
1950 | exit; | ||
1951 | } | ||
1952 | |||
1953 | // Display config form: | ||
1954 | list($timezone_form,$timezone_js) = templateTZform(); | ||
1955 | $timezone_html=''; if ($timezone_form!='') $timezone_html='<tr><td valign="top"><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>'; | ||
1956 | |||
1957 | $PAGE = new pageBuilder; | ||
1958 | $PAGE->assign('timezone_html',$timezone_html); | ||
1959 | $PAGE->assign('timezone_js',$timezone_js); | ||
1960 | $PAGE->renderPage('install'); | ||
1961 | exit; | ||
1962 | } | ||
1963 | |||
1964 | // Generates the timezone selection form and javascript. | ||
1965 | // Input: (optional) current timezone (can be 'UTC/UTC'). It will be pre-selected. | ||
1966 | // Output: array(html,js) | ||
1967 | // Example: list($htmlform,$js) = templateTZform('Europe/Paris'); // Europe/Paris pre-selected. | ||
1968 | // Returns array('','') if server does not support timezones list. (eg. php 5.1 on free.fr) | ||
1969 | function templateTZform($ptz=false) | ||
1970 | { | ||
1971 | if (function_exists('timezone_identifiers_list')) // because of old php version (5.1) which can be found on free.fr | ||
1972 | { | ||
1973 | // Try to split the provided timezone. | ||
1974 | if ($ptz==false) { $l=timezone_identifiers_list(); $ptz=$l[0]; } | ||
1975 | $spos=strpos($ptz,'/'); $pcontinent=substr($ptz,0,$spos); $pcity=substr($ptz,$spos+1); | ||
1976 | |||
1977 | // Display config form: | ||
1978 | $timezone_form = ''; | ||
1979 | $timezone_js = ''; | ||
1980 | // The list is in the forme "Europe/Paris", "America/Argentina/Buenos_Aires"... | ||
1981 | // We split the list in continents/cities. | ||
1982 | $continents = array(); | ||
1983 | $cities = array(); | ||
1984 | foreach(timezone_identifiers_list() as $tz) | ||
1985 | { | ||
1986 | if ($tz=='UTC') $tz='UTC/UTC'; | ||
1987 | $spos = strpos($tz,'/'); | ||
1988 | if ($spos!==false) | ||
1989 | { | ||
1990 | $continent=substr($tz,0,$spos); $city=substr($tz,$spos+1); | ||
1991 | $continents[$continent]=1; | ||
1992 | if (!isset($cities[$continent])) $cities[$continent]=''; | ||
1993 | $cities[$continent].='<option value="'.$city.'"'.($pcity==$city?'selected':'').'>'.$city.'</option>'; | ||
1994 | } | ||
1995 | } | ||
1996 | $continents_html = ''; | ||
1997 | $continents = array_keys($continents); | ||
1998 | foreach($continents as $continent) | ||
1999 | $continents_html.='<option value="'.$continent.'"'.($pcontinent==$continent?'selected':'').'>'.$continent.'</option>'; | ||
2000 | $cities_html = $cities[$pcontinent]; | ||
2001 | $timezone_form = "Continent: <select name=\"continent\" id=\"continent\" onChange=\"onChangecontinent();\">${continents_html}</select><br /><br />"; | ||
2002 | $timezone_form .= "City: <select name=\"city\" id=\"city\">${cities[$pcontinent]}</select><br /><br />"; | ||
2003 | $timezone_js = "<script language=\"JavaScript\">"; | ||
2004 | $timezone_js .= "function onChangecontinent(){document.getElementById(\"city\").innerHTML = citiescontinent[document.getElementById(\"continent\").value];}"; | ||
2005 | $timezone_js .= "var citiescontinent = ".json_encode($cities).";" ; | ||
2006 | $timezone_js .= "</script>" ; | ||
2007 | return array($timezone_form,$timezone_js); | ||
2008 | } | ||
2009 | return array('',''); | ||
2010 | } | ||
2011 | |||
2012 | // Tells if a timezone is valid or not. | ||
2013 | // If not valid, returns false. | ||
2014 | // If system does not support timezone list, returns false. | ||
2015 | function isTZvalid($continent,$city) | ||
2016 | { | ||
2017 | $tz = $continent.'/'.$city; | ||
2018 | if (function_exists('timezone_identifiers_list')) // because of old php version (5.1) which can be found on free.fr | ||
2019 | { | ||
2020 | if (in_array($tz, timezone_identifiers_list())) // it's a valid timezone ? | ||
2021 | return true; | ||
2022 | } | ||
2023 | return false; | ||
2024 | } | ||
2025 | |||
2026 | |||
2027 | // Webservices (for use with jQuery/jQueryUI) | ||
2028 | // eg. index.php?ws=tags&term=minecr | ||
2029 | function processWS() | ||
2030 | { | ||
2031 | if (empty($_GET['ws']) || empty($_GET['term'])) return; | ||
2032 | $term = $_GET['term']; | ||
2033 | $LINKSDB=new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). | ||
2034 | header('Content-Type: application/json; charset=utf-8'); | ||
2035 | |||
2036 | // Search in tags (case insentitive, cumulative search) | ||
2037 | if ($_GET['ws']=='tags') | ||
2038 | { | ||
2039 | $tags=explode(' ',str_replace(',',' ',$term)); $last = array_pop($tags); // Get the last term ("a b c d" ==> "a b c", "d") | ||
2040 | $addtags=''; if ($tags) $addtags=implode(' ',$tags).' '; // We will pre-pend previous tags | ||
2041 | $suggested=array(); | ||
2042 | /* To speed up things, we store list of tags in session */ | ||
2043 | if (empty($_SESSION['tags'])) $_SESSION['tags'] = $LINKSDB->allTags(); | ||
2044 | foreach($_SESSION['tags'] as $key=>$value) | ||
2045 | { | ||
2046 | if (startsWith($key,$last,$case=false) && !in_array($key,$tags)) $suggested[$addtags.$key.' ']=0; | ||
2047 | } | ||
2048 | echo json_encode(array_keys($suggested)); | ||
2049 | exit; | ||
2050 | } | ||
2051 | |||
2052 | // Search a single tag (case sentitive, single tag search) | ||
2053 | if ($_GET['ws']=='singletag') | ||
2054 | { | ||
2055 | /* To speed up things, we store list of tags in session */ | ||
2056 | if (empty($_SESSION['tags'])) $_SESSION['tags'] = $LINKSDB->allTags(); | ||
2057 | foreach($_SESSION['tags'] as $key=>$value) | ||
2058 | { | ||
2059 | if (startsWith($key,$term,$case=true)) $suggested[$key]=0; | ||
2060 | } | ||
2061 | echo json_encode(array_keys($suggested)); | ||
2062 | exit; | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | // Re-write configuration file according to globals. | ||
2067 | // Requires some $GLOBALS to be set (login,hash,salt,title). | ||
2068 | // If the config file cannot be saved, an error message is dislayed and the user is redirected to "Tools" menu. | ||
2069 | // (otherwise, the function simply returns.) | ||
2070 | function writeConfig() | ||
2071 | { | ||
2072 | if (is_file($GLOBALS['config']['CONFIG_FILE']) && !isLoggedIn()) die('You are not authorized to alter config.'); // Only logged in user can alter config. | ||
2073 | if (empty($GLOBALS['redirector'])) $GLOBALS['redirector']=''; | ||
2074 | if (empty($GLOBALS['disablesessionprotection'])) $GLOBALS['disablesessionprotection']=false; | ||
2075 | $config='<?php $GLOBALS[\'login\']='.var_export($GLOBALS['login'],true).'; $GLOBALS[\'hash\']='.var_export($GLOBALS['hash'],true).'; $GLOBALS[\'salt\']='.var_export($GLOBALS['salt'],true).'; '; | ||
2076 | $config .='$GLOBALS[\'timezone\']='.var_export($GLOBALS['timezone'],true).'; date_default_timezone_set('.var_export($GLOBALS['timezone'],true).'); $GLOBALS[\'title\']='.var_export($GLOBALS['title'],true).';'; | ||
2077 | $config .= '$GLOBALS[\'redirector\']='.var_export($GLOBALS['redirector'],true).'; '; | ||
2078 | $config .= '$GLOBALS[\'disablesessionprotection\']='.var_export($GLOBALS['disablesessionprotection'],true).'; '; | ||
2079 | $config .= ' ?>'; | ||
2080 | if (!file_put_contents($GLOBALS['config']['CONFIG_FILE'],$config) || strcmp(file_get_contents($GLOBALS['config']['CONFIG_FILE']),$config)!=0) | ||
2081 | { | ||
2082 | echo '<script language="JavaScript">alert("Shaarli could not create the config file. Please make sure Shaarli has the right to write in the folder is it installed in.");document.location=\'?\';</script>'; | ||
2083 | exit; | ||
2084 | } | ||
2085 | } | ||
2086 | |||
2087 | /* Because some f*cking services like Flickr require an extra HTTP request to get the thumbnail URL, | ||
2088 | I have deported the thumbnail URL code generation here, otherwise this would slow down page generation. | ||
2089 | The following function takes the URL a link (eg. a flickr page) and return the proper thumbnail. | ||
2090 | This function is called by passing the url: | ||
2091 | http://mywebsite.com/shaarli/?do=genthumbnail&hmac=[HMAC]&url=[URL] | ||
2092 | [URL] is the URL of the link (eg. a flickr page) | ||
2093 | [HMAC] is the signature for the [URL] (so that these URL cannot be forged). | ||
2094 | The function below will fetch the image from the webservice and store it in the cache. | ||
2095 | */ | ||
2096 | function genThumbnail() | ||
2097 | { | ||
2098 | // Make sure the parameters in the URL were generated by us. | ||
2099 | $sign = hash_hmac('sha256', $_GET['url'], $GLOBALS['salt']); | ||
2100 | if ($sign!=$_GET['hmac']) die('Naughty boy !'); | ||
2101 | |||
2102 | // Let's see if we don't already have the image for this URL in the cache. | ||
2103 | $thumbname=hash('sha1',$_GET['url']).'.jpg'; | ||
2104 | if (is_file($GLOBALS['config']['CACHEDIR'].'/'.$thumbname)) | ||
2105 | { // We have the thumbnail, just serve it: | ||
2106 | header('Content-Type: image/jpeg'); | ||
2107 | echo file_get_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname); | ||
2108 | return; | ||
2109 | } | ||
2110 | // We may also serve a blank image (if service did not respond) | ||
2111 | $blankname=hash('sha1',$_GET['url']).'.gif'; | ||
2112 | if (is_file($GLOBALS['config']['CACHEDIR'].'/'.$blankname)) | ||
2113 | { | ||
2114 | header('Content-Type: image/gif'); | ||
2115 | echo file_get_contents($GLOBALS['config']['CACHEDIR'].'/'.$blankname); | ||
2116 | return; | ||
2117 | } | ||
2118 | |||
2119 | // Otherwise, generate the thumbnail. | ||
2120 | $url = $_GET['url']; | ||
2121 | $domain = parse_url($url,PHP_URL_HOST); | ||
2122 | |||
2123 | if ($domain=='flickr.com' || endsWith($domain,'.flickr.com')) | ||
2124 | { | ||
2125 | // Crude replacement to handle new Flickr domain policy (They prefer www. now) | ||
2126 | $url = str_replace('http://flickr.com/','http://www.flickr.com/',$url); | ||
2127 | |||
2128 | // Is this a link to an image, or to a flickr page ? | ||
2129 | $imageurl=''; | ||
2130 | if (endswith(parse_url($url,PHP_URL_PATH),'.jpg')) | ||
2131 | { // This is a direct link to an image. eg. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg | ||
2132 | preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches); | ||
2133 | if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; | ||
2134 | } | ||
2135 | else // this is a flickr page (html) | ||
2136 | { | ||
2137 | list($httpstatus,$headers,$data) = getHTTP($url,20); // Get the flickr html page. | ||
2138 | if (strpos($httpstatus,'200 OK')!==false) | ||
2139 | { | ||
2140 | // Flickr now nicely provides the URL of the thumbnail in each flickr page. | ||
2141 | preg_match('!<link rel=\"image_src\" href=\"(.+?)\"!',$data,$matches); | ||
2142 | if (!empty($matches[1])) $imageurl=$matches[1]; | ||
2143 | |||
2144 | // In albums (and some other pages), the link rel="image_src" is not provided, | ||
2145 | // but flickr provides: | ||
2146 | // <meta property="og:image" content="http://farm4.staticflickr.com/3398/3239339068_25d13535ff_z.jpg" /> | ||
2147 | if ($imageurl=='') | ||
2148 | { | ||
2149 | preg_match('!<meta property=\"og:image\" content=\"(.+?)\"!',$data,$matches); | ||
2150 | if (!empty($matches[1])) $imageurl=$matches[1]; | ||
2151 | } | ||
2152 | } | ||
2153 | } | ||
2154 | |||
2155 | if ($imageurl!='') | ||
2156 | { // Let's download the image. | ||
2157 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); // Image is 240x120, so 10 seconds to download should be enough. | ||
2158 | if (strpos($httpstatus,'200 OK')!==false) | ||
2159 | { | ||
2160 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. | ||
2161 | header('Content-Type: image/jpeg'); | ||
2162 | echo $data; | ||
2163 | return; | ||
2164 | } | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | elseif ($domain=='vimeo.com' ) | ||
2169 | { | ||
2170 | // This is more complex: we have to perform a HTTP request, then parse the result. | ||
2171 | // Maybe we should deport this to javascript ? Example: http://stackoverflow.com/questions/1361149/get-img-thumbnails-from-vimeo/4285098#4285098 | ||
2172 | $vid = substr(parse_url($url,PHP_URL_PATH),1); | ||
2173 | list($httpstatus,$headers,$data) = getHTTP('http://vimeo.com/api/v2/video/'.htmlspecialchars($vid).'.php',5); | ||
2174 | if (strpos($httpstatus,'200 OK')!==false) | ||
2175 | { | ||
2176 | $t = unserialize($data); | ||
2177 | $imageurl = $t[0]['thumbnail_medium']; | ||
2178 | // Then we download the image and serve it to our client. | ||
2179 | list($httpstatus,$headers,$data) = getHTTP($imageurl,10); | ||
2180 | if (strpos($httpstatus,'200 OK')!==false) | ||
2181 | { | ||
2182 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$thumbname,$data); // Save image to cache. | ||
2183 | header('Content-Type: image/jpeg'); | ||
2184 | echo $data; | ||
2185 | return; | ||
2186 | } | ||
2187 | } | ||
2188 | } | ||
2189 | |||
2190 | elseif ($domain=='ted.com' || endsWith($domain,'.ted.com')) | ||
2191 | { | ||
2192 | // The thumbnail for TED talks is located in the <link rel="image_src" [...]> tag on that page | ||
2193 | // http://www.ted.com/talks/mikko_hypponen_fighting_viruses_defending_the_net.html | ||
2194 | // <link rel="image_src" href="http://images.ted.com/images/ted/28bced335898ba54d4441809c5b1112ffaf36781_389x292.jpg" /> | ||
2195 | list($httpstatus,$headers,$data) = getHTTP($url,5); | ||
2196 | if (strpos($httpstatus,'200 OK')!==false) | ||
2197 | { | ||
2198 | // Extract the link to the thumbnail | ||
2199 | preg_match('!link rel="image_src" href="(http://images.ted.com/images/ted/.+_\d+x\d+\.jpg)"!',$data,$matches); | ||
2200 | if (!empty($matches[1])) | ||
2201 | { // Let's download the image. | ||
2202 | $imageurl=$matches[1]; | ||
2203 | list($httpstatus,$headers,$data) = getHTTP($imageurl,20); // No control on image size, so wait long enough. | ||
2204 | if (strpos($httpstatus,'200 OK')!==false) | ||
2205 | { | ||
2206 | $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; | ||
2207 | file_put_contents($filepath,$data); // Save image to cache. | ||
2208 | if (resizeImage($filepath)) | ||
2209 | { | ||
2210 | header('Content-Type: image/jpeg'); | ||
2211 | echo file_get_contents($filepath); | ||
2212 | return; | ||
2213 | } | ||
2214 | } | ||
2215 | } | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2219 | elseif ($domain=='xkcd.com' || endsWith($domain,'.xkcd.com')) | ||
2220 | { | ||
2221 | // There is no thumbnail available for xkcd comics, so download the whole image and resize it. | ||
2222 | // http://xkcd.com/327/ | ||
2223 | // <img src="http://imgs.xkcd.com/comics/exploits_of_a_mom.png" title="<BLABLA>" alt="<BLABLA>" /> | ||
2224 | list($httpstatus,$headers,$data) = getHTTP($url,5); | ||
2225 | if (strpos($httpstatus,'200 OK')!==false) | ||
2226 | { | ||
2227 | // Extract the link to the thumbnail | ||
2228 | preg_match('!<img src="(http://imgs.xkcd.com/comics/.*)" title="[^s]!',$data,$matches); | ||
2229 | if (!empty($matches[1])) | ||
2230 | { // Let's download the image. | ||
2231 | $imageurl=$matches[1]; | ||
2232 | list($httpstatus,$headers,$data) = getHTTP($imageurl,20); // No control on image size, so wait long enough. | ||
2233 | if (strpos($httpstatus,'200 OK')!==false) | ||
2234 | { | ||
2235 | $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; | ||
2236 | file_put_contents($filepath,$data); // Save image to cache. | ||
2237 | if (resizeImage($filepath)) | ||
2238 | { | ||
2239 | header('Content-Type: image/jpeg'); | ||
2240 | echo file_get_contents($filepath); | ||
2241 | return; | ||
2242 | } | ||
2243 | } | ||
2244 | } | ||
2245 | } | ||
2246 | } | ||
2247 | |||
2248 | else | ||
2249 | { | ||
2250 | // For all other domains, we try to download the image and make a thumbnail. | ||
2251 | list($httpstatus,$headers,$data) = getHTTP($url,30); // We allow 30 seconds max to download (and downloads are limited to 4 Mb) | ||
2252 | if (strpos($httpstatus,'200 OK')!==false) | ||
2253 | { | ||
2254 | $filepath=$GLOBALS['config']['CACHEDIR'].'/'.$thumbname; | ||
2255 | file_put_contents($filepath,$data); // Save image to cache. | ||
2256 | if (resizeImage($filepath)) | ||
2257 | { | ||
2258 | header('Content-Type: image/jpeg'); | ||
2259 | echo file_get_contents($filepath); | ||
2260 | return; | ||
2261 | } | ||
2262 | } | ||
2263 | } | ||
2264 | |||
2265 | |||
2266 | // Otherwise, return an empty image (8x8 transparent gif) | ||
2267 | $blankgif = base64_decode('R0lGODlhCAAIAIAAAP///////yH5BAEKAAEALAAAAAAIAAgAAAIHjI+py+1dAAA7'); | ||
2268 | file_put_contents($GLOBALS['config']['CACHEDIR'].'/'.$blankname,$blankgif); // Also put something in cache so that this URL is not requested twice. | ||
2269 | header('Content-Type: image/gif'); | ||
2270 | echo $blankgif; | ||
2271 | } | ||
2272 | |||
2273 | // Make a thumbnail of the image (to width: 120 pixels) | ||
2274 | // Returns true if success, false otherwise. | ||
2275 | function resizeImage($filepath) | ||
2276 | { | ||
2277 | if (!function_exists('imagecreatefromjpeg')) return false; // GD not present: no thumbnail possible. | ||
2278 | |||
2279 | // Trick: some stupid people rename GIF as JPEG... or else. | ||
2280 | // So we really try to open each image type whatever the extension is. | ||
2281 | $header=file_get_contents($filepath,false,NULL,0,256); // Read first 256 bytes and try to sniff file type. | ||
2282 | $im=false; | ||
2283 | $i=strpos($header,'GIF8'); if (($i!==false) && ($i==0)) $im = imagecreatefromgif($filepath); // Well this is crude, but it should be enough. | ||
2284 | $i=strpos($header,'PNG'); if (($i!==false) && ($i==1)) $im = imagecreatefrompng($filepath); | ||
2285 | $i=strpos($header,'JFIF'); if ($i!==false) $im = imagecreatefromjpeg($filepath); | ||
2286 | if (!$im) return false; // Unable to open image (corrupted or not an image) | ||
2287 | $w = imagesx($im); | ||
2288 | $h = imagesy($im); | ||
2289 | $ystart = 0; $yheight=$h; | ||
2290 | if ($h>$w) { $ystart= ($h/2)-($w/2); $yheight=$w/2; } | ||
2291 | $nw = 120; // Desired width | ||
2292 | $nh = min(floor(($h*$nw)/$w),120); // Compute new width/height, but maximum 120 pixels height. | ||
2293 | // Resize image: | ||
2294 | $im2 = imagecreatetruecolor($nw,$nh); | ||
2295 | imagecopyresampled($im2, $im, 0, 0, 0, $ystart, $nw, $nh, $w, $yheight); | ||
2296 | imageinterlace($im2,true); // For progressive JPEG. | ||
2297 | $tempname=$filepath.'_TEMP.jpg'; | ||
2298 | imagejpeg($im2, $tempname, 90); | ||
2299 | imagedestroy($im); | ||
2300 | imagedestroy($im2); | ||
2301 | rename($tempname,$filepath); // Overwrite original picture with thumbnail. | ||
2302 | return true; | ||
2303 | } | ||
2304 | |||
2305 | // Invalidate caches when the database is changed or the user logs out. | ||
2306 | // (eg. tags cache). | ||
2307 | function invalidateCaches() | ||
2308 | { | ||
2309 | unset($_SESSION['tags']); // Purge cache attached to session. | ||
2310 | pageCache::purgeCache(); // Purge page cache shared by sessions. | ||
2311 | } | ||
2312 | |||
2313 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. | ||
2314 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=rss')) { showRSS(); exit; } | ||
2315 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=atom')) { showATOM(); exit; } | ||
2316 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; } | ||
2317 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=daily')) { showDaily(); exit; } | ||
2318 | if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'ws=')) { processWS(); exit; } // Webservices (for jQuery/jQueryUI) | ||
2319 | if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; | ||
2320 | renderPage(); | ||
2321 | ?> \ No newline at end of file | ||
diff --git a/tpl/addlink.html b/tpl/addlink.html new file mode 100644 index 00000000..853715dc --- /dev/null +++ b/tpl/addlink.html | |||
@@ -0,0 +1,16 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body onload="document.addform.post.focus();"> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <div id="headerform"> | ||
8 | <form method="GET" action="" name="addform" class="addform"> | ||
9 | <input type="text" name="post" style="width:50%;"> | ||
10 | <input type="submit" value="Add link" class="bigbutton"> | ||
11 | </form> | ||
12 | </div> | ||
13 | </div> | ||
14 | {include="page.footer"} | ||
15 | </body> | ||
16 | </html> \ No newline at end of file | ||
diff --git a/tpl/changepassword.html b/tpl/changepassword.html new file mode 100644 index 00000000..48cf5fa3 --- /dev/null +++ b/tpl/changepassword.html | |||
@@ -0,0 +1,15 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body onload="document.changepasswordform.oldpassword.focus();"> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <form method="POST" action="" name="changepasswordform" id="changepasswordform"> | ||
8 | Old password: <input type="password" name="oldpassword"> | ||
9 | New password: <input type="password" name="setpassword"> | ||
10 | <input type="hidden" name="token" value="{$token}"> | ||
11 | <input type="submit" name="Save" value="Save password" class="bigbutton"></form> | ||
12 | </div> | ||
13 | {include="page.footer"} | ||
14 | </body> | ||
15 | </html> \ No newline at end of file | ||
diff --git a/tpl/changetag.html b/tpl/changetag.html new file mode 100644 index 00000000..b0bd0d06 --- /dev/null +++ b/tpl/changetag.html | |||
@@ -0,0 +1,16 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body onload="document.changetag.fromtag.focus();"> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <form method="POST" action="" name="changetag" id="changetag"> | ||
8 | <input type="hidden" name="token" value="{$token}"> | ||
9 | Tag: <input type="text" name="fromtag" id="fromtag"> | ||
10 | <input type="text" name="totag" style="margin-left:40px;"><input type="submit" name="renametag" value="Rename tag" class="bigbutton"> | ||
11 | or <input type="submit" name="deletetag" value="Delete tag" class="bigbutton" onClick="return confirmDeleteTag();"><br>(Case sensitive)</form> | ||
12 | <script language="JavaScript">function confirmDeleteTag() { var agree=confirm("Are you sure you want to delete this tag from all links ?"); if (agree) return true ; else return false ; }</script> | ||
13 | </div> | ||
14 | {include="page.footer"} | ||
15 | </body> | ||
16 | </html> \ No newline at end of file | ||
diff --git a/tpl/configure.html b/tpl/configure.html new file mode 100644 index 00000000..00c41f28 --- /dev/null +++ b/tpl/configure.html | |||
@@ -0,0 +1,21 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body onload="document.configform.title.focus();"> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | {$timezone_js} | ||
8 | <form method="POST" action="" name="configform" id="configform"> | ||
9 | <input type="hidden" name="token" value="{$token}"> | ||
10 | <table border="0" cellpadding="20"> | ||
11 | <tr><td><b>Page title:</b></td><td><input type="text" name="title" id="title" size="50" value="{$title}"></td></tr> | ||
12 | <tr><td valign="top"><b>Timezone:</b></td><td>{$timezone_form}</td></tr> | ||
13 | <tr><td valign="top"><b>Redirector</b></td><td><input type="text" name="redirector" id="redirector" size="50" value="{$redirector}"><br>(e.g. <i>http://anonym.to/?</i> will mask the HTTP_REFERER)</td></tr> | ||
14 | <tr> <td valign="top">Security:</td> <td><input type="checkbox" name="disablesessionprotection" id="disablesessionprotection" {if="!empty($GLOBALS['disablesessionprotection'])"}checked{/if}><label for="disablesessionprotection"> Disable session cookie hijacking protection (Check this if you get disconnected often or if your IP address changes often.)</label></td></tr> | ||
15 | <tr><td></td><td align="right"><input type="submit" name="Save" value="Save config" class="bigbutton"></td></tr> | ||
16 | </table> | ||
17 | </form> | ||
18 | </div> | ||
19 | {include="page.footer"} | ||
20 | </body> | ||
21 | </html> \ No newline at end of file | ||
diff --git a/tpl/daily.html b/tpl/daily.html new file mode 100644 index 00000000..4bc8568b --- /dev/null +++ b/tpl/daily.html | |||
@@ -0,0 +1,63 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader">{include="page.header"}</div> | ||
6 | <div class="daily"> | ||
7 | <div class="dailyAbout"> | ||
8 | All links of one day<br>in a single page.<br> | ||
9 | {if="$previousday"} <a href="?do=daily&day={$previousday}"><b><</b>Previous day</a>{else}<b><</b>Previous day{/if} | ||
10 | - | ||
11 | {if="$nextday"}<a href="?do=daily&day={$nextday}">Next day<b>></b></a>{else}Next day<b>></b>{/if} | ||
12 | <br><br> | ||
13 | <a href="?do=dailyrss" title="1 RSS entry per day"><img src="images/feed-icon-14x14.png#" width="14" height="14" style="position:relative;top:3px; margin-right:4px;">Daily RSS Feed</a> | ||
14 | </div> | ||
15 | <div class="dailyTitle"><img src="../images/floral_left.png" width="51" height="50" class="nomobile"> The Daily Shaarli <img src="../images/floral_right.png" width="51" height="50" class="nomobile"></div> | ||
16 | <div class="dailyDate"><span class="nomobile">———————————</span> {$day} <span class="nomobile">———————————</span></div> | ||
17 | <div style="clear:both;"></div> | ||
18 | |||
19 | {if="$linksToDisplay"} | ||
20 | <div id="daily_col1"> | ||
21 | {loop="col1"} | ||
22 | <div class="dailyEntry"> | ||
23 | <div style="float:right;position:relative;top:-1px;"><a href="?{$value.linkdate|smallHash}"><img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"></a></div> | ||
24 | {if="$value.tags"}<div class="dailyEntryTags">{loop="value.taglist"}{$value|htmlspecialchars} - {/loop}</div>{/if} | ||
25 | <div class="dailyEntryTitle"><a href="{$value.url}">{$value.title|htmlspecialchars}</a></div> | ||
26 | {if="$value.thumbnail"}<div class="dailyEntryThumbnail">{$value.thumbnail}</div>{/if} | ||
27 | <div class="dailyEntryDescription">{$value.formatedDescription}</div> | ||
28 | </div> | ||
29 | {/loop} | ||
30 | </div> | ||
31 | |||
32 | <div id="daily_col2"> | ||
33 | {loop="col2"} | ||
34 | <div class="dailyEntry"> | ||
35 | <div style="float:right;position:relative;top:-1px;"><a href="?{$value.linkdate|smallHash}"><img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"></a></div> | ||
36 | {if="$value.tags"}<div class="dailyEntryTags">{loop="value.taglist"}{$value|htmlspecialchars} - {/loop}</div>{/if} | ||
37 | <div class="dailyEntryTitle"><a href="{$value.url}">{$value.title|htmlspecialchars}</a></div> | ||
38 | {if="$value.thumbnail"}<div class="dailyEntryThumbnail">{$value.thumbnail}</div>{/if} | ||
39 | <div class="dailyEntryDescription">{$value.formatedDescription}</div> | ||
40 | </div> | ||
41 | {/loop} | ||
42 | </div> | ||
43 | |||
44 | <div id="daily_col3"> | ||
45 | {loop="col3"} | ||
46 | <div class="dailyEntry"> | ||
47 | <div style="float:right;position:relative;top:-1px;"><a href="?{$value.linkdate|smallHash}"><img src="../images/squiggle2.png" width="25" height="26" title="permalink" alt="permalink"></a></div> | ||
48 | {if="$value.tags"}<div class="dailyEntryTags">{loop="value.taglist"}{$value|htmlspecialchars} - {/loop}</div>{/if} | ||
49 | <div class="dailyEntryTitle"><a href="{$value.url}">{$value.title|htmlspecialchars}</a></div> | ||
50 | {if="$value.thumbnail"}<div class="dailyEntryThumbnail">{$value.thumbnail}</div>{/if} | ||
51 | <div class="dailyEntryDescription">{$value.formatedDescription}</div> | ||
52 | </div> | ||
53 | {/loop} | ||
54 | </div> | ||
55 | {else} | ||
56 | <div style="text-align:center; padding:40px 0px 90px 0px;">No articles on this day.</div> | ||
57 | {/if} | ||
58 | <div style="clear:both;"></div> | ||
59 | <div style="text-align:center; padding-bottom:20px;"><img src="../images/squiggle_closing.png" width="66" height="61" alt="-"></div> | ||
60 | </div> | ||
61 | {include="page.footer"} | ||
62 | </body> | ||
63 | </html> \ No newline at end of file | ||
diff --git a/tpl/dailyrss.html b/tpl/dailyrss.html new file mode 100644 index 00000000..436e1cd2 --- /dev/null +++ b/tpl/dailyrss.html | |||
@@ -0,0 +1,8 @@ | |||
1 | {loop="links"} | ||
2 | <h3><a href="{$value.url}">{$value.title|htmlspecialchars}</a></h3> | ||
3 | <small>{if="!$GLOBALS['config']['HIDE_TIMESTAMPS']"}{$value.localdate|htmlspecialchars} - {/if}{if="$value.tags"}{$value.tags|htmlspecialchars}{/if}<br> | ||
4 | {$value.url|htmlspecialchars}</small><br> | ||
5 | {if="$value.thumbnail"}{$value.thumbnail}{/if}<br> | ||
6 | {if="$value.description"}{$value.formatedDescription}{/if} | ||
7 | <br><br><hr> | ||
8 | {/loop} \ No newline at end of file | ||
diff --git a/tpl/editlink.html b/tpl/editlink.html new file mode 100644 index 00000000..4ad43b35 --- /dev/null +++ b/tpl/editlink.html | |||
@@ -0,0 +1,28 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body | ||
5 | {if condition="$link.title==''"}onload="document.linkform.lf_title.focus();" | ||
6 | {elseif condition="$link.description==''"}onload="document.linkform.lf_description.focus();" | ||
7 | {else}onload="document.linkform.lf_tags.focus();"{/if} > | ||
8 | <div id="pageheader"> | ||
9 | {include="page.header"} | ||
10 | <div id="editlinkform"> | ||
11 | <form method="post" name="linkform"> | ||
12 | <input type="hidden" name="lf_linkdate" value="{$link.linkdate}"> | ||
13 | <i>URL</i><br><input type="text" name="lf_url" value="{$link.url|htmlspecialchars}" style="width:100%"><br> | ||
14 | <i>Title</i><br><input type="text" name="lf_title" value="{$link.title|htmlspecialchars}" style="width:100%"><br> | ||
15 | <i>Description</i><br><textarea name="lf_description" rows="4" cols="25" style="width:100%">{$link.description|htmlspecialchars}</textarea><br> | ||
16 | <i>Tags</i><br><input type="text" id="lf_tags" name="lf_tags" value="{$link.tags|htmlspecialchars}" style="width:100%"><br> | ||
17 | <input type="checkbox" {if condition="$link.private!=0"}checked="yes"{/if} style="margin:7 0 10 0;" name="lf_private" id="lf_private"> <label for="lf_private"><i>Private</i></label><br> | ||
18 | <input type="submit" value="Save" name="save_edit" class="bigbutton" style="margin-left:40px;"> | ||
19 | <input type="submit" value="Cancel" name="cancel_edit" class="bigbutton" style="margin-left:40px;"> | ||
20 | {if condition="!$link_is_new"}<input type="submit" value="Delete" name="delete_link" class="bigbutton" style="margin-left:180px;" onClick="return confirmDeleteLink();">{/if} | ||
21 | <input type="hidden" name="token" value="{$token}"> | ||
22 | {if condition="$http_referer"}<input type="hidden" name="returnurl" value="{$http_referer|htmlspecialchars}">{/if} | ||
23 | </form> | ||
24 | </div> | ||
25 | </div> | ||
26 | {include="page.footer"} | ||
27 | </body> | ||
28 | </html> \ No newline at end of file | ||
diff --git a/tpl/export.html b/tpl/export.html new file mode 100644 index 00000000..938cbe64 --- /dev/null +++ b/tpl/export.html | |||
@@ -0,0 +1,15 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <div id="toolsdiv"> | ||
8 | <a href="?do=export&what=all"><b>Export all</b> <span>: Export all links</span></a><br><br> | ||
9 | <a href="?do=export&what=public"><b>Export public</b> <span>: Export public links only</a><br><br> | ||
10 | <a href="?do=export&what=private"><b>Export private</b> <span>: Export private links only</a><br><br style="clear:both;"> | ||
11 | </div> | ||
12 | </div> | ||
13 | {include="page.footer"} | ||
14 | </body> | ||
15 | </html> \ No newline at end of file | ||
diff --git a/tpl/import.html b/tpl/import.html new file mode 100644 index 00000000..9e581fc9 --- /dev/null +++ b/tpl/import.html | |||
@@ -0,0 +1,21 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body onload="document.uploadform.filetoupload.focus();"> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <div id="uploaddiv"> | ||
8 | Import Netscape html bookmarks (as exported from Firefox/Chrome/Opera/delicious/diigo...) (Max: {$maxfilesize|htmlspecialchars} bytes). | ||
9 | <form method="POST" action="?do=upload" enctype="multipart/form-data" name="uploadform" id="uploadform"> | ||
10 | <input type="hidden" name="token" value="{$token}"> | ||
11 | <input type="file" name="filetoupload" size="80"> | ||
12 | <input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize|htmlspecialchars}"> | ||
13 | <input type="submit" name="import_file" value="Import" class="bigbutton"><br> | ||
14 | <input type="checkbox" name="private" id="private"><label for="private"> Import all links as private</label><br> | ||
15 | <input type="checkbox" name="overwrite" id="overwrite"><label for="overwrite"> Overwrite existing links</label> | ||
16 | </form> | ||
17 | </div> | ||
18 | </div> | ||
19 | {include="page.footer"} | ||
20 | </body> | ||
21 | </html> \ No newline at end of file | ||
diff --git a/tpl/includes.html b/tpl/includes.html new file mode 100644 index 00000000..5319f452 --- /dev/null +++ b/tpl/includes.html | |||
@@ -0,0 +1,10 @@ | |||
1 | <title>{$pagetitle}</title> | ||
2 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||
3 | <meta name="format-detection" content="telephone=no" /> | ||
4 | <meta name="viewport" content="width=device-width,initial-scale=1.0" /> | ||
5 | <link rel="alternate" type="application/rss+xml" href="{$feedurl}?do=rss{$searchcrits}#" title="RSS Feed" /> | ||
6 | <link rel="alternate" type="application/atom+xml" href="{$feedurl}?do=atom{$searchcrits}#" title="ATOM Feed" /> | ||
7 | <link href="images/favicon.ico#" rel="shortcut icon" type="image/x-icon" /> | ||
8 | <link type="text/css" rel="stylesheet" href="inc/shaarli.css?version={$version|urlencode}#" /> | ||
9 | {if condition="is_file('inc/user.css')"}<link type="text/css" rel="stylesheet" href="inc/user.css?version={$version}#" />{/if} | ||
10 | <script src="inc/jquery.min.js#"></script><script src="inc/jquery-ui.min.js#"></script> | ||
diff --git a/tpl/install.html b/tpl/install.html new file mode 100644 index 00000000..4034ef1b --- /dev/null +++ b/tpl/install.html | |||
@@ -0,0 +1,21 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}{$timezone_js}</head> | ||
4 | <body onload="document.installform.setlogin.focus();"> | ||
5 | <div style="margin-left:20px;"> | ||
6 | <h1>Shaarli</h1> | ||
7 | It looks like it's the first time you run Shaarli. Please configure it:<br> | ||
8 | <div style="color:white !important;"> | ||
9 | <form method="POST" action="" name="installform" id="installform" style="border:1px solid black; padding:10 10 10 10;"> | ||
10 | <table border="0" cellpadding="20"> | ||
11 | <tr><td><b>Login:</b></td><td><input type="text" name="setlogin" size="30"></td></tr> | ||
12 | <tr><td><b>Password:</b></td><td><input type="password" name="setpassword" size="30"></td></tr> | ||
13 | {$timezone_html} | ||
14 | <tr><td><b>Page title:</b></td><td><input type="text" name="title" size="30"></td></tr> | ||
15 | <tr><td></td><td align="right"><input type="submit" name="Save" value="Save config" class="bigbutton"></td></tr> | ||
16 | </table> | ||
17 | </form> | ||
18 | </div> | ||
19 | {include="page.footer"} | ||
20 | </body> | ||
21 | </html> \ No newline at end of file | ||
diff --git a/tpl/linklist.html b/tpl/linklist.html new file mode 100644 index 00000000..bfb1fcda --- /dev/null +++ b/tpl/linklist.html | |||
@@ -0,0 +1,76 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <div id="headerform" style="width:100%; white-space:nowrap;"> | ||
8 | <form method="GET" class="searchform" name="searchform" style="display:inline;"><input type="text" id="searchform_value" name="searchterm" style="width:30%" value=""> <input type="submit" value="Search" class="bigbutton"></form> | ||
9 | <form method="GET" class="tagfilter" name="tagfilter" style="display:inline;margin-left:24px;"><input type="text" name="searchtags" id="tagfilter_value" style="width:10%" value=""> <input type="submit" value="Filter by tag" class="bigbutton"></form> | ||
10 | </div> | ||
11 | </div> | ||
12 | |||
13 | <div id="linklist"> | ||
14 | |||
15 | {include="linklist.paging"} | ||
16 | |||
17 | {if="count($links)==0"} | ||
18 | <div id="searchcriteria">Nothing found.</i></div> | ||
19 | {else} | ||
20 | {if="$search_type=='fulltext'"} | ||
21 | <div id="searchcriteria">{$result_count} results for <i>{$search_crits}</i></div> | ||
22 | {/if} | ||
23 | {if="$search_type=='tags'"} | ||
24 | <div id="searchcriteria">{$result_count} results for tags <i> | ||
25 | {loop="search_crits"} | ||
26 | <span class="linktag" title="Remove tag"><a href="?removetag={$value|htmlspecialchars}">{$value|htmlspecialchars} <span style="border-left:1px solid #aaa; padding-left:5px; color:#6767A7;">x</span></a></span> | ||
27 | {/loop}</i></div> | ||
28 | {/if} | ||
29 | {/if} | ||
30 | <ul> | ||
31 | {loop="links"} | ||
32 | <li{if="$value.class"} class="{$value.class}"{/if}> | ||
33 | <div class="thumbnail">{$value.url|thumbnail}</div> | ||
34 | <div class="linkcontainer"> | ||
35 | <span class="linktitle"><a href="{$redirector}{$value.url}">{$value.title|htmlspecialchars}</a></span> | ||
36 | {if="isLoggedIn()"} | ||
37 | <form method="GET" class="buttoneditform"><input type="hidden" name="edit_link" value="{$value.linkdate}"><input type="image" alt="Edit" src="images/edit_icon.png#" title="Edit" class="button_edit"></form> | ||
38 | <form method="POST" class="buttoneditform"><input type="hidden" name="lf_linkdate" value="{$value.linkdate}"> | ||
39 | <input type="hidden" name="token" value="{$token}"><input type="hidden" name="delete_link"><input type="image" alt="Delete" src="images/delete_icon.png#" title="Delete" class="button_delete" onClick="return confirmDeleteLink();"></form> | ||
40 | {/if} | ||
41 | <br> | ||
42 | {if="$value.description"}<div class="linkdescription"{if condition="$search_type=='permalink'"} style="max-height:none !important;"{/if}>{$value.description}</div>{/if} | ||
43 | {if="!$GLOBALS['config']['HIDE_TIMESTAMPS'] || isLoggedIn()"} | ||
44 | <span class="linkdate" title="Permalink"><a href="?{$value.linkdate|smallHash}">{$value.localdate|htmlspecialchars} - permalink</a> - </span> | ||
45 | {else} | ||
46 | <span class="linkdate" title="Short link here"><a href="?{$value.linkdate|smallHash}">permalink</a> - </span> | ||
47 | {/if} | ||
48 | <div style="position:relative;display:inline;"><a href="http://invx.com/code/qrcode/?code={$scripturl|urlencode}%3F{$value.linkdate|smallHash}&width=200&height=200" onclick="return false;" class="qrcode"><img src="images/qrcode.png#" width="13" height="13" title="QR-Code"></a></div> - | ||
49 | <span class="linkurl" title="Short link">{$value.url|htmlspecialchars}</span><br> | ||
50 | {if="$value.tags"} | ||
51 | <div class="linktaglist"> | ||
52 | {loop="value.taglist"}<span class="linktag" title="Add tag"><a href="?addtag={$value|urlencode}">{$value|htmlspecialchars}</a></span> {/loop} | ||
53 | </div> | ||
54 | {/if} | ||
55 | </div> | ||
56 | </li> | ||
57 | {/loop} | ||
58 | </ul> | ||
59 | |||
60 | {include="linklist.paging"} | ||
61 | |||
62 | </div> | ||
63 | |||
64 | {include="page.footer"} | ||
65 | <script> | ||
66 | $(document).ready(function() { | ||
67 | $('a.qrcode').click(function(){ | ||
68 | hide_qrcode(); | ||
69 | var link = $(this).attr('href'); | ||
70 | $(this).after('<div class="qrcode" onclick="hide_qrcode();return false;"><img src="'+link+'#" width="200" height="200"><br>click to close</div>'); | ||
71 | }); | ||
72 | }); | ||
73 | function hide_qrcode() { $('div.qrcode').remove(); } | ||
74 | </script> | ||
75 | </body> | ||
76 | </html> \ No newline at end of file | ||
diff --git a/tpl/linklist.paging.html b/tpl/linklist.paging.html new file mode 100644 index 00000000..b0c119d9 --- /dev/null +++ b/tpl/linklist.paging.html | |||
@@ -0,0 +1,20 @@ | |||
1 | <div class="paging"> | ||
2 | {if="isLoggedIn()"} | ||
3 | <div id="paging_privatelinks"> | ||
4 | <a href="?privateonly"> | ||
5 | {if="$privateonly"} | ||
6 | <img src="images/private_16x16_active.png#" width="16" height="16" title="Click to see all links" alt="Click to see all links"> | ||
7 | {else} | ||
8 | <img src="images/private_16x16.png#" width="16" height="16" title="Click to see only private links" alt="Click to see only private links"> | ||
9 | {/if} | ||
10 | </a> | ||
11 | </div> | ||
12 | {/if} | ||
13 | <div id="paging_linksperpage"> | ||
14 | Links per page: <a href="?linksperpage=20">20</a> <a href="?linksperpage=50">50</a> <a href="?linksperpage=100">100</a> | ||
15 | <form method="GET" style="display:inline;" class="linksperpage"><input type="text" name="linksperpage" size="2" style="height:15px;"></form> | ||
16 | </div> | ||
17 | {if="$previous_page_url"} <a href="{$previous_page_url}" id="paging_older">◄Older</a> {/if} | ||
18 | <div id="paging_current">page {$page_current} / {$page_max} </div> | ||
19 | {if="$next_page_url"} <a href="{$next_page_url}" id="paging_newer">Newer►</a> {/if} | ||
20 | </div> \ No newline at end of file | ||
diff --git a/tpl/loginform.html b/tpl/loginform.html new file mode 100644 index 00000000..805a0148 --- /dev/null +++ b/tpl/loginform.html | |||
@@ -0,0 +1,26 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body{if="ban_canLogin()"} onload="document.loginform.login.focus();"{/if}> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | |||
8 | <div id="headerform"> | ||
9 | {if="!ban_canLogin()"} | ||
10 | You have been banned from login after too many failed attempts. Try later. | ||
11 | {else} | ||
12 | <form method="post" name="loginform"> | ||
13 | Login: <input type="text" name="login" tabindex="1"> | ||
14 | Password : <input type="password" name="password" tabindex="2"> | ||
15 | <input type="submit" value="Login" class="bigbutton" tabindex="4"><br> | ||
16 | <input style="margin:10 0 0 40;" type="checkbox" name="longlastingsession" id="longlastingsession" tabindex="3"><label for="longlastingsession"> Stay signed in (Do not check on public computers)</label> | ||
17 | <input type="hidden" name="token" value="{$token}"> | ||
18 | {if="$returnurl"}<input type="hidden" name="returnurl" value="{$returnurl|htmlspecialchars}">{/if} | ||
19 | </form> | ||
20 | {/if} | ||
21 | </div> | ||
22 | </div> | ||
23 | |||
24 | {include="page.footer"} | ||
25 | </body> | ||
26 | </html> \ No newline at end of file | ||
diff --git a/tpl/page.footer.html b/tpl/page.footer.html new file mode 100644 index 00000000..7fe15017 --- /dev/null +++ b/tpl/page.footer.html | |||
@@ -0,0 +1,20 @@ | |||
1 | <div id="footer"> | ||
2 | <b><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">Shaarli {$version|htmlspecialchars}</a></b> - The personal, minimalist, super-fast, no-database delicious clone. By <a href="http://sebsauvage.net" target="_blank">sebsauvage.net</a>. Theme by <a href="http://blog.idleman.fr" target="_blank">idleman.fr</a>. | ||
3 | </div> | ||
4 | {if="$newversion"} | ||
5 | <div id="newversion"><span style="text-decoration:blink;">●</span> Shaarli {$newversion|htmlspecialchars} is <a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli#download">available</a>.</div> | ||
6 | {/if} | ||
7 | {if="isLoggedIn()"} | ||
8 | <script language="JavaScript">function confirmDeleteLink() { var agree=confirm("Are you sure you want to delete this link ?"); if (agree) return true ; else return false ; }</script> | ||
9 | {/if} | ||
10 | |||
11 | {if="$GLOBALS['config']['OPEN_SHAARLI'] || isLoggedIn()"} | ||
12 | <script language="JavaScript"> | ||
13 | $(document).ready(function() | ||
14 | { | ||
15 | $('#lf_tags').autocomplete({source:'{$source}?ws=tags',minLength:1}); | ||
16 | $('#searchtags').autocomplete({source:'{$source}?ws=tags',minLength:1}); | ||
17 | $('#fromtag').autocomplete({source:'{$source}?ws=singletag',minLength:1}); | ||
18 | }); | ||
19 | </script> | ||
20 | {/if} | ||
diff --git a/tpl/page.header.html b/tpl/page.header.html new file mode 100644 index 00000000..60fc1767 --- /dev/null +++ b/tpl/page.header.html | |||
@@ -0,0 +1,26 @@ | |||
1 | |||
2 | <div id="logo" title="Share your links !" onclick="document.location='?';"></div> | ||
3 | <div style="float:right; font-style:italic; color:#bbb; text-align:right; padding:0 5 0 0;" class="nomobile">Shaare your links...<br> | ||
4 | {if="!empty($linkcount)"}{$linkcount} links{/if}</div> | ||
5 | <span id="shaarli_title"><a href="?">{$shaarlititle}</a></span> | ||
6 | |||
7 | {if="!empty($_GET['source']) && $_GET['source']=='bookmarklet'"} | ||
8 | {ignore} When called as a popup from bookmarklet, do not display menu. {/ignore} | ||
9 | {else} | ||
10 | <a href="?" class="nomobile">Home</a> | ||
11 | {if="isLoggedIn()"} | ||
12 | <a href="?do=logout">Logout</a><a href="?do=tools">Tools</a><a href="?do=addlink"><b>Add link</b></a> | ||
13 | {elseif="$GLOBALS['config']['OPEN_SHAARLI']"} | ||
14 | <a href="?do=tools">Tools</a><a href="?do=addlink"><b>Add link</b></a> | ||
15 | {else} | ||
16 | <a href="?do=login">Login</a> | ||
17 | {/if} | ||
18 | <a href="{$feedurl}?do=rss{$searchcrits}" class="nomobile">RSS Feed</a> | ||
19 | <a href="{$feedurl}?do=atom{$searchcrits}" style="padding-left:10px;" class="nomobile">ATOM Feed</a> | ||
20 | <a href="?do=tagcloud">Tag cloud</a> | ||
21 | <a href="?do=picwall{$searchcrits}">Picture wall</a> | ||
22 | <a href="?do=daily">Daily</a> | ||
23 | {/if} | ||
24 | <div class="clear"></div> | ||
25 | |||
26 | |||
diff --git a/tpl/page.html b/tpl/page.html new file mode 100644 index 00000000..834915ec --- /dev/null +++ b/tpl/page.html | |||
@@ -0,0 +1,9 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader">{include="page.header"}</div> | ||
6 | You body goes here... | ||
7 | {include="page.footer"} | ||
8 | </body> | ||
9 | </html> \ No newline at end of file | ||
diff --git a/tpl/picwall.html b/tpl/picwall.html new file mode 100644 index 00000000..2083a629 --- /dev/null +++ b/tpl/picwall.html | |||
@@ -0,0 +1,24 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"} | ||
4 | <script src="inc/jquery.lazyload.min.js#"></script> | ||
5 | </head> | ||
6 | <body> | ||
7 | <div id="pageheader">{include="page.header"}</div> | ||
8 | <center> | ||
9 | <div class="picwall_container"> | ||
10 | {loop="linksToDisplay"} | ||
11 | <div class="picwall_pictureframe"> | ||
12 | {$value.thumbnail}<a href="{$value.permalink}"><span class="info">{$value.title|htmlspecialchars}</span></a> | ||
13 | </div> | ||
14 | {/loop} | ||
15 | </div> | ||
16 | </center> | ||
17 | {include="page.footer"} | ||
18 | </body> | ||
19 | <script> | ||
20 | $(document).ready(function() { | ||
21 | $("img.lazyimage").show().lazyload(); | ||
22 | }); | ||
23 | </script> | ||
24 | </html> \ No newline at end of file | ||
diff --git a/tpl/picwall2.html b/tpl/picwall2.html new file mode 100644 index 00000000..44d08b0c --- /dev/null +++ b/tpl/picwall2.html | |||
@@ -0,0 +1,19 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader">{include="page.header"}</div> | ||
6 | <div style="background-color:#003;"> | ||
7 | {loop="linksToDisplay"} | ||
8 | <div style="float:left;width:48%;border-right:2px solid white;height:120px;overflow:hide;"> | ||
9 | <div style="float:left;width:120px;text-align:center">{$value.thumbnail}</div> | ||
10 | <a href="{$value.permalink}" style="color:yellow;font-weight:bold;text-decoration:none;">{$value.title|htmlspecialchars}</a><br> | ||
11 | <span style="font-size:8pt;color:#eee;">{$value.description|htmlspecialchars}</span> | ||
12 | <div style="clear:both;"></div> | ||
13 | </div><br> | ||
14 | {/loop} | ||
15 | </div> | ||
16 | |||
17 | {include="page.footer"} | ||
18 | </body> | ||
19 | </html> \ No newline at end of file | ||
diff --git a/tpl/readme.txt b/tpl/readme.txt new file mode 100644 index 00000000..b18deaed --- /dev/null +++ b/tpl/readme.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ===== Shaarli template organisation ===== | ||
2 | |||
3 | Any Shaarli page should conform to this RainTPL template: | ||
4 | |||
5 | ----------------------------------------------------- | ||
6 | <html> | ||
7 | <head>{include="includes"}</head> | ||
8 | <body> | ||
9 | <div id="pageheader">{include="page.header"}</div> | ||
10 | You body goes here... | ||
11 | {include="page.footer"} | ||
12 | </body> | ||
13 | </html> | ||
14 | ----------------------------------------------------- | ||
15 | |||
16 | If you want to also add something in the page header (in the dark area), do it here: | ||
17 | |||
18 | <div id="pageheader">{include="page.header"}My menu goes here...</div> | ||
19 | |||
20 | |||
21 | Example: "Add new link" form: | ||
22 | ----------------------------------------------------- | ||
23 | <html> | ||
24 | <head>{include="includes"}</head> | ||
25 | <body onload="document.addform.post.focus();"> | ||
26 | <div id="pageheader"> | ||
27 | {include="page.header"} | ||
28 | <div id="headerform"> | ||
29 | <form method="GET" action="" name="addform" class="addform"> | ||
30 | <input type="text" name="post" style="width:50%;"> | ||
31 | <input type="submit" value="Add link" class="bigbutton"> | ||
32 | </form> | ||
33 | </div> | ||
34 | </div> | ||
35 | {include="page.footer"} | ||
36 | </body> | ||
37 | </html> | ||
38 | ----------------------------------------------------- | ||
39 | |||
40 | |||
41 | |||
42 | |||
diff --git a/tpl/tagcloud.html b/tpl/tagcloud.html new file mode 100644 index 00000000..6918c7be --- /dev/null +++ b/tpl/tagcloud.html | |||
@@ -0,0 +1,15 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader">{include="page.header"}</div> | ||
6 | <center> | ||
7 | <div id="cloudtag"> | ||
8 | {loop="tags"} | ||
9 | <span style="color:#99f; font-size:9pt; padding-left:5px; padding-right:2px;">{$value.count}</span><a href="?searchtags={$key|htmlspecialchars}" style="font-size:{$value.size}pt; font-weight:bold; color:black; text-decoration:none">{$key|htmlspecialchars}</a> | ||
10 | {/loop} | ||
11 | </div> | ||
12 | </center> | ||
13 | {include="page.footer"} | ||
14 | </body> | ||
15 | </html> \ No newline at end of file | ||
diff --git a/tpl/tools.html b/tpl/tools.html new file mode 100644 index 00000000..48ecc97e --- /dev/null +++ b/tpl/tools.html | |||
@@ -0,0 +1,19 @@ | |||
1 | <!DOCTYPE html> | ||
2 | <html> | ||
3 | <head>{include="includes"}</head> | ||
4 | <body> | ||
5 | <div id="pageheader"> | ||
6 | {include="page.header"} | ||
7 | <div id="toolsdiv"> | ||
8 | {if="!$GLOBALS['config']['OPEN_SHAARLI']"}<a href="?do=changepasswd"><b>Change password</b> <span>: Change your password.</span></a><br><br>{/if} | ||
9 | <a href="?do=configure"><b>Configure your Shaarli</b> <span>: Change Title, timezone...</span></a><br><br> | ||
10 | <a href="?do=changetag"><b>Rename/delete tags</b> <span>: Rename or delete a tag in all links</span></a><br><br> | ||
11 | <a href="?do=import"><b>Import</b> <span>: Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)</span></a> <br><br> | ||
12 | <a href="?do=export"><b>Export</b> <span>: Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)</span></a><br><br> | ||
13 | <a class="smallbutton" onclick="alert('Drag this link to your bookmarks toolbar, or right-click it and choose Bookmark This Link...');return false;" href="javascript:javascript:(function(){var%20url%20=%20location.href;var%20title%20=%20document.title%20||%20url;window.open('{$pageabsaddr}?post='%20+%20encodeURIComponent(url)+'&title='%20+%20encodeURIComponent(title)+'&source=bookmarklet','_blank','menubar=no,height=390,width=600,toolbar=no,scrollbars=no,status=no,dialog=1');})();"><b>Shaare link</b></a> <a href="#" style="clear:none;"><span>⇐ Drag this link to your bookmarks toolbar (or right-click it and choose Bookmark This Link....).<br> Then click "Shaare link" button in any page you want to share.</span></a><br><br> | ||
14 | <div class="clear"></div> | ||
15 | </div> | ||
16 | </div> | ||
17 | {include="page.footer"} | ||
18 | </body> | ||
19 | </html> \ No newline at end of file | ||