Commit 127d4688fbd0ee3a34bf86ae90ecad9565d1a147

Authored by Kevin Fourie
1 parent 8846e474

Adding missing items back to thirdpartyjs.



git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@9749 c91229c3-7414-0410-bfa2-8a42b809f60b
thirdpartyjs/calendar/calendar-setup.js 0 → 100644
  1 +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
  2 + * ---------------------------------------------------------------------------
  3 + *
  4 + * The DHTML Calendar
  5 + *
  6 + * Details and latest version at:
  7 + * http://dynarch.com/mishoo/calendar.epl
  8 + *
  9 + * This script is distributed under the GNU Lesser General Public License.
  10 + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
  11 + *
  12 + * This file defines helper functions for setting up the calendar. They are
  13 + * intended to help non-programmers get a working calendar on their site
  14 + * quickly. This script should not be seen as part of the calendar. It just
  15 + * shows you what one can do with the calendar, while in the same time
  16 + * providing a quick and simple method for setting it up. If you need
  17 + * exhaustive customization of the calendar creation process feel free to
  18 + * modify this code to suit your needs (this is recommended and much better
  19 + * than modifying calendar.js itself).
  20 + */
  21 +
  22 +// $Id: calendar-setup.js 4576 2006-01-10 12:44:14Z bshuttle $
  23 +
  24 +/**
  25 + * This function "patches" an input field (or other element) to use a calendar
  26 + * widget for date selection.
  27 + *
  28 + * The "params" is a single object that can have the following properties:
  29 + *
  30 + * prop. name | description
  31 + * -------------------------------------------------------------------------------------------------
  32 + * inputField | the ID of an input field to store the date
  33 + * displayArea | the ID of a DIV or other element to show the date
  34 + * button | ID of a button or other element that will trigger the calendar
  35 + * eventName | event that will trigger the calendar, without the "on" prefix (default: "click")
  36 + * ifFormat | date format that will be stored in the input field
  37 + * daFormat | the date format that will be used to display the date in displayArea
  38 + * singleClick | (true/false) wether the calendar is in single click mode or not (default: true)
  39 + * mondayFirst | (true/false) if true Monday is the first day of week, Sunday otherwise (default: true)
  40 + * align | alignment (default: "Bl"); if you don't know what's this see the calendar documentation
  41 + * range | array with 2 elements. Default: [1900, 2999] -- the range of years available
  42 + * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers
  43 + * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
  44 + * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
  45 + * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
  46 + * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay)
  47 + * onClose | function that gets called when the calendar is closed. [default]
  48 + * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar.
  49 + * date | the date that the calendar will be initially displayed to
  50 + * showsTime | default: false; if true the calendar will include a time selector
  51 + * timeFormat | the time format; can be "12" or "24", default is "12"
  52 + *
  53 + * None of them is required, they all have default values. However, if you
  54 + * pass none of "inputField", "displayArea" or "button" you'll get a warning
  55 + * saying "nothing to setup".
  56 + */
  57 +Calendar.setup = function (params) {
  58 + function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
  59 +
  60 + param_default("inputField", null);
  61 + param_default("displayArea", null);
  62 + param_default("button", null);
  63 + param_default("eventName", "click");
  64 + param_default("ifFormat", "%Y/%m/%d");
  65 + param_default("daFormat", "%Y/%m/%d");
  66 + param_default("singleClick", true);
  67 + param_default("disableFunc", null);
  68 + param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined
  69 + param_default("mondayFirst", true);
  70 + param_default("align", "Bl");
  71 + param_default("range", [1900, 2999]);
  72 + param_default("weekNumbers", true);
  73 + param_default("flat", null);
  74 + param_default("flatCallback", null);
  75 + param_default("onSelect", null);
  76 + param_default("onClose", null);
  77 + param_default("onUpdate", null);
  78 + param_default("date", null);
  79 + param_default("showsTime", false);
  80 + param_default("timeFormat", "24");
  81 +
  82 + var tmp = ["inputField", "displayArea", "button"];
  83 + for (var i in tmp) {
  84 + if (typeof params[tmp[i]] == "string") {
  85 + params[tmp[i]] = document.getElementById(params[tmp[i]]);
  86 + }
  87 + }
  88 + if (!(params.flat || params.inputField || params.displayArea || params.button)) {
  89 + alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");
  90 + return false;
  91 + }
  92 +
  93 + function onSelect(cal) {
  94 + if (cal.params.flat) {
  95 + if (typeof cal.params.flatCallback == "function") {
  96 + cal.params.flatCallback(cal);
  97 + } else {
  98 + alert("No flatCallback given -- doing nothing.");
  99 + }
  100 + return false;
  101 + }
  102 + if (cal.params.inputField) {
  103 + cal.params.inputField.value = cal.date.print(cal.params.ifFormat);
  104 + }
  105 + if (cal.params.displayArea) {
  106 + cal.params.displayArea.innerHTML = cal.date.print(cal.params.daFormat);
  107 + }
  108 + if (cal.params.singleClick && cal.dateClicked) {
  109 + cal.callCloseHandler();
  110 + }
  111 + if (typeof cal.params.onUpdate == "function") {
  112 + cal.params.onUpdate(cal);
  113 + }
  114 + };
  115 +
  116 + if (params.flat != null) {
  117 + params.flat = document.getElementById(params.flat);
  118 + if (!params.flat) {
  119 + alert("Calendar.setup:\n Flat specified but can't find parent.");
  120 + return false;
  121 + }
  122 + var cal = new Calendar(params.mondayFirst, params.date, params.onSelect || onSelect);
  123 + cal.showsTime = params.showsTime;
  124 + cal.time24 = (params.timeFormat == "24");
  125 + cal.params = params;
  126 + cal.weekNumbers = params.weekNumbers;
  127 + cal.setRange(params.range[0], params.range[1]);
  128 + cal.setDateStatusHandler(params.dateStatusFunc);
  129 + cal.create(params.flat);
  130 + cal.show();
  131 + return false;
  132 + }
  133 +
  134 + var triggerEl = params.button || params.displayArea || params.inputField;
  135 + triggerEl["on" + params.eventName] = function() {
  136 + var dateEl = params.inputField || params.displayArea;
  137 + var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
  138 + var mustCreate = false;
  139 + var cal = window.calendar;
  140 + if (!window.calendar) {
  141 + window.calendar = cal = new Calendar(params.mondayFirst,
  142 + params.date,
  143 + params.onSelect || onSelect,
  144 + params.onClose || function(cal) { cal.hide(); });
  145 + cal.showsTime = params.showsTime;
  146 + cal.time24 = (params.timeFormat == "24");
  147 + cal.weekNumbers = params.weekNumbers;
  148 + mustCreate = true;
  149 + } else {
  150 + cal.hide();
  151 + }
  152 + cal.setRange(params.range[0], params.range[1]);
  153 + cal.params = params;
  154 + cal.setDateStatusHandler(params.dateStatusFunc);
  155 + cal.setDateFormat(dateFmt);
  156 + if (mustCreate)
  157 + cal.create();
  158 + cal.parseDate(dateEl.value || dateEl.innerHTML);
  159 + cal.refresh();
  160 + cal.showAtElement(params.displayArea || params.inputField, params.align);
  161 + return false;
  162 + };
  163 +};
thirdpartyjs/calendar/calendar-system.css 0 → 100644
  1 +/* The main calendar widget. DIV containing a table. */
  2 +
  3 +.calendar {
  4 + position: relative;
  5 + display: none;
  6 + border: 1px solid;
  7 + border-color: #fff #000 #000 #fff;
  8 + font-size: 11px;
  9 + cursor: default;
  10 + background: Window;
  11 + color: WindowText;
  12 + font-family: tahoma,verdana,sans-serif;
  13 +}
  14 +
  15 +.calendar table {
  16 + border: 1px solid;
  17 + border-color: #fff #000 #000 #fff;
  18 + font-size: 11px;
  19 + cursor: default;
  20 + background: Window;
  21 + color: WindowText;
  22 + font-family: tahoma,verdana,sans-serif;
  23 +}
  24 +
  25 +/* Header part -- contains navigation buttons and day names. */
  26 +
  27 +.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
  28 + text-align: center;
  29 + padding: 1px;
  30 + border: 1px solid;
  31 + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
  32 + background: ButtonFace;
  33 +}
  34 +
  35 +.calendar .nav {
  36 + background: ButtonFace url(menuarrow.gif) no-repeat 100% 100%;
  37 +}
  38 +
  39 +.calendar thead .title { /* This holds the current "month, year" */
  40 + font-weight: bold;
  41 + padding: 1px;
  42 + border: 1px solid #000;
  43 + background: ActiveCaption;
  44 + color: CaptionText;
  45 + text-align: center;
  46 +}
  47 +
  48 +.calendar thead .headrow { /* Row <TR> containing navigation buttons */
  49 +}
  50 +
  51 +.calendar thead .daynames { /* Row <TR> containing the day names */
  52 +}
  53 +
  54 +.calendar thead .name { /* Cells <TD> containing the day names */
  55 + border-bottom: 1px solid ButtonShadow;
  56 + padding: 2px;
  57 + text-align: center;
  58 + background: ButtonFace;
  59 + color: ButtonText;
  60 +}
  61 +
  62 +.calendar thead .weekend { /* How a weekend day name shows in header */
  63 + color: #f00;
  64 +}
  65 +
  66 +.calendar thead .hilite { /* How do the buttons in header appear when hover */
  67 + border: 2px solid;
  68 + padding: 0px;
  69 + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
  70 +}
  71 +
  72 +.calendar thead .active { /* Active (pressed) buttons in header */
  73 + border-width: 1px;
  74 + padding: 2px 0px 0px 2px;
  75 + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
  76 +}
  77 +
  78 +/* The body part -- contains all the days in month. */
  79 +
  80 +.calendar tbody .day { /* Cells <TD> containing month days dates */
  81 + width: 2em;
  82 + text-align: right;
  83 + padding: 2px 4px 2px 2px;
  84 +}
  85 +
  86 +.calendar table .wn {
  87 + padding: 2px 3px 2px 2px;
  88 + border-right: 1px solid ButtonShadow;
  89 + background: ButtonFace;
  90 + color: ButtonText;
  91 +}
  92 +
  93 +.calendar tbody .rowhilite td {
  94 + background: Highlight;
  95 + color: HighlightText;
  96 +}
  97 +
  98 +.calendar tbody td.hilite { /* Hovered cells <TD> */
  99 + padding: 1px 3px 1px 1px;
  100 + border-top: 1px solid #fff;
  101 + border-right: 1px solid #000;
  102 + border-bottom: 1px solid #000;
  103 + border-left: 1px solid #fff;
  104 +}
  105 +
  106 +.calendar tbody td.active { /* Active (pressed) cells <TD> */
  107 + padding: 2px 2px 0px 2px;
  108 + border: 1px solid;
  109 + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
  110 +}
  111 +
  112 +.calendar tbody td.selected { /* Cell showing selected date */
  113 + font-weight: bold;
  114 + border: 1px solid;
  115 + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
  116 + padding: 2px 2px 0px 2px;
  117 + background: ButtonFace;
  118 + color: ButtonText;
  119 +}
  120 +
  121 +.calendar tbody td.weekend { /* Cells showing weekend days */
  122 + color: #f00;
  123 +}
  124 +
  125 +.calendar tbody td.today { /* Cell showing today date */
  126 + font-weight: bold;
  127 + color: #00f;
  128 +}
  129 +
  130 +.calendar tbody td.disabled { color: GrayText; }
  131 +
  132 +.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
  133 + visibility: hidden;
  134 +}
  135 +
  136 +.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
  137 + display: none;
  138 +}
  139 +
  140 +/* The footer part -- status bar and "Close" button */
  141 +
  142 +.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
  143 +}
  144 +
  145 +.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
  146 + background: ButtonFace;
  147 + padding: 1px;
  148 + border: 1px solid;
  149 + border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
  150 + color: ButtonText;
  151 + text-align: center;
  152 +}
  153 +
  154 +.calendar tfoot .hilite { /* Hover style for buttons in footer */
  155 + border-top: 1px solid #fff;
  156 + border-right: 1px solid #000;
  157 + border-bottom: 1px solid #000;
  158 + border-left: 1px solid #fff;
  159 + padding: 1px;
  160 + background: #e4e0d8;
  161 +}
  162 +
  163 +.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
  164 + padding: 2px 0px 0px 2px;
  165 + border-top: 1px solid #000;
  166 + border-right: 1px solid #fff;
  167 + border-bottom: 1px solid #fff;
  168 + border-left: 1px solid #000;
  169 +}
  170 +
  171 +/* Combo boxes (menus that display months/years for direct selection) */
  172 +
  173 +.combo {
  174 + position: absolute;
  175 + display: none;
  176 + width: 4em;
  177 + top: 0px;
  178 + left: 0px;
  179 + cursor: default;
  180 + border: 1px solid;
  181 + border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
  182 + background: Menu;
  183 + color: MenuText;
  184 + font-size: smaller;
  185 + padding: 1px;
  186 +}
  187 +
  188 +.combo .label,
  189 +.combo .label-IEfix {
  190 + text-align: center;
  191 + padding: 1px;
  192 +}
  193 +
  194 +.combo .label-IEfix {
  195 + width: 4em;
  196 +}
  197 +
  198 +.combo .active {
  199 + padding: 0px;
  200 + border: 1px solid #000;
  201 +}
  202 +
  203 +.combo .hilite {
  204 + background: Highlight;
  205 + color: HighlightText;
  206 +}
  207 +
  208 +.calendar td.time {
  209 + border-top: 1px solid ButtonShadow;
  210 + padding: 1px 0px;
  211 + text-align: center;
  212 + background-color: ButtonFace;
  213 +}
  214 +
  215 +.calendar td.time .hour,
  216 +.calendar td.time .minute,
  217 +.calendar td.time .ampm {
  218 + padding: 0px 3px 0px 4px;
  219 + border: 1px solid #889;
  220 + font-weight: bold;
  221 + background-color: Menu;
  222 +}
  223 +
  224 +.calendar td.time .ampm {
  225 + text-align: center;
  226 +}
  227 +
  228 +.calendar td.time .colon {
  229 + padding: 0px 2px 0px 3px;
  230 + font-weight: bold;
  231 +}
  232 +
  233 +.calendar td.time span.hilite {
  234 + border-color: #000;
  235 + background-color: Highlight;
  236 + color: HighlightText;
  237 +}
  238 +
  239 +.calendar td.time span.active {
  240 + border-color: #f00;
  241 + background-color: #000;
  242 + color: #0f0;
  243 +}
thirdpartyjs/calendar/calendar.js 0 → 100644
  1 +/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
  2 + * ------------------------------------------------------------------
  3 + *
  4 + * The DHTML Calendar, version 0.9.5 "Your favorite time, bis"
  5 + *
  6 + * Details and latest version at:
  7 + * http://dynarch.com/mishoo/calendar.epl
  8 + *
  9 + * This script is distributed under the GNU Lesser General Public License.
  10 + * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
  11 + */
  12 +
  13 +// $Id: calendar.js 4576 2006-01-10 12:44:14Z bshuttle $
  14 +
  15 +/** The Calendar object constructor. */
  16 +Calendar = function (mondayFirst, dateStr, onSelected, onClose) {
  17 + // member variables
  18 + this.activeDiv = null;
  19 + this.currentDateEl = null;
  20 + this.getDateStatus = null;
  21 + this.timeout = null;
  22 + this.onSelected = onSelected || null;
  23 + this.onClose = onClose || null;
  24 + this.dragging = false;
  25 + this.hidden = false;
  26 + this.minYear = 1970;
  27 + this.maxYear = 2050;
  28 + this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
  29 + this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
  30 + this.isPopup = true;
  31 + this.weekNumbers = true;
  32 + this.mondayFirst = mondayFirst;
  33 + this.dateStr = dateStr;
  34 + this.ar_days = null;
  35 + this.showsTime = false;
  36 + this.time24 = true;
  37 + // HTML elements
  38 + this.table = null;
  39 + this.element = null;
  40 + this.tbody = null;
  41 + this.firstdayname = null;
  42 + // Combo boxes
  43 + this.monthsCombo = null;
  44 + this.yearsCombo = null;
  45 + this.hilitedMonth = null;
  46 + this.activeMonth = null;
  47 + this.hilitedYear = null;
  48 + this.activeYear = null;
  49 + // Information
  50 + this.dateClicked = false;
  51 +
  52 + // one-time initializations
  53 + if (typeof Calendar._SDN == "undefined") {
  54 + // table of short day names
  55 + if (typeof Calendar._SDN_len == "undefined")
  56 + Calendar._SDN_len = 3;
  57 + var ar = new Array();
  58 + for (var i = 8; i > 0;) {
  59 + ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
  60 + }
  61 + Calendar._SDN = ar;
  62 + // table of short month names
  63 + if (typeof Calendar._SMN_len == "undefined")
  64 + Calendar._SMN_len = 3;
  65 + ar = new Array();
  66 + for (var i = 12; i > 0;) {
  67 + ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
  68 + }
  69 + Calendar._SMN = ar;
  70 + }
  71 +};
  72 +
  73 +// ** constants
  74 +
  75 +/// "static", needed for event handlers.
  76 +Calendar._C = null;
  77 +
  78 +/// detect a special case of "web browser"
  79 +Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
  80 + !/opera/i.test(navigator.userAgent) );
  81 +
  82 +/// detect Opera browser
  83 +Calendar.is_opera = /opera/i.test(navigator.userAgent);
  84 +
  85 +/// detect KHTML-based browsers
  86 +Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
  87 +
  88 +// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
  89 +// library, at some point.
  90 +
  91 +Calendar.getAbsolutePos = function(el) {
  92 + var SL = 0, ST = 0;
  93 + var is_div = /^div$/i.test(el.tagName);
  94 + if (is_div && el.scrollLeft)
  95 + SL = el.scrollLeft;
  96 + if (is_div && el.scrollTop)
  97 + ST = el.scrollTop;
  98 + var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
  99 + if (el.offsetParent) {
  100 + var tmp = Calendar.getAbsolutePos(el.offsetParent);
  101 + r.x += tmp.x;
  102 + r.y += tmp.y;
  103 + }
  104 + return r;
  105 +};
  106 +
  107 +Calendar.isRelated = function (el, evt) {
  108 + var related = evt.relatedTarget;
  109 + if (!related) {
  110 + var type = evt.type;
  111 + if (type == "mouseover") {
  112 + related = evt.fromElement;
  113 + } else if (type == "mouseout") {
  114 + related = evt.toElement;
  115 + }
  116 + }
  117 + while (related) {
  118 + if (related == el) {
  119 + return true;
  120 + }
  121 + related = related.parentNode;
  122 + }
  123 + return false;
  124 +};
  125 +
  126 +Calendar.removeClass = function(el, className) {
  127 + if (!(el && el.className)) {
  128 + return;
  129 + }
  130 + var cls = el.className.split(" ");
  131 + var ar = new Array();
  132 + for (var i = cls.length; i > 0;) {
  133 + if (cls[--i] != className) {
  134 + ar[ar.length] = cls[i];
  135 + }
  136 + }
  137 + el.className = ar.join(" ");
  138 +};
  139 +
  140 +Calendar.addClass = function(el, className) {
  141 + Calendar.removeClass(el, className);
  142 + el.className += " " + className;
  143 +};
  144 +
  145 +Calendar.getElement = function(ev) {
  146 + if (Calendar.is_ie) {
  147 + return window.event.srcElement;
  148 + } else {
  149 + return ev.currentTarget;
  150 + }
  151 +};
  152 +
  153 +Calendar.getTargetElement = function(ev) {
  154 + if (Calendar.is_ie) {
  155 + return window.event.srcElement;
  156 + } else {
  157 + return ev.target;
  158 + }
  159 +};
  160 +
  161 +Calendar.stopEvent = function(ev) {
  162 + ev || (ev = window.event);
  163 + if (Calendar.is_ie) {
  164 + ev.cancelBubble = true;
  165 + ev.returnValue = false;
  166 + } else {
  167 + ev.preventDefault();
  168 + ev.stopPropagation();
  169 + }
  170 + return false;
  171 +};
  172 +
  173 +Calendar.addEvent = function(el, evname, func) {
  174 + if (el.attachEvent) { // IE
  175 + el.attachEvent("on" + evname, func);
  176 + } else if (el.addEventListener) { // Gecko / W3C
  177 + el.addEventListener(evname, func, true);
  178 + } else {
  179 + el["on" + evname] = func;
  180 + }
  181 +};
  182 +
  183 +Calendar.removeEvent = function(el, evname, func) {
  184 + if (el.detachEvent) { // IE
  185 + el.detachEvent("on" + evname, func);
  186 + } else if (el.removeEventListener) { // Gecko / W3C
  187 + el.removeEventListener(evname, func, true);
  188 + } else {
  189 + el["on" + evname] = null;
  190 + }
  191 +};
  192 +
  193 +Calendar.createElement = function(type, parent) {
  194 + var el = null;
  195 + if (document.createElementNS) {
  196 + // use the XHTML namespace; IE won't normally get here unless
  197 + // _they_ "fix" the DOM2 implementation.
  198 + el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
  199 + } else {
  200 + el = document.createElement(type);
  201 + }
  202 + if (typeof parent != "undefined") {
  203 + parent.appendChild(el);
  204 + }
  205 + return el;
  206 +};
  207 +
  208 +// END: UTILITY FUNCTIONS
  209 +
  210 +// BEGIN: CALENDAR STATIC FUNCTIONS
  211 +
  212 +/** Internal -- adds a set of events to make some element behave like a button. */
  213 +Calendar._add_evs = function(el) {
  214 + with (Calendar) {
  215 + addEvent(el, "mouseover", dayMouseOver);
  216 + addEvent(el, "mousedown", dayMouseDown);
  217 + addEvent(el, "mouseout", dayMouseOut);
  218 + if (is_ie) {
  219 + addEvent(el, "dblclick", dayMouseDblClick);
  220 + el.setAttribute("unselectable", true);
  221 + }
  222 + }
  223 +};
  224 +
  225 +Calendar.findMonth = function(el) {
  226 + if (typeof el.month != "undefined") {
  227 + return el;
  228 + } else if (typeof el.parentNode.month != "undefined") {
  229 + return el.parentNode;
  230 + }
  231 + return null;
  232 +};
  233 +
  234 +Calendar.findYear = function(el) {
  235 + if (typeof el.year != "undefined") {
  236 + return el;
  237 + } else if (typeof el.parentNode.year != "undefined") {
  238 + return el.parentNode;
  239 + }
  240 + return null;
  241 +};
  242 +
  243 +Calendar.showMonthsCombo = function () {
  244 + var cal = Calendar._C;
  245 + if (!cal) {
  246 + return false;
  247 + }
  248 + var cal = cal;
  249 + var cd = cal.activeDiv;
  250 + var mc = cal.monthsCombo;
  251 + if (cal.hilitedMonth) {
  252 + Calendar.removeClass(cal.hilitedMonth, "hilite");
  253 + }
  254 + if (cal.activeMonth) {
  255 + Calendar.removeClass(cal.activeMonth, "active");
  256 + }
  257 + var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
  258 + Calendar.addClass(mon, "active");
  259 + cal.activeMonth = mon;
  260 + var s = mc.style;
  261 + s.display = "block";
  262 + if (cd.navtype < 0)
  263 + s.left = cd.offsetLeft + "px";
  264 + else
  265 + s.left = (cd.offsetLeft + cd.offsetWidth - mc.offsetWidth) + "px";
  266 + s.top = (cd.offsetTop + cd.offsetHeight) + "px";
  267 +};
  268 +
  269 +Calendar.showYearsCombo = function (fwd) {
  270 + var cal = Calendar._C;
  271 + if (!cal) {
  272 + return false;
  273 + }
  274 + var cal = cal;
  275 + var cd = cal.activeDiv;
  276 + var yc = cal.yearsCombo;
  277 + if (cal.hilitedYear) {
  278 + Calendar.removeClass(cal.hilitedYear, "hilite");
  279 + }
  280 + if (cal.activeYear) {
  281 + Calendar.removeClass(cal.activeYear, "active");
  282 + }
  283 + cal.activeYear = null;
  284 + var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
  285 + var yr = yc.firstChild;
  286 + var show = false;
  287 + for (var i = 12; i > 0; --i) {
  288 + if (Y >= cal.minYear && Y <= cal.maxYear) {
  289 + yr.firstChild.data = Y;
  290 + yr.year = Y;
  291 + yr.style.display = "block";
  292 + show = true;
  293 + } else {
  294 + yr.style.display = "none";
  295 + }
  296 + yr = yr.nextSibling;
  297 + Y += fwd ? 2 : -2;
  298 + }
  299 + if (show) {
  300 + var s = yc.style;
  301 + s.display = "block";
  302 + if (cd.navtype < 0)
  303 + s.left = cd.offsetLeft + "px";
  304 + else
  305 + s.left = (cd.offsetLeft + cd.offsetWidth - yc.offsetWidth) + "px";
  306 + s.top = (cd.offsetTop + cd.offsetHeight) + "px";
  307 + }
  308 +};
  309 +
  310 +// event handlers
  311 +
  312 +Calendar.tableMouseUp = function(ev) {
  313 + var cal = Calendar._C;
  314 + if (!cal) {
  315 + return false;
  316 + }
  317 + if (cal.timeout) {
  318 + clearTimeout(cal.timeout);
  319 + }
  320 + var el = cal.activeDiv;
  321 + if (!el) {
  322 + return false;
  323 + }
  324 + var target = Calendar.getTargetElement(ev);
  325 + ev || (ev = window.event);
  326 + Calendar.removeClass(el, "active");
  327 + if (target == el || target.parentNode == el) {
  328 + Calendar.cellClick(el, ev);
  329 + }
  330 + var mon = Calendar.findMonth(target);
  331 + var date = null;
  332 + if (mon) {
  333 + date = new Date(cal.date);
  334 + if (mon.month != date.getMonth()) {
  335 + date.setMonth(mon.month);
  336 + cal.setDate(date);
  337 + cal.dateClicked = false;
  338 + cal.callHandler();
  339 + }
  340 + } else {
  341 + var year = Calendar.findYear(target);
  342 + if (year) {
  343 + date = new Date(cal.date);
  344 + if (year.year != date.getFullYear()) {
  345 + date.setFullYear(year.year);
  346 + cal.setDate(date);
  347 + cal.dateClicked = false;
  348 + cal.callHandler();
  349 + }
  350 + }
  351 + }
  352 + with (Calendar) {
  353 + removeEvent(document, "mouseup", tableMouseUp);
  354 + removeEvent(document, "mouseover", tableMouseOver);
  355 + removeEvent(document, "mousemove", tableMouseOver);
  356 + cal._hideCombos();
  357 + _C = null;
  358 + return stopEvent(ev);
  359 + }
  360 +};
  361 +
  362 +Calendar.tableMouseOver = function (ev) {
  363 + var cal = Calendar._C;
  364 + if (!cal) {
  365 + return;
  366 + }
  367 + var el = cal.activeDiv;
  368 + var target = Calendar.getTargetElement(ev);
  369 + if (target == el || target.parentNode == el) {
  370 + Calendar.addClass(el, "hilite active");
  371 + Calendar.addClass(el.parentNode, "rowhilite");
  372 + } else {
  373 + if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
  374 + Calendar.removeClass(el, "active");
  375 + Calendar.removeClass(el, "hilite");
  376 + Calendar.removeClass(el.parentNode, "rowhilite");
  377 + }
  378 + ev || (ev = window.event);
  379 + if (el.navtype == 50 && target != el) {
  380 + var pos = Calendar.getAbsolutePos(el);
  381 + var w = el.offsetWidth;
  382 + var x = ev.clientX;
  383 + var dx;
  384 + var decrease = true;
  385 + if (x > pos.x + w) {
  386 + dx = x - pos.x - w;
  387 + decrease = false;
  388 + } else
  389 + dx = pos.x - x;
  390 +
  391 + if (dx < 0) dx = 0;
  392 + var range = el._range;
  393 + var current = el._current;
  394 + var count = Math.floor(dx / 10) % range.length;
  395 + for (var i = range.length; --i >= 0;)
  396 + if (range[i] == current)
  397 + break;
  398 + while (count-- > 0)
  399 + if (decrease) {
  400 + if (!(--i in range))
  401 + i = range.length - 1;
  402 + } else if (!(++i in range))
  403 + i = 0;
  404 + var newval = range[i];
  405 + el.firstChild.data = newval;
  406 +
  407 + cal.onUpdateTime();
  408 + }
  409 + var mon = Calendar.findMonth(target);
  410 + if (mon) {
  411 + if (mon.month != cal.date.getMonth()) {
  412 + if (cal.hilitedMonth) {
  413 + Calendar.removeClass(cal.hilitedMonth, "hilite");
  414 + }
  415 + Calendar.addClass(mon, "hilite");
  416 + cal.hilitedMonth = mon;
  417 + } else if (cal.hilitedMonth) {
  418 + Calendar.removeClass(cal.hilitedMonth, "hilite");
  419 + }
  420 + } else {
  421 + if (cal.hilitedMonth) {
  422 + Calendar.removeClass(cal.hilitedMonth, "hilite");
  423 + }
  424 + var year = Calendar.findYear(target);
  425 + if (year) {
  426 + if (year.year != cal.date.getFullYear()) {
  427 + if (cal.hilitedYear) {
  428 + Calendar.removeClass(cal.hilitedYear, "hilite");
  429 + }
  430 + Calendar.addClass(year, "hilite");
  431 + cal.hilitedYear = year;
  432 + } else if (cal.hilitedYear) {
  433 + Calendar.removeClass(cal.hilitedYear, "hilite");
  434 + }
  435 + } else if (cal.hilitedYear) {
  436 + Calendar.removeClass(cal.hilitedYear, "hilite");
  437 + }
  438 + }
  439 + return Calendar.stopEvent(ev);
  440 +};
  441 +
  442 +Calendar.tableMouseDown = function (ev) {
  443 + if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
  444 + return Calendar.stopEvent(ev);
  445 + }
  446 +};
  447 +
  448 +Calendar.calDragIt = function (ev) {
  449 + var cal = Calendar._C;
  450 + if (!(cal && cal.dragging)) {
  451 + return false;
  452 + }
  453 + var posX;
  454 + var posY;
  455 + if (Calendar.is_ie) {
  456 + posY = window.event.clientY + document.body.scrollTop;
  457 + posX = window.event.clientX + document.body.scrollLeft;
  458 + } else {
  459 + posX = ev.pageX;
  460 + posY = ev.pageY;
  461 + }
  462 + cal.hideShowCovered();
  463 + var st = cal.element.style;
  464 + st.left = (posX - cal.xOffs) + "px";
  465 + st.top = (posY - cal.yOffs) + "px";
  466 + return Calendar.stopEvent(ev);
  467 +};
  468 +
  469 +Calendar.calDragEnd = function (ev) {
  470 + var cal = Calendar._C;
  471 + if (!cal) {
  472 + return false;
  473 + }
  474 + cal.dragging = false;
  475 + with (Calendar) {
  476 + removeEvent(document, "mousemove", calDragIt);
  477 + removeEvent(document, "mouseover", stopEvent);
  478 + removeEvent(document, "mouseup", calDragEnd);
  479 + tableMouseUp(ev);
  480 + }
  481 + cal.hideShowCovered();
  482 +};
  483 +
  484 +Calendar.dayMouseDown = function(ev) {
  485 + var el = Calendar.getElement(ev);
  486 + if (el.disabled) {
  487 + return false;
  488 + }
  489 + var cal = el.calendar;
  490 + cal.activeDiv = el;
  491 + Calendar._C = cal;
  492 + if (el.navtype != 300) with (Calendar) {
  493 + if (el.navtype == 50)
  494 + el._current = el.firstChild.data;
  495 + addClass(el, "hilite active");
  496 + addEvent(document, "mouseover", tableMouseOver);
  497 + addEvent(document, "mousemove", tableMouseOver);
  498 + addEvent(document, "mouseup", tableMouseUp);
  499 + } else if (cal.isPopup) {
  500 + cal._dragStart(ev);
  501 + }
  502 + if (el.navtype == -1 || el.navtype == 1) {
  503 + if (cal.timeout) clearTimeout(cal.timeout);
  504 + cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
  505 + } else if (el.navtype == -2 || el.navtype == 2) {
  506 + if (cal.timeout) clearTimeout(cal.timeout);
  507 + cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
  508 + } else {
  509 + cal.timeout = null;
  510 + }
  511 + return Calendar.stopEvent(ev);
  512 +};
  513 +
  514 +Calendar.dayMouseDblClick = function(ev) {
  515 + Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
  516 + if (Calendar.is_ie) {
  517 + document.selection.empty();
  518 + }
  519 +};
  520 +
  521 +Calendar.dayMouseOver = function(ev) {
  522 + var el = Calendar.getElement(ev);
  523 + if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
  524 + return false;
  525 + }
  526 + if (el.ttip) {
  527 + if (el.ttip.substr(0, 1) == "_") {
  528 + var date = null;
  529 + with (el.calendar.date) {
  530 + date = new Date(getFullYear(), getMonth(), el.caldate);
  531 + }
  532 + el.ttip = date.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
  533 + }
  534 + el.calendar.tooltips.firstChild.data = el.ttip;
  535 + }
  536 + if (el.navtype != 300) {
  537 + Calendar.addClass(el, "hilite");
  538 + if (el.caldate) {
  539 + Calendar.addClass(el.parentNode, "rowhilite");
  540 + }
  541 + }
  542 + return Calendar.stopEvent(ev);
  543 +};
  544 +
  545 +Calendar.dayMouseOut = function(ev) {
  546 + with (Calendar) {
  547 + var el = getElement(ev);
  548 + if (isRelated(el, ev) || _C || el.disabled) {
  549 + return false;
  550 + }
  551 + removeClass(el, "hilite");
  552 + if (el.caldate) {
  553 + removeClass(el.parentNode, "rowhilite");
  554 + }
  555 + el.calendar.tooltips.firstChild.data = _TT["SEL_DATE"];
  556 + return stopEvent(ev);
  557 + }
  558 +};
  559 +
  560 +/**
  561 + * A generic "click" handler :) handles all types of buttons defined in this
  562 + * calendar.
  563 + */
  564 +Calendar.cellClick = function(el, ev) {
  565 + var cal = el.calendar;
  566 + var closing = false;
  567 + var newdate = false;
  568 + var date = null;
  569 + if (typeof el.navtype == "undefined") {
  570 + Calendar.removeClass(cal.currentDateEl, "selected");
  571 + Calendar.addClass(el, "selected");
  572 + closing = (cal.currentDateEl == el);
  573 + if (!closing) {
  574 + cal.currentDateEl = el;
  575 + }
  576 + cal.date.setDate(el.caldate);
  577 + date = cal.date;
  578 + newdate = true;
  579 + // a date was clicked
  580 + cal.dateClicked = true;
  581 + } else {
  582 + if (el.navtype == 200) {
  583 + Calendar.removeClass(el, "hilite");
  584 + cal.callCloseHandler();
  585 + return;
  586 + }
  587 + date = (el.navtype == 0) ? new Date() : new Date(cal.date);
  588 + // unless "today" was clicked, we assume no date was clicked so
  589 + // the selected handler will know not to close the calenar when
  590 + // in single-click mode.
  591 + // cal.dateClicked = (el.navtype == 0);
  592 + cal.dateClicked = false;
  593 + var year = date.getFullYear();
  594 + var mon = date.getMonth();
  595 + function setMonth(m) {
  596 + var day = date.getDate();
  597 + var max = date.getMonthDays(m);
  598 + if (day > max) {
  599 + date.setDate(max);
  600 + }
  601 + date.setMonth(m);
  602 + };
  603 + switch (el.navtype) {
  604 + case 400:
  605 + Calendar.removeClass(el, "hilite");
  606 + var text = Calendar._TT["ABOUT"];
  607 + if (typeof text != "undefined") {
  608 + text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
  609 + } else {
  610 + // FIXME: this should be removed as soon as lang files get updated!
  611 + text = "Help and about box text is not translated into this language.\n" +
  612 + "If you know this language and you feel generous please update\n" +
  613 + "the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
  614 + "and send it back to <mishoo@infoiasi.ro> to get it into the distribution ;-)\n\n" +
  615 + "Thank you!\n" +
  616 + "http://dynarch.com/mishoo/calendar.epl\n";
  617 + }
  618 + alert(text);
  619 + return;
  620 + case -2:
  621 + if (year > cal.minYear) {
  622 + date.setFullYear(year - 1);
  623 + }
  624 + break;
  625 + case -1:
  626 + if (mon > 0) {
  627 + setMonth(mon - 1);
  628 + } else if (year-- > cal.minYear) {
  629 + date.setFullYear(year);
  630 + setMonth(11);
  631 + }
  632 + break;
  633 + case 1:
  634 + if (mon < 11) {
  635 + setMonth(mon + 1);
  636 + } else if (year < cal.maxYear) {
  637 + date.setFullYear(year + 1);
  638 + setMonth(0);
  639 + }
  640 + break;
  641 + case 2:
  642 + if (year < cal.maxYear) {
  643 + date.setFullYear(year + 1);
  644 + }
  645 + break;
  646 + case 100:
  647 + cal.setMondayFirst(!cal.mondayFirst);
  648 + return;
  649 + case 50:
  650 + var range = el._range;
  651 + var current = el.firstChild.data;
  652 + for (var i = range.length; --i >= 0;)
  653 + if (range[i] == current)
  654 + break;
  655 + if (ev && ev.shiftKey) {
  656 + if (!(--i in range))
  657 + i = range.length - 1;
  658 + } else if (!(++i in range))
  659 + i = 0;
  660 + var newval = range[i];
  661 + el.firstChild.data = newval;
  662 + cal.onUpdateTime();
  663 + return;
  664 + case 0:
  665 + // TODAY will bring us here
  666 + if ((typeof cal.getDateStatus == "function") && cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
  667 + // remember, "date" was previously set to new
  668 + // Date() if TODAY was clicked; thus, it
  669 + // contains today date.
  670 + return false;
  671 + }
  672 + break;
  673 + }
  674 + if (!date.equalsTo(cal.date)) {
  675 + cal.setDate(date);
  676 + newdate = true;
  677 + }
  678 + }
  679 + if (newdate) {
  680 + cal.callHandler();
  681 + }
  682 + if (closing) {
  683 + Calendar.removeClass(el, "hilite");
  684 + cal.callCloseHandler();
  685 + }
  686 +};
  687 +
  688 +// END: CALENDAR STATIC FUNCTIONS
  689 +
  690 +// BEGIN: CALENDAR OBJECT FUNCTIONS
  691 +
  692 +/**
  693 + * This function creates the calendar inside the given parent. If _par is
  694 + * null than it creates a popup calendar inside the BODY element. If _par is
  695 + * an element, be it BODY, then it creates a non-popup calendar (still
  696 + * hidden). Some properties need to be set before calling this function.
  697 + */
  698 +Calendar.prototype.create = function (_par) {
  699 + var parent = null;
  700 + if (! _par) {
  701 + // default parent is the document body, in which case we create
  702 + // a popup calendar.
  703 + parent = document.getElementsByTagName("body")[0];
  704 + this.isPopup = true;
  705 + } else {
  706 + parent = _par;
  707 + this.isPopup = false;
  708 + }
  709 + this.date = this.dateStr ? new Date(this.dateStr) : new Date();
  710 +
  711 + var table = Calendar.createElement("table");
  712 + this.table = table;
  713 + table.cellSpacing = 0;
  714 + table.cellPadding = 0;
  715 + table.calendar = this;
  716 + Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
  717 +
  718 + var div = Calendar.createElement("div");
  719 + this.element = div;
  720 + div.className = "calendar";
  721 + if (this.isPopup) {
  722 + div.style.position = "absolute";
  723 + div.style.display = "none";
  724 + }
  725 + div.appendChild(table);
  726 +
  727 + var thead = Calendar.createElement("thead", table);
  728 + var cell = null;
  729 + var row = null;
  730 +
  731 + var cal = this;
  732 + var hh = function (text, cs, navtype) {
  733 + cell = Calendar.createElement("td", row);
  734 + cell.colSpan = cs;
  735 + cell.className = "button";
  736 + if (navtype != 0 && Math.abs(navtype) <= 2)
  737 + cell.className += " nav";
  738 + Calendar._add_evs(cell);
  739 + cell.calendar = cal;
  740 + cell.navtype = navtype;
  741 + if (text.substr(0, 1) != "&") {
  742 + cell.appendChild(document.createTextNode(text));
  743 + }
  744 + else {
  745 + // FIXME: dirty hack for entities
  746 + cell.innerHTML = text;
  747 + }
  748 + return cell;
  749 + };
  750 +
  751 + row = Calendar.createElement("tr", thead);
  752 + var title_length = 6;
  753 + (this.isPopup) && --title_length;
  754 + (this.weekNumbers) && ++title_length;
  755 +
  756 + hh("?", 1, 400).ttip = Calendar._TT["INFO"];
  757 + this.title = hh("", title_length, 300);
  758 + this.title.className = "title";
  759 + if (this.isPopup) {
  760 + this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
  761 + this.title.style.cursor = "move";
  762 + hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
  763 + }
  764 +
  765 + row = Calendar.createElement("tr", thead);
  766 + row.className = "headrow";
  767 +
  768 + this._nav_py = hh("&#x00ab;", 1, -2);
  769 + this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
  770 +
  771 + this._nav_pm = hh("&#x2039;", 1, -1);
  772 + this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
  773 +
  774 + this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
  775 + this._nav_now.ttip = Calendar._TT["GO_TODAY"];
  776 +
  777 + this._nav_nm = hh("&#x203a;", 1, 1);
  778 + this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
  779 +
  780 + this._nav_ny = hh("&#x00bb;", 1, 2);
  781 + this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
  782 +
  783 + // day names
  784 + row = Calendar.createElement("tr", thead);
  785 + row.className = "daynames";
  786 + if (this.weekNumbers) {
  787 + cell = Calendar.createElement("td", row);
  788 + cell.className = "name wn";
  789 + cell.appendChild(document.createTextNode(Calendar._TT["WK"]));
  790 + }
  791 + for (var i = 7; i > 0; --i) {
  792 + cell = Calendar.createElement("td", row);
  793 + cell.appendChild(document.createTextNode(""));
  794 + if (!i) {
  795 + cell.navtype = 100;
  796 + cell.calendar = this;
  797 + Calendar._add_evs(cell);
  798 + }
  799 + }
  800 + this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
  801 + this._displayWeekdays();
  802 +
  803 + var tbody = Calendar.createElement("tbody", table);
  804 + this.tbody = tbody;
  805 +
  806 + for (i = 6; i > 0; --i) {
  807 + row = Calendar.createElement("tr", tbody);
  808 + if (this.weekNumbers) {
  809 + cell = Calendar.createElement("td", row);
  810 + cell.appendChild(document.createTextNode(""));
  811 + }
  812 + for (var j = 7; j > 0; --j) {
  813 + cell = Calendar.createElement("td", row);
  814 + cell.appendChild(document.createTextNode(""));
  815 + cell.calendar = this;
  816 + Calendar._add_evs(cell);
  817 + }
  818 + }
  819 +
  820 + if (this.showsTime) {
  821 + row = Calendar.createElement("tr", tbody);
  822 + row.className = "time";
  823 +
  824 + cell = Calendar.createElement("td", row);
  825 + cell.className = "time";
  826 + cell.colSpan = 2;
  827 + cell.innerHTML = "&nbsp;";
  828 +
  829 + cell = Calendar.createElement("td", row);
  830 + cell.className = "time";
  831 + cell.colSpan = this.weekNumbers ? 4 : 3;
  832 +
  833 + (function(){
  834 + function makeTimePart(className, init, range_start, range_end) {
  835 + var part = Calendar.createElement("span", cell);
  836 + part.className = className;
  837 + part.appendChild(document.createTextNode(init));
  838 + part.calendar = cal;
  839 + part.ttip = Calendar._TT["TIME_PART"];
  840 + part.navtype = 50;
  841 + part._range = [];
  842 + if (typeof range_start != "number")
  843 + part._range = range_start;
  844 + else {
  845 + for (var i = range_start; i <= range_end; ++i) {
  846 + var txt;
  847 + if (i < 10 && range_end >= 10) txt = '0' + i;
  848 + else txt = '' + i;
  849 + part._range[part._range.length] = txt;
  850 + }
  851 + }
  852 + Calendar._add_evs(part);
  853 + return part;
  854 + };
  855 + var hrs = cal.date.getHours();
  856 + var mins = cal.date.getMinutes();
  857 + var t12 = !cal.time24;
  858 + var pm = (hrs > 12);
  859 + if (t12 && pm) hrs -= 12;
  860 + var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
  861 + var span = Calendar.createElement("span", cell);
  862 + span.appendChild(document.createTextNode(":"));
  863 + span.className = "colon";
  864 + var M = makeTimePart("minute", mins, 0, 59);
  865 + var AP = null;
  866 + cell = Calendar.createElement("td", row);
  867 + cell.className = "time";
  868 + cell.colSpan = 2;
  869 + if (t12)
  870 + AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
  871 + else
  872 + cell.innerHTML = "&nbsp;";
  873 +
  874 + cal.onSetTime = function() {
  875 + var hrs = this.date.getHours();
  876 + var mins = this.date.getMinutes();
  877 + var pm = (hrs > 12);
  878 + if (pm && t12) hrs -= 12;
  879 + H.firstChild.data = (hrs < 10) ? ("0" + hrs) : hrs;
  880 + M.firstChild.data = (mins < 10) ? ("0" + mins) : mins;
  881 + if (t12)
  882 + AP.firstChild.data = pm ? "pm" : "am";
  883 + };
  884 +
  885 + cal.onUpdateTime = function() {
  886 + var date = this.date;
  887 + var h = parseInt(H.firstChild.data, 10);
  888 + if (t12) {
  889 + if (/pm/i.test(AP.firstChild.data) && h < 12)
  890 + h += 12;
  891 + else if (/am/i.test(AP.firstChild.data) && h == 12)
  892 + h = 0;
  893 + }
  894 + var d = date.getDate();
  895 + var m = date.getMonth();
  896 + var y = date.getFullYear();
  897 + date.setHours(h);
  898 + date.setMinutes(parseInt(M.firstChild.data, 10));
  899 + date.setFullYear(y);
  900 + date.setMonth(m);
  901 + date.setDate(d);
  902 + this.dateClicked = false;
  903 + this.callHandler();
  904 + };
  905 + })();
  906 + } else {
  907 + this.onSetTime = this.onUpdateTime = function() {};
  908 + }
  909 +
  910 + var tfoot = Calendar.createElement("tfoot", table);
  911 +
  912 + row = Calendar.createElement("tr", tfoot);
  913 + row.className = "footrow";
  914 +
  915 + cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
  916 + cell.className = "ttip";
  917 + if (this.isPopup) {
  918 + cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
  919 + cell.style.cursor = "move";
  920 + }
  921 + this.tooltips = cell;
  922 +
  923 + div = Calendar.createElement("div", this.element);
  924 + this.monthsCombo = div;
  925 + div.className = "combo";
  926 + for (i = 0; i < Calendar._MN.length; ++i) {
  927 + var mn = Calendar.createElement("div");
  928 + mn.className = Calendar.is_ie ? "label-IEfix" : "label";
  929 + mn.month = i;
  930 + mn.appendChild(document.createTextNode(Calendar._SMN[i]));
  931 + div.appendChild(mn);
  932 + }
  933 +
  934 + div = Calendar.createElement("div", this.element);
  935 + this.yearsCombo = div;
  936 + div.className = "combo";
  937 + for (i = 12; i > 0; --i) {
  938 + var yr = Calendar.createElement("div");
  939 + yr.className = Calendar.is_ie ? "label-IEfix" : "label";
  940 + yr.appendChild(document.createTextNode(""));
  941 + div.appendChild(yr);
  942 + }
  943 +
  944 + this._init(this.mondayFirst, this.date);
  945 + parent.appendChild(this.element);
  946 +};
  947 +
  948 +/** keyboard navigation, only for popup calendars */
  949 +Calendar._keyEvent = function(ev) {
  950 + if (!window.calendar) {
  951 + return false;
  952 + }
  953 + (Calendar.is_ie) && (ev = window.event);
  954 + var cal = window.calendar;
  955 + var act = (Calendar.is_ie || ev.type == "keypress");
  956 + if (ev.ctrlKey) {
  957 + switch (ev.keyCode) {
  958 + case 37: // KEY left
  959 + act && Calendar.cellClick(cal._nav_pm);
  960 + break;
  961 + case 38: // KEY up
  962 + act && Calendar.cellClick(cal._nav_py);
  963 + break;
  964 + case 39: // KEY right
  965 + act && Calendar.cellClick(cal._nav_nm);
  966 + break;
  967 + case 40: // KEY down
  968 + act && Calendar.cellClick(cal._nav_ny);
  969 + break;
  970 + default:
  971 + return false;
  972 + }
  973 + } else switch (ev.keyCode) {
  974 + case 32: // KEY space (now)
  975 + Calendar.cellClick(cal._nav_now);
  976 + break;
  977 + case 27: // KEY esc
  978 + act && cal.hide();
  979 + break;
  980 + case 37: // KEY left
  981 + case 38: // KEY up
  982 + case 39: // KEY right
  983 + case 40: // KEY down
  984 + if (act) {
  985 + var date = cal.date.getDate() - 1;
  986 + var el = cal.currentDateEl;
  987 + var ne = null;
  988 + var prev = (ev.keyCode == 37) || (ev.keyCode == 38);
  989 + switch (ev.keyCode) {
  990 + case 37: // KEY left
  991 + (--date >= 0) && (ne = cal.ar_days[date]);
  992 + break;
  993 + case 38: // KEY up
  994 + date -= 7;
  995 + (date >= 0) && (ne = cal.ar_days[date]);
  996 + break;
  997 + case 39: // KEY right
  998 + (++date < cal.ar_days.length) && (ne = cal.ar_days[date]);
  999 + break;
  1000 + case 40: // KEY down
  1001 + date += 7;
  1002 + (date < cal.ar_days.length) && (ne = cal.ar_days[date]);
  1003 + break;
  1004 + }
  1005 + if (!ne) {
  1006 + if (prev) {
  1007 + Calendar.cellClick(cal._nav_pm);
  1008 + } else {
  1009 + Calendar.cellClick(cal._nav_nm);
  1010 + }
  1011 + date = (prev) ? cal.date.getMonthDays() : 1;
  1012 + el = cal.currentDateEl;
  1013 + ne = cal.ar_days[date - 1];
  1014 + }
  1015 + Calendar.removeClass(el, "selected");
  1016 + Calendar.addClass(ne, "selected");
  1017 + cal.date.setDate(ne.caldate);
  1018 + cal.callHandler();
  1019 + cal.currentDateEl = ne;
  1020 + }
  1021 + break;
  1022 + case 13: // KEY enter
  1023 + if (act) {
  1024 + cal.callHandler();
  1025 + cal.hide();
  1026 + }
  1027 + break;
  1028 + default:
  1029 + return false;
  1030 + }
  1031 + return Calendar.stopEvent(ev);
  1032 +};
  1033 +
  1034 +/**
  1035 + * (RE)Initializes the calendar to the given date and style (if mondayFirst is
  1036 + * true it makes Monday the first day of week, otherwise the weeks start on
  1037 + * Sunday.
  1038 + */
  1039 +Calendar.prototype._init = function (mondayFirst, date) {
  1040 + var today = new Date();
  1041 + var year = date.getFullYear();
  1042 + if (year < this.minYear) {
  1043 + year = this.minYear;
  1044 + date.setFullYear(year);
  1045 + } else if (year > this.maxYear) {
  1046 + year = this.maxYear;
  1047 + date.setFullYear(year);
  1048 + }
  1049 + this.mondayFirst = mondayFirst;
  1050 + this.date = new Date(date);
  1051 + var month = date.getMonth();
  1052 + var mday = date.getDate();
  1053 + var no_days = date.getMonthDays();
  1054 + date.setDate(1);
  1055 + var wday = date.getDay();
  1056 + var MON = mondayFirst ? 1 : 0;
  1057 + var SAT = mondayFirst ? 5 : 6;
  1058 + var SUN = mondayFirst ? 6 : 0;
  1059 + if (mondayFirst) {
  1060 + wday = (wday > 0) ? (wday - 1) : 6;
  1061 + }
  1062 + var iday = 1;
  1063 + var row = this.tbody.firstChild;
  1064 + var MN = Calendar._SMN[month];
  1065 + var hasToday = ((today.getFullYear() == year) && (today.getMonth() == month));
  1066 + var todayDate = today.getDate();
  1067 + var week_number = date.getWeekNumber();
  1068 + var ar_days = new Array();
  1069 + for (var i = 0; i < 6; ++i) {
  1070 + if (iday > no_days) {
  1071 + row.className = "emptyrow";
  1072 + row = row.nextSibling;
  1073 + continue;
  1074 + }
  1075 + var cell = row.firstChild;
  1076 + if (this.weekNumbers) {
  1077 + cell.className = "day wn";
  1078 + cell.firstChild.data = week_number;
  1079 + cell = cell.nextSibling;
  1080 + }
  1081 + ++week_number;
  1082 + row.className = "daysrow";
  1083 + for (var j = 0; j < 7; ++j) {
  1084 + cell.className = "day";
  1085 + if ((!i && j < wday) || iday > no_days) {
  1086 + // cell.className = "emptycell";
  1087 + cell.innerHTML = "&nbsp;";
  1088 + cell.disabled = true;
  1089 + cell = cell.nextSibling;
  1090 + continue;
  1091 + }
  1092 + cell.disabled = false;
  1093 + cell.firstChild.data = iday;
  1094 + if (typeof this.getDateStatus == "function") {
  1095 + date.setDate(iday);
  1096 + var status = this.getDateStatus(date, year, month, iday);
  1097 + if (status === true) {
  1098 + cell.className += " disabled";
  1099 + cell.disabled = true;
  1100 + } else {
  1101 + if (/disabled/i.test(status))
  1102 + cell.disabled = true;
  1103 + cell.className += " " + status;
  1104 + }
  1105 + }
  1106 + if (!cell.disabled) {
  1107 + ar_days[ar_days.length] = cell;
  1108 + cell.caldate = iday;
  1109 + cell.ttip = "_";
  1110 + if (iday == mday) {
  1111 + cell.className += " selected";
  1112 + this.currentDateEl = cell;
  1113 + }
  1114 + if (hasToday && (iday == todayDate)) {
  1115 + cell.className += " today";
  1116 + cell.ttip += Calendar._TT["PART_TODAY"];
  1117 + }
  1118 + if (wday == SAT || wday == SUN) {
  1119 + cell.className += " weekend";
  1120 + }
  1121 + }
  1122 + ++iday;
  1123 + ((++wday) ^ 7) || (wday = 0);
  1124 + cell = cell.nextSibling;
  1125 + }
  1126 + row = row.nextSibling;
  1127 + }
  1128 + this.ar_days = ar_days;
  1129 + this.title.firstChild.data = Calendar._MN[month] + ", " + year;
  1130 + this.onSetTime();
  1131 + // PROFILE
  1132 + // this.tooltips.firstChild.data = "Generated in " + ((new Date()) - today) + " ms";
  1133 +};
  1134 +
  1135 +/**
  1136 + * Calls _init function above for going to a certain date (but only if the
  1137 + * date is different than the currently selected one).
  1138 + */
  1139 +Calendar.prototype.setDate = function (date) {
  1140 + if (!date.equalsTo(this.date)) {
  1141 + this._init(this.mondayFirst, date);
  1142 + }
  1143 +};
  1144 +
  1145 +/**
  1146 + * Refreshes the calendar. Useful if the "disabledHandler" function is
  1147 + * dynamic, meaning that the list of disabled date can change at runtime.
  1148 + * Just * call this function if you think that the list of disabled dates
  1149 + * should * change.
  1150 + */
  1151 +Calendar.prototype.refresh = function () {
  1152 + this._init(this.mondayFirst, this.date);
  1153 +};
  1154 +
  1155 +/** Modifies the "mondayFirst" parameter (EU/US style). */
  1156 +Calendar.prototype.setMondayFirst = function (mondayFirst) {
  1157 + this._init(mondayFirst, this.date);
  1158 + this._displayWeekdays();
  1159 +};
  1160 +
  1161 +/**
  1162 + * Allows customization of what dates are enabled. The "unaryFunction"
  1163 + * parameter must be a function object that receives the date (as a JS Date
  1164 + * object) and returns a boolean value. If the returned value is true then
  1165 + * the passed date will be marked as disabled.
  1166 + */
  1167 +Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
  1168 + this.getDateStatus = unaryFunction;
  1169 +};
  1170 +
  1171 +/** Customization of allowed year range for the calendar. */
  1172 +Calendar.prototype.setRange = function (a, z) {
  1173 + this.minYear = a;
  1174 + this.maxYear = z;
  1175 +};
  1176 +
  1177 +/** Calls the first user handler (selectedHandler). */
  1178 +Calendar.prototype.callHandler = function () {
  1179 + if (this.onSelected) {
  1180 + this.onSelected(this, this.date.print(this.dateFormat));
  1181 + }
  1182 +};
  1183 +
  1184 +/** Calls the second user handler (closeHandler). */
  1185 +Calendar.prototype.callCloseHandler = function () {
  1186 + if (this.onClose) {
  1187 + this.onClose(this);
  1188 + }
  1189 + this.hideShowCovered();
  1190 +};
  1191 +
  1192 +/** Removes the calendar object from the DOM tree and destroys it. */
  1193 +Calendar.prototype.destroy = function () {
  1194 + var el = this.element.parentNode;
  1195 + el.removeChild(this.element);
  1196 + Calendar._C = null;
  1197 + window.calendar = null;
  1198 +};
  1199 +
  1200 +/**
  1201 + * Moves the calendar element to a different section in the DOM tree (changes
  1202 + * its parent).
  1203 + */
  1204 +Calendar.prototype.reparent = function (new_parent) {
  1205 + var el = this.element;
  1206 + el.parentNode.removeChild(el);
  1207 + new_parent.appendChild(el);
  1208 +};
  1209 +
  1210 +// This gets called when the user presses a mouse button anywhere in the
  1211 +// document, if the calendar is shown. If the click was outside the open
  1212 +// calendar this function closes it.
  1213 +Calendar._checkCalendar = function(ev) {
  1214 + if (!window.calendar) {
  1215 + return false;
  1216 + }
  1217 + var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
  1218 + for (; el != null && el != calendar.element; el = el.parentNode);
  1219 + if (el == null) {
  1220 + // calls closeHandler which should hide the calendar.
  1221 + window.calendar.callCloseHandler();
  1222 + return Calendar.stopEvent(ev);
  1223 + }
  1224 +};
  1225 +
  1226 +/** Shows the calendar. */
  1227 +Calendar.prototype.show = function () {
  1228 + var rows = this.table.getElementsByTagName("tr");
  1229 + for (var i = rows.length; i > 0;) {
  1230 + var row = rows[--i];
  1231 + Calendar.removeClass(row, "rowhilite");
  1232 + var cells = row.getElementsByTagName("td");
  1233 + for (var j = cells.length; j > 0;) {
  1234 + var cell = cells[--j];
  1235 + Calendar.removeClass(cell, "hilite");
  1236 + Calendar.removeClass(cell, "active");
  1237 + }
  1238 + }
  1239 + this.element.style.display = "block";
  1240 + this.hidden = false;
  1241 + if (this.isPopup) {
  1242 + window.calendar = this;
  1243 + Calendar.addEvent(document, "keydown", Calendar._keyEvent);
  1244 + Calendar.addEvent(document, "keypress", Calendar._keyEvent);
  1245 + Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
  1246 + }
  1247 + this.hideShowCovered();
  1248 +};
  1249 +
  1250 +/**
  1251 + * Hides the calendar. Also removes any "hilite" from the class of any TD
  1252 + * element.
  1253 + */
  1254 +Calendar.prototype.hide = function () {
  1255 + if (this.isPopup) {
  1256 + Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
  1257 + Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
  1258 + Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
  1259 + }
  1260 + this.element.style.display = "none";
  1261 + this.hidden = true;
  1262 + this.hideShowCovered();
  1263 +};
  1264 +
  1265 +/**
  1266 + * Shows the calendar at a given absolute position (beware that, depending on
  1267 + * the calendar element style -- position property -- this might be relative
  1268 + * to the parent's containing rectangle).
  1269 + */
  1270 +Calendar.prototype.showAt = function (x, y) {
  1271 + var s = this.element.style;
  1272 + s.left = x + "px";
  1273 + s.top = y + "px";
  1274 + this.show();
  1275 +};
  1276 +
  1277 +/** Shows the calendar near a given element. */
  1278 +Calendar.prototype.showAtElement = function (el, opts) {
  1279 + var self = this;
  1280 + var p = Calendar.getAbsolutePos(el);
  1281 + if (!opts || typeof opts != "string") {
  1282 + this.showAt(p.x, p.y + el.offsetHeight);
  1283 + return true;
  1284 + }
  1285 + this.element.style.display = "block";
  1286 + Calendar.continuation_for_the_fucking_khtml_browser = function() {
  1287 + var w = self.element.offsetWidth;
  1288 + var h = self.element.offsetHeight;
  1289 + self.element.style.display = "none";
  1290 + var valign = opts.substr(0, 1);
  1291 + var halign = "l";
  1292 + if (opts.length > 1) {
  1293 + halign = opts.substr(1, 1);
  1294 + }
  1295 + // vertical alignment
  1296 + switch (valign) {
  1297 + case "T": p.y -= h; break;
  1298 + case "B": p.y += el.offsetHeight; break;
  1299 + case "C": p.y += (el.offsetHeight - h) / 2; break;
  1300 + case "t": p.y += el.offsetHeight - h; break;
  1301 + case "b": break; // already there
  1302 + }
  1303 + // horizontal alignment
  1304 + switch (halign) {
  1305 + case "L": p.x -= w; break;
  1306 + case "R": p.x += el.offsetWidth; break;
  1307 + case "C": p.x += (el.offsetWidth - w) / 2; break;
  1308 + case "r": p.x += el.offsetWidth - w; break;
  1309 + case "l": break; // already there
  1310 + }
  1311 + self.showAt(p.x, p.y);
  1312 + };
  1313 + if (Calendar.is_khtml)
  1314 + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
  1315 + else
  1316 + Calendar.continuation_for_the_fucking_khtml_browser();
  1317 +};
  1318 +
  1319 +/** Customizes the date format. */
  1320 +Calendar.prototype.setDateFormat = function (str) {
  1321 + this.dateFormat = str;
  1322 +};
  1323 +
  1324 +/** Customizes the tooltip date format. */
  1325 +Calendar.prototype.setTtDateFormat = function (str) {
  1326 + this.ttDateFormat = str;
  1327 +};
  1328 +
  1329 +/**
  1330 + * Tries to identify the date represented in a string. If successful it also
  1331 + * calls this.setDate which moves the calendar to the given date.
  1332 + */
  1333 +Calendar.prototype.parseDate = function (str, fmt) {
  1334 + var y = 0;
  1335 + var m = -1;
  1336 + var d = 0;
  1337 + var a = str.split(/\W+/);
  1338 + if (!fmt) {
  1339 + fmt = this.dateFormat;
  1340 + }
  1341 + var b = [];
  1342 + fmt.replace(/(%.)/g, function(str, par) {
  1343 + return b[b.length] = par;
  1344 + });
  1345 + var i = 0, j = 0;
  1346 + var hr = 0;
  1347 + var min = 0;
  1348 + for (i = 0; i < a.length; ++i) {
  1349 + if (b[i] == "%a" || b[i] == "%A") {
  1350 + continue;
  1351 + }
  1352 + if (b[i] == "%d" || b[i] == "%e") {
  1353 + d = parseInt(a[i], 10);
  1354 + }
  1355 + if (b[i] == "%m") {
  1356 + m = parseInt(a[i], 10) - 1;
  1357 + }
  1358 + if (b[i] == "%Y" || b[i] == "%y") {
  1359 + y = parseInt(a[i], 10);
  1360 + (y < 100) && (y += (y > 29) ? 1900 : 2000);
  1361 + }
  1362 + if (b[i] == "%b" || b[i] == "%B") {
  1363 + for (j = 0; j < 12; ++j) {
  1364 + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
  1365 + }
  1366 + } else if (/%[HIkl]/.test(b[i])) {
  1367 + hr = parseInt(a[i], 10);
  1368 + } else if (/%[pP]/.test(b[i])) {
  1369 + if (/pm/i.test(a[i]) && hr < 12)
  1370 + hr += 12;
  1371 + } else if (b[i] == "%M") {
  1372 + min = parseInt(a[i], 10);
  1373 + }
  1374 + }
  1375 + if (y != 0 && m != -1 && d != 0) {
  1376 + this.setDate(new Date(y, m, d, hr, min, 0));
  1377 + return;
  1378 + }
  1379 + y = 0; m = -1; d = 0;
  1380 + for (i = 0; i < a.length; ++i) {
  1381 + if (a[i].search(/[a-zA-Z]+/) != -1) {
  1382 + var t = -1;
  1383 + for (j = 0; j < 12; ++j) {
  1384 + if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
  1385 + }
  1386 + if (t != -1) {
  1387 + if (m != -1) {
  1388 + d = m+1;
  1389 + }
  1390 + m = t;
  1391 + }
  1392 + } else if (parseInt(a[i], 10) <= 12 && m == -1) {
  1393 + m = a[i]-1;
  1394 + } else if (parseInt(a[i], 10) > 31 && y == 0) {
  1395 + y = parseInt(a[i], 10);
  1396 + (y < 100) && (y += (y > 29) ? 1900 : 2000);
  1397 + } else if (d == 0) {
  1398 + d = a[i];
  1399 + }
  1400 + }
  1401 + if (y == 0) {
  1402 + var today = new Date();
  1403 + y = today.getFullYear();
  1404 + }
  1405 + if (m != -1 && d != 0) {
  1406 + this.setDate(new Date(y, m, d, hr, min, 0));
  1407 + }
  1408 +};
  1409 +
  1410 +Calendar.prototype.hideShowCovered = function () {
  1411 + var self = this;
  1412 + Calendar.continuation_for_the_fucking_khtml_browser = function() {
  1413 + function getVisib(obj){
  1414 + var value = obj.style.visibility;
  1415 + if (!value) {
  1416 + if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
  1417 + if (!Calendar.is_khtml)
  1418 + value = document.defaultView.
  1419 + getComputedStyle(obj, "").getPropertyValue("visibility");
  1420 + else
  1421 + value = '';
  1422 + } else if (obj.currentStyle) { // IE
  1423 + value = obj.currentStyle.visibility;
  1424 + } else
  1425 + value = '';
  1426 + }
  1427 + return value;
  1428 + };
  1429 +
  1430 + var tags = new Array("applet", "iframe", "select");
  1431 + var el = self.element;
  1432 +
  1433 + var p = Calendar.getAbsolutePos(el);
  1434 + var EX1 = p.x;
  1435 + var EX2 = el.offsetWidth + EX1;
  1436 + var EY1 = p.y;
  1437 + var EY2 = el.offsetHeight + EY1;
  1438 +
  1439 + for (var k = tags.length; k > 0; ) {
  1440 + var ar = document.getElementsByTagName(tags[--k]);
  1441 + var cc = null;
  1442 +
  1443 + for (var i = ar.length; i > 0;) {
  1444 + cc = ar[--i];
  1445 +
  1446 + p = Calendar.getAbsolutePos(cc);
  1447 + var CX1 = p.x;
  1448 + var CX2 = cc.offsetWidth + CX1;
  1449 + var CY1 = p.y;
  1450 + var CY2 = cc.offsetHeight + CY1;
  1451 +
  1452 + if (self.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
  1453 + if (!cc.__msh_save_visibility) {
  1454 + cc.__msh_save_visibility = getVisib(cc);
  1455 + }
  1456 + cc.style.visibility = cc.__msh_save_visibility;
  1457 + } else {
  1458 + if (!cc.__msh_save_visibility) {
  1459 + cc.__msh_save_visibility = getVisib(cc);
  1460 + }
  1461 + cc.style.visibility = "hidden";
  1462 + }
  1463 + }
  1464 + }
  1465 + };
  1466 + if (Calendar.is_khtml)
  1467 + setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
  1468 + else
  1469 + Calendar.continuation_for_the_fucking_khtml_browser();
  1470 +};
  1471 +
  1472 +/** Internal function; it displays the bar with the names of the weekday. */
  1473 +Calendar.prototype._displayWeekdays = function () {
  1474 + var MON = this.mondayFirst ? 0 : 1;
  1475 + var SUN = this.mondayFirst ? 6 : 0;
  1476 + var SAT = this.mondayFirst ? 5 : 6;
  1477 + var cell = this.firstdayname;
  1478 + for (var i = 0; i < 7; ++i) {
  1479 + cell.className = "day name";
  1480 + if (!i) {
  1481 + cell.ttip = this.mondayFirst ? Calendar._TT["SUN_FIRST"] : Calendar._TT["MON_FIRST"];
  1482 + cell.navtype = 100;
  1483 + cell.calendar = this;
  1484 + Calendar._add_evs(cell);
  1485 + }
  1486 + if (i == SUN || i == SAT) {
  1487 + Calendar.addClass(cell, "weekend");
  1488 + }
  1489 + cell.firstChild.data = Calendar._SDN[i + 1 - MON];
  1490 + cell = cell.nextSibling;
  1491 + }
  1492 +};
  1493 +
  1494 +/** Internal function. Hides all combo boxes that might be displayed. */
  1495 +Calendar.prototype._hideCombos = function () {
  1496 + this.monthsCombo.style.display = "none";
  1497 + this.yearsCombo.style.display = "none";
  1498 +};
  1499 +
  1500 +/** Internal function. Starts dragging the element. */
  1501 +Calendar.prototype._dragStart = function (ev) {
  1502 + if (this.dragging) {
  1503 + return;
  1504 + }
  1505 + this.dragging = true;
  1506 + var posX;
  1507 + var posY;
  1508 + if (Calendar.is_ie) {
  1509 + posY = window.event.clientY + document.body.scrollTop;
  1510 + posX = window.event.clientX + document.body.scrollLeft;
  1511 + } else {
  1512 + posY = ev.clientY + window.scrollY;
  1513 + posX = ev.clientX + window.scrollX;
  1514 + }
  1515 + var st = this.element.style;
  1516 + this.xOffs = posX - parseInt(st.left);
  1517 + this.yOffs = posY - parseInt(st.top);
  1518 + with (Calendar) {
  1519 + addEvent(document, "mousemove", calDragIt);
  1520 + addEvent(document, "mouseover", stopEvent);
  1521 + addEvent(document, "mouseup", calDragEnd);
  1522 + }
  1523 +};
  1524 +
  1525 +// BEGIN: DATE OBJECT PATCHES
  1526 +
  1527 +/** Adds the number of days array to the Date object. */
  1528 +Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
  1529 +
  1530 +/** Constants used for time computations */
  1531 +Date.SECOND = 1000 /* milliseconds */;
  1532 +Date.MINUTE = 60 * Date.SECOND;
  1533 +Date.HOUR = 60 * Date.MINUTE;
  1534 +Date.DAY = 24 * Date.HOUR;
  1535 +Date.WEEK = 7 * Date.DAY;
  1536 +
  1537 +/** Returns the number of days in the current month */
  1538 +Date.prototype.getMonthDays = function(month) {
  1539 + var year = this.getFullYear();
  1540 + if (typeof month == "undefined") {
  1541 + month = this.getMonth();
  1542 + }
  1543 + if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
  1544 + return 29;
  1545 + } else {
  1546 + return Date._MD[month];
  1547 + }
  1548 +};
  1549 +
  1550 +/** Returns the number of day in the year. */
  1551 +Date.prototype.getDayOfYear = function() {
  1552 + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
  1553 + var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0);
  1554 + var time = now - then;
  1555 + return Math.floor(time / Date.DAY);
  1556 +};
  1557 +
  1558 +/** Returns the number of the week in year, as defined in ISO 8601. */
  1559 +Date.prototype.getWeekNumber = function() {
  1560 + var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
  1561 + var then = new Date(this.getFullYear(), 0, 1, 0, 0, 0);
  1562 + var time = now - then;
  1563 + var day = then.getDay(); // 0 means Sunday
  1564 + if (day == 0) day = 7;
  1565 + (day > 4) && (day -= 4) || (day += 3);
  1566 + return Math.round(((time / Date.DAY) + day) / 7);
  1567 +};
  1568 +
  1569 +/** Checks dates equality (ignores time) */
  1570 +Date.prototype.equalsTo = function(date) {
  1571 + return ((this.getFullYear() == date.getFullYear()) &&
  1572 + (this.getMonth() == date.getMonth()) &&
  1573 + (this.getDate() == date.getDate()) &&
  1574 + (this.getHours() == date.getHours()) &&
  1575 + (this.getMinutes() == date.getMinutes()));
  1576 +};
  1577 +
  1578 +/** Prints the date in a string according to the given format. */
  1579 +Date.prototype.print = function (str) {
  1580 + var m = this.getMonth();
  1581 + var d = this.getDate();
  1582 + var y = this.getFullYear();
  1583 + var wn = this.getWeekNumber();
  1584 + var w = this.getDay();
  1585 + var s = {};
  1586 + var hr = this.getHours();
  1587 + var pm = (hr >= 12);
  1588 + var ir = (pm) ? (hr - 12) : hr;
  1589 + var dy = this.getDayOfYear();
  1590 + if (ir == 0)
  1591 + ir = 12;
  1592 + var min = this.getMinutes();
  1593 + var sec = this.getSeconds();
  1594 + s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
  1595 + s["%A"] = Calendar._DN[w]; // full weekday name
  1596 + s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
  1597 + s["%B"] = Calendar._MN[m]; // full month name
  1598 + // FIXME: %c : preferred date and time representation for the current locale
  1599 + s["%C"] = 1 + Math.floor(y / 100); // the century number
  1600 + s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
  1601 + s["%e"] = d; // the day of the month (range 1 to 31)
  1602 + // FIXME: %D : american date style: %m/%d/%y
  1603 + // FIXME: %E, %F, %G, %g, %h (man strftime)
  1604 + s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
  1605 + s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
  1606 + s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
  1607 + s["%k"] = hr; // hour, range 0 to 23 (24h format)
  1608 + s["%l"] = ir; // hour, range 1 to 12 (12h format)
  1609 + s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
  1610 + s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
  1611 + s["%n"] = "\n"; // a newline character
  1612 + s["%p"] = pm ? "PM" : "AM";
  1613 + s["%P"] = pm ? "pm" : "am";
  1614 + // FIXME: %r : the time in am/pm notation %I:%M:%S %p
  1615 + // FIXME: %R : the time in 24-hour notation %H:%M
  1616 + s["%s"] = Math.floor(this.getTime() / 1000);
  1617 + s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
  1618 + s["%t"] = "\t"; // a tab character
  1619 + // FIXME: %T : the time in 24-hour notation (%H:%M:%S)
  1620 + s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
  1621 + s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
  1622 + s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
  1623 + // FIXME: %x : preferred date representation for the current locale without the time
  1624 + // FIXME: %X : preferred time representation for the current locale without the date
  1625 + s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
  1626 + s["%Y"] = y; // year with the century
  1627 + s["%%"] = "%"; // a literal '%' character
  1628 + var re = Date._msh_formatRegexp;
  1629 + if (typeof re == "undefined") {
  1630 + var tmp = "";
  1631 + for (var i in s)
  1632 + tmp += tmp ? ("|" + i) : i;
  1633 + Date._msh_formatRegexp = re = new RegExp("(" + tmp + ")", 'g');
  1634 + }
  1635 + return str.replace(re, function(match, par) { return s[par]; });
  1636 +};
  1637 +
  1638 +// END: DATE OBJECT PATCHES
  1639 +
  1640 +// global object that remembers the calendar
  1641 +window.calendar = null;
thirdpartyjs/curvycorners/lgpl.txt 0 → 100644
  1 + GNU LESSER GENERAL PUBLIC LICENSE
  2 + Version 2.1, February 1999
  3 +
  4 + Copyright (C) 1991, 1999 Free Software Foundation, Inc.
  5 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  6 + Everyone is permitted to copy and distribute verbatim copies
  7 + of this license document, but changing it is not allowed.
  8 +
  9 +[This is the first released version of the Lesser GPL. It also counts
  10 + as the successor of the GNU Library Public License, version 2, hence
  11 + the version number 2.1.]
  12 +
  13 + Preamble
  14 +
  15 + The licenses for most software are designed to take away your
  16 +freedom to share and change it. By contrast, the GNU General Public
  17 +Licenses are intended to guarantee your freedom to share and change
  18 +free software--to make sure the software is free for all its users.
  19 +
  20 + This license, the Lesser General Public License, applies to some
  21 +specially designated software packages--typically libraries--of the
  22 +Free Software Foundation and other authors who decide to use it. You
  23 +can use it too, but we suggest you first think carefully about whether
  24 +this license or the ordinary General Public License is the better
  25 +strategy to use in any particular case, based on the explanations below.
  26 +
  27 + When we speak of free software, we are referring to freedom of use,
  28 +not price. Our General Public Licenses are designed to make sure that
  29 +you have the freedom to distribute copies of free software (and charge
  30 +for this service if you wish); that you receive source code or can get
  31 +it if you want it; that you can change the software and use pieces of
  32 +it in new free programs; and that you are informed that you can do
  33 +these things.
  34 +
  35 + To protect your rights, we need to make restrictions that forbid
  36 +distributors to deny you these rights or to ask you to surrender these
  37 +rights. These restrictions translate to certain responsibilities for
  38 +you if you distribute copies of the library or if you modify it.
  39 +
  40 + For example, if you distribute copies of the library, whether gratis
  41 +or for a fee, you must give the recipients all the rights that we gave
  42 +you. You must make sure that they, too, receive or can get the source
  43 +code. If you link other code with the library, you must provide
  44 +complete object files to the recipients, so that they can relink them
  45 +with the library after making changes to the library and recompiling
  46 +it. And you must show them these terms so they know their rights.
  47 +
  48 + We protect your rights with a two-step method: (1) we copyright the
  49 +library, and (2) we offer you this license, which gives you legal
  50 +permission to copy, distribute and/or modify the library.
  51 +
  52 + To protect each distributor, we want to make it very clear that
  53 +there is no warranty for the free library. Also, if the library is
  54 +modified by someone else and passed on, the recipients should know
  55 +that what they have is not the original version, so that the original
  56 +author's reputation will not be affected by problems that might be
  57 +introduced by others.
  58 +
  59 + Finally, software patents pose a constant threat to the existence of
  60 +any free program. We wish to make sure that a company cannot
  61 +effectively restrict the users of a free program by obtaining a
  62 +restrictive license from a patent holder. Therefore, we insist that
  63 +any patent license obtained for a version of the library must be
  64 +consistent with the full freedom of use specified in this license.
  65 +
  66 + Most GNU software, including some libraries, is covered by the
  67 +ordinary GNU General Public License. This license, the GNU Lesser
  68 +General Public License, applies to certain designated libraries, and
  69 +is quite different from the ordinary General Public License. We use
  70 +this license for certain libraries in order to permit linking those
  71 +libraries into non-free programs.
  72 +
  73 + When a program is linked with a library, whether statically or using
  74 +a shared library, the combination of the two is legally speaking a
  75 +combined work, a derivative of the original library. The ordinary
  76 +General Public License therefore permits such linking only if the
  77 +entire combination fits its criteria of freedom. The Lesser General
  78 +Public License permits more lax criteria for linking other code with
  79 +the library.
  80 +
  81 + We call this license the "Lesser" General Public License because it
  82 +does Less to protect the user's freedom than the ordinary General
  83 +Public License. It also provides other free software developers Less
  84 +of an advantage over competing non-free programs. These disadvantages
  85 +are the reason we use the ordinary General Public License for many
  86 +libraries. However, the Lesser license provides advantages in certain
  87 +special circumstances.
  88 +
  89 + For example, on rare occasions, there may be a special need to
  90 +encourage the widest possible use of a certain library, so that it becomes
  91 +a de-facto standard. To achieve this, non-free programs must be
  92 +allowed to use the library. A more frequent case is that a free
  93 +library does the same job as widely used non-free libraries. In this
  94 +case, there is little to gain by limiting the free library to free
  95 +software only, so we use the Lesser General Public License.
  96 +
  97 + In other cases, permission to use a particular library in non-free
  98 +programs enables a greater number of people to use a large body of
  99 +free software. For example, permission to use the GNU C Library in
  100 +non-free programs enables many more people to use the whole GNU
  101 +operating system, as well as its variant, the GNU/Linux operating
  102 +system.
  103 +
  104 + Although the Lesser General Public License is Less protective of the
  105 +users' freedom, it does ensure that the user of a program that is
  106 +linked with the Library has the freedom and the wherewithal to run
  107 +that program using a modified version of the Library.
  108 +
  109 + The precise terms and conditions for copying, distribution and
  110 +modification follow. Pay close attention to the difference between a
  111 +"work based on the library" and a "work that uses the library". The
  112 +former contains code derived from the library, whereas the latter must
  113 +be combined with the library in order to run.
  114 +
  115 + GNU LESSER GENERAL PUBLIC LICENSE
  116 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  117 +
  118 + 0. This License Agreement applies to any software library or other
  119 +program which contains a notice placed by the copyright holder or
  120 +other authorized party saying it may be distributed under the terms of
  121 +this Lesser General Public License (also called "this License").
  122 +Each licensee is addressed as "you".
  123 +
  124 + A "library" means a collection of software functions and/or data
  125 +prepared so as to be conveniently linked with application programs
  126 +(which use some of those functions and data) to form executables.
  127 +
  128 + The "Library", below, refers to any such software library or work
  129 +which has been distributed under these terms. A "work based on the
  130 +Library" means either the Library or any derivative work under
  131 +copyright law: that is to say, a work containing the Library or a
  132 +portion of it, either verbatim or with modifications and/or translated
  133 +straightforwardly into another language. (Hereinafter, translation is
  134 +included without limitation in the term "modification".)
  135 +
  136 + "Source code" for a work means the preferred form of the work for
  137 +making modifications to it. For a library, complete source code means
  138 +all the source code for all modules it contains, plus any associated
  139 +interface definition files, plus the scripts used to control compilation
  140 +and installation of the library.
  141 +
  142 + Activities other than copying, distribution and modification are not
  143 +covered by this License; they are outside its scope. The act of
  144 +running a program using the Library is not restricted, and output from
  145 +such a program is covered only if its contents constitute a work based
  146 +on the Library (independent of the use of the Library in a tool for
  147 +writing it). Whether that is true depends on what the Library does
  148 +and what the program that uses the Library does.
  149 +
  150 + 1. You may copy and distribute verbatim copies of the Library's
  151 +complete source code as you receive it, in any medium, provided that
  152 +you conspicuously and appropriately publish on each copy an
  153 +appropriate copyright notice and disclaimer of warranty; keep intact
  154 +all the notices that refer to this License and to the absence of any
  155 +warranty; and distribute a copy of this License along with the
  156 +Library.
  157 +
  158 + You may charge a fee for the physical act of transferring a copy,
  159 +and you may at your option offer warranty protection in exchange for a
  160 +fee.
  161 +
  162 + 2. You may modify your copy or copies of the Library or any portion
  163 +of it, thus forming a work based on the Library, and copy and
  164 +distribute such modifications or work under the terms of Section 1
  165 +above, provided that you also meet all of these conditions:
  166 +
  167 + a) The modified work must itself be a software library.
  168 +
  169 + b) You must cause the files modified to carry prominent notices
  170 + stating that you changed the files and the date of any change.
  171 +
  172 + c) You must cause the whole of the work to be licensed at no
  173 + charge to all third parties under the terms of this License.
  174 +
  175 + d) If a facility in the modified Library refers to a function or a
  176 + table of data to be supplied by an application program that uses
  177 + the facility, other than as an argument passed when the facility
  178 + is invoked, then you must make a good faith effort to ensure that,
  179 + in the event an application does not supply such function or
  180 + table, the facility still operates, and performs whatever part of
  181 + its purpose remains meaningful.
  182 +
  183 + (For example, a function in a library to compute square roots has
  184 + a purpose that is entirely well-defined independent of the
  185 + application. Therefore, Subsection 2d requires that any
  186 + application-supplied function or table used by this function must
  187 + be optional: if the application does not supply it, the square
  188 + root function must still compute square roots.)
  189 +
  190 +These requirements apply to the modified work as a whole. If
  191 +identifiable sections of that work are not derived from the Library,
  192 +and can be reasonably considered independent and separate works in
  193 +themselves, then this License, and its terms, do not apply to those
  194 +sections when you distribute them as separate works. But when you
  195 +distribute the same sections as part of a whole which is a work based
  196 +on the Library, the distribution of the whole must be on the terms of
  197 +this License, whose permissions for other licensees extend to the
  198 +entire whole, and thus to each and every part regardless of who wrote
  199 +it.
  200 +
  201 +Thus, it is not the intent of this section to claim rights or contest
  202 +your rights to work written entirely by you; rather, the intent is to
  203 +exercise the right to control the distribution of derivative or
  204 +collective works based on the Library.
  205 +
  206 +In addition, mere aggregation of another work not based on the Library
  207 +with the Library (or with a work based on the Library) on a volume of
  208 +a storage or distribution medium does not bring the other work under
  209 +the scope of this License.
  210 +
  211 + 3. You may opt to apply the terms of the ordinary GNU General Public
  212 +License instead of this License to a given copy of the Library. To do
  213 +this, you must alter all the notices that refer to this License, so
  214 +that they refer to the ordinary GNU General Public License, version 2,
  215 +instead of to this License. (If a newer version than version 2 of the
  216 +ordinary GNU General Public License has appeared, then you can specify
  217 +that version instead if you wish.) Do not make any other change in
  218 +these notices.
  219 +
  220 + Once this change is made in a given copy, it is irreversible for
  221 +that copy, so the ordinary GNU General Public License applies to all
  222 +subsequent copies and derivative works made from that copy.
  223 +
  224 + This option is useful when you wish to copy part of the code of
  225 +the Library into a program that is not a library.
  226 +
  227 + 4. You may copy and distribute the Library (or a portion or
  228 +derivative of it, under Section 2) in object code or executable form
  229 +under the terms of Sections 1 and 2 above provided that you accompany
  230 +it with the complete corresponding machine-readable source code, which
  231 +must be distributed under the terms of Sections 1 and 2 above on a
  232 +medium customarily used for software interchange.
  233 +
  234 + If distribution of object code is made by offering access to copy
  235 +from a designated place, then offering equivalent access to copy the
  236 +source code from the same place satisfies the requirement to
  237 +distribute the source code, even though third parties are not
  238 +compelled to copy the source along with the object code.
  239 +
  240 + 5. A program that contains no derivative of any portion of the
  241 +Library, but is designed to work with the Library by being compiled or
  242 +linked with it, is called a "work that uses the Library". Such a
  243 +work, in isolation, is not a derivative work of the Library, and
  244 +therefore falls outside the scope of this License.
  245 +
  246 + However, linking a "work that uses the Library" with the Library
  247 +creates an executable that is a derivative of the Library (because it
  248 +contains portions of the Library), rather than a "work that uses the
  249 +library". The executable is therefore covered by this License.
  250 +Section 6 states terms for distribution of such executables.
  251 +
  252 + When a "work that uses the Library" uses material from a header file
  253 +that is part of the Library, the object code for the work may be a
  254 +derivative work of the Library even though the source code is not.
  255 +Whether this is true is especially significant if the work can be
  256 +linked without the Library, or if the work is itself a library. The
  257 +threshold for this to be true is not precisely defined by law.
  258 +
  259 + If such an object file uses only numerical parameters, data
  260 +structure layouts and accessors, and small macros and small inline
  261 +functions (ten lines or less in length), then the use of the object
  262 +file is unrestricted, regardless of whether it is legally a derivative
  263 +work. (Executables containing this object code plus portions of the
  264 +Library will still fall under Section 6.)
  265 +
  266 + Otherwise, if the work is a derivative of the Library, you may
  267 +distribute the object code for the work under the terms of Section 6.
  268 +Any executables containing that work also fall under Section 6,
  269 +whether or not they are linked directly with the Library itself.
  270 +
  271 + 6. As an exception to the Sections above, you may also combine or
  272 +link a "work that uses the Library" with the Library to produce a
  273 +work containing portions of the Library, and distribute that work
  274 +under terms of your choice, provided that the terms permit
  275 +modification of the work for the customer's own use and reverse
  276 +engineering for debugging such modifications.
  277 +
  278 + You must give prominent notice with each copy of the work that the
  279 +Library is used in it and that the Library and its use are covered by
  280 +this License. You must supply a copy of this License. If the work
  281 +during execution displays copyright notices, you must include the
  282 +copyright notice for the Library among them, as well as a reference
  283 +directing the user to the copy of this License. Also, you must do one
  284 +of these things:
  285 +
  286 + a) Accompany the work with the complete corresponding
  287 + machine-readable source code for the Library including whatever
  288 + changes were used in the work (which must be distributed under
  289 + Sections 1 and 2 above); and, if the work is an executable linked
  290 + with the Library, with the complete machine-readable "work that
  291 + uses the Library", as object code and/or source code, so that the
  292 + user can modify the Library and then relink to produce a modified
  293 + executable containing the modified Library. (It is understood
  294 + that the user who changes the contents of definitions files in the
  295 + Library will not necessarily be able to recompile the application
  296 + to use the modified definitions.)
  297 +
  298 + b) Use a suitable shared library mechanism for linking with the
  299 + Library. A suitable mechanism is one that (1) uses at run time a
  300 + copy of the library already present on the user's computer system,
  301 + rather than copying library functions into the executable, and (2)
  302 + will operate properly with a modified version of the library, if
  303 + the user installs one, as long as the modified version is
  304 + interface-compatible with the version that the work was made with.
  305 +
  306 + c) Accompany the work with a written offer, valid for at
  307 + least three years, to give the same user the materials
  308 + specified in Subsection 6a, above, for a charge no more
  309 + than the cost of performing this distribution.
  310 +
  311 + d) If distribution of the work is made by offering access to copy
  312 + from a designated place, offer equivalent access to copy the above
  313 + specified materials from the same place.
  314 +
  315 + e) Verify that the user has already received a copy of these
  316 + materials or that you have already sent this user a copy.
  317 +
  318 + For an executable, the required form of the "work that uses the
  319 +Library" must include any data and utility programs needed for
  320 +reproducing the executable from it. However, as a special exception,
  321 +the materials to be distributed need not include anything that is
  322 +normally distributed (in either source or binary form) with the major
  323 +components (compiler, kernel, and so on) of the operating system on
  324 +which the executable runs, unless that component itself accompanies
  325 +the executable.
  326 +
  327 + It may happen that this requirement contradicts the license
  328 +restrictions of other proprietary libraries that do not normally
  329 +accompany the operating system. Such a contradiction means you cannot
  330 +use both them and the Library together in an executable that you
  331 +distribute.
  332 +
  333 + 7. You may place library facilities that are a work based on the
  334 +Library side-by-side in a single library together with other library
  335 +facilities not covered by this License, and distribute such a combined
  336 +library, provided that the separate distribution of the work based on
  337 +the Library and of the other library facilities is otherwise
  338 +permitted, and provided that you do these two things:
  339 +
  340 + a) Accompany the combined library with a copy of the same work
  341 + based on the Library, uncombined with any other library
  342 + facilities. This must be distributed under the terms of the
  343 + Sections above.
  344 +
  345 + b) Give prominent notice with the combined library of the fact
  346 + that part of it is a work based on the Library, and explaining
  347 + where to find the accompanying uncombined form of the same work.
  348 +
  349 + 8. You may not copy, modify, sublicense, link with, or distribute
  350 +the Library except as expressly provided under this License. Any
  351 +attempt otherwise to copy, modify, sublicense, link with, or
  352 +distribute the Library is void, and will automatically terminate your
  353 +rights under this License. However, parties who have received copies,
  354 +or rights, from you under this License will not have their licenses
  355 +terminated so long as such parties remain in full compliance.
  356 +
  357 + 9. You are not required to accept this License, since you have not
  358 +signed it. However, nothing else grants you permission to modify or
  359 +distribute the Library or its derivative works. These actions are
  360 +prohibited by law if you do not accept this License. Therefore, by
  361 +modifying or distributing the Library (or any work based on the
  362 +Library), you indicate your acceptance of this License to do so, and
  363 +all its terms and conditions for copying, distributing or modifying
  364 +the Library or works based on it.
  365 +
  366 + 10. Each time you redistribute the Library (or any work based on the
  367 +Library), the recipient automatically receives a license from the
  368 +original licensor to copy, distribute, link with or modify the Library
  369 +subject to these terms and conditions. You may not impose any further
  370 +restrictions on the recipients' exercise of the rights granted herein.
  371 +You are not responsible for enforcing compliance by third parties with
  372 +this License.
  373 +
  374 + 11. If, as a consequence of a court judgment or allegation of patent
  375 +infringement or for any other reason (not limited to patent issues),
  376 +conditions are imposed on you (whether by court order, agreement or
  377 +otherwise) that contradict the conditions of this License, they do not
  378 +excuse you from the conditions of this License. If you cannot
  379 +distribute so as to satisfy simultaneously your obligations under this
  380 +License and any other pertinent obligations, then as a consequence you
  381 +may not distribute the Library at all. For example, if a patent
  382 +license would not permit royalty-free redistribution of the Library by
  383 +all those who receive copies directly or indirectly through you, then
  384 +the only way you could satisfy both it and this License would be to
  385 +refrain entirely from distribution of the Library.
  386 +
  387 +If any portion of this section is held invalid or unenforceable under any
  388 +particular circumstance, the balance of the section is intended to apply,
  389 +and the section as a whole is intended to apply in other circumstances.
  390 +
  391 +It is not the purpose of this section to induce you to infringe any
  392 +patents or other property right claims or to contest validity of any
  393 +such claims; this section has the sole purpose of protecting the
  394 +integrity of the free software distribution system which is
  395 +implemented by public license practices. Many people have made
  396 +generous contributions to the wide range of software distributed
  397 +through that system in reliance on consistent application of that
  398 +system; it is up to the author/donor to decide if he or she is willing
  399 +to distribute software through any other system and a licensee cannot
  400 +impose that choice.
  401 +
  402 +This section is intended to make thoroughly clear what is believed to
  403 +be a consequence of the rest of this License.
  404 +
  405 + 12. If the distribution and/or use of the Library is restricted in
  406 +certain countries either by patents or by copyrighted interfaces, the
  407 +original copyright holder who places the Library under this License may add
  408 +an explicit geographical distribution limitation excluding those countries,
  409 +so that distribution is permitted only in or among countries not thus
  410 +excluded. In such case, this License incorporates the limitation as if
  411 +written in the body of this License.
  412 +
  413 + 13. The Free Software Foundation may publish revised and/or new
  414 +versions of the Lesser General Public License from time to time.
  415 +Such new versions will be similar in spirit to the present version,
  416 +but may differ in detail to address new problems or concerns.
  417 +
  418 +Each version is given a distinguishing version number. If the Library
  419 +specifies a version number of this License which applies to it and
  420 +"any later version", you have the option of following the terms and
  421 +conditions either of that version or of any later version published by
  422 +the Free Software Foundation. If the Library does not specify a
  423 +license version number, you may choose any version ever published by
  424 +the Free Software Foundation.
  425 +
  426 + 14. If you wish to incorporate parts of the Library into other free
  427 +programs whose distribution conditions are incompatible with these,
  428 +write to the author to ask for permission. For software which is
  429 +copyrighted by the Free Software Foundation, write to the Free
  430 +Software Foundation; we sometimes make exceptions for this. Our
  431 +decision will be guided by the two goals of preserving the free status
  432 +of all derivatives of our free software and of promoting the sharing
  433 +and reuse of software generally.
  434 +
  435 + NO WARRANTY
  436 +
  437 + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
  438 +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
  439 +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
  440 +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
  441 +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
  442 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  443 +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
  444 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
  445 +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  446 +
  447 + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
  448 +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
  449 +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
  450 +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
  451 +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
  452 +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
  453 +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
  454 +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
  455 +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  456 +DAMAGES.
  457 +
  458 + END OF TERMS AND CONDITIONS
  459 +
  460 + How to Apply These Terms to Your New Libraries
  461 +
  462 + If you develop a new library, and you want it to be of the greatest
  463 +possible use to the public, we recommend making it free software that
  464 +everyone can redistribute and change. You can do so by permitting
  465 +redistribution under these terms (or, alternatively, under the terms of the
  466 +ordinary General Public License).
  467 +
  468 + To apply these terms, attach the following notices to the library. It is
  469 +safest to attach them to the start of each source file to most effectively
  470 +convey the exclusion of warranty; and each file should have at least the
  471 +"copyright" line and a pointer to where the full notice is found.
  472 +
  473 + <one line to give the library's name and a brief idea of what it does.>
  474 + Copyright (C) <year> <name of author>
  475 +
  476 + This library is free software; you can redistribute it and/or
  477 + modify it under the terms of the GNU Lesser General Public
  478 + License as published by the Free Software Foundation; either
  479 + version 2.1 of the License, or (at your option) any later version.
  480 +
  481 + This library is distributed in the hope that it will be useful,
  482 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  483 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  484 + Lesser General Public License for more details.
  485 +
  486 + You should have received a copy of the GNU Lesser General Public
  487 + License along with this library; if not, write to the Free Software
  488 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  489 +
  490 +Also add information on how to contact you by electronic and paper mail.
  491 +
  492 +You should also get your employer (if you work as a programmer) or your
  493 +school, if any, to sign a "copyright disclaimer" for the library, if
  494 +necessary. Here is a sample; alter the names:
  495 +
  496 + Yoyodyne, Inc., hereby disclaims all copyright interest in the
  497 + library `Frob' (a library for tweaking knobs) written by James Random Hacker.
  498 +
  499 + <signature of Ty Coon>, 1 April 1990
  500 + Ty Coon, President of Vice
  501 +
  502 +That's all there is to it!
0 \ No newline at end of file 503 \ No newline at end of file
thirdpartyjs/curvycorners/rounded_corners.inc.js 0 → 100644
  1 +
  2 + /****************************************************************
  3 + * *
  4 + * curvyCorners *
  5 + * ------------ *
  6 + * *
  7 + * This script generates rounded corners for your divs. *
  8 + * *
  9 + * Version 1.2.9 *
  10 + * Copyright (c) 2006 Cameron Cooke *
  11 + * By: Cameron Cooke and Tim Hutchison. *
  12 + * *
  13 + * *
  14 + * Website: http://www.curvycorners.net *
  15 + * Email: info@totalinfinity.com *
  16 + * Forum: http://www.curvycorners.net/forum/ *
  17 + * *
  18 + * *
  19 + * This library is free software; you can redistribute *
  20 + * it and/or modify it under the terms of the GNU *
  21 + * Lesser General Public License as published by the *
  22 + * Free Software Foundation; either version 2.1 of the *
  23 + * License, or (at your option) any later version. *
  24 + * *
  25 + * This library is distributed in the hope that it will *
  26 + * be useful, but WITHOUT ANY WARRANTY; without even the *
  27 + * implied warranty of MERCHANTABILITY or FITNESS FOR A *
  28 + * PARTICULAR PURPOSE. See the GNU Lesser General Public *
  29 + * License for more details. *
  30 + * *
  31 + * You should have received a copy of the GNU Lesser *
  32 + * General Public License along with this library; *
  33 + * Inc., 59 Temple Place, Suite 330, Boston, *
  34 + * MA 02111-1307 USA *
  35 + * *
  36 + ****************************************************************/
  37 +
  38 + // Browser detection
  39 + var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1;
  40 + var isMoz = document.implementation && document.implementation.createDocument;
  41 + var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false;
  42 + var masterCorners = new Array();
  43 +
  44 + /*
  45 + Usage:
  46 +
  47 + newCornersObj = new curvyCorners(settingsObj, "classNameStr");
  48 + newCornersObj = new curvyCorners(settingsObj, divObj1[, divObj2[, divObj3[, . . . [, divObjN]]]]);
  49 + */
  50 + function curvyCorners()
  51 + {
  52 + // Check parameters
  53 + if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object.");
  54 + if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name.");
  55 +
  56 + // Get object(s)
  57 + if(typeof(arguments[1]) == "string")
  58 + {
  59 + // Get elements by class name
  60 + var startIndex = 0;
  61 + var boxCol = getElementsByClass(arguments[1]);
  62 + }
  63 + else
  64 + {
  65 + // Get objects
  66 + var startIndex = 1;
  67 + var boxCol = arguments;
  68 + }
  69 +
  70 + // Create return collection/object
  71 + var curvyCornersCol = new Array();
  72 +
  73 + // Create array of html elements that can have rounded corners
  74 + if(arguments[0].validTags)
  75 + var validElements = arguments[0].validTags;
  76 + else
  77 + var validElements = ["div"]; // Default
  78 +
  79 + // Loop through each argument
  80 + for(var i = startIndex, j = boxCol.length; i < j; i++)
  81 + {
  82 + // Current element tag name
  83 + var currentTag = boxCol[i].tagName.toLowerCase();
  84 +
  85 + if(inArray(validElements, currentTag) !== false)
  86 + {
  87 + curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);
  88 + }
  89 + }
  90 +
  91 + this.objects = curvyCornersCol;
  92 +
  93 + // Applies the curvyCorners to all objects
  94 + this.applyCornersToAll = function()
  95 + {
  96 + for(var x = 0, k = this.objects.length; x < k; x++)
  97 + {
  98 + this.objects[x].applyCorners();
  99 + }
  100 + }
  101 + }
  102 +
  103 + // curvyCorners object (can be called directly)
  104 + function curvyObject()
  105 + {
  106 + // Setup Globals
  107 + this.box = arguments[1];
  108 + this.settings = arguments[0];
  109 + this.topContainer = null;
  110 + this.bottomContainer = null;
  111 +
  112 + this.contentDIV = null;
  113 +
  114 + // Get box formatting details
  115 + var boxHeight = get_style(this.box, "height", "height");
  116 + var boxWidth = get_style(this.box, "width", "width");
  117 + var borderWidth = get_style(this.box, "borderTopWidth", "border-top-width");
  118 + var borderColour = get_style(this.box, "borderTopColor", "border-top-color");
  119 + var boxColour = get_style(this.box, "backgroundColor", "background-color");
  120 + var backgroundImage = get_style(this.box, "backgroundImage", "background-image");
  121 + var boxPosition = get_style(this.box, "position", "position");
  122 + var boxPadding = get_style(this.box, "paddingTop", "padding-top");
  123 +
  124 + // Set formatting propertes
  125 + this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight));
  126 + this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth));
  127 + this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0));
  128 + this.boxColour = format_colour(boxColour);
  129 + this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0));
  130 + this.borderColour = format_colour(borderColour);
  131 + this.borderString = this.borderWidth + "px" + " solid " + this.borderColour;
  132 + this.backgroundImage = ((backgroundImage != "none")? backgroundImage : "");
  133 + this.boxContent = this.box.innerHTML;
  134 +
  135 + // Make box relative if not already absolute and remove any padding
  136 + if(boxPosition != "absolute") this.box.style.position = "relative";
  137 + this.box.style.padding = "0px";
  138 +
  139 + // If IE and height and width are not set, we need to set width so that we get positioning
  140 + if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%";
  141 +
  142 + // Resize box so that it stays to the orignal height
  143 +
  144 +
  145 + // Remove content if box is using autoPad
  146 + if(this.settings.autoPad == true && this.boxPadding > 0)
  147 + this.box.innerHTML = "";
  148 +
  149 + /*
  150 + This method creates the corners and
  151 + applies them to the div element.
  152 + */
  153 + this.applyCorners = function()
  154 + {
  155 + /*
  156 + Create top and bottom containers.
  157 + These will be used as a parent for the corners and bars.
  158 + */
  159 + for(var t = 0; t < 2; t++)
  160 + {
  161 + switch(t)
  162 + {
  163 + // Top
  164 + case 0:
  165 +
  166 + // Only build top bar if a top corner is to be draw
  167 + if(this.settings.tl || this.settings.tr)
  168 + {
  169 + var newMainContainer = document.createElement("DIV");
  170 + newMainContainer.style.width = "100%";
  171 + newMainContainer.style.fontSize = "1px";
  172 + newMainContainer.style.overflow = "hidden";
  173 + newMainContainer.style.position = "absolute";
  174 + newMainContainer.style.paddingLeft = this.borderWidth + "px";
  175 + newMainContainer.style.paddingRight = this.borderWidth + "px";
  176 + var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0);
  177 + newMainContainer.style.height = topMaxRadius + "px";
  178 + newMainContainer.style.top = 0 - topMaxRadius + "px";
  179 + newMainContainer.style.left = 0 - this.borderWidth + "px";
  180 + this.topContainer = this.box.appendChild(newMainContainer);
  181 + }
  182 + break;
  183 +
  184 + // Bottom
  185 + case 1:
  186 +
  187 + // Only build bottom bar if a top corner is to be draw
  188 + if(this.settings.bl || this.settings.br)
  189 + {
  190 + var newMainContainer = document.createElement("DIV");
  191 + newMainContainer.style.width = "100%";
  192 + newMainContainer.style.fontSize = "1px";
  193 + newMainContainer.style.overflow = "hidden";
  194 + newMainContainer.style.position = "absolute";
  195 + newMainContainer.style.paddingLeft = this.borderWidth + "px";
  196 + newMainContainer.style.paddingRight = this.borderWidth + "px";
  197 + var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0);
  198 + newMainContainer.style.height = botMaxRadius + "px";
  199 + newMainContainer.style.bottom = 0 - botMaxRadius + "px";
  200 + newMainContainer.style.left = 0 - this.borderWidth + "px";
  201 + this.bottomContainer = this.box.appendChild(newMainContainer);
  202 + }
  203 + break;
  204 + }
  205 + }
  206 +
  207 + // Turn off current borders
  208 + if(this.topContainer) this.box.style.borderTopWidth = "0px";
  209 + if(this.bottomContainer) this.box.style.borderBottomWidth = "0px";
  210 +
  211 + // Create array of available corners
  212 + var corners = ["tr", "tl", "br", "bl"];
  213 +
  214 + /*
  215 + Loop for each corner
  216 + */
  217 + for(var i in corners)
  218 + {
  219 +
  220 + // FIX for prototype lib
  221 + if(i > -1 < 4)
  222 + {
  223 +
  224 + // Get current corner type from array
  225 + var cc = corners[i];
  226 + myobj = cc;
  227 + // alert(myobj + ' ' + cc + ' ' + i);
  228 +
  229 + // Has the user requested the currentCorner be round?
  230 + if(!this.settings[cc])
  231 + {
  232 + // No
  233 + if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
  234 + {
  235 + // We need to create a filler div to fill the space upto the next horzontal corner.
  236 + var newCorner = document.createElement("DIV");
  237 +
  238 + // Setup corners properties
  239 + newCorner.style.position = "relative";
  240 + newCorner.style.fontSize = "1px";
  241 + newCorner.style.overflow = "hidden";
  242 +
  243 + // Add background image?
  244 + if(this.backgroundImage == "")
  245 + newCorner.style.backgroundColor = this.boxColour;
  246 + else
  247 + newCorner.style.backgroundImage = this.backgroundImage;
  248 +
  249 + switch(cc)
  250 + {
  251 + case "tl":
  252 + newCorner.style.height = topMaxRadius - this.borderWidth + "px";
  253 + newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px";
  254 + newCorner.style.borderLeft = this.borderString;
  255 + newCorner.style.borderTop = this.borderString;
  256 + newCorner.style.left = -this.borderWidth + "px";
  257 + break;
  258 +
  259 + case "tr":
  260 + newCorner.style.height = topMaxRadius - this.borderWidth + "px";
  261 + newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px";
  262 + newCorner.style.borderRight = this.borderString;
  263 + newCorner.style.borderTop = this.borderString;
  264 + newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px";
  265 + newCorner.style.left = this.borderWidth + "px";
  266 + break;
  267 +
  268 + case "bl":
  269 + newCorner.style.height = botMaxRadius - this.borderWidth + "px";
  270 + newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px";
  271 + newCorner.style.borderLeft = this.borderString;
  272 + newCorner.style.borderBottom = this.borderString;
  273 + newCorner.style.left = -this.borderWidth + "px";
  274 + newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px";
  275 + break;
  276 +
  277 + case "br":
  278 + newCorner.style.height = botMaxRadius - this.borderWidth + "px";
  279 + newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px";
  280 + newCorner.style.borderRight = this.borderString;
  281 + newCorner.style.borderBottom = this.borderString;
  282 + newCorner.style.left = this.borderWidth + "px"
  283 + newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px";
  284 + break;
  285 + }
  286 + }
  287 + }
  288 + else
  289 + {
  290 + /*
  291 + PERFORMANCE NOTE:
  292 +
  293 + If more than one corner is requested and a corner has been already
  294 + created for the same radius then that corner will be used as a master and cloned.
  295 + The pixel bars will then be repositioned to form the new corner type.
  296 + All new corners start as a bottom right corner.
  297 + */
  298 + //alert(masterCorners["boxId: "+ cc]+ cc);
  299 + /*if(cc == "tr"){
  300 + if(masterCorners[this.settings[cc].radius])
  301 + var newCorner = masterCorners[this.settings["tr"].radius].cloneNode(true);
  302 + //alert("cloning tr");
  303 + }else if(cc == "br"){
  304 + if(masterCorners[this.settings[cc].radius])
  305 + var newCorner = masterCorners[this.settings["br"].radius].cloneNode(true);
  306 + //alert("cloning br");
  307 + }*/
  308 +
  309 + if(masterCorners[this.settings[cc].radius] && cc == "tl"){
  310 + var newCorner = masterCorners[this.settings["tr"].radius].cloneNode(true);
  311 + }else if(masterCorners[this.settings[cc].radius] && cc == "bl"){
  312 + var newCorner = masterCorners[this.settings["br"].radius].cloneNode(true);
  313 + }else{
  314 + // Yes, we need to create a new corner
  315 + var newCorner = document.createElement("DIV");
  316 + newCorner.style.height = this.settings[cc].radius + "px";
  317 + newCorner.style.width = this.settings[cc].radius + "px";
  318 + newCorner.style.position = "absolute";
  319 + newCorner.style.fontSize = "1px";
  320 + newCorner.style.overflow = "hidden";
  321 +
  322 + // THE FOLLOWING BLOCK OF CODE CREATES A ROUNDED CORNER
  323 + // ---------------------------------------------------- TOP
  324 +
  325 + // Get border radius
  326 + var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth);
  327 +
  328 + // Cycle the x-axis
  329 + for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
  330 + {
  331 + // Calculate the value of y1 which identifies the pixels inside the border
  332 + if((intx +1) >= borderRadius)
  333 + var y1 = -1;
  334 + else
  335 + var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1);
  336 +
  337 + // Only calculate y2 and y3 if there is a border defined
  338 + if(borderRadius != j)
  339 + {
  340 + if((intx) >= borderRadius)
  341 + var y2 = -1;
  342 + else
  343 + var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2)));
  344 +
  345 + if((intx+1) >= j)
  346 + var y3 = -1;
  347 + else
  348 + var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);
  349 + }
  350 +
  351 + // Calculate y4
  352 + if((intx) >= j)
  353 + var y4 = -1;
  354 + else
  355 + var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2)));
  356 +
  357 + // Draw bar on inside of the border with foreground colour
  358 + if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius,cc);
  359 +
  360 + // Only draw border/foreground antialiased pixels and border if there is a border defined
  361 + if(borderRadius != j)
  362 + {
  363 + // Cycle the y-axis
  364 + for(var inty = (y1 + 1); inty < y2; inty++)
  365 + {
  366 + // Draw anti-alias pixels
  367 + if(this.settings.antiAlias)
  368 + {
  369 + // For each of the pixels that need anti aliasing between the foreground and border colour draw single pixel divs
  370 + if(this.backgroundImage != "")
  371 + {
  372 + var borderFract = (pixelFraction(intx, inty, borderRadius) * 100);
  373 +
  374 + if(borderFract < 30)
  375 + {
  376 + this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius,myobj);
  377 + }else{
  378 + this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius,myobj);
  379 + }
  380 + }
  381 + else
  382 + {
  383 + var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius));
  384 + this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, myobj);
  385 + }
  386 + }
  387 + }
  388 +
  389 + // Draw bar for the border
  390 + if(this.settings.antiAlias)
  391 + {
  392 + if(y3 >= y2)
  393 + {
  394 + if (y2 == -1) y2 = 0;
  395 + this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0,myobj);
  396 + }
  397 + }
  398 + else
  399 + {
  400 + if(y3 >= y1)
  401 + {
  402 + this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0,myobj);
  403 + }
  404 + }
  405 +
  406 + // Set the colour for the outside curve
  407 + var outsideColour = this.borderColour;
  408 + }
  409 + else
  410 + {
  411 + // Set the coour for the outside curve
  412 + var outsideColour = this.boxColour;
  413 + var y3 = y1;
  414 + }
  415 +
  416 + // Draw aa pixels?
  417 + if(this.settings.antiAlias)
  418 + {
  419 + // Cycle the y-axis and draw the anti aliased pixels on the outside of the curve
  420 + for(var inty = (y3 + 1); inty < y4; inty++)
  421 + {
  422 + // For each of the pixels that need anti aliasing between the foreground/border colour & background draw single pixel divs
  423 + this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius,myobj);
  424 + }
  425 + }
  426 + }
  427 +
  428 + // END OF CORNER CREATION
  429 + // ---------------------------------------------------- END
  430 +
  431 + // We now need to store the current corner in the masterConers array
  432 + masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);
  433 + }
  434 +
  435 + /*
  436 + Now we have a new corner we need to reposition all the pixels unless
  437 + the current corner is the bottom right.
  438 + */
  439 + if(cc != "br")
  440 + {
  441 + // Loop through all children (pixel bars)
  442 + for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
  443 + {
  444 + // Get current pixel bar
  445 + var pixelBar = newCorner.childNodes[t];
  446 +
  447 + // Get current top and left properties
  448 + var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px")));
  449 + var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px")));
  450 + var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px")));
  451 +
  452 + // Reposition pixels
  453 + if(cc == "tl" || cc == "bl"){
  454 + pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px"; // Left
  455 + }
  456 + if(cc == "tr" || cc == "tl"){
  457 + pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px"; // Top
  458 + }
  459 +
  460 + switch(cc)
  461 + {
  462 + case "tr":
  463 + pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px";
  464 + break;
  465 +
  466 + case "tl":
  467 + pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px";
  468 + break;
  469 +
  470 + case "bl":
  471 + pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px";
  472 + break;
  473 + }
  474 + }
  475 + }
  476 + }
  477 +
  478 + if(newCorner)
  479 + {
  480 + // Position the container
  481 + switch(cc)
  482 + {
  483 + case "tl":
  484 + if(newCorner.style.position == "absolute") newCorner.style.top = "0px";
  485 + if(newCorner.style.position == "absolute") newCorner.style.left = "0px";
  486 + if(this.topContainer) this.topContainer.appendChild(newCorner);
  487 + break;
  488 +
  489 + case "tr":
  490 + if(newCorner.style.position == "absolute") newCorner.style.top = "0px";
  491 + if(newCorner.style.position == "absolute") newCorner.style.right = "0px";
  492 + if(this.topContainer) this.topContainer.appendChild(newCorner);
  493 + break;
  494 +
  495 + case "bl":
  496 + if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px";
  497 + if(newCorner.style.position == "absolute") newCorner.style.left = "0px";
  498 + if(this.bottomContainer) this.bottomContainer.appendChild(newCorner);
  499 + break;
  500 +
  501 + case "br":
  502 + if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px";
  503 + if(newCorner.style.position == "absolute") newCorner.style.right = "0px";
  504 + if(this.bottomContainer) this.bottomContainer.appendChild(newCorner);
  505 + break;
  506 + }
  507 + }
  508 + }
  509 + }
  510 +
  511 + /*
  512 + The last thing to do is draw the rest of the filler DIVs.
  513 + We only need to create a filler DIVs when two corners have
  514 + diffrent radiuses in either the top or bottom container.
  515 + */
  516 +
  517 + // Find out which corner has the biiger radius and get the difference amount
  518 + var radiusDiff = new Array();
  519 + radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
  520 + radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius);
  521 +
  522 + for(z in radiusDiff)
  523 + {
  524 + // FIX for prototype lib
  525 + if(z == "t" || z == "b")
  526 + {
  527 + if(radiusDiff[z])
  528 + {
  529 + // Get the type of corner that is the smaller one
  530 + var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r");
  531 +
  532 + // First we need to create a DIV for the space under the smaller corner
  533 + var newFiller = document.createElement("DIV");
  534 + newFiller.style.height = radiusDiff[z] + "px";
  535 + newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
  536 + newFiller.style.position = "absolute";
  537 + newFiller.style.fontSize = "1px";
  538 + newFiller.style.overflow = "hidden";
  539 + newFiller.style.backgroundColor = this.boxColour;
  540 + //newFiller.style.backgroundColor = get_random_color();
  541 +
  542 + // Position filler
  543 + switch(smallerCornerType)
  544 + {
  545 + case "tl":
  546 + newFiller.style.bottom = "0px";
  547 + newFiller.style.left = "0px";
  548 + newFiller.style.borderLeft = this.borderString;
  549 + this.topContainer.appendChild(newFiller);
  550 + break;
  551 +
  552 + case "tr":
  553 + newFiller.style.bottom = "0px";
  554 + newFiller.style.right = "0px";
  555 + newFiller.style.borderRight = this.borderString;
  556 + this.topContainer.appendChild(newFiller);
  557 + break;
  558 +
  559 + case "bl":
  560 + newFiller.style.top = "0px";
  561 + newFiller.style.left = "0px";
  562 + newFiller.style.borderLeft = this.borderString;
  563 + this.bottomContainer.appendChild(newFiller);
  564 + break;
  565 +
  566 + case "br":
  567 + newFiller.style.top = "0px";
  568 + newFiller.style.right = "0px";
  569 + newFiller.style.borderRight = this.borderString;
  570 + this.bottomContainer.appendChild(newFiller);
  571 + break;
  572 + }
  573 + }
  574 +
  575 + // Create the bar to fill the gap between each corner horizontally
  576 + var newFillerBar = document.createElement("DIV");
  577 + newFillerBar.style.position = "relative";
  578 + newFillerBar.style.fontSize = "1px";
  579 + newFillerBar.style.overflow = "hidden";
  580 + newFillerBar.style.backgroundColor = this.boxColour;
  581 + newFillerBar.style.backgroundImage = this.backgroundImage;
  582 +
  583 + switch(z)
  584 + {
  585 + case "t":
  586 + // Top Bar
  587 + if(this.topContainer)
  588 + {
  589 + // Edit by Asger Hallas: Check if settings.xx.radius is not false
  590 + if(this.settings.tl.radius && this.settings.tr.radius)
  591 + {
  592 + newFillerBar.style.height = topMaxRadius - this.borderWidth + "px";
  593 + newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px";
  594 + newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px";
  595 + newFillerBar.style.borderTop = this.borderString;
  596 +
  597 + if(this.backgroundImage != "")
  598 + newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px";
  599 +
  600 + this.topContainer.appendChild(newFillerBar);
  601 + }
  602 + if(this.box.id == "loginbox" || this.box.id == "loginbox_skin")
  603 + newFillerBar.style.backgroundImage = "";
  604 + // Repos the boxes background image
  605 + this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";
  606 + }
  607 + break;
  608 +
  609 + case "b":
  610 + if(this.bottomContainer)
  611 + {
  612 + // Edit by Asger Hallas: Check if settings.xx.radius is not false
  613 + if(this.settings.bl.radius && this.settings.br.radius)
  614 + {
  615 + // Bottom Bar
  616 + newFillerBar.style.height = botMaxRadius - this.borderWidth + "px";
  617 + newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px";
  618 + newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px";
  619 + newFillerBar.style.borderBottom = this.borderString;
  620 +
  621 + if(this.box.id == "ktBlock" || this.box.id == "pageBody" || this.box.id == "ktInfo" || this.box.id == "ktError" || this.box.id == "loginbox" || this.box.id == "loginbox_skin" || this.box.id == "portlet" || this.box.id == "portlet expanded")
  622 + newFillerBar.style.backgroundImage = "";
  623 + if(this.box.id == "pageBody")
  624 + newFillerBar.style.backgroundColor = "#D1D1D1";
  625 + if(this.backgroundImage != "")
  626 + newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px";
  627 + this.bottomContainer.appendChild(newFillerBar);
  628 + }
  629 + }
  630 + break;
  631 + }
  632 + }
  633 + }
  634 +
  635 + /*
  636 + AutoPad! apply padding if set.
  637 + */
  638 + if(this.settings.autoPad == true && this.boxPadding > 0)
  639 + {
  640 + // Create content container
  641 + var contentContainer = document.createElement("DIV");
  642 +
  643 + // Set contentContainer's properties
  644 + contentContainer.style.position = "relative";
  645 + contentContainer.innerHTML = this.boxContent;
  646 + contentContainer.className = "autoPadDiv";
  647 +
  648 + // Get padding amounts
  649 + var topPadding = Math.abs(topMaxRadius - this.boxPadding);
  650 + var botPadding = Math.abs(botMaxRadius - this.boxPadding);
  651 +
  652 + // Apply top padding
  653 + if(topMaxRadius < this.boxPadding)
  654 + contentContainer.style.paddingTop = topPadding + "px";
  655 +
  656 + // Apply Bottom padding
  657 + if(botMaxRadius < this.boxPadding)
  658 + contentContainer.style.paddingBottom = botMaxRadius + "px";
  659 +
  660 + // Apply left and right padding
  661 + contentContainer.style.paddingLeft = this.boxPadding + "px";
  662 + contentContainer.style.paddingRight = this.boxPadding + "px";
  663 +
  664 + // Append contentContainer
  665 + this.contentDIV = this.box.appendChild(contentContainer);
  666 + }
  667 + }
  668 +
  669 + /*
  670 + This function draws the pixles
  671 + */
  672 +
  673 +
  674 + this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius, corner)
  675 + {
  676 + // Create pixel
  677 + var pixel = document.createElement("DIV");
  678 + pixel.style.height = height + "px";
  679 + pixel.style.width = "1px";
  680 + pixel.style.position = "absolute";
  681 + pixel.style.fontSize = "1px";
  682 + pixel.style.overflow = "hidden";
  683 +
  684 + // Max Top Radius
  685 + var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius);
  686 +
  687 + // Dont apply background image to border pixels
  688 + if(image == -1 && this.backgroundImage != "")
  689 + {
  690 + if (corner != 'bl' && corner != 'br')
  691 + pixel.style.backgroundImage = this.backgroundImage;
  692 + else
  693 + if(this.box.id == "pageBody")
  694 + pixel.style.backgroundColor = "#D1D1D1";
  695 + else
  696 + pixel.style.backgroundColor = colour;
  697 +
  698 + pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";
  699 + }
  700 + else
  701 + {
  702 + pixel.style.backgroundColor = colour;
  703 + }
  704 +
  705 + // Set opacity if the transparency is anything other than 100
  706 + if (transAmount != 100)
  707 + setOpacity(pixel, transAmount);
  708 +
  709 + // Set the pixels position
  710 + pixel.style.top = inty + "px";
  711 + pixel.style.left = intx + "px";
  712 +
  713 + newCorner.appendChild(pixel);
  714 + }
  715 + }
  716 +
  717 + // ------------- UTILITY FUNCTIONS
  718 +
  719 + // Inserts a element after another
  720 + function insertAfter(parent, node, referenceNode)
  721 + {
  722 + parent.insertBefore(node, referenceNode.nextSibling);
  723 + }
  724 +
  725 + /*
  726 + Blends the two colours by the fraction
  727 + returns the resulting colour as a string in the format "#FFFFFF"
  728 + */
  729 + function BlendColour(Col1, Col2, Col1Fraction)
  730 + {
  731 + var red1 = parseInt(Col1.substr(1,2),16);
  732 + var green1 = parseInt(Col1.substr(3,2),16);
  733 + var blue1 = parseInt(Col1.substr(5,2),16);
  734 + var red2 = parseInt(Col2.substr(1,2),16);
  735 + var green2 = parseInt(Col2.substr(3,2),16);
  736 + var blue2 = parseInt(Col2.substr(5,2),16);
  737 +
  738 + if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1;
  739 +
  740 + var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction)));
  741 + if(endRed > 255) endRed = 255;
  742 + if(endRed < 0) endRed = 0;
  743 +
  744 + var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction)));
  745 + if(endGreen > 255) endGreen = 255;
  746 + if(endGreen < 0) endGreen = 0;
  747 +
  748 + var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction)));
  749 + if(endBlue > 255) endBlue = 255;
  750 + if(endBlue < 0) endBlue = 0;
  751 +
  752 + return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);
  753 + }
  754 +
  755 + /*
  756 + Converts a number to hexadecimal format
  757 + */
  758 + function IntToHex(strNum)
  759 + {
  760 + base = strNum / 16;
  761 + rem = strNum % 16;
  762 + base = base - (rem / 16);
  763 + baseS = MakeHex(base);
  764 + remS = MakeHex(rem);
  765 +
  766 + return baseS + '' + remS;
  767 + }
  768 +
  769 +
  770 + /*
  771 + gets the hex bits of a number
  772 + */
  773 + function MakeHex(x)
  774 + {
  775 + if((x >= 0) && (x <= 9))
  776 + {
  777 + return x;
  778 + }
  779 + else
  780 + {
  781 + switch(x)
  782 + {
  783 + case 10: return "A";
  784 + case 11: return "B";
  785 + case 12: return "C";
  786 + case 13: return "D";
  787 + case 14: return "E";
  788 + case 15: return "F";
  789 + }
  790 + }
  791 + }
  792 +
  793 +
  794 + /*
  795 + For a pixel cut by the line determines the fraction of the pixel on the 'inside' of the
  796 + line. Returns a number between 0 and 1
  797 + */
  798 + function pixelFraction(x, y, r)
  799 + {
  800 + var pixelfraction = 0;
  801 +
  802 + /*
  803 + determine the co-ordinates of the two points on the perimeter of the pixel that the
  804 + circle crosses
  805 + */
  806 + var xvalues = new Array(1);
  807 + var yvalues = new Array(1);
  808 + var point = 0;
  809 + var whatsides = "";
  810 +
  811 + // x + 0 = Left
  812 + var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2)));
  813 +
  814 + if ((intersect >= y) && (intersect < (y+1)))
  815 + {
  816 + whatsides = "Left";
  817 + xvalues[point] = 0;
  818 + yvalues[point] = intersect - y;
  819 + point = point + 1;
  820 + }
  821 + // y + 1 = Top
  822 + var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2)));
  823 +
  824 + if ((intersect >= x) && (intersect < (x+1)))
  825 + {
  826 + whatsides = whatsides + "Top";
  827 + xvalues[point] = intersect - x;
  828 + yvalues[point] = 1;
  829 + point = point + 1;
  830 + }
  831 + // x + 1 = Right
  832 + var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2)));
  833 +
  834 + if ((intersect >= y) && (intersect < (y+1)))
  835 + {
  836 + whatsides = whatsides + "Right";
  837 + xvalues[point] = 1;
  838 + yvalues[point] = intersect - y;
  839 + point = point + 1;
  840 + }
  841 + // y + 0 = Bottom
  842 + var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2)));
  843 +
  844 + if ((intersect >= x) && (intersect < (x+1)))
  845 + {
  846 + whatsides = whatsides + "Bottom";
  847 + xvalues[point] = intersect - x;
  848 + yvalues[point] = 0;
  849 + }
  850 +
  851 + /*
  852 + depending on which sides of the perimeter of the pixel the circle crosses calculate the
  853 + fraction of the pixel inside the circle
  854 + */
  855 + switch (whatsides)
  856 + {
  857 + case "LeftRight":
  858 + pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2);
  859 + break;
  860 +
  861 + case "TopRight":
  862 + pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2);
  863 + break;
  864 +
  865 + case "TopBottom":
  866 + pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2);
  867 + break;
  868 +
  869 + case "LeftBottom":
  870 + pixelfraction = (yvalues[0]*xvalues[1])/2;
  871 + break;
  872 +
  873 + default:
  874 + pixelfraction = 1;
  875 + }
  876 +
  877 + return pixelfraction;
  878 + }
  879 +
  880 +
  881 + // This function converts CSS rgb(x, x, x) to hexadecimal
  882 + function rgb2Hex(rgbColour)
  883 + {
  884 + try{
  885 +
  886 + // Get array of RGB values
  887 + var rgbArray = rgb2Array(rgbColour);
  888 +
  889 + // Get RGB values
  890 + var red = parseInt(rgbArray[0]);
  891 + var green = parseInt(rgbArray[1]);
  892 + var blue = parseInt(rgbArray[2]);
  893 +
  894 + // Build hex colour code
  895 + var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);
  896 + }
  897 + catch(e){
  898 +
  899 + alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");
  900 + }
  901 +
  902 + return hexColour;
  903 + }
  904 +
  905 + // Returns an array of rbg values
  906 + function rgb2Array(rgbColour)
  907 + {
  908 + // Remove rgb()
  909 + var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")"));
  910 +
  911 + // Split RGB into array
  912 + var rgbArray = rgbValues.split(", ");
  913 +
  914 + return rgbArray;
  915 + }
  916 +
  917 + /*
  918 + Function by Simon Willison from sitepoint.com
  919 + Modified by Cameron Cooke adding Safari's rgba support
  920 + */
  921 + function setOpacity(obj, opacity)
  922 + {
  923 + opacity = (opacity == 100)?99.999:opacity;
  924 +
  925 + if(isSafari && obj.tagName != "IFRAME")
  926 + {
  927 + // Get array of RGB values
  928 + var rgbArray = rgb2Array(obj.style.backgroundColor);
  929 +
  930 + // Get RGB values
  931 + var red = parseInt(rgbArray[0]);
  932 + var green = parseInt(rgbArray[1]);
  933 + var blue = parseInt(rgbArray[2]);
  934 +
  935 + // Safari using RGBA support
  936 + obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";
  937 + }
  938 + else if(typeof(obj.style.opacity) != "undefined")
  939 + {
  940 + // W3C
  941 + obj.style.opacity = opacity/100;
  942 + }
  943 + else if(typeof(obj.style.MozOpacity) != "undefined")
  944 + {
  945 + // Older Mozilla
  946 + obj.style.MozOpacity = opacity/100;
  947 + }
  948 + else if(typeof(obj.style.filter) != "undefined")
  949 + {
  950 + // IE
  951 + obj.style.filter = "alpha(opacity:" + opacity + ")";
  952 + }
  953 + else if(typeof(obj.style.KHTMLOpacity) != "undefined")
  954 + {
  955 + // Older KHTML Based Browsers
  956 + obj.style.KHTMLOpacity = opacity/100;
  957 + }
  958 + }
  959 +
  960 + /*
  961 + Returns index if the passed value is found in the
  962 + array otherwise returns false.
  963 + */
  964 + function inArray(array, value)
  965 + {
  966 + for(var i = 0; i < array.length; i++){
  967 +
  968 + // Matches identical (===), not just similar (==).
  969 + if (array[i] === value) return i;
  970 + }
  971 +
  972 + return false;
  973 + }
  974 +
  975 + /*
  976 + Returns true if the passed value is found as a key
  977 + in the array otherwise returns false.
  978 + */
  979 + function inArrayKey(array, value)
  980 + {
  981 + for(key in array){
  982 +
  983 + // Matches identical (===), not just similar (==).
  984 + if(key === value) return true;
  985 + }
  986 +
  987 + return false;
  988 + }
  989 +
  990 + // Cross browser add event wrapper
  991 + function addEvent(elm, evType, fn, useCapture) {
  992 + if (elm.addEventListener) {
  993 + elm.addEventListener(evType, fn, useCapture);
  994 + return true;
  995 + }
  996 + else if (elm.attachEvent) {
  997 + var r = elm.attachEvent('on' + evType, fn);
  998 + return r;
  999 + }
  1000 + else {
  1001 + elm['on' + evType] = fn;
  1002 + }
  1003 + }
  1004 +
  1005 + // Cross browser remove event wrapper
  1006 + function removeEvent(obj, evType, fn, useCapture){
  1007 + if (obj.removeEventListener){
  1008 + obj.removeEventListener(evType, fn, useCapture);
  1009 + return true;
  1010 + } else if (obj.detachEvent){
  1011 + var r = obj.detachEvent("on"+evType, fn);
  1012 + return r;
  1013 + } else {
  1014 + alert("Handler could not be removed");
  1015 + }
  1016 + }
  1017 +
  1018 + // Formats colours
  1019 + function format_colour(colour)
  1020 + {
  1021 + var returnColour = "#ffffff";
  1022 +
  1023 + // Make sure colour is set and not transparent
  1024 + if(colour != "" && colour != "transparent")
  1025 + {
  1026 + // RGB Value?
  1027 + if(colour.substr(0, 3) == "rgb")
  1028 + {
  1029 + // Get HEX aquiv.
  1030 + returnColour = rgb2Hex(colour);
  1031 + }
  1032 + else if(colour.length == 4)
  1033 + {
  1034 + // 3 chr colour code add remainder
  1035 + returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);
  1036 + }
  1037 + else
  1038 + {
  1039 + // Normal valid hex colour
  1040 + returnColour = colour;
  1041 + }
  1042 + }
  1043 +
  1044 + return returnColour;
  1045 + }
  1046 +
  1047 + // Returns the style value for the property specfied
  1048 + function get_style(obj, property, propertyNS)
  1049 + {
  1050 + try
  1051 + {
  1052 + if(obj.currentStyle)
  1053 + {
  1054 + var returnVal = eval("obj.currentStyle." + property);
  1055 + }
  1056 + else
  1057 + {
  1058 + /*
  1059 + Safari does not expose any information for the object if display is
  1060 + set to none is set so we temporally enable it.
  1061 + */
  1062 + if(isSafari && obj.style.display == "none")
  1063 + {
  1064 + obj.style.display = "";
  1065 + var wasHidden = true;
  1066 + }
  1067 +
  1068 + var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS);
  1069 +
  1070 + // Rehide the object
  1071 + if(isSafari && wasHidden)
  1072 + {
  1073 + obj.style.display = "none";
  1074 + }
  1075 + }
  1076 + }
  1077 + catch(e)
  1078 + {
  1079 + // Do nothing
  1080 + }
  1081 +
  1082 + return returnVal;
  1083 + }
  1084 +
  1085 + // Get elements by class by Dustin Diaz.
  1086 + function getElementsByClass(searchClass, node, tag)
  1087 + {
  1088 + var classElements = new Array();
  1089 +
  1090 + if(node == null)
  1091 + node = document;
  1092 + if(tag == null)
  1093 + tag = '*';
  1094 +
  1095 + var els = node.getElementsByTagName(tag);
  1096 + var elsLen = els.length;
  1097 + var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)");
  1098 +
  1099 + for (i = 0, j = 0; i < elsLen; i++)
  1100 + {
  1101 + if(pattern.test(els[i].className))
  1102 + {
  1103 + classElements[j] = els[i];
  1104 + j++;
  1105 + }
  1106 + }
  1107 +
  1108 + return classElements;
  1109 + }
  1110 +
  1111 + // Displays error message
  1112 + function newCurvyError(errorMessage)
  1113 + {
  1114 + return new Error("curvyCorners Error:\n" + errorMessage)
  1115 + }
0 \ No newline at end of file 1116 \ No newline at end of file
thirdpartyjs/curvycorners/rounded_corners_lite.inc.js 0 → 100644
  1 +
  2 + /****************************************************************
  3 + * *
  4 + * curvyCorners *
  5 + * ------------ *
  6 + * *
  7 + * This script generates rounded corners for your divs. *
  8 + * *
  9 + * Version 1.2.9 *
  10 + * Copyright (c) 2006 Cameron Cooke *
  11 + * By: Cameron Cooke and Tim Hutchison. *
  12 + * *
  13 + * *
  14 + * Website: http://www.curvycorners.net *
  15 + * Email: info@totalinfinity.com *
  16 + * Forum: http://www.curvycorners.net/forum/ *
  17 + * *
  18 + * *
  19 + * This library is free software; you can redistribute *
  20 + * it and/or modify it under the terms of the GNU *
  21 + * Lesser General Public License as published by the *
  22 + * Free Software Foundation; either version 2.1 of the *
  23 + * License, or (at your option) any later version. *
  24 + * *
  25 + * This library is distributed in the hope that it will *
  26 + * be useful, but WITHOUT ANY WARRANTY; without even the *
  27 + * implied warranty of MERCHANTABILITY or FITNESS FOR A *
  28 + * PARTICULAR PURPOSE. See the GNU Lesser General Public *
  29 + * License for more details. *
  30 + * *
  31 + * You should have received a copy of the GNU Lesser *
  32 + * General Public License along with this library; *
  33 + * Inc., 59 Temple Place, Suite 330, Boston, *
  34 + * MA 02111-1307 USA *
  35 + * *
  36 + ****************************************************************/
  37 +
  38 +var isIE = navigator.userAgent.toLowerCase().indexOf("msie") > -1; var isMoz = document.implementation && document.implementation.createDocument; var isSafari = ((navigator.userAgent.toLowerCase().indexOf('safari')!=-1)&&(navigator.userAgent.toLowerCase().indexOf('mac')!=-1))?true:false; function curvyCorners()
  39 +{ if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object."); if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name."); if(typeof(arguments[1]) == "string")
  40 +{ var startIndex = 0; var boxCol = getElementsByClass(arguments[1]);}
  41 +else
  42 +{ var startIndex = 1; var boxCol = arguments;}
  43 +var curvyCornersCol = new Array(); if(arguments[0].validTags)
  44 +var validElements = arguments[0].validTags; else
  45 +var validElements = ["div"]; for(var i = startIndex, j = boxCol.length; i < j; i++)
  46 +{ var currentTag = boxCol[i].tagName.toLowerCase(); if(inArray(validElements, currentTag) !== false)
  47 +{ curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);}
  48 +}
  49 +this.objects = curvyCornersCol; this.applyCornersToAll = function()
  50 +{ for(var x = 0, k = this.objects.length; x < k; x++)
  51 +{ this.objects[x].applyCorners();}
  52 +}
  53 +}
  54 +function curvyObject()
  55 +{ this.box = arguments[1]; this.settings = arguments[0]; this.topContainer = null; this.bottomContainer = null; this.masterCorners = new Array(); this.contentDIV = null; var boxHeight = get_style(this.box, "height", "height"); var boxWidth = get_style(this.box, "width", "width"); var borderWidth = get_style(this.box, "borderTopWidth", "border-top-width"); var borderColour = get_style(this.box, "borderTopColor", "border-top-color"); var boxColour = get_style(this.box, "backgroundColor", "background-color"); var backgroundImage = get_style(this.box, "backgroundImage", "background-image"); var boxPosition = get_style(this.box, "position", "position"); var boxPadding = get_style(this.box, "paddingTop", "padding-top"); this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight)); this.boxWidth = parseInt(((boxWidth != "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1)? boxWidth.substring(0, boxWidth.indexOf("px")) : this.box.scrollWidth)); this.borderWidth = parseInt(((borderWidth != "" && borderWidth.indexOf("px") !== -1)? borderWidth.slice(0, borderWidth.indexOf("px")) : 0)); this.boxColour = format_colour(boxColour); this.boxPadding = parseInt(((boxPadding != "" && boxPadding.indexOf("px") !== -1)? boxPadding.slice(0, boxPadding.indexOf("px")) : 0)); this.borderColour = format_colour(borderColour); this.borderString = this.borderWidth + "px" + " solid " + this.borderColour; this.backgroundImage = ((backgroundImage != "none")? backgroundImage : ""); this.boxContent = this.box.innerHTML; if(boxPosition != "absolute") this.box.style.position = "relative"; this.box.style.padding = "0px"; if(isIE && boxWidth == "auto" && boxHeight == "auto") this.box.style.width = "100%"; if(this.settings.autoPad == true && this.boxPadding > 0)
  56 +this.box.innerHTML = ""; this.applyCorners = function()
  57 +{ for(var t = 0; t < 2; t++)
  58 +{ switch(t)
  59 +{ case 0:
  60 +if(this.settings.tl || this.settings.tr)
  61 +{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0); newMainContainer.style.height = topMaxRadius + "px"; newMainContainer.style.top = 0 - topMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.topContainer = this.box.appendChild(newMainContainer);}
  62 +break; case 1:
  63 +if(this.settings.bl || this.settings.br)
  64 +{ var newMainContainer = document.createElement("DIV"); newMainContainer.style.width = "100%"; newMainContainer.style.fontSize = "1px"; newMainContainer.style.overflow = "hidden"; newMainContainer.style.position = "absolute"; newMainContainer.style.paddingLeft = this.borderWidth + "px"; newMainContainer.style.paddingRight = this.borderWidth + "px"; var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0); newMainContainer.style.height = botMaxRadius + "px"; newMainContainer.style.bottom = 0 - botMaxRadius + "px"; newMainContainer.style.left = 0 - this.borderWidth + "px"; this.bottomContainer = this.box.appendChild(newMainContainer);}
  65 +break;}
  66 +}
  67 +if(this.topContainer) this.box.style.borderTopWidth = "0px"; if(this.bottomContainer) this.box.style.borderBottomWidth = "0px"; var corners = ["tr", "tl", "br", "bl"]; for(var i in corners)
  68 +{ if(i > -1 < 4)
  69 +{ var cc = corners[i]; if(!this.settings[cc])
  70 +{ if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null))
  71 +{ var newCorner = document.createElement("DIV"); newCorner.style.position = "relative"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; if(this.backgroundImage == "")
  72 +newCorner.style.backgroundColor = this.boxColour; else
  73 +newCorner.style.backgroundImage = this.backgroundImage; switch(cc)
  74 +{ case "tl":
  75 +newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.tr.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.left = -this.borderWidth + "px"; break; case "tr":
  76 +newCorner.style.height = topMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.tl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderTop = this.borderString; newCorner.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; newCorner.style.left = this.borderWidth + "px"; break; case "bl":
  77 +newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginRight = this.settings.br.radius - (this.borderWidth*2) + "px"; newCorner.style.borderLeft = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = -this.borderWidth + "px"; newCorner.style.backgroundPosition = "-" + (this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break; case "br":
  78 +newCorner.style.height = botMaxRadius - this.borderWidth + "px"; newCorner.style.marginLeft = this.settings.bl.radius - (this.borderWidth*2) + "px"; newCorner.style.borderRight = this.borderString; newCorner.style.borderBottom = this.borderString; newCorner.style.left = this.borderWidth + "px"
  79 +newCorner.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (botMaxRadius + this.borderWidth)) + "px"; break;}
  80 +}
  81 +}
  82 +else
  83 +{ if(this.masterCorners[this.settings[cc].radius])
  84 +{ var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);}
  85 +else
  86 +{ var newCorner = document.createElement("DIV"); newCorner.style.height = this.settings[cc].radius + "px"; newCorner.style.width = this.settings[cc].radius + "px"; newCorner.style.position = "absolute"; newCorner.style.fontSize = "1px"; newCorner.style.overflow = "hidden"; var borderRadius = parseInt(this.settings[cc].radius - this.borderWidth); for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++)
  87 +{ if((intx +1) >= borderRadius)
  88 +var y1 = -1; else
  89 +var y1 = (Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1); if(borderRadius != j)
  90 +{ if((intx) >= borderRadius)
  91 +var y2 = -1; else
  92 +var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2))); if((intx+1) >= j)
  93 +var y3 = -1; else
  94 +var y3 = (Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1);}
  95 +if((intx) >= j)
  96 +var y4 = -1; else
  97 +var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2))); if(y1 > -1) this.drawPixel(intx, 0, this.boxColour, 100, (y1+1), newCorner, -1, this.settings[cc].radius); if(borderRadius != j)
  98 +{ for(var inty = (y1 + 1); inty < y2; inty++)
  99 +{ if(this.settings.antiAlias)
  100 +{ if(this.backgroundImage != "")
  101 +{ var borderFract = (pixelFraction(intx, inty, borderRadius) * 100); if(borderFract < 30)
  102 +{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, 0, this.settings[cc].radius);}
  103 +else
  104 +{ this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);}
  105 +}
  106 +else
  107 +{ var pixelcolour = BlendColour(this.boxColour, this.borderColour, pixelFraction(intx, inty, borderRadius)); this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius, cc);}
  108 +}
  109 +}
  110 +if(this.settings.antiAlias)
  111 +{ if(y3 >= y2)
  112 +{ if (y2 == -1) y2 = 0; this.drawPixel(intx, y2, this.borderColour, 100, (y3 - y2 + 1), newCorner, 0, 0);}
  113 +}
  114 +else
  115 +{ if(y3 >= y1)
  116 +{ this.drawPixel(intx, (y1 + 1), this.borderColour, 100, (y3 - y1), newCorner, 0, 0);}
  117 +}
  118 +var outsideColour = this.borderColour;}
  119 +else
  120 +{ var outsideColour = this.boxColour; var y3 = y1;}
  121 +if(this.settings.antiAlias)
  122 +{ for(var inty = (y3 + 1); inty < y4; inty++)
  123 +{ this.drawPixel(intx, inty, outsideColour, (pixelFraction(intx, inty , j) * 100), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);}
  124 +}
  125 +}
  126 +this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);}
  127 +if(cc != "br")
  128 +{ for(var t = 0, k = newCorner.childNodes.length; t < k; t++)
  129 +{ var pixelBar = newCorner.childNodes[t]; var pixelBarTop = parseInt(pixelBar.style.top.substring(0, pixelBar.style.top.indexOf("px"))); var pixelBarLeft = parseInt(pixelBar.style.left.substring(0, pixelBar.style.left.indexOf("px"))); var pixelBarHeight = parseInt(pixelBar.style.height.substring(0, pixelBar.style.height.indexOf("px"))); if(cc == "tl" || cc == "bl"){ pixelBar.style.left = this.settings[cc].radius -pixelBarLeft -1 + "px";}
  130 +if(cc == "tr" || cc == "tl"){ pixelBar.style.top = this.settings[cc].radius -pixelBarHeight -pixelBarTop + "px";}
  131 +switch(cc)
  132 +{ case "tr":
  133 +pixelBar.style.backgroundPosition = "-" + Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "tl":
  134 +pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px"; break; case "bl":
  135 +pixelBar.style.backgroundPosition = "-" + Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px -" + Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px"; break;}
  136 +}
  137 +}
  138 +}
  139 +if(newCorner)
  140 +{ switch(cc)
  141 +{ case "tl":
  142 +if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "tr":
  143 +if(newCorner.style.position == "absolute") newCorner.style.top = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.topContainer) this.topContainer.appendChild(newCorner); break; case "bl":
  144 +if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.left = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break; case "br":
  145 +if(newCorner.style.position == "absolute") newCorner.style.bottom = "0px"; if(newCorner.style.position == "absolute") newCorner.style.right = "0px"; if(this.bottomContainer) this.bottomContainer.appendChild(newCorner); break;}
  146 +}
  147 +}
  148 +}
  149 +var radiusDiff = new Array(); radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius)
  150 +radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius); for(z in radiusDiff)
  151 +{ if(z == "t" || z == "b")
  152 +{ if(radiusDiff[z])
  153 +{ var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r"); var newFiller = document.createElement("DIV"); newFiller.style.height = radiusDiff[z] + "px"; newFiller.style.width = this.settings[smallerCornerType].radius+ "px"
  154 +newFiller.style.position = "absolute"; newFiller.style.fontSize = "1px"; newFiller.style.overflow = "hidden"; newFiller.style.backgroundColor = this.boxColour; switch(smallerCornerType)
  155 +{ case "tl":
  156 +newFiller.style.bottom = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.topContainer.appendChild(newFiller); break; case "tr":
  157 +newFiller.style.bottom = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.topContainer.appendChild(newFiller); break; case "bl":
  158 +newFiller.style.top = "0px"; newFiller.style.left = "0px"; newFiller.style.borderLeft = this.borderString; this.bottomContainer.appendChild(newFiller); break; case "br":
  159 +newFiller.style.top = "0px"; newFiller.style.right = "0px"; newFiller.style.borderRight = this.borderString; this.bottomContainer.appendChild(newFiller); break;}
  160 +}
  161 +var newFillerBar = document.createElement("DIV"); newFillerBar.style.position = "relative"; newFillerBar.style.fontSize = "1px"; newFillerBar.style.overflow = "hidden"; newFillerBar.style.backgroundColor = this.boxColour; newFillerBar.style.backgroundImage = this.backgroundImage; switch(z)
  162 +{ case "t":
  163 +if(this.topContainer)
  164 +{ if(this.settings.tl.radius && this.settings.tr.radius)
  165 +{ newFillerBar.style.height = topMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.tl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.tr.radius - this.borderWidth + "px"; newFillerBar.style.borderTop = this.borderString; if(this.backgroundImage != "")
  166 +newFillerBar.style.backgroundPosition = "-" + (topMaxRadius + this.borderWidth) + "px 0px"; this.topContainer.appendChild(newFillerBar);}
  167 +this.box.style.backgroundPosition = "0px -" + (topMaxRadius - this.borderWidth) + "px";}
  168 +break; case "b":
  169 +if(this.bottomContainer)
  170 +{ if(this.settings.bl.radius && this.settings.br.radius)
  171 +{ newFillerBar.style.height = botMaxRadius - this.borderWidth + "px"; newFillerBar.style.marginLeft = this.settings.bl.radius - this.borderWidth + "px"; newFillerBar.style.marginRight = this.settings.br.radius - this.borderWidth + "px"; newFillerBar.style.borderBottom = this.borderString; if(this.backgroundImage != "")
  172 +newFillerBar.style.backgroundPosition = "-" + (botMaxRadius + this.borderWidth) + "px -" + (this.boxHeight + (topMaxRadius + this.borderWidth)) + "px"; this.bottomContainer.appendChild(newFillerBar);}
  173 +}
  174 +break;}
  175 +}
  176 +}
  177 +if(this.settings.autoPad == true && this.boxPadding > 0)
  178 +{ var contentContainer = document.createElement("DIV"); contentContainer.style.position = "relative"; contentContainer.innerHTML = this.boxContent; contentContainer.className = "autoPadDiv"; var topPadding = Math.abs(topMaxRadius - this.boxPadding); var botPadding = Math.abs(botMaxRadius - this.boxPadding); if(topMaxRadius < this.boxPadding)
  179 +contentContainer.style.paddingTop = topPadding + "px"; if(botMaxRadius < this.boxPadding)
  180 +contentContainer.style.paddingBottom = botMaxRadius + "px"; contentContainer.style.paddingLeft = this.boxPadding + "px"; contentContainer.style.paddingRight = this.boxPadding + "px"; this.contentDIV = this.box.appendChild(contentContainer);}
  181 +}
  182 +this.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius)
  183 +{ var pixel = document.createElement("DIV"); pixel.style.height = height + "px"; pixel.style.width = "1px"; pixel.style.position = "absolute"; pixel.style.fontSize = "1px"; pixel.style.overflow = "hidden"; var topMaxRadius = Math.max(this.settings["tr"].radius, this.settings["tl"].radius); if(image == -1 && this.backgroundImage != "")
  184 +{ pixel.style.backgroundImage = this.backgroundImage; pixel.style.backgroundPosition = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) -this.borderWidth) + "px";}
  185 +else
  186 +{ pixel.style.backgroundColor = colour;}
  187 +if (transAmount != 100)
  188 +setOpacity(pixel, transAmount); pixel.style.top = inty + "px"; pixel.style.left = intx + "px"; newCorner.appendChild(pixel);}
  189 +}
  190 +function insertAfter(parent, node, referenceNode)
  191 +{ parent.insertBefore(node, referenceNode.nextSibling);}
  192 +function BlendColour(Col1, Col2, Col1Fraction)
  193 +{ var red1 = parseInt(Col1.substr(1,2),16); var green1 = parseInt(Col1.substr(3,2),16); var blue1 = parseInt(Col1.substr(5,2),16); var red2 = parseInt(Col2.substr(1,2),16); var green2 = parseInt(Col2.substr(3,2),16); var blue2 = parseInt(Col2.substr(5,2),16); if(Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1; var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction))); if(endRed > 255) endRed = 255; if(endRed < 0) endRed = 0; var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction))); if(endGreen > 255) endGreen = 255; if(endGreen < 0) endGreen = 0; var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction))); if(endBlue > 255) endBlue = 255; if(endBlue < 0) endBlue = 0; return "#" + IntToHex(endRed)+ IntToHex(endGreen)+ IntToHex(endBlue);}
  194 +function IntToHex(strNum)
  195 +{ base = strNum / 16; rem = strNum % 16; base = base - (rem / 16); baseS = MakeHex(base); remS = MakeHex(rem); return baseS + '' + remS;}
  196 +function MakeHex(x)
  197 +{ if((x >= 0) && (x <= 9))
  198 +{ return x;}
  199 +else
  200 +{ switch(x)
  201 +{ case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F";}
  202 +}
  203 +}
  204 +function pixelFraction(x, y, r)
  205 +{ var pixelfraction = 0; var xvalues = new Array(1); var yvalues = new Array(1); var point = 0; var whatsides = ""; var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2))); if ((intersect >= y) && (intersect < (y+1)))
  206 +{ whatsides = "Left"; xvalues[point] = 0; yvalues[point] = intersect - y; point = point + 1;}
  207 +var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2))); if ((intersect >= x) && (intersect < (x+1)))
  208 +{ whatsides = whatsides + "Top"; xvalues[point] = intersect - x; yvalues[point] = 1; point = point + 1;}
  209 +var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2))); if ((intersect >= y) && (intersect < (y+1)))
  210 +{ whatsides = whatsides + "Right"; xvalues[point] = 1; yvalues[point] = intersect - y; point = point + 1;}
  211 +var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2))); if ((intersect >= x) && (intersect < (x+1)))
  212 +{ whatsides = whatsides + "Bottom"; xvalues[point] = intersect - x; yvalues[point] = 0;}
  213 +switch (whatsides)
  214 +{ case "LeftRight":
  215 +pixelfraction = Math.min(yvalues[0],yvalues[1]) + ((Math.max(yvalues[0],yvalues[1]) - Math.min(yvalues[0],yvalues[1]))/2); break; case "TopRight":
  216 +pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2); break; case "TopBottom":
  217 +pixelfraction = Math.min(xvalues[0],xvalues[1]) + ((Math.max(xvalues[0],xvalues[1]) - Math.min(xvalues[0],xvalues[1]))/2); break; case "LeftBottom":
  218 +pixelfraction = (yvalues[0]*xvalues[1])/2; break; default:
  219 +pixelfraction = 1;}
  220 +return pixelfraction;}
  221 +function rgb2Hex(rgbColour)
  222 +{ try{ var rgbArray = rgb2Array(rgbColour); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); var hexColour = "#" + IntToHex(red) + IntToHex(green) + IntToHex(blue);}
  223 +catch(e){ alert("There was an error converting the RGB value to Hexadecimal in function rgb2Hex");}
  224 +return hexColour;}
  225 +function rgb2Array(rgbColour)
  226 +{ var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")")); var rgbArray = rgbValues.split(", "); return rgbArray;}
  227 +function setOpacity(obj, opacity)
  228 +{ opacity = (opacity == 100)?99.999:opacity; if(isSafari && obj.tagName != "IFRAME")
  229 +{ var rgbArray = rgb2Array(obj.style.backgroundColor); var red = parseInt(rgbArray[0]); var green = parseInt(rgbArray[1]); var blue = parseInt(rgbArray[2]); obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";}
  230 +else if(typeof(obj.style.opacity) != "undefined")
  231 +{ obj.style.opacity = opacity/100;}
  232 +else if(typeof(obj.style.MozOpacity) != "undefined")
  233 +{ obj.style.MozOpacity = opacity/100;}
  234 +else if(typeof(obj.style.filter) != "undefined")
  235 +{ obj.style.filter = "alpha(opacity:" + opacity + ")";}
  236 +else if(typeof(obj.style.KHTMLOpacity) != "undefined")
  237 +{ obj.style.KHTMLOpacity = opacity/100;}
  238 +}
  239 +function inArray(array, value)
  240 +{ for(var i = 0; i < array.length; i++){ if (array[i] === value) return i;}
  241 +return false;}
  242 +function inArrayKey(array, value)
  243 +{ for(key in array){ if(key === value) return true;}
  244 +return false;}
  245 +function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true;}
  246 +else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r;}
  247 +else { elm['on' + evType] = fn;}
  248 +}
  249 +function removeEvent(obj, evType, fn, useCapture){ if (obj.removeEventListener){ obj.removeEventListener(evType, fn, useCapture); return true;} else if (obj.detachEvent){ var r = obj.detachEvent("on"+evType, fn); return r;} else { alert("Handler could not be removed");}
  250 +}
  251 +function format_colour(colour)
  252 +{ var returnColour = "#ffffff"; if(colour != "" && colour != "transparent")
  253 +{ if(colour.substr(0, 3) == "rgb")
  254 +{ returnColour = rgb2Hex(colour);}
  255 +else if(colour.length == 4)
  256 +{ returnColour = "#" + colour.substring(1, 2) + colour.substring(1, 2) + colour.substring(2, 3) + colour.substring(2, 3) + colour.substring(3, 4) + colour.substring(3, 4);}
  257 +else
  258 +{ returnColour = colour;}
  259 +}
  260 +return returnColour;}
  261 +function get_style(obj, property, propertyNS)
  262 +{ try
  263 +{ if(obj.currentStyle)
  264 +{ var returnVal = eval("obj.currentStyle." + property);}
  265 +else
  266 +{ if(isSafari && obj.style.display == "none")
  267 +{ obj.style.display = ""; var wasHidden = true;}
  268 +var returnVal = document.defaultView.getComputedStyle(obj, '').getPropertyValue(propertyNS); if(isSafari && wasHidden)
  269 +{ obj.style.display = "none";}
  270 +}
  271 +}
  272 +catch(e)
  273 +{ }
  274 +return returnVal;}
  275 +function getElementsByClass(searchClass, node, tag)
  276 +{ var classElements = new Array(); if(node == null)
  277 +node = document; if(tag == null)
  278 +tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\s)"+searchClass+"(\s|$)"); for (i = 0, j = 0; i < elsLen; i++)
  279 +{ if(pattern.test(els[i].className))
  280 +{ classElements[j] = els[i]; j++;}
  281 +}
  282 +return classElements;}
  283 +function newCurvyError(errorMessage)
  284 +{ return new Error("curvyCorners Error:\n" + errorMessage)
  285 +}