diff options
53 files changed, 1 insertions, 8807 deletions
diff --git a/js/liststudy.js b/js/liststudy.js deleted file mode 100644 index 2d340c9..0000000 --- a/js/liststudy.js +++ /dev/null @@ -1,171 +0,0 @@ -/* - liststudy.js - this script formats the data in batch_data and reviews_data to make a nice table out of it. -*/ - -var items = []; - -var max_score = 0; -var med_score = 0; -var avg_score = 0; - -function show_batch_table() { - process_items(); - show_contents_table(); - show_reviews_table(); -} - -function process_items() { - var item_idx = {}; - - for (var i = 0; i < batch_data.items.length; i++) { - var d = batch_data.items[i]; - item_idx[d[0]] = items.length; - items.push( - { - "info": d, - "win": 0, "fail": 0, - "score": 0, "marker": "", - } - ); - } - - // Calculate total wins and losses - for (var i = 0; i < reviews_data.length; i++) { - for (var j = 0; j < reviews_data[i].results.length; j++) { - var n = reviews_data[i].results[j][0]; - var s = reviews_data[i].results[j][1]; - var k = item_idx[n]; - if (s == 1) { - items[k].win++; - items[k].score++; - } else if (s == -1) { - items[k].fail++; - items[k].score--; - } - } - } - - // Make marker indication : -1 (fail) -> red, 0 (dunno) -> yellow - if (reviews_data.length > 0) { - var t = reviews_data[reviews_data.length - 1].results; - for (var j = 0; j < t.length; j++) { - var s = t[j][1]; - if (s == 1) continue; - var n = t[j][0]; - var k = item_idx[n]; - items[k].marker = items[k].marker + '<span style="color: ' + (s == 0 ? '#FFAA00' : '#FF0000') + '">*</span>'; - } - } - - - // Get max score - for (var i = 0; i < items.length; i++) { - if (items[i].score > max_score) max_score = items[i].score; - avg_score += items[i].score; - } - avg_score = Math.ceil(avg_score * 20 / items.length) / 20; - med_score = max_score / 2; -} - -function show_contents_table() { - var html = '<table><tr><th class="invisible_td"></th>'; - for (var i = 0; i < batch_data.columns.length; i++) { - var c = batch_data.columns[i]; - html += '<th>' + c + ' <a class="tool_link" href="#" onclick="ch(' + i + ')" id="chsl' + i + '">hide</a>' + - (i != 0 ? ' <a class="tool_link" href="#" onclick="lcol(' + i + ')">list</a>' : '') + '</th>' ; - } - html += '<th>win</th><th>fail</th><th>score</th></tr>'; - for (var i = 0; i < items.length; i++) { - html += '<tr onclick="edit_note(' + i + ');">'; - html += '<td class="invisible_td"><span style="font-weight: bold">' + items[i].marker + '</span>' + - '</td>'; - for (var j = 0; j < items[i].info.length; j++) { - html += '<td><span class="cd' + j + '">' + items[i].info[j] + '</span></td>'; - } - html += '<td>' + items[i].win + '</td>'; - html += '<td' + (items[i].fail > 0 ? (items[i].fail > items[i].win ? ' style="background-color: #ff7777"' : ' style="background-color: #FFFF00"') : '') + '>' + items[i].fail + '</td>'; - html += '<td style="background-color: ' + - (items[i].score == max_score ? '#00aa00' : - (items[i].score >= med_score ? '#55FF55' : - (items[i].score < 0 ? '#FF7777' : '#FFFF00'))) + '">' + items[i].score + '</td></tr>'; - if (notes[items[i].info[0]]) { - var note = notes[items[i].info[0]]; - html += '<tr><td class="invisible_td"></td><td class="study_note_td" colspan="' - + (items[i].info.length) + '">' + note.replace(/\|\|/g, '<br/>') + '</td></tr>'; - } - } - html += '</table>'; - html += '<p>Average score : ' + avg_score + '</p>'; - $("items").innerHTML = html; -} - -function ch(col) { - $$(".cd"+col).invoke("hide"); - $("chsl"+col).innerHTML = 'show'; - $("chsl"+col).onclick = function() { cs(col); }; -} - -function cs(col) { - $$(".cd"+col).invoke("show"); - $("chsl"+col).innerHTML = 'hide'; - $("chsl"+col).onclick = function() { ch(col); }; -} - -function lcol(col) { - html = '<p><a href="#" onclick="show_contents_table()">Show complete table</a></p><ul>'; - for (var i = 0; i < items.length; i++) { - html += '<li><p><span class="info">' + items[i].info[0] + '</span>' + items[i].info[col] + '</p></li>'; - } - html += '</ul>'; - $("items").innerHTML = html; -} - -function show_reviews_table() { - // eventually, will also show a graph of progress. or maybee not. - if (reviews_data.length == 0) { - $("reviews").innerHTML = "No reviews... yet."; - } else { - var html = '<table><tr><th>review date</th><th>score</th></tr>'; - for (var i = 0; i < reviews_data.length; i++) { - var color = ''; - if (reviews_data[i].score == 100) - color = '#00aa00'; - else if (reviews_data[i].score >= 90) - color = '#22EE22'; - else if (reviews_data[i].score >= 80) - color = '#55FF55'; - else if (reviews_data[i].score >= 60) - color = '#eeee00'; - else if (reviews_data[i].score >= 40) - color = '#FFAA22'; - else - color = '#FF7777'; - html += '<tr><td>' + reviews_data[i].date + '</td><td style="background-color: ' + color + '">' + reviews_data[i].score + '/100</td></tr>'; - } - html += '</table>'; - - $("reviews").innerHTML = html; - } -} - - -function edit_note(id) { - var idd = items[id].info[0]; - var note = prompt("Add note for item:\n(you might want to add a long note, so I'm adding this text to make the prompt box bigger)", notes[idd] || ''); - if (note != null) notes[idd] = note; - if (notes[idd] == '') delete notes[idd]; - show_contents_table(); - - new Ajax.Request('index.php?p=brresults-study-' + batchid, { - method: 'post', - parameters: { - notes: Object.toJSON(notes), - }, - onSuccess: function(transport) { - // nothing... - }, - }); -} - - diff --git a/js/prototype.js b/js/prototype.js deleted file mode 100644 index 474b223..0000000 --- a/js/prototype.js +++ /dev/null @@ -1,6082 +0,0 @@ -/* Prototype JavaScript framework, version 1.7 - * (c) 2005-2010 Sam Stephenson - * - * Prototype is freely distributable under the terms of an MIT-style license. - * For details, see the Prototype web site: http://www.prototypejs.org/ - * - *--------------------------------------------------------------------------*/ - -var Prototype = { - - Version: '1.7', - - Browser: (function(){ - var ua = navigator.userAgent; - var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; - return { - IE: !!window.attachEvent && !isOpera, - Opera: isOpera, - WebKit: ua.indexOf('AppleWebKit/') > -1, - Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, - MobileSafari: /Apple.*Mobile/.test(ua) - } - })(), - - BrowserFeatures: { - XPath: !!document.evaluate, - - SelectorsAPI: !!document.querySelector, - - ElementExtensions: (function() { - var constructor = window.Element || window.HTMLElement; - return !!(constructor && constructor.prototype); - })(), - SpecificElementExtensions: (function() { - if (typeof window.HTMLDivElement !== 'undefined') - return true; - - var div = document.createElement('div'), - form = document.createElement('form'), - isSupported = false; - - if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { - isSupported = true; - } - - div = form = null; - - return isSupported; - })() - }, - - ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', - JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, - - emptyFunction: function() { }, - - K: function(x) { return x } -}; - -if (Prototype.Browser.MobileSafari) - Prototype.BrowserFeatures.SpecificElementExtensions = false; - - -var Abstract = { }; - - -var Try = { - these: function() { - var returnValue; - - for (var i = 0, length = arguments.length; i < length; i++) { - var lambda = arguments[i]; - try { - returnValue = lambda(); - break; - } catch (e) { } - } - - return returnValue; - } -}; - -/* Based on Alex Arnell's inheritance implementation. */ - -var Class = (function() { - - var IS_DONTENUM_BUGGY = (function(){ - for (var p in { toString: 1 }) { - if (p === 'toString') return false; - } - return true; - })(); - - function subclass() {}; - function create() { - var parent = null, properties = $A(arguments); - if (Object.isFunction(properties[0])) - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } - - Object.extend(klass, Class.Methods); - klass.superclass = parent; - klass.subclasses = []; - - if (parent) { - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.subclasses.push(klass); - } - - for (var i = 0, length = properties.length; i < length; i++) - klass.addMethods(properties[i]); - - if (!klass.prototype.initialize) - klass.prototype.initialize = Prototype.emptyFunction; - - klass.prototype.constructor = klass; - return klass; - } - - function addMethods(source) { - var ancestor = this.superclass && this.superclass.prototype, - properties = Object.keys(source); - - if (IS_DONTENUM_BUGGY) { - if (source.toString != Object.prototype.toString) - properties.push("toString"); - if (source.valueOf != Object.prototype.valueOf) - properties.push("valueOf"); - } - - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && Object.isFunction(value) && - value.argumentNames()[0] == "$super") { - var method = value; - value = (function(m) { - return function() { return ancestor[m].apply(this, arguments); }; - })(property).wrap(method); - - value.valueOf = method.valueOf.bind(method); - value.toString = method.toString.bind(method); - } - this.prototype[property] = value; - } - - return this; - } - - return { - create: create, - Methods: { - addMethods: addMethods - } - }; -})(); -(function() { - - var _toString = Object.prototype.toString, - NULL_TYPE = 'Null', - UNDEFINED_TYPE = 'Undefined', - BOOLEAN_TYPE = 'Boolean', - NUMBER_TYPE = 'Number', - STRING_TYPE = 'String', - OBJECT_TYPE = 'Object', - FUNCTION_CLASS = '[object Function]', - BOOLEAN_CLASS = '[object Boolean]', - NUMBER_CLASS = '[object Number]', - STRING_CLASS = '[object String]', - ARRAY_CLASS = '[object Array]', - DATE_CLASS = '[object Date]', - NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && - typeof JSON.stringify === 'function' && - JSON.stringify(0) === '0' && - typeof JSON.stringify(Prototype.K) === 'undefined'; - - function Type(o) { - switch(o) { - case null: return NULL_TYPE; - case (void 0): return UNDEFINED_TYPE; - } - var type = typeof o; - switch(type) { - case 'boolean': return BOOLEAN_TYPE; - case 'number': return NUMBER_TYPE; - case 'string': return STRING_TYPE; - } - return OBJECT_TYPE; - } - - function extend(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; - } - - function inspect(object) { - try { - if (isUndefined(object)) return 'undefined'; - if (object === null) return 'null'; - return object.inspect ? object.inspect() : String(object); - } catch (e) { - if (e instanceof RangeError) return '...'; - throw e; - } - } - - function toJSON(value) { - return Str('', { '': value }, []); - } - - function Str(key, holder, stack) { - var value = holder[key], - type = typeof value; - - if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - - var _class = _toString.call(value); - - switch (_class) { - case NUMBER_CLASS: - case BOOLEAN_CLASS: - case STRING_CLASS: - value = value.valueOf(); - } - - switch (value) { - case null: return 'null'; - case true: return 'true'; - case false: return 'false'; - } - - type = typeof value; - switch (type) { - case 'string': - return value.inspect(true); - case 'number': - return isFinite(value) ? String(value) : 'null'; - case 'object': - - for (var i = 0, length = stack.length; i < length; i++) { - if (stack[i] === value) { throw new TypeError(); } - } - stack.push(value); - - var partial = []; - if (_class === ARRAY_CLASS) { - for (var i = 0, length = value.length; i < length; i++) { - var str = Str(i, value, stack); - partial.push(typeof str === 'undefined' ? 'null' : str); - } - partial = '[' + partial.join(',') + ']'; - } else { - var keys = Object.keys(value); - for (var i = 0, length = keys.length; i < length; i++) { - var key = keys[i], str = Str(key, value, stack); - if (typeof str !== "undefined") { - partial.push(key.inspect(true)+ ':' + str); - } - } - partial = '{' + partial.join(',') + '}'; - } - stack.pop(); - return partial; - } - } - - function stringify(object) { - return JSON.stringify(object); - } - - function toQueryString(object) { - return $H(object).toQueryString(); - } - - function toHTML(object) { - return object && object.toHTML ? object.toHTML() : String.interpret(object); - } - - function keys(object) { - if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } - var results = []; - for (var property in object) { - if (object.hasOwnProperty(property)) { - results.push(property); - } - } - return results; - } - - function values(object) { - var results = []; - for (var property in object) - results.push(object[property]); - return results; - } - - function clone(object) { - return extend({ }, object); - } - - function isElement(object) { - return !!(object && object.nodeType == 1); - } - - function isArray(object) { - return _toString.call(object) === ARRAY_CLASS; - } - - var hasNativeIsArray = (typeof Array.isArray == 'function') - && Array.isArray([]) && !Array.isArray({}); - - if (hasNativeIsArray) { - isArray = Array.isArray; - } - - function isHash(object) { - return object instanceof Hash; - } - - function isFunction(object) { - return _toString.call(object) === FUNCTION_CLASS; - } - - function isString(object) { - return _toString.call(object) === STRING_CLASS; - } - - function isNumber(object) { - return _toString.call(object) === NUMBER_CLASS; - } - - function isDate(object) { - return _toString.call(object) === DATE_CLASS; - } - - function isUndefined(object) { - return typeof object === "undefined"; - } - - extend(Object, { - extend: extend, - inspect: inspect, - toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, - toQueryString: toQueryString, - toHTML: toHTML, - keys: Object.keys || keys, - values: values, - clone: clone, - isElement: isElement, - isArray: isArray, - isHash: isHash, - isFunction: isFunction, - isString: isString, - isNumber: isNumber, - isDate: isDate, - isUndefined: isUndefined - }); -})(); -Object.extend(Function.prototype, (function() { - var slice = Array.prototype.slice; - - function update(array, args) { - var arrayLength = array.length, length = args.length; - while (length--) array[arrayLength + length] = args[length]; - return array; - } - - function merge(array, args) { - array = slice.call(array, 0); - return update(array, args); - } - - function argumentNames() { - var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] - .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') - .replace(/\s+/g, '').split(','); - return names.length == 1 && !names[0] ? [] : names; - } - - function bind(context) { - if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; - var __method = this, args = slice.call(arguments, 1); - return function() { - var a = merge(args, arguments); - return __method.apply(context, a); - } - } - - function bindAsEventListener(context) { - var __method = this, args = slice.call(arguments, 1); - return function(event) { - var a = update([event || window.event], args); - return __method.apply(context, a); - } - } - - function curry() { - if (!arguments.length) return this; - var __method = this, args = slice.call(arguments, 0); - return function() { - var a = merge(args, arguments); - return __method.apply(this, a); - } - } - - function delay(timeout) { - var __method = this, args = slice.call(arguments, 1); - timeout = timeout * 1000; - return window.setTimeout(function() { - return __method.apply(__method, args); - }, timeout); - } - - function defer() { - var args = update([0.01], arguments); - return this.delay.apply(this, args); - } - - function wrap(wrapper) { - var __method = this; - return function() { - var a = update([__method.bind(this)], arguments); - return wrapper.apply(this, a); - } - } - - function methodize() { - if (this._methodized) return this._methodized; - var __method = this; - return this._methodized = function() { - var a = update([this], arguments); - return __method.apply(null, a); - }; - } - - return { - argumentNames: argumentNames, - bind: bind, - bindAsEventListener: bindAsEventListener, - curry: curry, - delay: delay, - defer: defer, - wrap: wrap, - methodize: methodize - } -})()); - - - -(function(proto) { - - - function toISOString() { - return this.getUTCFullYear() + '-' + - (this.getUTCMonth() + 1).toPaddedString(2) + '-' + - this.getUTCDate().toPaddedString(2) + 'T' + - this.getUTCHours().toPaddedString(2) + ':' + - this.getUTCMinutes().toPaddedString(2) + ':' + - this.getUTCSeconds().toPaddedString(2) + 'Z'; - } - - - function toJSON() { - return this.toISOString(); - } - - if (!proto.toISOString) proto.toISOString = toISOString; - if (!proto.toJSON) proto.toJSON = toJSON; - -})(Date.prototype); - - -RegExp.prototype.match = RegExp.prototype.test; - -RegExp.escape = function(str) { - return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); -}; -var PeriodicalExecuter = Class.create({ - initialize: function(callback, frequency) { - this.callback = callback; - this.frequency = frequency; - this.currentlyExecuting = false; - - this.registerCallback(); - }, - - registerCallback: function() { - this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); - }, - - execute: function() { - this.callback(this); - }, - - stop: function() { - if (!this.timer) return; - clearInterval(this.timer); - this.timer = null; - }, - - onTimerEvent: function() { - if (!this.currentlyExecuting) { - try { - this.currentlyExecuting = true; - this.execute(); - this.currentlyExecuting = false; - } catch(e) { - this.currentlyExecuting = false; - throw e; - } - } - } -}); -Object.extend(String, { - interpret: function(value) { - return value == null ? '' : String(value); - }, - specialChar: { - '\b': '\\b', - '\t': '\\t', - '\n': '\\n', - '\f': '\\f', - '\r': '\\r', - '\\': '\\\\' - } -}); - -Object.extend(String.prototype, (function() { - var NATIVE_JSON_PARSE_SUPPORT = window.JSON && - typeof JSON.parse === 'function' && - JSON.parse('{"test": true}').test; - - function prepareReplacement(replacement) { - if (Object.isFunction(replacement)) return replacement; - var template = new Template(replacement); - return function(match) { return template.evaluate(match) }; - } - - function gsub(pattern, replacement) { - var result = '', source = this, match; - replacement = prepareReplacement(replacement); - - if (Object.isString(pattern)) - pattern = RegExp.escape(pattern); - - if (!(pattern.length || pattern.source)) { - replacement = replacement(''); - return replacement + source.split('').join(replacement) + replacement; - } - - while (source.length > 0) { - if (match = source.match(pattern)) { - result += source.slice(0, match.index); - result += String.interpret(replacement(match)); - source = source.slice(match.index + match[0].length); - } else { - result += source, source = ''; - } - } - return result; - } - - function sub(pattern, replacement, count) { - replacement = prepareReplacement(replacement); - count = Object.isUndefined(count) ? 1 : count; - - return this.gsub(pattern, function(match) { - if (--count < 0) return match[0]; - return replacement(match); - }); - } - - function scan(pattern, iterator) { - this.gsub(pattern, iterator); - return String(this); - } - - function truncate(length, truncation) { - length = length || 30; - truncation = Object.isUndefined(truncation) ? '...' : truncation; - return this.length > length ? - this.slice(0, length - truncation.length) + truncation : String(this); - } - - function strip() { - return this.replace(/^\s+/, '').replace(/\s+$/, ''); - } - - function stripTags() { - return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); - } - - function stripScripts() { - return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); - } - - function extractScripts() { - var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), - matchOne = new RegExp(Prototype.ScriptFragment, 'im'); - return (this.match(matchAll) || []).map(function(scriptTag) { - return (scriptTag.match(matchOne) || ['', ''])[1]; - }); - } - - function evalScripts() { - return this.extractScripts().map(function(script) { return eval(script) }); - } - - function escapeHTML() { - return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); - } - - function unescapeHTML() { - return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&'); - } - - - function toQueryParams(separator) { - var match = this.strip().match(/([^?#]*)(#.*)?$/); - if (!match) return { }; - - return match[1].split(separator || '&').inject({ }, function(hash, pair) { - if ((pair = pair.split('='))[0]) { - var key = decodeURIComponent(pair.shift()), - value = pair.length > 1 ? pair.join('=') : pair[0]; - - if (value != undefined) value = decodeURIComponent(value); - - if (key in hash) { - if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; - hash[key].push(value); - } - else hash[key] = value; - } - return hash; - }); - } - - function toArray() { - return this.split(''); - } - - function succ() { - return this.slice(0, this.length - 1) + - String.fromCharCode(this.charCodeAt(this.length - 1) + 1); - } - - function times(count) { - return count < 1 ? '' : new Array(count + 1).join(this); - } - - function camelize() { - return this.replace(/-+(.)?/g, function(match, chr) { - return chr ? chr.toUpperCase() : ''; - }); - } - - function capitalize() { - return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); - } - - function underscore() { - return this.replace(/::/g, '/') - .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') - .replace(/([a-z\d])([A-Z])/g, '$1_$2') - .replace(/-/g, '_') - .toLowerCase(); - } - - function dasherize() { - return this.replace(/_/g, '-'); - } - - function inspect(useDoubleQuotes) { - var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { - if (character in String.specialChar) { - return String.specialChar[character]; - } - return '\\u00' + character.charCodeAt().toPaddedString(2, 16); - }); - if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; - return "'" + escapedString.replace(/'/g, '\\\'') + "'"; - } - - function unfilterJSON(filter) { - return this.replace(filter || Prototype.JSONFilter, '$1'); - } - - function isJSON() { - var str = this; - if (str.blank()) return false; - str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); - str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); - str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); - return (/^[\],:{}\s]*$/).test(str); - } - - function evalJSON(sanitize) { - var json = this.unfilterJSON(), - cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; - if (cx.test(json)) { - json = json.replace(cx, function (a) { - return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); - }); - } - try { - if (!sanitize || json.isJSON()) return eval('(' + json + ')'); - } catch (e) { } - throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); - } - - function parseJSON() { - var json = this.unfilterJSON(); - return JSON.parse(json); - } - - function include(pattern) { - return this.indexOf(pattern) > -1; - } - - function startsWith(pattern) { - return this.lastIndexOf(pattern, 0) === 0; - } - - function endsWith(pattern) { - var d = this.length - pattern.length; - return d >= 0 && this.indexOf(pattern, d) === d; - } - - function empty() { - return this == ''; - } - - function blank() { - return /^\s*$/.test(this); - } - - function interpolate(object, pattern) { - return new Template(this, pattern).evaluate(object); - } - - return { - gsub: gsub, - sub: sub, - scan: scan, - truncate: truncate, - strip: String.prototype.trim || strip, - stripTags: stripTags, - stripScripts: stripScripts, - extractScripts: extractScripts, - evalScripts: evalScripts, - escapeHTML: escapeHTML, - unescapeHTML: unescapeHTML, - toQueryParams: toQueryParams, - parseQuery: toQueryParams, - toArray: toArray, - succ: succ, - times: times, - camelize: camelize, - capitalize: capitalize, - underscore: underscore, - dasherize: dasherize, - inspect: inspect, - unfilterJSON: unfilterJSON, - isJSON: isJSON, - evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, - include: include, - startsWith: startsWith, - endsWith: endsWith, - empty: empty, - blank: blank, - interpolate: interpolate - }; -})()); - -var Template = Class.create({ - initialize: function(template, pattern) { - this.template = template.toString(); - this.pattern = pattern || Template.Pattern; - }, - - evaluate: function(object) { - if (object && Object.isFunction(object.toTemplateReplacements)) - object = object.toTemplateReplacements(); - - return this.template.gsub(this.pattern, function(match) { - if (object == null) return (match[1] + ''); - - var before = match[1] || ''; - if (before == '\\') return match[2]; - - var ctx = object, expr = match[3], - pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; - - match = pattern.exec(expr); - if (match == null) return before; - - while (match != null) { - var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1]; - ctx = ctx[comp]; - if (null == ctx || '' == match[3]) break; - expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); - match = pattern.exec(expr); - } - - return before + String.interpret(ctx); - }); - } -}); -Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; - -var $break = { }; - -var Enumerable = (function() { - function each(iterator, context) { - var index = 0; - try { - this._each(function(value) { - iterator.call(context, value, index++); - }); - } catch (e) { - if (e != $break) throw e; - } - return this; - } - - function eachSlice(number, iterator, context) { - var index = -number, slices = [], array = this.toArray(); - if (number < 1) return array; - while ((index += number) < array.length) - slices.push(array.slice(index, index+number)); - return slices.collect(iterator, context); - } - - function all(iterator, context) { - iterator = iterator || Prototype.K; - var result = true; - this.each(function(value, index) { - result = result && !!iterator.call(context, value, index); - if (!result) throw $break; - }); - return result; - } - - function any(iterator, context) { - iterator = iterator || Prototype.K; - var result = false; - this.each(function(value, index) { - if (result = !!iterator.call(context, value, index)) - throw $break; - }); - return result; - } - - function collect(iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - this.each(function(value, index) { - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function detect(iterator, context) { - var result; - this.each(function(value, index) { - if (iterator.call(context, value, index)) { - result = value; - throw $break; - } - }); - return result; - } - - function findAll(iterator, context) { - var results = []; - this.each(function(value, index) { - if (iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function grep(filter, iterator, context) { - iterator = iterator || Prototype.K; - var results = []; - - if (Object.isString(filter)) - filter = new RegExp(RegExp.escape(filter)); - - this.each(function(value, index) { - if (filter.match(value)) - results.push(iterator.call(context, value, index)); - }); - return results; - } - - function include(object) { - if (Object.isFunction(this.indexOf)) - if (this.indexOf(object) != -1) return true; - - var found = false; - this.each(function(value) { - if (value == object) { - found = true; - throw $break; - } - }); - return found; - } - - function inGroupsOf(number, fillWith) { - fillWith = Object.isUndefined(fillWith) ? null : fillWith; - return this.eachSlice(number, function(slice) { - while(slice.length < number) slice.push(fillWith); - return slice; - }); - } - - function inject(memo, iterator, context) { - this.each(function(value, index) { - memo = iterator.call(context, memo, value, index); - }); - return memo; - } - - function invoke(method) { - var args = $A(arguments).slice(1); - return this.map(function(value) { - return value[method].apply(value, args); - }); - } - - function max(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value >= result) - result = value; - }); - return result; - } - - function min(iterator, context) { - iterator = iterator || Prototype.K; - var result; - this.each(function(value, index) { - value = iterator.call(context, value, index); - if (result == null || value < result) - result = value; - }); - return result; - } - - function partition(iterator, context) { - iterator = iterator || Prototype.K; - var trues = [], falses = []; - this.each(function(value, index) { - (iterator.call(context, value, index) ? - trues : falses).push(value); - }); - return [trues, falses]; - } - - function pluck(property) { - var results = []; - this.each(function(value) { - results.push(value[property]); - }); - return results; - } - - function reject(iterator, context) { - var results = []; - this.each(function(value, index) { - if (!iterator.call(context, value, index)) - results.push(value); - }); - return results; - } - - function sortBy(iterator, context) { - return this.map(function(value, index) { - return { - value: value, - criteria: iterator.call(context, value, index) - }; - }).sort(function(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - }).pluck('value'); - } - - function toArray() { - return this.map(); - } - - function zip() { - var iterator = Prototype.K, args = $A(arguments); - if (Object.isFunction(args.last())) - iterator = args.pop(); - - var collections = [this].concat(args).map($A); - return this.map(function(value, index) { - return iterator(collections.pluck(index)); - }); - } - - function size() { - return this.toArray().length; - } - - function inspect() { - return '#<Enumerable:' + this.toArray().inspect() + '>'; - } - - - - - - - - - - return { - each: each, - eachSlice: eachSlice, - all: all, - every: all, - any: any, - some: any, - collect: collect, - map: collect, - detect: detect, - findAll: findAll, - select: findAll, - filter: findAll, - grep: grep, - include: include, - member: include, - inGroupsOf: inGroupsOf, - inject: inject, - invoke: invoke, - max: max, - min: min, - partition: partition, - pluck: pluck, - reject: reject, - sortBy: sortBy, - toArray: toArray, - entries: toArray, - zip: zip, - size: size, - inspect: inspect, - find: detect - }; -})(); - -function $A(iterable) { - if (!iterable) return []; - if ('toArray' in Object(iterable)) return iterable.toArray(); - var length = iterable.length || 0, results = new Array(length); - while (length--) results[length] = iterable[length]; - return results; -} - - -function $w(string) { - if (!Object.isString(string)) return []; - string = string.strip(); - return string ? string.split(/\s+/) : []; -} - -Array.from = $A; - - -(function() { - var arrayProto = Array.prototype, - slice = arrayProto.slice, - _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available - - function each(iterator, context) { - for (var i = 0, length = this.length >>> 0; i < length; i++) { - if (i in this) iterator.call(context, this[i], i, this); - } - } - if (!_each) _each = each; - - function clear() { - this.length = 0; - return this; - } - - function first() { - return this[0]; - } - - function last() { - return this[this.length - 1]; - } - - function compact() { - return this.select(function(value) { - return value != null; - }); - } - - function flatten() { - return this.inject([], function(array, value) { - if (Object.isArray(value)) - return array.concat(value.flatten()); - array.push(value); - return array; - }); - } - - function without() { - var values = slice.call(arguments, 0); - return this.select(function(value) { - return !values.include(value); - }); - } - - function reverse(inline) { - return (inline === false ? this.toArray() : this)._reverse(); - } - - function uniq(sorted) { - return this.inject([], function(array, value, index) { - if (0 == index || (sorted ? array.last() != value : !array.include(value))) - array.push(value); - return array; - }); - } - - function intersect(array) { - return this.uniq().findAll(function(item) { - return array.detect(function(value) { return item === value }); - }); - } - - - function clone() { - return slice.call(this, 0); - } - - function size() { - return this.length; - } - - function inspect() { - return '[' + this.map(Object.inspect).join(', ') + ']'; - } - - function indexOf(item, i) { - i || (i = 0); - var length = this.length; - if (i < 0) i = length + i; - for (; i < length; i++) - if (this[i] === item) return i; - return -1; - } - - function lastIndexOf(item, i) { - i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; - var n = this.slice(0, i).reverse().indexOf(item); - return (n < 0) ? n : i - n - 1; - } - - function concat() { - var array = slice.call(this, 0), item; - for (var i = 0, length = arguments.length; i < length; i++) { - item = arguments[i]; - if (Object.isArray(item) && !('callee' in item)) { - for (var j = 0, arrayLength = item.length; j < arrayLength; j++) - array.push(item[j]); - } else { - array.push(item); - } - } - return array; - } - - Object.extend(arrayProto, Enumerable); - - if (!arrayProto._reverse) - arrayProto._reverse = arrayProto.reverse; - - Object.extend(arrayProto, { - _each: _each, - clear: clear, - first: first, - last: last, - compact: compact, - flatten: flatten, - without: without, - reverse: reverse, - uniq: uniq, - intersect: intersect, - clone: clone, - toArray: clone, - size: size, - inspect: inspect - }); - - var CONCAT_ARGUMENTS_BUGGY = (function() { - return [].concat(arguments)[0][0] !== 1; - })(1,2) - - if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; - - if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; - if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; -})(); -function $H(object) { - return new Hash(object); -}; - -var Hash = Class.create(Enumerable, (function() { - function initialize(object) { - this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); - } - - - function _each(iterator) { - for (var key in this._object) { - var value = this._object[key], pair = [key, value]; - pair.key = key; - pair.value = value; - iterator(pair); - } - } - - function set(key, value) { - return this._object[key] = value; - } - - function get(key) { - if (this._object[key] !== Object.prototype[key]) - return this._object[key]; - } - - function unset(key) { - var value = this._object[key]; - delete this._object[key]; - return value; - } - - function toObject() { - return Object.clone(this._object); - } - - - - function keys() { - return this.pluck('key'); - } - - function values() { - return this.pluck('value'); - } - - function index(value) { - var match = this.detect(function(pair) { - return pair.value === value; - }); - return match && match.key; - } - - function merge(object) { - return this.clone().update(object); - } - - function update(object) { - return new Hash(object).inject(this, function(result, pair) { - result.set(pair.key, pair.value); - return result; - }); - } - - function toQueryPair(key, value) { - if (Object.isUndefined(value)) return key; - return key + '=' + encodeURIComponent(String.interpret(value)); - } - - function toQueryString() { - return this.inject([], function(results, pair) { - var key = encodeURIComponent(pair.key), values = pair.value; - - if (values && typeof values == 'object') { - if (Object.isArray(values)) { - var queryValues = []; - for (var i = 0, len = values.length, value; i < len; i++) { - value = values[i]; - queryValues.push(toQueryPair(key, value)); - } - return results.concat(queryValues); - } - } else results.push(toQueryPair(key, values)); - return results; - }).join('&'); - } - - function inspect() { - return '#<Hash:{' + this.map(function(pair) { - return pair.map(Object.inspect).join(': '); - }).join(', ') + '}>'; - } - - function clone() { - return new Hash(this); - } - - return { - initialize: initialize, - _each: _each, - set: set, - get: get, - unset: unset, - toObject: toObject, - toTemplateReplacements: toObject, - keys: keys, - values: values, - index: index, - merge: merge, - update: update, - toQueryString: toQueryString, - inspect: inspect, - toJSON: toObject, - clone: clone - }; -})()); - -Hash.from = $H; -Object.extend(Number.prototype, (function() { - function toColorPart() { - return this.toPaddedString(2, 16); - } - - function succ() { - return this + 1; - } - - function times(iterator, context) { - $R(0, this, true).each(iterator, context); - return this; - } - - function toPaddedString(length, radix) { - var string = this.toString(radix || 10); - return '0'.times(length - string.length) + string; - } - - function abs() { - return Math.abs(this); - } - - function round() { - return Math.round(this); - } - - function ceil() { - return Math.ceil(this); - } - - function floor() { - return Math.floor(this); - } - - return { - toColorPart: toColorPart, - succ: succ, - times: times, - toPaddedString: toPaddedString, - abs: abs, - round: round, - ceil: ceil, - floor: floor - }; -})()); - -function $R(start, end, exclusive) { - return new ObjectRange(start, end, exclusive); -} - -var ObjectRange = Class.create(Enumerable, (function() { - function initialize(start, end, exclusive) { - this.start = start; - this.end = end; - this.exclusive = exclusive; - } - - function _each(iterator) { - var value = this.start; - while (this.include(value)) { - iterator(value); - value = value.succ(); - } - } - - function include(value) { - if (value < this.start) - return false; - if (this.exclusive) - return value < this.end; - return value <= this.end; - } - - return { - initialize: initialize, - _each: _each, - include: include - }; -})()); - - - -var Ajax = { - getTransport: function() { - return Try.these( - function() {return new XMLHttpRequest()}, - function() {return new ActiveXObject('Msxml2.XMLHTTP')}, - function() {return new ActiveXObject('Microsoft.XMLHTTP')} - ) || false; - }, - - activeRequestCount: 0 -}; - -Ajax.Responders = { - responders: [], - - _each: function(iterator) { - this.responders._each(iterator); - }, - - register: function(responder) { - if (!this.include(responder)) - this.responders.push(responder); - }, - - unregister: function(responder) { - this.responders = this.responders.without(responder); - }, - - dispatch: function(callback, request, transport, json) { - this.each(function(responder) { - if (Object.isFunction(responder[callback])) { - try { - responder[callback].apply(responder, [request, transport, json]); - } catch (e) { } - } - }); - } -}; - -Object.extend(Ajax.Responders, Enumerable); - -Ajax.Responders.register({ - onCreate: function() { Ajax.activeRequestCount++ }, - onComplete: function() { Ajax.activeRequestCount-- } -}); -Ajax.Base = Class.create({ - initialize: function(options) { - this.options = { - method: 'post', - asynchronous: true, - contentType: 'application/x-www-form-urlencoded', - encoding: 'UTF-8', - parameters: '', - evalJSON: true, - evalJS: true - }; - Object.extend(this.options, options || { }); - - this.options.method = this.options.method.toLowerCase(); - - if (Object.isHash(this.options.parameters)) - this.options.parameters = this.options.parameters.toObject(); - } -}); -Ajax.Request = Class.create(Ajax.Base, { - _complete: false, - - initialize: function($super, url, options) { - $super(options); - this.transport = Ajax.getTransport(); - this.request(url); - }, - - request: function(url) { - this.url = url; - this.method = this.options.method; - var params = Object.isString(this.options.parameters) ? - this.options.parameters : - Object.toQueryString(this.options.parameters); - - if (!['get', 'post'].include(this.method)) { - params += (params ? '&' : '') + "_method=" + this.method; - this.method = 'post'; - } - - if (params && this.method === 'get') { - this.url += (this.url.include('?') ? '&' : '?') + params; - } - - this.parameters = params.toQueryParams(); - - try { - var response = new Ajax.Response(this); - if (this.options.onCreate) this.options.onCreate(response); - Ajax.Responders.dispatch('onCreate', this, response); - - this.transport.open(this.method.toUpperCase(), this.url, - this.options.asynchronous); - - if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); - - this.transport.onreadystatechange = this.onStateChange.bind(this); - this.setRequestHeaders(); - - this.body = this.method == 'post' ? (this.options.postBody || params) : null; - this.transport.send(this.body); - - /* Force Firefox to handle ready state 4 for synchronous requests */ - if (!this.options.asynchronous && this.transport.overrideMimeType) - this.onStateChange(); - - } - catch (e) { - this.dispatchException(e); - } - }, - - onStateChange: function() { - var readyState = this.transport.readyState; - if (readyState > 1 && !((readyState == 4) && this._complete)) - this.respondToReadyState(this.transport.readyState); - }, - - setRequestHeaders: function() { - var headers = { - 'X-Requested-With': 'XMLHttpRequest', - 'X-Prototype-Version': Prototype.Version, - 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' - }; - - if (this.method == 'post') { - headers['Content-type'] = this.options.contentType + - (this.options.encoding ? '; charset=' + this.options.encoding : ''); - - /* Force "Connection: close" for older Mozilla browsers to work - * around a bug where XMLHttpRequest sends an incorrect - * Content-length header. See Mozilla Bugzilla #246651. - */ - if (this.transport.overrideMimeType && - (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) - headers['Connection'] = 'close'; - } - - if (typeof this.options.requestHeaders == 'object') { - var extras = this.options.requestHeaders; - - if (Object.isFunction(extras.push)) - for (var i = 0, length = extras.length; i < length; i += 2) - headers[extras[i]] = extras[i+1]; - else - $H(extras).each(function(pair) { headers[pair.key] = pair.value }); - } - - for (var name in headers) - this.transport.setRequestHeader(name, headers[name]); - }, - - success: function() { - var status = this.getStatus(); - return !status || (status >= 200 && status < 300) || status == 304; - }, - - getStatus: function() { - try { - if (this.transport.status === 1223) return 204; - return this.transport.status || 0; - } catch (e) { return 0 } - }, - - respondToReadyState: function(readyState) { - var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); - - if (state == 'Complete') { - try { - this._complete = true; - (this.options['on' + response.status] - || this.options['on' + (this.success() ? 'Success' : 'Failure')] - || Prototype.emptyFunction)(response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - var contentType = response.getHeader('Content-type'); - if (this.options.evalJS == 'force' - || (this.options.evalJS && this.isSameOrigin() && contentType - && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) - this.evalResponse(); - } - - try { - (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); - Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); - } catch (e) { - this.dispatchException(e); - } - - if (state == 'Complete') { - this.transport.onreadystatechange = Prototype.emptyFunction; - } - }, - - isSameOrigin: function() { - var m = this.url.match(/^\s*https?:\/\/[^\/]*/); - return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ - protocol: location.protocol, - domain: document.domain, - port: location.port ? ':' + location.port : '' - })); - }, - - getHeader: function(name) { - try { - return this.transport.getResponseHeader(name) || null; - } catch (e) { return null; } - }, - - evalResponse: function() { - try { - return eval((this.transport.responseText || '').unfilterJSON()); - } catch (e) { - this.dispatchException(e); - } - }, - - dispatchException: function(exception) { - (this.options.onException || Prototype.emptyFunction)(this, exception); - Ajax.Responders.dispatch('onException', this, exception); - } -}); - -Ajax.Request.Events = - ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; - - - - - - - - -Ajax.Response = Class.create({ - initialize: function(request){ - this.request = request; - var transport = this.transport = request.transport, - readyState = this.readyState = transport.readyState; - - if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { - this.status = this.getStatus(); - this.statusText = this.getStatusText(); - this.responseText = String.interpret(transport.responseText); - this.headerJSON = this._getHeaderJSON(); - } - - if (readyState == 4) { - var xml = transport.responseXML; - this.responseXML = Object.isUndefined(xml) ? null : xml; - this.responseJSON = this._getResponseJSON(); - } - }, - - status: 0, - - statusText: '', - - getStatus: Ajax.Request.prototype.getStatus, - - getStatusText: function() { - try { - return this.transport.statusText || ''; - } catch (e) { return '' } - }, - - getHeader: Ajax.Request.prototype.getHeader, - - getAllHeaders: function() { - try { - return this.getAllResponseHeaders(); - } catch (e) { return null } - }, - - getResponseHeader: function(name) { - return this.transport.getResponseHeader(name); - }, - - getAllResponseHeaders: function() { - return this.transport.getAllResponseHeaders(); - }, - - _getHeaderJSON: function() { - var json = this.getHeader('X-JSON'); - if (!json) return null; - json = decodeURIComponent(escape(json)); - try { - return json.evalJSON(this.request.options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - }, - - _getResponseJSON: function() { - var options = this.request.options; - if (!options.evalJSON || (options.evalJSON != 'force' && - !(this.getHeader('Content-type') || '').include('application/json')) || - this.responseText.blank()) - return null; - try { - return this.responseText.evalJSON(options.sanitizeJSON || - !this.request.isSameOrigin()); - } catch (e) { - this.request.dispatchException(e); - } - } -}); - -Ajax.Updater = Class.create(Ajax.Request, { - initialize: function($super, container, url, options) { - this.container = { - success: (container.success || container), - failure: (container.failure || (container.success ? null : container)) - }; - - options = Object.clone(options); - var onComplete = options.onComplete; - options.onComplete = (function(response, json) { - this.updateContent(response.responseText); - if (Object.isFunction(onComplete)) onComplete(response, json); - }).bind(this); - - $super(url, options); - }, - - updateContent: function(responseText) { - var receiver = this.container[this.success() ? 'success' : 'failure'], - options = this.options; - - if (!options.evalScripts) responseText = responseText.stripScripts(); - - if (receiver = $(receiver)) { - if (options.insertion) { - if (Object.isString(options.insertion)) { - var insertion = { }; insertion[options.insertion] = responseText; - receiver.insert(insertion); - } - else options.insertion(receiver, responseText); - } - else receiver.update(responseText); - } - } -}); - -Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { - initialize: function($super, container, url, options) { - $super(options); - this.onComplete = this.options.onComplete; - - this.frequency = (this.options.frequency || 2); - this.decay = (this.options.decay || 1); - - this.updater = { }; - this.container = container; - this.url = url; - - this.start(); - }, - - start: function() { - this.options.onComplete = this.updateComplete.bind(this); - this.onTimerEvent(); - }, - - stop: function() { - this.updater.options.onComplete = undefined; - clearTimeout(this.timer); - (this.onComplete || Prototype.emptyFunction).apply(this, arguments); - }, - - updateComplete: function(response) { - if (this.options.decay) { - this.decay = (response.responseText == this.lastText ? - this.decay * this.options.decay : 1); - - this.lastText = response.responseText; - } - this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); - }, - - onTimerEvent: function() { - this.updater = new Ajax.Updater(this.container, this.url, this.options); - } -}); - - -function $(element) { - if (arguments.length > 1) { - for (var i = 0, elements = [], length = arguments.length; i < length; i++) - elements.push($(arguments[i])); - return elements; - } - if (Object.isString(element)) - element = document.getElementById(element); - return Element.extend(element); -} - -if (Prototype.BrowserFeatures.XPath) { - document._getElementsByXPath = function(expression, parentElement) { - var results = []; - var query = document.evaluate(expression, $(parentElement) || document, - null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - for (var i = 0, length = query.snapshotLength; i < length; i++) - results.push(Element.extend(query.snapshotItem(i))); - return results; - }; -} - -/*--------------------------------------------------------------------------*/ - -if (!Node) var Node = { }; - -if (!Node.ELEMENT_NODE) { - Object.extend(Node, { - ELEMENT_NODE: 1, - ATTRIBUTE_NODE: 2, - TEXT_NODE: 3, - CDATA_SECTION_NODE: 4, - ENTITY_REFERENCE_NODE: 5, - ENTITY_NODE: 6, - PROCESSING_INSTRUCTION_NODE: 7, - COMMENT_NODE: 8, - DOCUMENT_NODE: 9, - DOCUMENT_TYPE_NODE: 10, - DOCUMENT_FRAGMENT_NODE: 11, - NOTATION_NODE: 12 - }); -} - - - -(function(global) { - function shouldUseCache(tagName, attributes) { - if (tagName === 'select') return false; - if ('type' in attributes) return false; - return true; - } - - var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ - try { - var el = document.createElement('<input name="x">'); - return el.tagName.toLowerCase() === 'input' && el.name === 'x'; - } - catch(err) { - return false; - } - })(); - - var element = global.Element; - - global.Element = function(tagName, attributes) { - attributes = attributes || { }; - tagName = tagName.toLowerCase(); - var cache = Element.cache; - - if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { - tagName = '<' + tagName + ' name="' + attributes.name + '">'; - delete attributes.name; - return Element.writeAttribute(document.createElement(tagName), attributes); - } - - if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); - - var node = shouldUseCache(tagName, attributes) ? - cache[tagName].cloneNode(false) : document.createElement(tagName); - - return Element.writeAttribute(node, attributes); - }; - - Object.extend(global.Element, element || { }); - if (element) global.Element.prototype = element.prototype; - -})(this); - -Element.idCounter = 1; -Element.cache = { }; - -Element._purgeElement = function(element) { - var uid = element._prototypeUID; - if (uid) { - Element.stopObserving(element); - element._prototypeUID = void 0; - delete Element.Storage[uid]; - } -} - -Element.Methods = { - visible: function(element) { - return $(element).style.display != 'none'; - }, - - toggle: function(element) { - element = $(element); - Element[Element.visible(element) ? 'hide' : 'show'](element); - return element; - }, - - hide: function(element) { - element = $(element); - element.style.display = 'none'; - return element; - }, - - show: function(element) { - element = $(element); - element.style.display = ''; - return element; - }, - - remove: function(element) { - element = $(element); - element.parentNode.removeChild(element); - return element; - }, - - update: (function(){ - - var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ - var el = document.createElement("select"), - isBuggy = true; - el.innerHTML = "<option value=\"test\">test</option>"; - if (el.options && el.options[0]) { - isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; - } - el = null; - return isBuggy; - })(); - - var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ - try { - var el = document.createElement("table"); - if (el && el.tBodies) { - el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; - var isBuggy = typeof el.tBodies[0] == "undefined"; - el = null; - return isBuggy; - } - } catch (e) { - return true; - } - })(); - - var LINK_ELEMENT_INNERHTML_BUGGY = (function() { - try { - var el = document.createElement('div'); - el.innerHTML = "<link>"; - var isBuggy = (el.childNodes.length === 0); - el = null; - return isBuggy; - } catch(e) { - return true; - } - })(); - - var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || - TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; - - var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { - var s = document.createElement("script"), - isBuggy = false; - try { - s.appendChild(document.createTextNode("")); - isBuggy = !s.firstChild || - s.firstChild && s.firstChild.nodeType !== 3; - } catch (e) { - isBuggy = true; - } - s = null; - return isBuggy; - })(); - - - function update(element, content) { - element = $(element); - var purgeElement = Element._purgeElement; - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - while (i--) purgeElement(descendants[i]); - - if (content && content.toElement) - content = content.toElement(); - - if (Object.isElement(content)) - return element.update().insert(content); - - content = Object.toHTML(content); - - var tagName = element.tagName.toUpperCase(); - - if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { - element.text = content; - return element; - } - - if (ANY_INNERHTML_BUGGY) { - if (tagName in Element._insertionTranslations.tags) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - Element._getContentFromAnonymousElement(tagName, content.stripScripts()) - .each(function(node) { - element.appendChild(node) - }); - } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true); - nodes.each(function(node) { element.appendChild(node) }); - } - else { - element.innerHTML = content.stripScripts(); - } - } - else { - element.innerHTML = content.stripScripts(); - } - - content.evalScripts.bind(content).defer(); - return element; - } - - return update; - })(), - - replace: function(element, content) { - element = $(element); - if (content && content.toElement) content = content.toElement(); - else if (!Object.isElement(content)) { - content = Object.toHTML(content); - var range = element.ownerDocument.createRange(); - range.selectNode(element); - content.evalScripts.bind(content).defer(); - content = range.createContextualFragment(content.stripScripts()); - } - element.parentNode.replaceChild(content, element); - return element; - }, - - insert: function(element, insertions) { - element = $(element); - - if (Object.isString(insertions) || Object.isNumber(insertions) || - Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML))) - insertions = {bottom:insertions}; - - var content, insert, tagName, childNodes; - - for (var position in insertions) { - content = insertions[position]; - position = position.toLowerCase(); - insert = Element._insertionTranslations[position]; - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - insert(element, content); - continue; - } - - content = Object.toHTML(content); - - tagName = ((position == 'before' || position == 'after') - ? element.parentNode : element).tagName.toUpperCase(); - - childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - - if (position == 'top' || position == 'after') childNodes.reverse(); - childNodes.each(insert.curry(element)); - - content.evalScripts.bind(content).defer(); - } - - return element; - }, - - wrap: function(element, wrapper, attributes) { - element = $(element); - if (Object.isElement(wrapper)) - $(wrapper).writeAttribute(attributes || { }); - else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes); - else wrapper = new Element('div', wrapper); - if (element.parentNode) - element.parentNode.replaceChild(wrapper, element); - wrapper.appendChild(element); - return wrapper; - }, - - inspect: function(element) { - element = $(element); - var result = '<' + element.tagName.toLowerCase(); - $H({'id': 'id', 'className': 'class'}).each(function(pair) { - var property = pair.first(), - attribute = pair.last(), - value = (element[property] || '').toString(); - if (value) result += ' ' + attribute + '=' + value.inspect(true); - }); - return result + '>'; - }, - - recursivelyCollect: function(element, property, maximumLength) { - element = $(element); - maximumLength = maximumLength || -1; - var elements = []; - - while (element = element[property]) { - if (element.nodeType == 1) - elements.push(Element.extend(element)); - if (elements.length == maximumLength) - break; - } - - return elements; - }, - - ancestors: function(element) { - return Element.recursivelyCollect(element, 'parentNode'); - }, - - descendants: function(element) { - return Element.select(element, "*"); - }, - - firstDescendant: function(element) { - element = $(element).firstChild; - while (element && element.nodeType != 1) element = element.nextSibling; - return $(element); - }, - - immediateDescendants: function(element) { - var results = [], child = $(element).firstChild; - while (child) { - if (child.nodeType === 1) { - results.push(Element.extend(child)); - } - child = child.nextSibling; - } - return results; - }, - - previousSiblings: function(element, maximumLength) { - return Element.recursivelyCollect(element, 'previousSibling'); - }, - - nextSiblings: function(element) { - return Element.recursivelyCollect(element, 'nextSibling'); - }, - - siblings: function(element) { - element = $(element); - return Element.previousSiblings(element).reverse() - .concat(Element.nextSiblings(element)); - }, - - match: function(element, selector) { - element = $(element); - if (Object.isString(selector)) - return Prototype.Selector.match(element, selector); - return selector.match(element); - }, - - up: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return $(element.parentNode); - var ancestors = Element.ancestors(element); - return Object.isNumber(expression) ? ancestors[expression] : - Prototype.Selector.find(ancestors, expression, index); - }, - - down: function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return Element.firstDescendant(element); - return Object.isNumber(expression) ? Element.descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - }, - - previous: function(element, expression, index) { - element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; - - if (expression) { - return Prototype.Selector.find(element.previousSiblings(), expression, index); - } else { - return element.recursivelyCollect("previousSibling", index + 1)[index]; - } - }, - - next: function(element, expression, index) { - element = $(element); - if (Object.isNumber(expression)) index = expression, expression = false; - if (!Object.isNumber(index)) index = 0; - - if (expression) { - return Prototype.Selector.find(element.nextSiblings(), expression, index); - } else { - var maximumLength = Object.isNumber(index) ? index + 1 : 1; - return element.recursivelyCollect("nextSibling", index + 1)[index]; - } - }, - - - select: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element); - }, - - adjacent: function(element) { - element = $(element); - var expressions = Array.prototype.slice.call(arguments, 1).join(', '); - return Prototype.Selector.select(expressions, element.parentNode).without(element); - }, - - identify: function(element) { - element = $(element); - var id = Element.readAttribute(element, 'id'); - if (id) return id; - do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); - Element.writeAttribute(element, 'id', id); - return id; - }, - - readAttribute: function(element, name) { - element = $(element); - if (Prototype.Browser.IE) { - var t = Element._attributeTranslations.read; - if (t.values[name]) return t.values[name](element, name); - if (t.names[name]) name = t.names[name]; - if (name.include(':')) { - return (!element.attributes || !element.attributes[name]) ? null : - element.attributes[name].value; - } - } - return element.getAttribute(name); - }, - - writeAttribute: function(element, name, value) { - element = $(element); - var attributes = { }, t = Element._attributeTranslations.write; - - if (typeof name == 'object') attributes = name; - else attributes[name] = Object.isUndefined(value) ? true : value; - - for (var attr in attributes) { - name = t.names[attr] || attr; - value = attributes[attr]; - if (t.values[attr]) name = t.values[attr](element, value); - if (value === false || value === null) - element.removeAttribute(name); - else if (value === true) - element.setAttribute(name, name); - else element.setAttribute(name, value); - } - return element; - }, - - getHeight: function(element) { - return Element.getDimensions(element).height; - }, - - getWidth: function(element) { - return Element.getDimensions(element).width; - }, - - classNames: function(element) { - return new Element.ClassNames(element); - }, - - hasClassName: function(element, className) { - if (!(element = $(element))) return; - var elementClassName = element.className; - return (elementClassName.length > 0 && (elementClassName == className || - new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); - }, - - addClassName: function(element, className) { - if (!(element = $(element))) return; - if (!Element.hasClassName(element, className)) - element.className += (element.className ? ' ' : '') + className; - return element; - }, - - removeClassName: function(element, className) { - if (!(element = $(element))) return; - element.className = element.className.replace( - new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); - return element; - }, - - toggleClassName: function(element, className) { - if (!(element = $(element))) return; - return Element[Element.hasClassName(element, className) ? - 'removeClassName' : 'addClassName'](element, className); - }, - - cleanWhitespace: function(element) { - element = $(element); - var node = element.firstChild; - while (node) { - var nextNode = node.nextSibling; - if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) - element.removeChild(node); - node = nextNode; - } - return element; - }, - - empty: function(element) { - return $(element).innerHTML.blank(); - }, - - descendantOf: function(element, ancestor) { - element = $(element), ancestor = $(ancestor); - - if (element.compareDocumentPosition) - return (element.compareDocumentPosition(ancestor) & 8) === 8; - - if (ancestor.contains) - return ancestor.contains(element) && ancestor !== element; - - while (element = element.parentNode) - if (element == ancestor) return true; - - return false; - }, - - scrollTo: function(element) { - element = $(element); - var pos = Element.cumulativeOffset(element); - window.scrollTo(pos[0], pos[1]); - return element; - }, - - getStyle: function(element, style) { - element = $(element); - style = style == 'float' ? 'cssFloat' : style.camelize(); - var value = element.style[style]; - if (!value || value == 'auto') { - var css = document.defaultView.getComputedStyle(element, null); - value = css ? css[style] : null; - } - if (style == 'opacity') return value ? parseFloat(value) : 1.0; - return value == 'auto' ? null : value; - }, - - getOpacity: function(element) { - return $(element).getStyle('opacity'); - }, - - setStyle: function(element, styles) { - element = $(element); - var elementStyle = element.style, match; - if (Object.isString(styles)) { - element.style.cssText += ';' + styles; - return styles.include('opacity') ? - element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element; - } - for (var property in styles) - if (property == 'opacity') element.setOpacity(styles[property]); - else - elementStyle[(property == 'float' || property == 'cssFloat') ? - (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') : - property] = styles[property]; - - return element; - }, - - setOpacity: function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - return element; - }, - - makePositioned: function(element) { - element = $(element); - var pos = Element.getStyle(element, 'position'); - if (pos == 'static' || !pos) { - element._madePositioned = true; - element.style.position = 'relative'; - if (Prototype.Browser.Opera) { - element.style.top = 0; - element.style.left = 0; - } - } - return element; - }, - - undoPositioned: function(element) { - element = $(element); - if (element._madePositioned) { - element._madePositioned = undefined; - element.style.position = - element.style.top = - element.style.left = - element.style.bottom = - element.style.right = ''; - } - return element; - }, - - makeClipping: function(element) { - element = $(element); - if (element._overflow) return element; - element._overflow = Element.getStyle(element, 'overflow') || 'auto'; - if (element._overflow !== 'hidden') - element.style.overflow = 'hidden'; - return element; - }, - - undoClipping: function(element) { - element = $(element); - if (!element._overflow) return element; - element.style.overflow = element._overflow == 'auto' ? '' : element._overflow; - element._overflow = null; - return element; - }, - - clonePosition: function(element, source) { - var options = Object.extend({ - setLeft: true, - setTop: true, - setWidth: true, - setHeight: true, - offsetTop: 0, - offsetLeft: 0 - }, arguments[2] || { }); - - source = $(source); - var p = Element.viewportOffset(source), delta = [0, 0], parent = null; - - element = $(element); - - if (Element.getStyle(element, 'position') == 'absolute') { - parent = Element.getOffsetParent(element); - delta = Element.viewportOffset(parent); - } - - if (parent == document.body) { - delta[0] -= document.body.offsetLeft; - delta[1] -= document.body.offsetTop; - } - - if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; - if (options.setTop) element.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; - if (options.setWidth) element.style.width = source.offsetWidth + 'px'; - if (options.setHeight) element.style.height = source.offsetHeight + 'px'; - return element; - } -}; - -Object.extend(Element.Methods, { - getElementsBySelector: Element.Methods.select, - - childElements: Element.Methods.immediateDescendants -}); - -Element._attributeTranslations = { - write: { - names: { - className: 'class', - htmlFor: 'for' - }, - values: { } - } -}; - -if (Prototype.Browser.Opera) { - Element.Methods.getStyle = Element.Methods.getStyle.wrap( - function(proceed, element, style) { - switch (style) { - case 'height': case 'width': - if (!Element.visible(element)) return null; - - var dim = parseInt(proceed(element, style), 10); - - if (dim !== element['offset' + style.capitalize()]) - return dim + 'px'; - - var properties; - if (style === 'height') { - properties = ['border-top-width', 'padding-top', - 'padding-bottom', 'border-bottom-width']; - } - else { - properties = ['border-left-width', 'padding-left', - 'padding-right', 'border-right-width']; - } - return properties.inject(dim, function(memo, property) { - var val = proceed(element, property); - return val === null ? memo : memo - parseInt(val, 10); - }) + 'px'; - default: return proceed(element, style); - } - } - ); - - Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( - function(proceed, element, attribute) { - if (attribute === 'title') return element.title; - return proceed(element, attribute); - } - ); -} - -else if (Prototype.Browser.IE) { - Element.Methods.getStyle = function(element, style) { - element = $(element); - style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize(); - var value = element.style[style]; - if (!value && element.currentStyle) value = element.currentStyle[style]; - - if (style == 'opacity') { - if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/)) - if (value[1]) return parseFloat(value[1]) / 100; - return 1.0; - } - - if (value == 'auto') { - if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none')) - return element['offset' + style.capitalize()] + 'px'; - return null; - } - return value; - }; - - Element.Methods.setOpacity = function(element, value) { - function stripAlpha(filter){ - return filter.replace(/alpha\([^\)]*\)/gi,''); - } - element = $(element); - var currentStyle = element.currentStyle; - if ((currentStyle && !currentStyle.hasLayout) || - (!currentStyle && element.style.zoom == 'normal')) - element.style.zoom = 1; - - var filter = element.getStyle('filter'), style = element.style; - if (value == 1 || value === '') { - (filter = stripAlpha(filter)) ? - style.filter = filter : style.removeAttribute('filter'); - return element; - } else if (value < 0.00001) value = 0; - style.filter = stripAlpha(filter) + - 'alpha(opacity=' + (value * 100) + ')'; - return element; - }; - - Element._attributeTranslations = (function(){ - - var classProp = 'className', - forProp = 'for', - el = document.createElement('div'); - - el.setAttribute(classProp, 'x'); - - if (el.className !== 'x') { - el.setAttribute('class', 'x'); - if (el.className === 'x') { - classProp = 'class'; - } - } - el = null; - - el = document.createElement('label'); - el.setAttribute(forProp, 'x'); - if (el.htmlFor !== 'x') { - el.setAttribute('htmlFor', 'x'); - if (el.htmlFor === 'x') { - forProp = 'htmlFor'; - } - } - el = null; - - return { - read: { - names: { - 'class': classProp, - 'className': classProp, - 'for': forProp, - 'htmlFor': forProp - }, - values: { - _getAttr: function(element, attribute) { - return element.getAttribute(attribute); - }, - _getAttr2: function(element, attribute) { - return element.getAttribute(attribute, 2); - }, - _getAttrNode: function(element, attribute) { - var node = element.getAttributeNode(attribute); - return node ? node.value : ""; - }, - _getEv: (function(){ - - var el = document.createElement('div'), f; - el.onclick = Prototype.emptyFunction; - var value = el.getAttribute('onclick'); - - if (String(value).indexOf('{') > -1) { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - attribute = attribute.toString(); - attribute = attribute.split('{')[1]; - attribute = attribute.split('}')[0]; - return attribute.strip(); - }; - } - else if (value === '') { - f = function(element, attribute) { - attribute = element.getAttribute(attribute); - if (!attribute) return null; - return attribute.strip(); - }; - } - el = null; - return f; - })(), - _flag: function(element, attribute) { - return $(element).hasAttribute(attribute) ? attribute : null; - }, - style: function(element) { - return element.style.cssText.toLowerCase(); - }, - title: function(element) { - return element.title; - } - } - } - } - })(); - - Element._attributeTranslations.write = { - names: Object.extend({ - cellpadding: 'cellPadding', - cellspacing: 'cellSpacing' - }, Element._attributeTranslations.read.names), - values: { - checked: function(element, value) { - element.checked = !!value; - }, - - style: function(element, value) { - element.style.cssText = value ? value : ''; - } - } - }; - - Element._attributeTranslations.has = {}; - - $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + - 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { - Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; - Element._attributeTranslations.has[attr.toLowerCase()] = attr; - }); - - (function(v) { - Object.extend(v, { - href: v._getAttr2, - src: v._getAttr2, - type: v._getAttr, - action: v._getAttrNode, - disabled: v._flag, - checked: v._flag, - readonly: v._flag, - multiple: v._flag, - onload: v._getEv, - onunload: v._getEv, - onclick: v._getEv, - ondblclick: v._getEv, - onmousedown: v._getEv, - onmouseup: v._getEv, - onmouseover: v._getEv, - onmousemove: v._getEv, - onmouseout: v._getEv, - onfocus: v._getEv, - onblur: v._getEv, - onkeypress: v._getEv, - onkeydown: v._getEv, - onkeyup: v._getEv, - onsubmit: v._getEv, - onreset: v._getEv, - onselect: v._getEv, - onchange: v._getEv - }); - })(Element._attributeTranslations.read.values); - - if (Prototype.BrowserFeatures.ElementExtensions) { - (function() { - function _descendants(element) { - var nodes = element.getElementsByTagName('*'), results = []; - for (var i = 0, node; node = nodes[i]; i++) - if (node.tagName !== "!") // Filter out comment nodes. - results.push(node); - return results; - } - - Element.Methods.down = function(element, expression, index) { - element = $(element); - if (arguments.length == 1) return element.firstDescendant(); - return Object.isNumber(expression) ? _descendants(element)[expression] : - Element.select(element, expression)[index || 0]; - } - })(); - } - -} - -else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1) ? 0.999999 : - (value === '') ? '' : (value < 0.00001) ? 0 : value; - return element; - }; -} - -else if (Prototype.Browser.WebKit) { - Element.Methods.setOpacity = function(element, value) { - element = $(element); - element.style.opacity = (value == 1 || value === '') ? '' : - (value < 0.00001) ? 0 : value; - - if (value == 1) - if (element.tagName.toUpperCase() == 'IMG' && element.width) { - element.width++; element.width--; - } else try { - var n = document.createTextNode(' '); - element.appendChild(n); - element.removeChild(n); - } catch (e) { } - - return element; - }; -} - -if ('outerHTML' in document.documentElement) { - Element.Methods.replace = function(element, content) { - element = $(element); - - if (content && content.toElement) content = content.toElement(); - if (Object.isElement(content)) { - element.parentNode.replaceChild(content, element); - return element; - } - - content = Object.toHTML(content); - var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); - - if (Element._insertionTranslations.tags[tagName]) { - var nextSibling = element.next(), - fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts()); - parent.removeChild(element); - if (nextSibling) - fragments.each(function(node) { parent.insertBefore(node, nextSibling) }); - else - fragments.each(function(node) { parent.appendChild(node) }); - } - else element.outerHTML = content.stripScripts(); - - content.evalScripts.bind(content).defer(); - return element; - }; -} - -Element._returnOffset = function(l, t) { - var result = [l, t]; - result.left = l; - result.top = t; - return result; -}; - -Element._getContentFromAnonymousElement = function(tagName, html, force) { - var div = new Element('div'), - t = Element._insertionTranslations.tags[tagName]; - - var workaround = false; - if (t) workaround = true; - else if (force) { - workaround = true; - t = ['', '', 0]; - } - - if (workaround) { - div.innerHTML = ' ' + t[0] + html + t[1]; - div.removeChild(div.firstChild); - for (var i = t[2]; i--; ) { - div = div.firstChild; - } - } - else { - div.innerHTML = html; - } - return $A(div.childNodes); -}; - -Element._insertionTranslations = { - before: function(element, node) { - element.parentNode.insertBefore(node, element); - }, - top: function(element, node) { - element.insertBefore(node, element.firstChild); - }, - bottom: function(element, node) { - element.appendChild(node); - }, - after: function(element, node) { - element.parentNode.insertBefore(node, element.nextSibling); - }, - tags: { - TABLE: ['<table>', '</table>', 1], - TBODY: ['<table><tbody>', '</tbody></table>', 2], - TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], - TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], - SELECT: ['<select>', '</select>', 1] - } -}; - -(function() { - var tags = Element._insertionTranslations.tags; - Object.extend(tags, { - THEAD: tags.TBODY, - TFOOT: tags.TBODY, - TH: tags.TD - }); -})(); - -Element.Methods.Simulated = { - hasAttribute: function(element, attribute) { - attribute = Element._attributeTranslations.has[attribute] || attribute; - var node = $(element).getAttributeNode(attribute); - return !!(node && node.specified); - } -}; - -Element.Methods.ByTag = { }; - -Object.extend(Element, Element.Methods); - -(function(div) { - - if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { - window.HTMLElement = { }; - window.HTMLElement.prototype = div['__proto__']; - Prototype.BrowserFeatures.ElementExtensions = true; - } - - div = null; - -})(document.createElement('div')); - -Element.extend = (function() { - - function checkDeficiency(tagName) { - if (typeof window.Element != 'undefined') { - var proto = window.Element.prototype; - if (proto) { - var id = '_' + (Math.random()+'').slice(2), - el = document.createElement(tagName); - proto[id] = 'x'; - var isBuggy = (el[id] !== 'x'); - delete proto[id]; - el = null; - return isBuggy; - } - } - return false; - } - - function extendElementWith(element, methods) { - for (var property in methods) { - var value = methods[property]; - if (Object.isFunction(value) && !(property in element)) - element[property] = value.methodize(); - } - } - - var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); - - if (Prototype.BrowserFeatures.SpecificElementExtensions) { - if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { - return function(element) { - if (element && typeof element._extendedByPrototype == 'undefined') { - var t = element.tagName; - if (t && (/^(?:object|applet|embed)$/i.test(t))) { - extendElementWith(element, Element.Methods); - extendElementWith(element, Element.Methods.Simulated); - extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); - } - } - return element; - } - } - return Prototype.K; - } - - var Methods = { }, ByTag = Element.Methods.ByTag; - - var extend = Object.extend(function(element) { - if (!element || typeof element._extendedByPrototype != 'undefined' || - element.nodeType != 1 || element == window) return element; - - var methods = Object.clone(Methods), - tagName = element.tagName.toUpperCase(); - - if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); - - extendElementWith(element, methods); - - element._extendedByPrototype = Prototype.emptyFunction; - return element; - - }, { - refresh: function() { - if (!Prototype.BrowserFeatures.ElementExtensions) { - Object.extend(Methods, Element.Methods); - Object.extend(Methods, Element.Methods.Simulated); - } - } - }); - - extend.refresh(); - return extend; -})(); - -if (document.documentElement.hasAttribute) { - Element.hasAttribute = function(element, attribute) { - return element.hasAttribute(attribute); - }; -} -else { - Element.hasAttribute = Element.Methods.Simulated.hasAttribute; -} - -Element.addMethods = function(methods) { - var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; - - if (!methods) { - Object.extend(Form, Form.Methods); - Object.extend(Form.Element, Form.Element.Methods); - Object.extend(Element.Methods.ByTag, { - "FORM": Object.clone(Form.Methods), - "INPUT": Object.clone(Form.Element.Methods), - "SELECT": Object.clone(Form.Element.Methods), - "TEXTAREA": Object.clone(Form.Element.Methods), - "BUTTON": Object.clone(Form.Element.Methods) - }); - } - - if (arguments.length == 2) { - var tagName = methods; - methods = arguments[1]; - } - - if (!tagName) Object.extend(Element.Methods, methods || { }); - else { - if (Object.isArray(tagName)) tagName.each(extend); - else extend(tagName); - } - - function extend(tagName) { - tagName = tagName.toUpperCase(); - if (!Element.Methods.ByTag[tagName]) - Element.Methods.ByTag[tagName] = { }; - Object.extend(Element.Methods.ByTag[tagName], methods); - } - - function copy(methods, destination, onlyIfAbsent) { - onlyIfAbsent = onlyIfAbsent || false; - for (var property in methods) { - var value = methods[property]; - if (!Object.isFunction(value)) continue; - if (!onlyIfAbsent || !(property in destination)) - destination[property] = value.methodize(); - } - } - - function findDOMClass(tagName) { - var klass; - var trans = { - "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph", - "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList", - "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading", - "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote", - "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION": - "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD": - "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR": - "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": - "FrameSet", "IFRAME": "IFrame" - }; - if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName + 'Element'; - if (window[klass]) return window[klass]; - klass = 'HTML' + tagName.capitalize() + 'Element'; - if (window[klass]) return window[klass]; - - var element = document.createElement(tagName), - proto = element['__proto__'] || element.constructor.prototype; - - element = null; - return proto; - } - - var elementPrototype = window.HTMLElement ? HTMLElement.prototype : - Element.prototype; - - if (F.ElementExtensions) { - copy(Element.Methods, elementPrototype); - copy(Element.Methods.Simulated, elementPrototype, true); - } - - if (F.SpecificElementExtensions) { - for (var tag in Element.Methods.ByTag) { - var klass = findDOMClass(tag); - if (Object.isUndefined(klass)) continue; - copy(T[tag], klass.prototype); - } - } - - Object.extend(Element, Element.Methods); - delete Element.ByTag; - - if (Element.extend.refresh) Element.extend.refresh(); - Element.cache = { }; -}; - - -document.viewport = { - - getDimensions: function() { - return { width: this.getWidth(), height: this.getHeight() }; - }, - - getScrollOffsets: function() { - return Element._returnOffset( - window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, - window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop); - } -}; - -(function(viewport) { - var B = Prototype.Browser, doc = document, element, property = {}; - - function getRootElement() { - if (B.WebKit && !doc.evaluate) - return document; - - if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) - return document.body; - - return document.documentElement; - } - - function define(D) { - if (!element) element = getRootElement(); - - property[D] = 'client' + D; - - viewport['get' + D] = function() { return element[property[D]] }; - return viewport['get' + D](); - } - - viewport.getWidth = define.curry('Width'); - - viewport.getHeight = define.curry('Height'); -})(document.viewport); - - -Element.Storage = { - UID: 1 -}; - -Element.addMethods({ - getStorage: function(element) { - if (!(element = $(element))) return; - - var uid; - if (element === window) { - uid = 0; - } else { - if (typeof element._prototypeUID === "undefined") - element._prototypeUID = Element.Storage.UID++; - uid = element._prototypeUID; - } - - if (!Element.Storage[uid]) - Element.Storage[uid] = $H(); - - return Element.Storage[uid]; - }, - - store: function(element, key, value) { - if (!(element = $(element))) return; - - if (arguments.length === 2) { - Element.getStorage(element).update(key); - } else { - Element.getStorage(element).set(key, value); - } - - return element; - }, - - retrieve: function(element, key, defaultValue) { - if (!(element = $(element))) return; - var hash = Element.getStorage(element), value = hash.get(key); - - if (Object.isUndefined(value)) { - hash.set(key, defaultValue); - value = defaultValue; - } - - return value; - }, - - clone: function(element, deep) { - if (!(element = $(element))) return; - var clone = element.cloneNode(deep); - clone._prototypeUID = void 0; - if (deep) { - var descendants = Element.select(clone, '*'), - i = descendants.length; - while (i--) { - descendants[i]._prototypeUID = void 0; - } - } - return Element.extend(clone); - }, - - purge: function(element) { - if (!(element = $(element))) return; - var purgeElement = Element._purgeElement; - - purgeElement(element); - - var descendants = element.getElementsByTagName('*'), - i = descendants.length; - - while (i--) purgeElement(descendants[i]); - - return null; - } -}); - -(function() { - - function toDecimal(pctString) { - var match = pctString.match(/^(\d+)%?$/i); - if (!match) return null; - return (Number(match[1]) / 100); - } - - function getPixelValue(value, property, context) { - var element = null; - if (Object.isElement(value)) { - element = value; - value = element.getStyle(property); - } - - if (value === null) { - return null; - } - - if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { - return window.parseFloat(value); - } - - var isPercentage = value.include('%'), isViewport = (context === document.viewport); - - if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) { - var style = element.style.left, rStyle = element.runtimeStyle.left; - element.runtimeStyle.left = element.currentStyle.left; - element.style.left = value || 0; - value = element.style.pixelLeft; - element.style.left = style; - element.runtimeStyle.left = rStyle; - - return value; - } - - if (element && isPercentage) { - context = context || element.parentNode; - var decimal = toDecimal(value); - var whole = null; - var position = element.getStyle('position'); - - var isHorizontal = property.include('left') || property.include('right') || - property.include('width'); - - var isVertical = property.include('top') || property.include('bottom') || - property.include('height'); - - if (context === document.viewport) { - if (isHorizontal) { - whole = document.viewport.getWidth(); - } else if (isVertical) { - whole = document.viewport.getHeight(); - } - } else { - if (isHorizontal) { - whole = $(context).measure('width'); - } else if (isVertical) { - whole = $(context).measure('height'); - } - } - - return (whole === null) ? 0 : whole * decimal; - } - - return 0; - } - - function toCSSPixels(number) { - if (Object.isString(number) && number.endsWith('px')) { - return number; - } - return number + 'px'; - } - - function isDisplayed(element) { - var originalElement = element; - while (element && element.parentNode) { - var display = element.getStyle('display'); - if (display === 'none') { - return false; - } - element = $(element.parentNode); - } - return true; - } - - var hasLayout = Prototype.K; - if ('currentStyle' in document.documentElement) { - hasLayout = function(element) { - if (!element.currentStyle.hasLayout) { - element.style.zoom = 1; - } - return element; - }; - } - - function cssNameFor(key) { - if (key.include('border')) key = key + '-width'; - return key.camelize(); - } - - Element.Layout = Class.create(Hash, { - initialize: function($super, element, preCompute) { - $super(); - this.element = $(element); - - Element.Layout.PROPERTIES.each( function(property) { - this._set(property, null); - }, this); - - if (preCompute) { - this._preComputing = true; - this._begin(); - Element.Layout.PROPERTIES.each( this._compute, this ); - this._end(); - this._preComputing = false; - } - }, - - _set: function(property, value) { - return Hash.prototype.set.call(this, property, value); - }, - - set: function(property, value) { - throw "Properties of Element.Layout are read-only."; - }, - - get: function($super, property) { - var value = $super(property); - return value === null ? this._compute(property) : value; - }, - - _begin: function() { - if (this._prepared) return; - - var element = this.element; - if (isDisplayed(element)) { - this._prepared = true; - return; - } - - var originalStyles = { - position: element.style.position || '', - width: element.style.width || '', - visibility: element.style.visibility || '', - display: element.style.display || '' - }; - - element.store('prototype_original_styles', originalStyles); - - var position = element.getStyle('position'), - width = element.getStyle('width'); - - if (width === "0px" || width === null) { - element.style.display = 'block'; - width = element.getStyle('width'); - } - - var context = (position === 'fixed') ? document.viewport : - element.parentNode; - - element.setStyle({ - position: 'absolute', - visibility: 'hidden', - display: 'block' - }); - - var positionedWidth = element.getStyle('width'); - - var newWidth; - if (width && (positionedWidth === width)) { - newWidth = getPixelValue(element, 'width', context); - } else if (position === 'absolute' || position === 'fixed') { - newWidth = getPixelValue(element, 'width', context); - } else { - var parent = element.parentNode, pLayout = $(parent).getLayout(); - - newWidth = pLayout.get('width') - - this.get('margin-left') - - this.get('border-left') - - this.get('padding-left') - - this.get('padding-right') - - this.get('border-right') - - this.get('margin-right'); - } - - element.setStyle({ width: newWidth + 'px' }); - - this._prepared = true; - }, - - _end: function() { - var element = this.element; - var originalStyles = element.retrieve('prototype_original_styles'); - element.store('prototype_original_styles', null); - element.setStyle(originalStyles); - this._prepared = false; - }, - - _compute: function(property) { - var COMPUTATIONS = Element.Layout.COMPUTATIONS; - if (!(property in COMPUTATIONS)) { - throw "Property not found."; - } - - return this._set(property, COMPUTATIONS[property].call(this, this.element)); - }, - - toObject: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var obj = {}; - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - var value = this.get(key); - if (value != null) obj[key] = value; - }, this); - return obj; - }, - - toHash: function() { - var obj = this.toObject.apply(this, arguments); - return new Hash(obj); - }, - - toCSS: function() { - var args = $A(arguments); - var keys = (args.length === 0) ? Element.Layout.PROPERTIES : - args.join(' ').split(' '); - var css = {}; - - keys.each( function(key) { - if (!Element.Layout.PROPERTIES.include(key)) return; - if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; - - var value = this.get(key); - if (value != null) css[cssNameFor(key)] = value + 'px'; - }, this); - return css; - }, - - inspect: function() { - return "#<Element.Layout>"; - } - }); - - Object.extend(Element.Layout, { - PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'), - - COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'), - - COMPUTATIONS: { - 'height': function(element) { - if (!this._preComputing) this._begin(); - - var bHeight = this.get('border-box-height'); - if (bHeight <= 0) { - if (!this._preComputing) this._end(); - return 0; - } - - var bTop = this.get('border-top'), - bBottom = this.get('border-bottom'); - - var pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - if (!this._preComputing) this._end(); - - return bHeight - bTop - bBottom - pTop - pBottom; - }, - - 'width': function(element) { - if (!this._preComputing) this._begin(); - - var bWidth = this.get('border-box-width'); - if (bWidth <= 0) { - if (!this._preComputing) this._end(); - return 0; - } - - var bLeft = this.get('border-left'), - bRight = this.get('border-right'); - - var pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - if (!this._preComputing) this._end(); - - return bWidth - bLeft - bRight - pLeft - pRight; - }, - - 'padding-box-height': function(element) { - var height = this.get('height'), - pTop = this.get('padding-top'), - pBottom = this.get('padding-bottom'); - - return height + pTop + pBottom; - }, - - 'padding-box-width': function(element) { - var width = this.get('width'), - pLeft = this.get('padding-left'), - pRight = this.get('padding-right'); - - return width + pLeft + pRight; - }, - - 'border-box-height': function(element) { - if (!this._preComputing) this._begin(); - var height = element.offsetHeight; - if (!this._preComputing) this._end(); - return height; - }, - - 'border-box-width': function(element) { - if (!this._preComputing) this._begin(); - var width = element.offsetWidth; - if (!this._preComputing) this._end(); - return width; - }, - - 'margin-box-height': function(element) { - var bHeight = this.get('border-box-height'), - mTop = this.get('margin-top'), - mBottom = this.get('margin-bottom'); - - if (bHeight <= 0) return 0; - - return bHeight + mTop + mBottom; - }, - - 'margin-box-width': function(element) { - var bWidth = this.get('border-box-width'), - mLeft = this.get('margin-left'), - mRight = this.get('margin-right'); - - if (bWidth <= 0) return 0; - - return bWidth + mLeft + mRight; - }, - - 'top': function(element) { - var offset = element.positionedOffset(); - return offset.top; - }, - - 'bottom': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pHeight = parent.measure('height'); - - var mHeight = this.get('border-box-height'); - - return pHeight - mHeight - offset.top; - }, - - 'left': function(element) { - var offset = element.positionedOffset(); - return offset.left; - }, - - 'right': function(element) { - var offset = element.positionedOffset(), - parent = element.getOffsetParent(), - pWidth = parent.measure('width'); - - var mWidth = this.get('border-box-width'); - - return pWidth - mWidth - offset.left; - }, - - 'padding-top': function(element) { - return getPixelValue(element, 'paddingTop'); - }, - - 'padding-bottom': function(element) { - return getPixelValue(element, 'paddingBottom'); - }, - - 'padding-left': function(element) { - return getPixelValue(element, 'paddingLeft'); - }, - - 'padding-right': function(element) { - return getPixelValue(element, 'paddingRight'); - }, - - 'border-top': function(element) { - return getPixelValue(element, 'borderTopWidth'); - }, - - 'border-bottom': function(element) { - return getPixelValue(element, 'borderBottomWidth'); - }, - - 'border-left': function(element) { - return getPixelValue(element, 'borderLeftWidth'); - }, - - 'border-right': function(element) { - return getPixelValue(element, 'borderRightWidth'); - }, - - 'margin-top': function(element) { - return getPixelValue(element, 'marginTop'); - }, - - 'margin-bottom': function(element) { - return getPixelValue(element, 'marginBottom'); - }, - - 'margin-left': function(element) { - return getPixelValue(element, 'marginLeft'); - }, - - 'margin-right': function(element) { - return getPixelValue(element, 'marginRight'); - } - } - }); - - if ('getBoundingClientRect' in document.documentElement) { - Object.extend(Element.Layout.COMPUTATIONS, { - 'right': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.right - rect.right).round(); - }, - - 'bottom': function(element) { - var parent = hasLayout(element.getOffsetParent()); - var rect = element.getBoundingClientRect(), - pRect = parent.getBoundingClientRect(); - - return (pRect.bottom - rect.bottom).round(); - } - }); - } - - Element.Offset = Class.create({ - initialize: function(left, top) { - this.left = left.round(); - this.top = top.round(); - - this[0] = this.left; - this[1] = this.top; - }, - - relativeTo: function(offset) { - return new Element.Offset( - this.left - offset.left, - this.top - offset.top - ); - }, - - inspect: function() { - return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this); - }, - - toString: function() { - return "[#{left}, #{top}]".interpolate(this); - }, - - toArray: function() { - return [this.left, this.top]; - } - }); - - function getLayout(element, preCompute) { - return new Element.Layout(element, preCompute); - } - - function measure(element, property) { - return $(element).getLayout().get(property); - } - - function getDimensions(element) { - element = $(element); - var display = Element.getStyle(element, 'display'); - - if (display && display !== 'none') { - return { width: element.offsetWidth, height: element.offsetHeight }; - } - - var style = element.style; - var originalStyles = { - visibility: style.visibility, - position: style.position, - display: style.display - }; - - var newStyles = { - visibility: 'hidden', - display: 'block' - }; - - if (originalStyles.position !== 'fixed') - newStyles.position = 'absolute'; - - Element.setStyle(element, newStyles); - - var dimensions = { - width: element.offsetWidth, - height: element.offsetHeight - }; - - Element.setStyle(element, originalStyles); - - return dimensions; - } - - function getOffsetParent(element) { - element = $(element); - - if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) - return $(document.body); - - var isInline = (Element.getStyle(element, 'display') === 'inline'); - if (!isInline && element.offsetParent) return $(element.offsetParent); - - while ((element = element.parentNode) && element !== document.body) { - if (Element.getStyle(element, 'position') !== 'static') { - return isHtml(element) ? $(document.body) : $(element); - } - } - - return $(document.body); - } - - - function cumulativeOffset(element) { - element = $(element); - var valueT = 0, valueL = 0; - if (element.parentNode) { - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - } while (element); - } - return new Element.Offset(valueL, valueT); - } - - function positionedOffset(element) { - element = $(element); - - var layout = element.getLayout(); - - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - element = element.offsetParent; - if (element) { - if (isBody(element)) break; - var p = Element.getStyle(element, 'position'); - if (p !== 'static') break; - } - } while (element); - - valueL -= layout.get('margin-top'); - valueT -= layout.get('margin-left'); - - return new Element.Offset(valueL, valueT); - } - - function cumulativeScrollOffset(element) { - var valueT = 0, valueL = 0; - do { - valueT += element.scrollTop || 0; - valueL += element.scrollLeft || 0; - element = element.parentNode; - } while (element); - return new Element.Offset(valueL, valueT); - } - - function viewportOffset(forElement) { - element = $(element); - var valueT = 0, valueL = 0, docBody = document.body; - - var element = forElement; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == docBody && - Element.getStyle(element, 'position') == 'absolute') break; - } while (element = element.offsetParent); - - element = forElement; - do { - if (element != docBody) { - valueT -= element.scrollTop || 0; - valueL -= element.scrollLeft || 0; - } - } while (element = element.parentNode); - return new Element.Offset(valueL, valueT); - } - - function absolutize(element) { - element = $(element); - - if (Element.getStyle(element, 'position') === 'absolute') { - return element; - } - - var offsetParent = getOffsetParent(element); - var eOffset = element.viewportOffset(), - pOffset = offsetParent.viewportOffset(); - - var offset = eOffset.relativeTo(pOffset); - var layout = element.getLayout(); - - element.store('prototype_absolutize_original_styles', { - left: element.getStyle('left'), - top: element.getStyle('top'), - width: element.getStyle('width'), - height: element.getStyle('height') - }); - - element.setStyle({ - position: 'absolute', - top: offset.top + 'px', - left: offset.left + 'px', - width: layout.get('width') + 'px', - height: layout.get('height') + 'px' - }); - - return element; - } - - function relativize(element) { - element = $(element); - if (Element.getStyle(element, 'position') === 'relative') { - return element; - } - - var originalStyles = - element.retrieve('prototype_absolutize_original_styles'); - - if (originalStyles) element.setStyle(originalStyles); - return element; - } - - if (Prototype.Browser.IE) { - getOffsetParent = getOffsetParent.wrap( - function(proceed, element) { - element = $(element); - - if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element)) - return $(document.body); - - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - } - ); - - positionedOffset = positionedOffset.wrap(function(proceed, element) { - element = $(element); - if (!element.parentNode) return new Element.Offset(0, 0); - var position = element.getStyle('position'); - if (position !== 'static') return proceed(element); - - var offsetParent = element.getOffsetParent(); - if (offsetParent && offsetParent.getStyle('position') === 'fixed') - hasLayout(offsetParent); - - element.setStyle({ position: 'relative' }); - var value = proceed(element); - element.setStyle({ position: position }); - return value; - }); - } else if (Prototype.Browser.Webkit) { - cumulativeOffset = function(element) { - element = $(element); - var valueT = 0, valueL = 0; - do { - valueT += element.offsetTop || 0; - valueL += element.offsetLeft || 0; - if (element.offsetParent == document.body) - if (Element.getStyle(element, 'position') == 'absolute') break; - - element = element.offsetParent; - } while (element); - - return new Element.Offset(valueL, valueT); - }; - } - - - Element.addMethods({ - getLayout: getLayout, - measure: measure, - getDimensions: getDimensions, - getOffsetParent: getOffsetParent, - cumulativeOffset: cumulativeOffset, - positionedOffset: positionedOffset, - cumulativeScrollOffset: cumulativeScrollOffset, - viewportOffset: viewportOffset, - absolutize: absolutize, - relativize: relativize - }); - - function isBody(element) { - return element.nodeName.toUpperCase() === 'BODY'; - } - - function isHtml(element) { - return element.nodeName.toUpperCase() === 'HTML'; - } - - function isDocument(element) { - return element.nodeType === Node.DOCUMENT_NODE; - } - - function isDetached(element) { - return element !== document.body && - !Element.descendantOf(element, document.body); - } - - if ('getBoundingClientRect' in document.documentElement) { - Element.addMethods({ - viewportOffset: function(element) { - element = $(element); - if (isDetached(element)) return new Element.Offset(0, 0); - - var rect = element.getBoundingClientRect(), - docEl = document.documentElement; - return new Element.Offset(rect.left - docEl.clientLeft, - rect.top - docEl.clientTop); - } - }); - } -})(); -window.$$ = function() { - var expression = $A(arguments).join(', '); - return Prototype.Selector.select(expression, document); -}; - -Prototype.Selector = (function() { - - function select() { - throw new Error('Method "Prototype.Selector.select" must be defined.'); - } - - function match() { - throw new Error('Method "Prototype.Selector.match" must be defined.'); - } - - function find(elements, expression, index) { - index = index || 0; - var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i; - - for (i = 0; i < length; i++) { - if (match(elements[i], expression) && index == matchIndex++) { - return Element.extend(elements[i]); - } - } - } - - function extendElements(elements) { - for (var i = 0, length = elements.length; i < length; i++) { - Element.extend(elements[i]); - } - return elements; - } - - - var K = Prototype.K; - - return { - select: select, - match: match, - find: find, - extendElements: (Element.extend === K) ? K : extendElements, - extendElement: Element.extend - }; -})(); -Prototype._original_property = window.Sizzle; -/*! - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -[0, 0].sort(function(){ - baseHasDuplicate = false; - return 0; -}); - -var Sizzle = function(selector, context, results, seed) { - results = results || []; - var origContext = context = context || document; - - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context), - soFar = selector; - - while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); - - while ( parts.length ) { - selector = parts.shift(); - - if ( Expr.relative[ selector ] ) - selector += parts.shift(); - - set = posProcess( selector, set ); - } - } - } else { - if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && - Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { - var ret = Sizzle.find( parts.shift(), context, contextXML ); - context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0]; - } - - if ( context ) { - var ret = seed ? - { expr: parts.pop(), set: makeArray(seed) } : - Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); - set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set; - - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; - } - - while ( parts.length ) { - var cur = parts.pop(), pop = cur; - - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } - - if ( pop == null ) { - pop = context; - } - - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } - - if ( !checkSet ) { - checkSet = set; - } - - if ( !checkSet ) { - throw "Syntax error, unrecognized expression: " + (cur || selector); - } - - if ( toString.call(checkSet) === "[object Array]" ) { - if ( !prune ) { - results.push.apply( results, checkSet ); - } else if ( context && context.nodeType === 1 ) { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { - results.push( set[i] ); - } - } - } else { - for ( var i = 0; checkSet[i] != null; i++ ) { - if ( checkSet[i] && checkSet[i].nodeType === 1 ) { - results.push( set[i] ); - } - } - } - } else { - makeArray( checkSet, results ); - } - - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } - - return results; -}; - -Sizzle.uniqueSort = function(results){ - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); - - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } - } - } - } - - return results; -}; - -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; - -Sizzle.find = function(expr, context, isXML){ - var set, match; - - if ( !expr ) { - return []; - } - - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } - - if ( !set ) { - set = context.getElementsByTagName("*"); - } - - return {set: set, expr: expr}; -}; - -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && isXML(set[0]); - - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.match[ type ].exec( expr )) != null ) { - var filter = Expr.filter[ type ], found, item; - anyFound = false; - - if ( curLoop == result ) { - result = []; - } - - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); - - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } - - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; - - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } - - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } - - expr = expr.replace( Expr.match[ type ], "" ); - - if ( !anyFound ) { - return []; - } - - break; - } - } - } - - if ( expr == old ) { - if ( anyFound == null ) { - throw "Syntax error, unrecognized expression: " + expr; - } else { - break; - } - } - - old = expr; - } - - return curLoop; -}; - -var Expr = Sizzle.selectors = { - order: [ "ID", "NAME", "TAG" ], - match: { - ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/, - NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/, - ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/, - POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/, - PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/ - }, - leftMatch: {}, - attrMap: { - "class": "className", - "for": "htmlFor" - }, - attrHandle: { - href: function(elem){ - return elem.getAttribute("href"); - } - }, - relative: { - "+": function(checkSet, part, isXML){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; - - if ( isTag && !isXML ) { - part = part.toUpperCase(); - } - - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} - - checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ? - elem || false : - elem === part; - } - } - - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part, isXML){ - var isPartStr = typeof part === "string"; - - if ( isPartStr && !/\W/.test(part) ) { - part = isXML ? part : part.toUpperCase(); - - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - var parent = elem.parentNode; - checkSet[i] = parent.nodeName === part ? parent : false; - } - } - } else { - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - checkSet[i] = isPartStr ? - elem.parentNode : - elem.parentNode === part; - } - } - - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } - } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); - checkFn = dirNodeCheck; - } - - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck; - - if ( typeof part === "string" && !/\W/.test(part) ) { - var nodeCheck = part = isXML ? part : part.toUpperCase(); - checkFn = dirNodeCheck; - } - - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context, isXML){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); - - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } - } - - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; - - if ( isXML ) { - return match; - } - - for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { - if ( elem ) { - if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) { - if ( !inplace ) - result.push( elem ); - } else if ( inplace ) { - curLoop[i] = false; - } - } - } - - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - for ( var i = 0; curLoop[i] === false; i++ ){} - return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase(); - }, - CHILD: function(match){ - if ( match[1] == "nth" ) { - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); - - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; - } - - match[0] = done++; - - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } - - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } - - return match; - }, - PSEUDO: function(match, curLoop, inplace, result, not){ - if ( match[1] === "not" ) { - if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { - match[3] = Sizzle(match[3], null, null, curLoop); - } else { - var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); - if ( !inplace ) { - result.push.apply( result, ret ); - } - return false; - } - } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { - return true; - } - - return match; - }, - POS: function(match){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return /h\d/i.test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON"; - }, - input: function(elem){ - return /input|select|textarea|button/i.test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 == i; - }, - eq: function(elem, i, match){ - return match[3] - 0 == i; - } - }, - filter: { - PSEUDO: function(elem, match, i, array){ - var name = match[1], filter = Expr.filters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var i = 0, l = not.length; i < l; i++ ) { - if ( not[i] === elem ) { - return false; - } - } - - return true; - } - }, - CHILD: function(elem, match){ - var type = match[1], node = elem; - switch (type) { - case 'only': - case 'first': - while ( (node = node.previousSibling) ) { - if ( node.nodeType === 1 ) return false; - } - if ( type == 'first') return true; - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) return false; - } - return true; - case 'nth': - var first = match[2], last = match[3]; - - if ( first == 1 && last == 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first == 0 ) { - return diff == 0; - } else { - return ( diff % first == 0 && diff / first >= 0 ); - } - } - }, - ID: function(elem, match){ - return elem.nodeType === 1 && elem.getAttribute("id") === match; - }, - TAG: function(elem, match){ - return (match === "*" && elem.nodeType === 1) || elem.nodeName === match; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value != check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; - -var origPOS = Expr.match.POS; - -for ( var type in Expr.match ) { - Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source ); - Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source ); -} - -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); - - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; - -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 ); - -} catch(e){ - makeArray = function(array, results) { - var ret = results || []; - - if ( toString.call(array) === "[object Array]" ) { - Array.prototype.push.apply( ret, array ); - } else { - if ( typeof array.length === "number" ) { - for ( var i = 0, l = array.length; i < l; i++ ) { - ret.push( array[i] ); - } - } else { - for ( var i = 0; array[i]; i++ ) { - ret.push( array[i] ); - } - } - } - - return ret; - }; -} - -var sortOrder; - -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var ret = a.sourceIndex - b.sourceIndex; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} else if ( document.createRange ) { - sortOrder = function( a, b ) { - if ( !a.ownerDocument || !b.ownerDocument ) { - if ( a == b ) { - hasDuplicate = true; - } - return 0; - } - - var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); - aRange.setStart(a, 0); - aRange.setEnd(a, 0); - bRange.setStart(b, 0); - bRange.setEnd(b, 0); - var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange); - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; - }; -} - -(function(){ - var form = document.createElement("div"), - id = "script" + (new Date).getTime(); - form.innerHTML = "<a name='" + id + "'/>"; - - var root = document.documentElement; - root.insertBefore( form, root.firstChild ); - - if ( !!document.getElementById( id ) ) { - Expr.find.ID = function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : []; - } - }; - - Expr.filter.ID = function(elem, match){ - var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); - return elem.nodeType === 1 && node && node.nodeValue === match; - }; - } - - root.removeChild( form ); - root = form = null; // release memory in IE -})(); - -(function(){ - - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); - - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); - - if ( match[1] === "*" ) { - var tmp = []; - - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); - } - } - - results = tmp; - } - - return results; - }; - } - - div.innerHTML = "<a href='#'></a>"; - if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && - div.firstChild.getAttribute("href") !== "#" ) { - Expr.attrHandle.href = function(elem){ - return elem.getAttribute("href", 2); - }; - } - - div = null; // release memory in IE -})(); - -if ( document.querySelectorAll ) (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "<p class='TEST'></p>"; - - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; - - if ( !seed && context.nodeType === 9 && !isXML(context) ) { - try { - return makeArray( context.querySelectorAll(query), extra ); - } catch(e){} - } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE -})(); - -if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){ - var div = document.createElement("div"); - div.innerHTML = "<div class='test e'></div><div class='test'></div>"; - - if ( div.getElementsByClassName("e").length === 0 ) - return; - - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) - return; - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - - div = null; // release memory in IE -})(); - -function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - if ( sibDir && elem.nodeType === 1 ){ - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; - } - - if ( elem.nodeName === cur ) { - match = elem; - break; - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { - var sibDir = dir == "previousSibling" && !isXML; - for ( var i = 0, l = checkSet.length; i < l; i++ ) { - var elem = checkSet[i]; - if ( elem ) { - if ( sibDir && elem.nodeType === 1 ) { - elem.sizcache = doneName; - elem.sizset = i; - } - elem = elem[dir]; - var match = false; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } - - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; - } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; - break; - } - - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; - } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -var contains = document.compareDocumentPosition ? function(a, b){ - return a.compareDocumentPosition(b) & 16; -} : function(a, b){ - return a !== b && (a.contains ? a.contains(b) : true); -}; - -var isXML = function(elem){ - return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || - !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML"; -}; - -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; - - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } - - selector = Expr.relative[selector] ? selector + "*" : selector; - - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } - - return Sizzle.filter( later, tmpSet ); -}; - - -window.Sizzle = Sizzle; - -})(); - -;(function(engine) { - var extendElements = Prototype.Selector.extendElements; - - function select(selector, scope) { - return extendElements(engine(selector, scope || document)); - } - - function match(element, selector) { - return engine.matches(selector, [element]).length == 1; - } - - Prototype.Selector.engine = engine; - Prototype.Selector.select = select; - Prototype.Selector.match = match; -})(Sizzle); - -window.Sizzle = Prototype._original_property; -delete Prototype._original_property; - -var Form = { - reset: function(form) { - form = $(form); - form.reset(); - return form; - }, - - serializeElements: function(elements, options) { - if (typeof options != 'object') options = { hash: !!options }; - else if (Object.isUndefined(options.hash)) options.hash = true; - var key, value, submitted = false, submit = options.submit, accumulator, initial; - - if (options.hash) { - initial = {}; - accumulator = function(result, key, value) { - if (key in result) { - if (!Object.isArray(result[key])) result[key] = [result[key]]; - result[key].push(value); - } else result[key] = value; - return result; - }; - } else { - initial = ''; - accumulator = function(result, key, value) { - return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value); - } - } - - return elements.inject(initial, function(result, element) { - if (!element.disabled && element.name) { - key = element.name; value = $(element).getValue(); - if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted && - submit !== false && (!submit || key == submit) && (submitted = true)))) { - result = accumulator(result, key, value); - } - } - return result; - }); - } -}; - -Form.Methods = { - serialize: function(form, options) { - return Form.serializeElements(Form.getElements(form), options); - }, - - getElements: function(form) { - var elements = $(form).getElementsByTagName('*'), - element, - arr = [ ], - serializers = Form.Element.Serializers; - for (var i = 0; element = elements[i]; i++) { - arr.push(element); - } - return arr.inject([], function(elements, child) { - if (serializers[child.tagName.toLowerCase()]) - elements.push(Element.extend(child)); - return elements; - }) - }, - - getInputs: function(form, typeName, name) { - form = $(form); - var inputs = form.getElementsByTagName('input'); - - if (!typeName && !name) return $A(inputs).map(Element.extend); - - for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) { - var input = inputs[i]; - if ((typeName && input.type != typeName) || (name && input.name != name)) - continue; - matchingInputs.push(Element.extend(input)); - } - - return matchingInputs; - }, - - disable: function(form) { - form = $(form); - Form.getElements(form).invoke('disable'); - return form; - }, - - enable: function(form) { - form = $(form); - Form.getElements(form).invoke('enable'); - return form; - }, - - findFirstElement: function(form) { - var elements = $(form).getElements().findAll(function(element) { - return 'hidden' != element.type && !element.disabled; - }); - var firstByIndex = elements.findAll(function(element) { - return element.hasAttribute('tabIndex') && element.tabIndex >= 0; - }).sortBy(function(element) { return element.tabIndex }).first(); - - return firstByIndex ? firstByIndex : elements.find(function(element) { - return /^(?:input|select|textarea)$/i.test(element.tagName); - }); - }, - - focusFirstElement: function(form) { - form = $(form); - var element = form.findFirstElement(); - if (element) element.activate(); - return form; - }, - - request: function(form, options) { - form = $(form), options = Object.clone(options || { }); - - var params = options.parameters, action = form.readAttribute('action') || ''; - if (action.blank()) action = window.location.href; - options.parameters = form.serialize(true); - - if (params) { - if (Object.isString(params)) params = params.toQueryParams(); - Object.extend(options.parameters, params); - } - - if (form.hasAttribute('method') && !options.method) - options.method = form.method; - - return new Ajax.Request(action, options); - } -}; - -/*--------------------------------------------------------------------------*/ - - -Form.Element = { - focus: function(element) { - $(element).focus(); - return element; - }, - - select: function(element) { - $(element).select(); - return element; - } -}; - -Form.Element.Methods = { - - serialize: function(element) { - element = $(element); - if (!element.disabled && element.name) { - var value = element.getValue(); - if (value != undefined) { - var pair = { }; - pair[element.name] = value; - return Object.toQueryString(pair); - } - } - return ''; - }, - - getValue: function(element) { - element = $(element); - var method = element.tagName.toLowerCase(); - return Form.Element.Serializers[method](element); - }, - - setValue: function(element, value) { - element = $(element); - var method = element.tagName.toLowerCase(); - Form.Element.Serializers[method](element, value); - return element; - }, - - clear: function(element) { - $(element).value = ''; - return element; - }, - - present: function(element) { - return $(element).value != ''; - }, - - activate: function(element) { - element = $(element); - try { - element.focus(); - if (element.select && (element.tagName.toLowerCase() != 'input' || - !(/^(?:button|reset|submit)$/i.test(element.type)))) - element.select(); - } catch (e) { } - return element; - }, - - disable: function(element) { - element = $(element); - element.disabled = true; - return element; - }, - - enable: function(element) { - element = $(element); - element.disabled = false; - return element; - } -}; - -/*--------------------------------------------------------------------------*/ - -var Field = Form.Element; - -var $F = Form.Element.Methods.getValue; - -/*--------------------------------------------------------------------------*/ - -Form.Element.Serializers = (function() { - function input(element, value) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - return inputSelector(element, value); - default: - return valueSelector(element, value); - } - } - - function inputSelector(element, value) { - if (Object.isUndefined(value)) - return element.checked ? element.value : null; - else element.checked = !!value; - } - - function valueSelector(element, value) { - if (Object.isUndefined(value)) return element.value; - else element.value = value; - } - - function select(element, value) { - if (Object.isUndefined(value)) - return (element.type === 'select-one' ? selectOne : selectMany)(element); - - var opt, currentValue, single = !Object.isArray(value); - for (var i = 0, length = element.length; i < length; i++) { - opt = element.options[i]; - currentValue = this.optionValue(opt); - if (single) { - if (currentValue == value) { - opt.selected = true; - return; - } - } - else opt.selected = value.include(currentValue); - } - } - - function selectOne(element) { - var index = element.selectedIndex; - return index >= 0 ? optionValue(element.options[index]) : null; - } - - function selectMany(element) { - var values, length = element.length; - if (!length) return null; - - for (var i = 0, values = []; i < length; i++) { - var opt = element.options[i]; - if (opt.selected) values.push(optionValue(opt)); - } - return values; - } - - function optionValue(opt) { - return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; - } - - return { - input: input, - inputSelector: inputSelector, - textarea: valueSelector, - select: select, - selectOne: selectOne, - selectMany: selectMany, - optionValue: optionValue, - button: valueSelector - }; -})(); - -/*--------------------------------------------------------------------------*/ - - -Abstract.TimedObserver = Class.create(PeriodicalExecuter, { - initialize: function($super, element, frequency, callback) { - $super(callback, frequency); - this.element = $(element); - this.lastValue = this.getValue(); - }, - - execute: function() { - var value = this.getValue(); - if (Object.isString(this.lastValue) && Object.isString(value) ? - this.lastValue != value : String(this.lastValue) != String(value)) { - this.callback(this.element, value); - this.lastValue = value; - } - } -}); - -Form.Element.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.Observer = Class.create(Abstract.TimedObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); - -/*--------------------------------------------------------------------------*/ - -Abstract.EventObserver = Class.create({ - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; - - this.lastValue = this.getValue(); - if (this.element.tagName.toLowerCase() == 'form') - this.registerFormCallbacks(); - else - this.registerCallback(this.element); - }, - - onElementEvent: function() { - var value = this.getValue(); - if (this.lastValue != value) { - this.callback(this.element, value); - this.lastValue = value; - } - }, - - registerFormCallbacks: function() { - Form.getElements(this.element).each(this.registerCallback, this); - }, - - registerCallback: function(element) { - if (element.type) { - switch (element.type.toLowerCase()) { - case 'checkbox': - case 'radio': - Event.observe(element, 'click', this.onElementEvent.bind(this)); - break; - default: - Event.observe(element, 'change', this.onElementEvent.bind(this)); - break; - } - } - } -}); - -Form.Element.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.Element.getValue(this.element); - } -}); - -Form.EventObserver = Class.create(Abstract.EventObserver, { - getValue: function() { - return Form.serialize(this.element); - } -}); -(function() { - - var Event = { - KEY_BACKSPACE: 8, - KEY_TAB: 9, - KEY_RETURN: 13, - KEY_ESC: 27, - KEY_LEFT: 37, - KEY_UP: 38, - KEY_RIGHT: 39, - KEY_DOWN: 40, - KEY_DELETE: 46, - KEY_HOME: 36, - KEY_END: 35, - KEY_PAGEUP: 33, - KEY_PAGEDOWN: 34, - KEY_INSERT: 45, - - cache: {} - }; - - var docEl = document.documentElement; - var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl - && 'onmouseleave' in docEl; - - - - var isIELegacyEvent = function(event) { return false; }; - - if (window.attachEvent) { - if (window.addEventListener) { - isIELegacyEvent = function(event) { - return !(event instanceof window.Event); - }; - } else { - isIELegacyEvent = function(event) { return true; }; - } - } - - var _isButton; - - function _isButtonForDOMEvents(event, code) { - return event.which ? (event.which === code + 1) : (event.button === code); - } - - var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; - function _isButtonForLegacyEvents(event, code) { - return event.button === legacyButtonMap[code]; - } - - function _isButtonForWebKit(event, code) { - switch (code) { - case 0: return event.which == 1 && !event.metaKey; - case 1: return event.which == 2 || (event.which == 1 && event.metaKey); - case 2: return event.which == 3; - default: return false; - } - } - - if (window.attachEvent) { - if (!window.addEventListener) { - _isButton = _isButtonForLegacyEvents; - } else { - _isButton = function(event, code) { - return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : - _isButtonForDOMEvents(event, code); - } - } - } else if (Prototype.Browser.WebKit) { - _isButton = _isButtonForWebKit; - } else { - _isButton = _isButtonForDOMEvents; - } - - function isLeftClick(event) { return _isButton(event, 0) } - - function isMiddleClick(event) { return _isButton(event, 1) } - - function isRightClick(event) { return _isButton(event, 2) } - - function element(event) { - event = Event.extend(event); - - var node = event.target, type = event.type, - currentTarget = event.currentTarget; - - if (currentTarget && currentTarget.tagName) { - if (type === 'load' || type === 'error' || - (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' - && currentTarget.type === 'radio')) - node = currentTarget; - } - - if (node.nodeType == Node.TEXT_NODE) - node = node.parentNode; - - return Element.extend(node); - } - - function findElement(event, expression) { - var element = Event.element(event); - - if (!expression) return element; - while (element) { - if (Object.isElement(element) && Prototype.Selector.match(element, expression)) { - return Element.extend(element); - } - element = element.parentNode; - } - } - - function pointer(event) { - return { x: pointerX(event), y: pointerY(event) }; - } - - function pointerX(event) { - var docElement = document.documentElement, - body = document.body || { scrollLeft: 0 }; - - return event.pageX || (event.clientX + - (docElement.scrollLeft || body.scrollLeft) - - (docElement.clientLeft || 0)); - } - - function pointerY(event) { - var docElement = document.documentElement, - body = document.body || { scrollTop: 0 }; - - return event.pageY || (event.clientY + - (docElement.scrollTop || body.scrollTop) - - (docElement.clientTop || 0)); - } - - - function stop(event) { - Event.extend(event); - event.preventDefault(); - event.stopPropagation(); - - event.stopped = true; - } - - - Event.Methods = { - isLeftClick: isLeftClick, - isMiddleClick: isMiddleClick, - isRightClick: isRightClick, - - element: element, - findElement: findElement, - - pointer: pointer, - pointerX: pointerX, - pointerY: pointerY, - - stop: stop - }; - - var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { - m[name] = Event.Methods[name].methodize(); - return m; - }); - - if (window.attachEvent) { - function _relatedTarget(event) { - var element; - switch (event.type) { - case 'mouseover': - case 'mouseenter': - element = event.fromElement; - break; - case 'mouseout': - case 'mouseleave': - element = event.toElement; - break; - default: - return null; - } - return Element.extend(element); - } - - var additionalMethods = { - stopPropagation: function() { this.cancelBubble = true }, - preventDefault: function() { this.returnValue = false }, - inspect: function() { return '[object Event]' } - }; - - Event.extend = function(event, element) { - if (!event) return false; - - if (!isIELegacyEvent(event)) return event; - - if (event._extendedByPrototype) return event; - event._extendedByPrototype = Prototype.emptyFunction; - - var pointer = Event.pointer(event); - - Object.extend(event, { - target: event.srcElement || element, - relatedTarget: _relatedTarget(event), - pageX: pointer.x, - pageY: pointer.y - }); - - Object.extend(event, methods); - Object.extend(event, additionalMethods); - - return event; - }; - } else { - Event.extend = Prototype.K; - } - - if (window.addEventListener) { - Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__; - Object.extend(Event.prototype, methods); - } - - function _createResponder(element, eventName, handler) { - var registry = Element.retrieve(element, 'prototype_event_registry'); - - if (Object.isUndefined(registry)) { - CACHE.push(element); - registry = Element.retrieve(element, 'prototype_event_registry', $H()); - } - - var respondersForEvent = registry.get(eventName); - if (Object.isUndefined(respondersForEvent)) { - respondersForEvent = []; - registry.set(eventName, respondersForEvent); - } - - if (respondersForEvent.pluck('handler').include(handler)) return false; - - var responder; - if (eventName.include(":")) { - responder = function(event) { - if (Object.isUndefined(event.eventName)) - return false; - - if (event.eventName !== eventName) - return false; - - Event.extend(event, element); - handler.call(element, event); - }; - } else { - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED && - (eventName === "mouseenter" || eventName === "mouseleave")) { - if (eventName === "mouseenter" || eventName === "mouseleave") { - responder = function(event) { - Event.extend(event, element); - - var parent = event.relatedTarget; - while (parent && parent !== element) { - try { parent = parent.parentNode; } - catch(e) { parent = element; } - } - - if (parent === element) return; - - handler.call(element, event); - }; - } - } else { - responder = function(event) { - Event.extend(event, element); - handler.call(element, event); - }; - } - } - - responder.handler = handler; - respondersForEvent.push(responder); - return responder; - } - - function _destroyCache() { - for (var i = 0, length = CACHE.length; i < length; i++) { - Event.stopObserving(CACHE[i]); - CACHE[i] = null; - } - } - - var CACHE = []; - - if (Prototype.Browser.IE) - window.attachEvent('onunload', _destroyCache); - - if (Prototype.Browser.WebKit) - window.addEventListener('unload', Prototype.emptyFunction, false); - - - var _getDOMEventName = Prototype.K, - translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; - - if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { - _getDOMEventName = function(eventName) { - return (translations[eventName] || eventName); - }; - } - - function observe(element, eventName, handler) { - element = $(element); - - var responder = _createResponder(element, eventName, handler); - - if (!responder) return element; - - if (eventName.include(':')) { - if (element.addEventListener) - element.addEventListener("dataavailable", responder, false); - else { - element.attachEvent("ondataavailable", responder); - element.attachEvent("onlosecapture", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); - - if (element.addEventListener) - element.addEventListener(actualEventName, responder, false); - else - element.attachEvent("on" + actualEventName, responder); - } - - return element; - } - - function stopObserving(element, eventName, handler) { - element = $(element); - - var registry = Element.retrieve(element, 'prototype_event_registry'); - if (!registry) return element; - - if (!eventName) { - registry.each( function(pair) { - var eventName = pair.key; - stopObserving(element, eventName); - }); - return element; - } - - var responders = registry.get(eventName); - if (!responders) return element; - - if (!handler) { - responders.each(function(r) { - stopObserving(element, eventName, r.handler); - }); - return element; - } - - var i = responders.length, responder; - while (i--) { - if (responders[i].handler === handler) { - responder = responders[i]; - break; - } - } - if (!responder) return element; - - if (eventName.include(':')) { - if (element.removeEventListener) - element.removeEventListener("dataavailable", responder, false); - else { - element.detachEvent("ondataavailable", responder); - element.detachEvent("onlosecapture", responder); - } - } else { - var actualEventName = _getDOMEventName(eventName); - if (element.removeEventListener) - element.removeEventListener(actualEventName, responder, false); - else - element.detachEvent('on' + actualEventName, responder); - } - - registry.set(eventName, responders.without(responder)); - - return element; - } - - function fire(element, eventName, memo, bubble) { - element = $(element); - - if (Object.isUndefined(bubble)) - bubble = true; - - if (element == document && document.createEvent && !element.dispatchEvent) - element = document.documentElement; - - var event; - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent('dataavailable', bubble, true); - } else { - event = document.createEventObject(); - event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; - } - - event.eventName = eventName; - event.memo = memo || { }; - - if (document.createEvent) - element.dispatchEvent(event); - else - element.fireEvent(event.eventType, event); - - return Event.extend(event); - } - - Event.Handler = Class.create({ - initialize: function(element, eventName, selector, callback) { - this.element = $(element); - this.eventName = eventName; - this.selector = selector; - this.callback = callback; - this.handler = this.handleEvent.bind(this); - }, - - start: function() { - Event.observe(this.element, this.eventName, this.handler); - return this; - }, - - stop: function() { - Event.stopObserving(this.element, this.eventName, this.handler); - return this; - }, - - handleEvent: function(event) { - var element = Event.findElement(event, this.selector); - if (element) this.callback.call(this.element, event, element); - } - }); - - function on(element, eventName, selector, callback) { - element = $(element); - if (Object.isFunction(selector) && Object.isUndefined(callback)) { - callback = selector, selector = null; - } - - return new Event.Handler(element, eventName, selector, callback).start(); - } - - Object.extend(Event, Event.Methods); - - Object.extend(Event, { - fire: fire, - observe: observe, - stopObserving: stopObserving, - on: on - }); - - Element.addMethods({ - fire: fire, - - observe: observe, - - stopObserving: stopObserving, - - on: on - }); - - Object.extend(document, { - fire: fire.methodize(), - - observe: observe.methodize(), - - stopObserving: stopObserving.methodize(), - - on: on.methodize(), - - loaded: false - }); - - if (window.Event) Object.extend(window.Event, Event); - else window.Event = Event; -})(); - -(function() { - /* Support for the DOMContentLoaded event is based on work by Dan Webb, - Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ - - var timer; - - function fireContentLoadedEvent() { - if (document.loaded) return; - if (timer) window.clearTimeout(timer); - document.loaded = true; - document.fire('dom:loaded'); - } - - function checkReadyState() { - if (document.readyState === 'complete') { - document.stopObserving('readystatechange', checkReadyState); - fireContentLoadedEvent(); - } - } - - function pollDoScroll() { - try { document.documentElement.doScroll('left'); } - catch(e) { - timer = pollDoScroll.defer(); - return; - } - fireContentLoadedEvent(); - } - - if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false); - } else { - document.observe('readystatechange', checkReadyState); - if (window == top) - timer = pollDoScroll.defer(); - } - - Event.observe(window, 'load', fireContentLoadedEvent); -})(); - -Element.addMethods(); - -/*------------------------------- DEPRECATED -------------------------------*/ - -Hash.toQueryString = Object.toQueryString; - -var Toggle = { display: Element.toggle }; - -Element.Methods.childOf = Element.Methods.descendantOf; - -var Insertion = { - Before: function(element, content) { - return Element.insert(element, {before:content}); - }, - - Top: function(element, content) { - return Element.insert(element, {top:content}); - }, - - Bottom: function(element, content) { - return Element.insert(element, {bottom:content}); - }, - - After: function(element, content) { - return Element.insert(element, {after:content}); - } -}; - -var $continue = new Error('"throw $continue" is deprecated, use "return" instead'); - -var Position = { - includeScrollOffsets: false, - - prepare: function() { - this.deltaX = window.pageXOffset - || document.documentElement.scrollLeft - || document.body.scrollLeft - || 0; - this.deltaY = window.pageYOffset - || document.documentElement.scrollTop - || document.body.scrollTop - || 0; - }, - - within: function(element, x, y) { - if (this.includeScrollOffsets) - return this.withinIncludingScrolloffsets(element, x, y); - this.xcomp = x; - this.ycomp = y; - this.offset = Element.cumulativeOffset(element); - - return (y >= this.offset[1] && - y < this.offset[1] + element.offsetHeight && - x >= this.offset[0] && - x < this.offset[0] + element.offsetWidth); - }, - - withinIncludingScrolloffsets: function(element, x, y) { - var offsetcache = Element.cumulativeScrollOffset(element); - - this.xcomp = x + offsetcache[0] - this.deltaX; - this.ycomp = y + offsetcache[1] - this.deltaY; - this.offset = Element.cumulativeOffset(element); - - return (this.ycomp >= this.offset[1] && - this.ycomp < this.offset[1] + element.offsetHeight && - this.xcomp >= this.offset[0] && - this.xcomp < this.offset[0] + element.offsetWidth); - }, - - overlap: function(mode, element) { - if (!mode) return 0; - if (mode == 'vertical') - return ((this.offset[1] + element.offsetHeight) - this.ycomp) / - element.offsetHeight; - if (mode == 'horizontal') - return ((this.offset[0] + element.offsetWidth) - this.xcomp) / - element.offsetWidth; - }, - - - cumulativeOffset: Element.Methods.cumulativeOffset, - - positionedOffset: Element.Methods.positionedOffset, - - absolutize: function(element) { - Position.prepare(); - return Element.absolutize(element); - }, - - relativize: function(element) { - Position.prepare(); - return Element.relativize(element); - }, - - realOffset: Element.Methods.cumulativeScrollOffset, - - offsetParent: Element.Methods.getOffsetParent, - - page: Element.Methods.viewportOffset, - - clone: function(source, target, options) { - options = options || { }; - return Element.clonePosition(target, source, options); - } -}; - -/*--------------------------------------------------------------------------*/ - -if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){ - function iter(name) { - return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]"; - } - - instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ? - function(element, className) { - className = className.toString().strip(); - var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className); - return cond ? document._getElementsByXPath('.//*' + cond, element) : []; - } : function(element, className) { - className = className.toString().strip(); - var elements = [], classNames = (/\s/.test(className) ? $w(className) : null); - if (!classNames && !className) return elements; - - var nodes = $(element).getElementsByTagName('*'); - className = ' ' + className + ' '; - - for (var i = 0, child, cn; child = nodes[i]; i++) { - if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) || - (classNames && classNames.all(function(name) { - return !name.toString().blank() && cn.include(' ' + name + ' '); - })))) - elements.push(Element.extend(child)); - } - return elements; - }; - - return function(className, parentElement) { - return $(parentElement || document.body).getElementsByClassName(className); - }; -}(Element.Methods); - -/*--------------------------------------------------------------------------*/ - -Element.ClassNames = Class.create(); -Element.ClassNames.prototype = { - initialize: function(element) { - this.element = $(element); - }, - - _each: function(iterator) { - this.element.className.split(/\s+/).select(function(name) { - return name.length > 0; - })._each(iterator); - }, - - set: function(className) { - this.element.className = className; - }, - - add: function(classNameToAdd) { - if (this.include(classNameToAdd)) return; - this.set($A(this).concat(classNameToAdd).join(' ')); - }, - - remove: function(classNameToRemove) { - if (!this.include(classNameToRemove)) return; - this.set($A(this).without(classNameToRemove).join(' ')); - }, - - toString: function() { - return $A(this).join(' '); - } -}; - -Object.extend(Element.ClassNames.prototype, Enumerable); - -/*--------------------------------------------------------------------------*/ - -(function() { - window.Selector = Class.create({ - initialize: function(expression) { - this.expression = expression.strip(); - }, - - findElements: function(rootElement) { - return Prototype.Selector.select(this.expression, rootElement); - }, - - match: function(element) { - return Prototype.Selector.match(element, this.expression); - }, - - toString: function() { - return this.expression; - }, - - inspect: function() { - return "#<Selector: " + this.expression + ">"; - } - }); - - Object.extend(Selector, { - matchElements: function(elements, expression) { - var match = Prototype.Selector.match, - results = []; - - for (var i = 0, length = elements.length; i < length; i++) { - var element = elements[i]; - if (match(element, expression)) { - results.push(Element.extend(element)); - } - } - return results; - }, - - findElement: function(elements, expression, index) { - index = index || 0; - var matchIndex = 0, element; - for (var i = 0, length = elements.length; i < length; i++) { - element = elements[i]; - if (Prototype.Selector.match(element, expression) && index === matchIndex++) { - return Element.extend(element); - } - } - }, - - findChildElements: function(element, expressions) { - var selector = expressions.toArray().join(', '); - return Prototype.Selector.select(selector, element || document); - } - }); -})(); diff --git a/js/reviewdesu.js b/js/reviewdesu.js deleted file mode 100644 index d93bda4..0000000 --- a/js/reviewdesu.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - reviewdesu.js - this scripts proceeds to doing a review of the things you should know -*/ - -// UTILITY (copied from about.com) -// thank you the internets -Array.prototype.shuffle = function() { - var s = []; - while (this.length) s.push(this.splice(Math.random() * this.length, 1)[0]); - while (s.length) this.push(s.pop()); - return this; -} - -var questions = []; -var results = []; -var question = []; -var score = 0; - -var total = 0; -var question_nb = 0; - -function start_review() { - prepare_questions(); - next_question(); -} - -function prepare_questions() { - for (var j = 0; j < batch_data.questions.length; j++) { - var tq = []; - - var q = batch_data.questions[j]; - for (var i = 0; i < batch_data.items.length; i++) { - if (q.col) { - var answer = ''; - for (var k = 0; k < batch_data.items[i].length; k++) { - answer += '<p class="review_item_prop"><strong>' + batch_data.columns[k] + '</strong>' + batch_data.items[i][k] + "</p>"; - } - tq.push({ - "question": '<p class="review_item_q">' + batch_data.items[i][q.col] + '</p>', - "answer": answer, - "key": batch_data.items[i][0], - }); - } else { - var qu = q.q; - var an = q.a; - for (var k = 0; k < batch_data.items[i].length; k++) { - qu = qu.replace('%' + k, batch_data.items[i][k]); - an = an.replace('%' + k, batch_data.items[i][k]); - } - tq.push({ - "question": qu, - "answer": an, - "key": batch_data.items[i][0], - }); - } - } - - tq.shuffle(); - // first question asked is the last in array questions, so just put them in reverse order. - questions = tq.concat(questions); - } - total = questions.length; -} - -function next_question() { - if (questions.length == 0) { - score = Math.ceil(score * 100 / total); - $("core").innerHTML = '<p>Finished. Score : ' + score + '/100. Saving data...</p>'; - new Ajax.Request('index.php?p=brresults-study-' + batchid, { - method: 'post', - parameters: { - score: score, - results: Object.toJSON(results), - }, - onSuccess: function(transport) { - $("core").innerHTML = '<p>Finished. Score : ' + score + '/100. ' + transport.responseText + '. <a href="batch-study-' + batchid + '">back to batch</a></p>'; - }, - }); - } else { - question = questions[questions.length - 1]; - questions.pop(); - question_nb++; - - html = '<h3>Question ' + question_nb + ' of ' + total + '</h3>'; - html += '<div class="review_item">'; - html += '<div class="box">' + question.question + '</div>'; - html += '<p><button id="flipbtn" onclick="show_answer();">answer</button></p>'; - html += '</div>'; - $("core").innerHTML = html; - $("flipbtn").focus(); - } -} - -function show_answer() { - html = '<h3>Question ' + question_nb + ' of ' + total + '</h3>'; - html += '<div class="review_item">'; - html += '<div class="box2">' + question.answer + '</div>'; - html += '<div class="boxn" onclick="edit_note();" id="notebox">' + - (notes[question.key] || '<em>click to add note...</em>').replace(/\|\|/g, '<br />') + '</div>'; - html += '<p><button taborder="1" onclick="answer_question(-1);">fail</button>'; - html += '<button taborder="2" id="dunnobtn" onclick="answer_question(0);">dunno</button>'; - html += '<button taborder="3" id="winbtn" onclick="answer_question(1);">win</button></p>'; - html += '</div>'; - $("core").innerHTML = html; - $("winbtn").focus(); -} - -function answer_question(a) { - results.push([question.key, a]); - score += a; - next_question(); -} - -function edit_note() { - var idd = question.key; - var note = prompt("Add note for item:\n(you might want to add a long note, so I'm adding this text to make the prompt box bigger)", notes[idd] || ''); - if (note != null) notes[idd] = note; - if (notes[idd] == '') delete notes[idd]; - $("notebox").innerHTML = (notes[idd] || '<em>click to add note...</em>').replace(/\|\|/g, '<br />'); - - new Ajax.Request('index.php?p=brresults-study-' + batchid, { - method: 'post', - parameters: { - notes: Object.toJSON(notes), - }, - onSuccess: function(transport) { - // nothing... - }, - }); -} - diff --git a/lib/JSON/JSON.php b/lib/JSON/JSON.php deleted file mode 100644 index 0cddbdd..0000000 --- a/lib/JSON/JSON.php +++ /dev/null @@ -1,806 +0,0 @@ -<?php -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ - -/** - * Converts to and from JSON format. - * - * JSON (JavaScript Object Notation) is a lightweight data-interchange - * format. It is easy for humans to read and write. It is easy for machines - * to parse and generate. It is based on a subset of the JavaScript - * Programming Language, Standard ECMA-262 3rd Edition - December 1999. - * This feature can also be found in Python. JSON is a text format that is - * completely language independent but uses conventions that are familiar - * to programmers of the C-family of languages, including C, C++, C#, Java, - * JavaScript, Perl, TCL, and many others. These properties make JSON an - * ideal data-interchange language. - * - * This package provides a simple encoder and decoder for JSON notation. It - * is intended for use with client-side Javascript applications that make - * use of HTTPRequest to perform server communication functions - data can - * be encoded into JSON notation for use in a client-side javascript, or - * decoded from incoming Javascript requests. JSON format is native to - * Javascript, and can be directly eval()'ed with no further parsing - * overhead - * - * All strings should be in ASCII or UTF-8 format! - * - * LICENSE: Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: Redistributions of source code must retain the - * above copyright notice, this list of conditions and the following - * disclaimer. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR - * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * @category - * @package Services_JSON - * @author Michal Migurski <mike-json@teczno.com> - * @author Matt Knapp <mdknapp[at]gmail[dot]com> - * @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com> - * @copyright 2005 Michal Migurski - * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ - * @license http://www.opensource.org/licenses/bsd-license.php - * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 - */ - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_SLICE', 1); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_STR', 2); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_ARR', 3); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_OBJ', 4); - -/** - * Marker constant for Services_JSON::decode(), used to flag stack state - */ -define('SERVICES_JSON_IN_CMT', 5); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_LOOSE_TYPE', 16); - -/** - * Behavior switch for Services_JSON::decode() - */ -define('SERVICES_JSON_SUPPRESS_ERRORS', 32); - -/** - * Converts to and from JSON format. - * - * Brief example of use: - * - * <code> - * // create a new instance of Services_JSON - * $json = new Services_JSON(); - * - * // convert a complexe value to JSON notation, and send it to the browser - * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); - * $output = $json->encode($value); - * - * print($output); - * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] - * - * // accept incoming POST data, assumed to be in JSON notation - * $input = file_get_contents('php://input', 1000000); - * $value = $json->decode($input); - * </code> - */ -class Services_JSON -{ - /** - * constructs a new JSON instance - * - * @param int $use object behavior flags; combine with boolean-OR - * - * possible values: - * - SERVICES_JSON_LOOSE_TYPE: loose typing. - * "{...}" syntax creates associative arrays - * instead of objects in decode(). - * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. - * Values which can't be encoded (e.g. resources) - * appear as NULL instead of throwing errors. - * By default, a deeply-nested resource will - * bubble up with an error, so all return values - * from encode() should be checked with isError() - */ - function Services_JSON($use = 0) - { - $this->use = $use; - } - - /** - * convert a string from one UTF-16 char to one UTF-8 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf16 UTF-16 character - * @return string UTF-8 character - * @access private - */ - function utf162utf8($utf16) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); - } - - $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); - - switch(true) { - case ((0x7F & $bytes) == $bytes): - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x7F & $bytes); - - case (0x07FF & $bytes) == $bytes: - // return a 2-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xC0 | (($bytes >> 6) & 0x1F)) - . chr(0x80 | ($bytes & 0x3F)); - - case (0xFFFF & $bytes) == $bytes: - // return a 3-byte UTF-8 character - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0xE0 | (($bytes >> 12) & 0x0F)) - . chr(0x80 | (($bytes >> 6) & 0x3F)) - . chr(0x80 | ($bytes & 0x3F)); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * convert a string from one UTF-8 char to one UTF-16 char - * - * Normally should be handled by mb_convert_encoding, but - * provides a slower PHP-only method for installations - * that lack the multibye string extension. - * - * @param string $utf8 UTF-8 character - * @return string UTF-16 character - * @access private - */ - function utf82utf16($utf8) - { - // oh please oh please oh please oh please oh please - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); - } - - switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; - - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) - . chr((0xC0 & (ord($utf8{0}) << 6)) - | (0x3F & ord($utf8{1}))); - - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) - | (0x0F & (ord($utf8{1}) >> 2))) - . chr((0xC0 & (ord($utf8{1}) << 6)) - | (0x7F & ord($utf8{2}))); - } - - // ignoring UTF-32 for now, sorry - return ''; - } - - /** - * encodes an arbitrary variable into JSON format - * - * @param mixed $var any number, boolean, string, array, or object to be encoded. - * see argument 1 to Services_JSON() above for array-parsing behavior. - * if var is a strng, note that encode() always expects it - * to be in ASCII or UTF-8 format! - * - * @return mixed JSON string representation of input var or an error if a problem occurs - * @access public - */ - function encode($var) - { - switch (gettype($var)) { - case 'boolean': - return $var ? 'true' : 'false'; - - case 'NULL': - return 'null'; - - case 'integer': - return (int) $var; - - case 'double': - case 'float': - return (float) $var; - - case 'string': - // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT - $ascii = ''; - $strlen_var = strlen($var); - - /* - * Iterate over every character in the string, - * escaping with a slash or encoding to UTF-8 where necessary - */ - for ($c = 0; $c < $strlen_var; ++$c) { - - $ord_var_c = ord($var{$c}); - - switch (true) { - case $ord_var_c == 0x08: - $ascii .= '\b'; - break; - case $ord_var_c == 0x09: - $ascii .= '\t'; - break; - case $ord_var_c == 0x0A: - $ascii .= '\n'; - break; - case $ord_var_c == 0x0C: - $ascii .= '\f'; - break; - case $ord_var_c == 0x0D: - $ascii .= '\r'; - break; - - case $ord_var_c == 0x22: - case $ord_var_c == 0x2F: - case $ord_var_c == 0x5C: - // double quote, slash, slosh - $ascii .= '\\'.$var{$c}; - break; - - case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): - // characters U-00000000 - U-0000007F (same as ASCII) - $ascii .= $var{$c}; - break; - - case (($ord_var_c & 0xE0) == 0xC0): - // characters U-00000080 - U-000007FF, mask 110XXXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, ord($var{$c + 1})); - $c += 1; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF0) == 0xE0): - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2})); - $c += 2; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xF8) == 0xF0): - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3})); - $c += 3; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFC) == 0xF8): - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4})); - $c += 4; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - - case (($ord_var_c & 0xFE) == 0xFC): - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $char = pack('C*', $ord_var_c, - ord($var{$c + 1}), - ord($var{$c + 2}), - ord($var{$c + 3}), - ord($var{$c + 4}), - ord($var{$c + 5})); - $c += 5; - $utf16 = $this->utf82utf16($char); - $ascii .= sprintf('\u%04s', bin2hex($utf16)); - break; - } - } - - return '"'.$ascii.'"'; - - case 'array': - /* - * As per JSON spec if any array key is not an integer - * we must treat the the whole array as an object. We - * also try to catch a sparsely populated associative - * array with numeric keys here because some JS engines - * will create an array with empty indexes up to - * max_index which can cause memory issues and because - * the keys, which may be relevant, will be remapped - * otherwise. - * - * As per the ECMA and JSON specification an object may - * have any string as a property. Unfortunately due to - * a hole in the ECMA specification if the key is a - * ECMA reserved word or starts with a digit the - * parameter is only accessible using ECMAScript's - * bracket notation. - */ - - // treat as a JSON object - if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { - $properties = array_map(array($this, 'name_value'), - array_keys($var), - array_values($var)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - } - - // treat it like a regular array - $elements = array_map(array($this, 'encode'), $var); - - foreach($elements as $element) { - if(Services_JSON::isError($element)) { - return $element; - } - } - - return '[' . join(',', $elements) . ']'; - - case 'object': - $vars = get_object_vars($var); - - $properties = array_map(array($this, 'name_value'), - array_keys($vars), - array_values($vars)); - - foreach($properties as $property) { - if(Services_JSON::isError($property)) { - return $property; - } - } - - return '{' . join(',', $properties) . '}'; - - default: - return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) - ? 'null' - : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); - } - } - - /** - * array-walking function for use in generating JSON-formatted name-value pairs - * - * @param string $name name of key to use - * @param mixed $value reference to an array element to be encoded - * - * @return string JSON-formatted name-value pair, like '"name":value' - * @access private - */ - function name_value($name, $value) - { - $encoded_value = $this->encode($value); - - if(Services_JSON::isError($encoded_value)) { - return $encoded_value; - } - - return $this->encode(strval($name)) . ':' . $encoded_value; - } - - /** - * reduce a string by removing leading and trailing comments and whitespace - * - * @param $str string string value to strip of comments and whitespace - * - * @return string string value stripped of comments and whitespace - * @access private - */ - function reduce_string($str) - { - $str = preg_replace(array( - - // eliminate single line comments in '// ...' form - '#^\s*//(.+)$#m', - - // eliminate multi-line comments in '/* ... */' form, at start of string - '#^\s*/\*(.+)\*/#Us', - - // eliminate multi-line comments in '/* ... */' form, at end of string - '#/\*(.+)\*/\s*$#Us' - - ), '', $str); - - // eliminate extraneous space - return trim($str); - } - - /** - * decodes a JSON string into appropriate variable - * - * @param string $str JSON-formatted string - * - * @return mixed number, boolean, string, array, or object - * corresponding to given JSON input string. - * See argument 1 to Services_JSON() above for object-output behavior. - * Note that decode() always returns strings - * in ASCII or UTF-8 format! - * @access public - */ - function decode($str) - { - $str = $this->reduce_string($str); - - switch (strtolower($str)) { - case 'true': - return true; - - case 'false': - return false; - - case 'null': - return null; - - default: - $m = array(); - - if (is_numeric($str)) { - // Lookie-loo, it's a number - - // This would work on its own, but I'm trying to be - // good about returning integers where appropriate: - // return (float)$str; - - // Return float or int, as appropriate - return ((float)$str == (integer)$str) - ? (integer)$str - : (float)$str; - - } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { - // STRINGS RETURNED IN UTF-8 FORMAT - $delim = substr($str, 0, 1); - $chrs = substr($str, 1, -1); - $utf8 = ''; - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c < $strlen_chrs; ++$c) { - - $substr_chrs_c_2 = substr($chrs, $c, 2); - $ord_chrs_c = ord($chrs{$c}); - - switch (true) { - case $substr_chrs_c_2 == '\b': - $utf8 .= chr(0x08); - ++$c; - break; - case $substr_chrs_c_2 == '\t': - $utf8 .= chr(0x09); - ++$c; - break; - case $substr_chrs_c_2 == '\n': - $utf8 .= chr(0x0A); - ++$c; - break; - case $substr_chrs_c_2 == '\f': - $utf8 .= chr(0x0C); - ++$c; - break; - case $substr_chrs_c_2 == '\r': - $utf8 .= chr(0x0D); - ++$c; - break; - - case $substr_chrs_c_2 == '\\"': - case $substr_chrs_c_2 == '\\\'': - case $substr_chrs_c_2 == '\\\\': - case $substr_chrs_c_2 == '\\/': - if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || - ($delim == "'" && $substr_chrs_c_2 != '\\"')) { - $utf8 .= $chrs{++$c}; - } - break; - - case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): - // single, escaped unicode character - $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) - . chr(hexdec(substr($chrs, ($c + 4), 2))); - $utf8 .= $this->utf162utf8($utf16); - $c += 5; - break; - - case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): - $utf8 .= $chrs{$c}; - break; - - case ($ord_chrs_c & 0xE0) == 0xC0: - // characters U-00000080 - U-000007FF, mask 110XXXXX - //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 2); - ++$c; - break; - - case ($ord_chrs_c & 0xF0) == 0xE0: - // characters U-00000800 - U-0000FFFF, mask 1110XXXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 3); - $c += 2; - break; - - case ($ord_chrs_c & 0xF8) == 0xF0: - // characters U-00010000 - U-001FFFFF, mask 11110XXX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 4); - $c += 3; - break; - - case ($ord_chrs_c & 0xFC) == 0xF8: - // characters U-00200000 - U-03FFFFFF, mask 111110XX - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 5); - $c += 4; - break; - - case ($ord_chrs_c & 0xFE) == 0xFC: - // characters U-04000000 - U-7FFFFFFF, mask 1111110X - // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - $utf8 .= substr($chrs, $c, 6); - $c += 5; - break; - - } - - } - - return $utf8; - - } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { - // array, or object notation - - if ($str{0} == '[') { - $stk = array(SERVICES_JSON_IN_ARR); - $arr = array(); - } else { - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = array(); - } else { - $stk = array(SERVICES_JSON_IN_OBJ); - $obj = new stdClass(); - } - } - - array_push($stk, array('what' => SERVICES_JSON_SLICE, - 'where' => 0, - 'delim' => false)); - - $chrs = substr($str, 1, -1); - $chrs = $this->reduce_string($chrs); - - if ($chrs == '') { - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } else { - return $obj; - - } - } - - //print("\nparsing {$chrs}\n"); - - $strlen_chrs = strlen($chrs); - - for ($c = 0; $c <= $strlen_chrs; ++$c) { - - $top = end($stk); - $substr_chrs_c_2 = substr($chrs, $c, 2); - - if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { - // found a comma that is not inside a string, array, etc., - // OR we've reached the end of the character list - $slice = substr($chrs, $top['where'], ($c - $top['where'])); - array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); - //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - // we are in an array, so just push an element onto the stack - array_push($arr, $this->decode($slice)); - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - // we are in an object, so figure - // out the property name and set an - // element in an associative array, - // for now - $parts = array(); - - if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // "name":value pair - $key = $this->decode($parts[1]); - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { - // name:value pair, where name is unquoted - $key = $parts[1]; - $val = $this->decode($parts[2]); - - if ($this->use & SERVICES_JSON_LOOSE_TYPE) { - $obj[$key] = $val; - } else { - $obj->$key = $val; - } - } - - } - - } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { - // found a quote, and we are not inside a string - array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); - //print("Found start of string at {$c}\n"); - - } elseif (($chrs{$c} == $top['delim']) && - ($top['what'] == SERVICES_JSON_IN_STR) && - ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { - // found a quote, we're in a string, and it's not escaped - // we know that it's not escaped becase there is _not_ an - // odd number of backslashes at the end of the string so far - array_pop($stk); - //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '[') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-bracket, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); - //print("Found start of array at {$c}\n"); - - } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { - // found a right-bracket, and we're in an array - array_pop($stk); - //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($chrs{$c} == '{') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a left-brace, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); - //print("Found start of object at {$c}\n"); - - } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { - // found a right-brace, and we're in an object - array_pop($stk); - //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } elseif (($substr_chrs_c_2 == '/*') && - in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { - // found a comment start, and we are in an array, object, or slice - array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); - $c++; - //print("Found start of comment at {$c}\n"); - - } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { - // found a comment end, and we're in one now - array_pop($stk); - $c++; - - for ($i = $top['where']; $i <= $c; ++$i) - $chrs = substr_replace($chrs, ' ', $i, 1); - - //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); - - } - - } - - if (reset($stk) == SERVICES_JSON_IN_ARR) { - return $arr; - - } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { - return $obj; - - } - - } - } - } - - /** - * @todo Ultimately, this should just call PEAR::isError() - */ - function isError($data, $code = null) - { - if (class_exists('pear')) { - return PEAR::isError($data, $code); - } elseif (is_object($data) && (get_class($data) == 'services_json_error' || - is_subclass_of($data, 'services_json_error'))) { - return true; - } - - return false; - } -} - -if (class_exists('PEAR_Error')) { - - class Services_JSON_Error extends PEAR_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - parent::PEAR_Error($message, $code, $mode, $options, $userinfo); - } - } - -} else { - - /** - * @todo Ultimately, this class shall be descended from PEAR_Error - */ - class Services_JSON_Error - { - function Services_JSON_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - - } - } - -} - -?> diff --git a/lib/JSON/inc_json.php b/lib/JSON/inc_json.php deleted file mode 100644 index b36c2a4..0000000 --- a/lib/JSON/inc_json.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php - -if (!function_exists('json_decode')) { - function json_decode($content, $assoc=false) { - require_once 'lib/JSON/JSON.php'; - if ($assoc) { - $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); - } - else { - $json = new Services_JSON; - } - return $json->decode($content); - } -} - -if (!function_exists('json_encode')) { - function json_encode($content) { - require_once 'lib/JSON/JSON.php'; - $json = new Services_JSON; - return $json->encode($content); - } -} diff --git a/lib/conf/apps.php b/lib/conf/apps.php index 8e755b1..c3efea4 100644 --- a/lib/conf/apps.php +++ b/lib/conf/apps.php @@ -4,7 +4,7 @@ $homepage = "blog"; $apps = array( - // Image upload application + // File upload application "file" => array( "index" => 1, "delete" => 1, @@ -48,43 +48,5 @@ $apps = array( "delcom" => 2, ), - // Studies application - "deck" => array( - "index" => 0, - "new" => 1, - "view" => 0, - // function called for editing - "edit" => 1, // change title, comment - "addent" => 1, // add card - "rment" => 1, // remove card - "edent" => 1, // edit card - "mvent" => 1, // move card - ), - "list" => array( - "index" => 0, - "view" => 0, - "new" => 1, - "edit" => 1, // edit global info = name, desc, ... - - "addbatch" => 1, - "edbatch" => 1, - "rmbatch" => 1, - ), - - "study" => array ( - "index" => 0, - "deckadd" => 1, - "deck" => 1, - "deckrm" => 1, - "setrate" => 1, - "setcard" => 1, - - "listadd" => 1, // create list_study - "list" => 1, // !!!!!! show global progress for a list_study - "listrm" => 1, // delete list_study - "batch" => 1, // (JS) shows progress for a batch_study - "batchreview" => 1, // (JS) batch review app - "brresults" => 1, - ), ); diff --git a/lib/deck/add.php b/lib/deck/add.php deleted file mode 100644 index d7f8e9f..0000000 --- a/lib/deck/add.php +++ /dev/null @@ -1,5 +0,0 @@ -<?php - -$title = "olol"; -$message = 'Placeholder. Go to <a href="deck">study decks</a>.'; -require("tpl/general/empty.php"); diff --git a/lib/deck/addent.php b/lib/deck/addent.php deleted file mode 100644 index a860df1..0000000 --- a/lib/deck/addent.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) == 3, 'deck'); -$deckid = intval($args[2]); - -$deck = mysql_fetch_assoc(sql( - "SELECT decks.id AS id, decks.name AS name, decks.comment_md AS comment, decks.owner AS owner_id ". - "FROM decks ". - "WHERE decks.id = $deckid")); -assert_error($deck && $deck['owner_id'] == $user['id'], - "This deck does not exist, or you are not allowed to edit it."); - -$card_name = ""; -$card_text = ""; -if (isset($_POST['name']) && isset($_POST['text'])) { - $card_name = esca($_POST['name']); - $card_text = esca($_POST['text']); - $card_text_html = Markdown($card_text); - if ($card_name == "") { - $error = "You must give your card a name."; - } else if ($card_text == "") { - $error = "You must put some text in your card."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM cards WHERE deck = $deckid AND name = '" . escs($card_name)."'"))) { - $error = "You already have a card using that name."; - } else { - $n = mysql_fetch_assoc(sql("SELECT MAX(number) AS n FROM cards WHERE deck = $deckid")); - $number = $n['n'] + 1; - sql( - "INSERT INTO cards(deck, number, name, text_md, text_html) ". - "VALUES($deckid, $number, '" . escs($card_name) . "', '" . escs($card_text) . "', '" . escs($card_text_html). "')"); - header("Location: view-deck-$deckid"); - die(); - } -} - -$title = "Add card to " . $deck['name']; -$message = "Your card will be added at the end of the deck. You can always move it afterwards."; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $card_name), - array("label" => "Text : ", "name" => "text", "type" => "textarea", "value" => $card_text), -); -$validate = "Add card"; - -require("tpl/deck/ef.php"); diff --git a/lib/deck/edent.php b/lib/deck/edent.php deleted file mode 100644 index 8bdfac3..0000000 --- a/lib/deck/edent.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) == 3, 'deck'); -$cardid = intval($args[2]); - -$card = mysql_fetch_assoc(sql( - "SELECT decks.id AS deckid, decks.owner AS deckowner, decks.name AS deckname, cards.name AS name, cards.text_md AS text ". - "FROM cards LEFT JOIN decks ON decks.id = cards.deck ". - "WHERE cards.id = $cardid")); -assert_error($card && $card["deckowner"] == $user['id'], - "This card does not exist, or you are not allowed to edit it."); -$deck = array("id" => $card['deckid'], 'name' => $card['deckname']); - -$card_name = $card['name']; -$card_text = $card['text']; -if (isset($_POST['name']) && isset($_POST['text'])) { - $card_name = esca($_POST['name']); - $card_text = esca($_POST['text']); - $card_text_html = Markdown($card_text); - if ($card_name == "") { - $error = "You must give your card a name."; - } else if ($card_text == "") { - $error = "You must put some text in your card."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM cards WHERE deck = " . $deck['id'] . " AND name = '" . escs($card_name)."' AND id != $cardid"))) { - $error = "You already have a card using that name."; - } else { - sql("UPDATE cards SET name = '" . escs($card_name) . "', text_md = '" . escs($card_text) . "', text_html = '" . escs($card_text_html) . "'" . - " WHERE id = $cardid"); - header("Location: view-deck-" . $deck['id']); - die(); - } -} - -$title = "Edit card in " . $deck['name']; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $card_name), - array("label" => "Text : ", "name" => "text", "type" => "textarea", "value" => $card_text), -); -$validate = "Edit card"; - -require("tpl/deck/ef.php"); - diff --git a/lib/deck/edit.php b/lib/deck/edit.php deleted file mode 100644 index d4102bb..0000000 --- a/lib/deck/edit.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) == 3, 'deck'); -$deckid = intval($args[2]); - -$deck = mysql_fetch_assoc(sql( - "SELECT decks.id AS id, decks.name AS name, decks.comment_md AS comment, account.id AS owner_id ". - "FROM decks LEFT JOIN account ON account.id = decks.owner ". - "WHERE decks.id = $deckid")); -assert_error($deck && $deck['owner_id'] == $user['id'], - "This deck does not exist, or you are not allowed to edit it."); - -$deck_name = $deck['name']; -$deck_comment = $deck['comment']; -if (isset($_POST['name']) && isset($_POST['comment'])) { - $deck_name = esca($_POST['name']); - $deck_comment = esca($_POST['comment']); - $deck_comment_html = Markdown($deck_comment); - if ($deck_name == "") { - $error = "You must enter a name for your deck."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM decks WHERE owner = " . $user['id'] . " AND name = '" . escs($deck_name) . "' AND id != $deckid"))) { - $error = "You already have a deck with that title."; - } else if ($deck_comment == "") { - $error = "Please enter a comment on your deck."; - } else { - sql("UPDATE decks SET name = '" . escs($deck_name) . "', comment_md = '" . escs($deck_comment) . - "', comment_html = '" . escs($deck_comment_html) . "' WHERE id = $deckid"); - header("Location: view-deck-" . $deckid); - die(); - } -} - -$title = "Edit deck : " . $deck['name']; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $deck_name), - array("label" => "Comment : ", "name" => "comment", "type" => "textarea", "value" => $deck_comment), -); -$validate = "Edit deck"; - -require("tpl/deck/ef.php"); diff --git a/lib/deck/index.php b/lib/deck/index.php deleted file mode 100644 index ad497d5..0000000 --- a/lib/deck/index.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -$filters = array ( - "order" => array ( - "nbUsers" => "popularity", - "name" => "name", - "owner" => "author", - ), - "way" => $ord_ways, -); -$fdefaults = array ( - "order" => "nbUsers", - "way" => "DESC", -); - -$decks = array(); -$n = sql( - "SELECT decks.id AS id, decks.name AS name, account.login AS owner, COUNT(deck_study.id) AS nbUsers ". - "FROM decks LEFT JOIN account ON decks.owner = account.id LEFT JOIN deck_study ON deck_study.deck = decks.id ". - "GROUP BY decks.id ORDER BY " . get_filter("order") . " " . get_filter("way") - ); -while ($nn = mysql_fetch_assoc($n)) $decks[] = $nn; - -require("tpl/deck/index.php"); - diff --git a/lib/deck/mvent.php b/lib/deck/mvent.php deleted file mode 100644 index 28a7fa3..0000000 --- a/lib/deck/mvent.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) == 4, 'deck'); -$cardid = intval($args[2]); -$pos = intval($args[3]); - -$card = mysql_fetch_assoc(sql( - "SELECT decks.id AS deckid, decks.owner AS deckowner, decks.name AS deckname, cards.name AS name, cards.text_md AS text, cards.number AS number ". - "FROM cards LEFT JOIN decks ON decks.id = cards.deck ". - "WHERE cards.id = $cardid")); -assert_error($card && $card["deckowner"] == $user['id'], - "This card does not exist, or you are not allowed to edit it."); -$deck = array("id" => $card['deckid'], 'name' => $card['deckname']); -$deckid = $card['deckid']; - -$mn = mysql_fetch_assoc(sql("SELECT COUNT(*) AS c FROM cards WHERE deck = $deckid")); -$mn = $mn['c']; -if ($pos > $mn) { - $error = "That number is too big. You don't even have that much cards in your deck."; -} else if ($pos < 1) { - $error = "A position is at least one..."; -} else { - sql("UPDATE cards SET number = 0 WHERE id = $cardid"); - sql("UPDATE cards SET number = number - 1 WHERE number > " . $card['number'] . " AND deck = $deckid ORDER BY number ASC"); - sql("UPDATE cards SET number = number + 1 WHERE number >= $pos AND deck = $deckid ORDER BY number DESC"); - sql("UPDATE cards SET number = $pos WHERE id = $cardid"); - sql("UPDATE deck_study SET need_check = 1 WHERE deck = $deckid"); - header("Location: view-deck-$deckid"); -} - -require("tpl/deck/ef.php"); diff --git a/lib/deck/new.php b/lib/deck/new.php deleted file mode 100644 index 2ff1b50..0000000 --- a/lib/deck/new.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -require("lib/markdown.php"); - -$deck_name = ""; -$deck_comment = ""; -if (isset($_POST["name"]) && isset($_POST['comment'])) { - $deck_name = esca($_POST['name']); - $deck_comment = esca($_POST['comment']); - $deck_comment_html = Markdown($deck_comment); - if ($deck_name == "") { - $error = "You must enter a name for your deck."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM decks WHERE owner = " . $user['id'] . " AND name = '" . escs($deck_name) . "'"))) { - $error = "You already have a deck with that title."; - } else if ($deck_comment == "") { - $error = "Please enter a comment on your deck."; - } else { - sql("INSERT INTO decks(owner, name, comment_md, comment_html) ". - "VALUES(" . $user['id'] . ", '" . escs($deck_name) . "', '" . escs($deck_comment) . "', '" . escs($deck_comment_html) . "')"); - header("Location: view-deck-" . mysql_insert_id()); - die(); - } -} - -$title = "Create deck"; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $deck_name), - array("label" => "Comment : ", "name" => "comment", "type" => "textarea", "value" => $deck_comment), - ); -$validate = "Create deck"; - -require("tpl/deck/new.php"); diff --git a/lib/deck/rment.php b/lib/deck/rment.php deleted file mode 100644 index c4f86c8..0000000 --- a/lib/deck/rment.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) >= 3, 'deck'); -$cardid = intval($args[2]); - -$card = mysql_fetch_assoc(sql( - "SELECT decks.id AS deckid, decks.owner AS deckowner, decks.name AS deckname, cards.name AS name, cards.text_md AS text, cards.number AS number ". - "FROM cards LEFT JOIN decks ON decks.id = cards.deck ". - "WHERE cards.id = $cardid")); -assert_error($card && $card["deckowner"] == $user['id'], - "This card does not exist, or you are not allowed to edit it."); - -token_validate("Do you really want to delete this card ?", "view-deck-". $card['deckid']); -sql("DELETE FROM cards WHERE id = $cardid"); -sql("UPDATE cards SET number = number - 1 WHERE number > " . $card['number'] . " AND deck = " . $card['deckid'] . " ORDER BY number ASC"); -sql("UPDATE deck_study SET need_check = 1 WHERE deck = " . $card['deckid']); -header("Location: view-deck-" . $card['deckid']); -die(); diff --git a/lib/deck/view.php b/lib/deck/view.php deleted file mode 100644 index e9a83e6..0000000 --- a/lib/deck/view.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'deck'); -$deckid = intval($args[2]); - -$deck = mysql_fetch_assoc(sql( - "SELECT decks.id AS id, decks.name AS name, decks.comment_html AS comment, account.login AS owner, account.id AS owner_id ". - "FROM decks LEFT JOIN account ON account.id = decks.owner ". - "WHERE decks.id = $deckid")); -assert_error($deck, "This deck does not exist."); - -$can_edit = false; -if ($deck["owner_id"] == $user['id']) $can_edit = true; - -$filters = array ( - "order" => array ( - "name" => "card name", - "number" => "card number", - ), - "way" => $ord_ways, -); -$fdefaults = array ( - "order" => "number", - "way" => ($can_edit ? "DESC" : "ASC"), -); - -$cards = array(); -$n = sql( - "SELECT id, number, name, text_html AS text FROM cards WHERE deck = $deckid ". - "ORDER BY " . get_filter("order") . " " . get_filter("way") - ); -while ($nn = mysql_fetch_assoc($n)) $cards[] = $nn; - -$can_start_study = false; -if ($user['id'] != 0) { - if (!mysql_fetch_assoc(sql("SELECT id FROM deck_study WHERE deck = $deckid AND user = " . $user['id']))) - $can_start_study = true; -} else { - $message = "You should create an account in order to study this deck."; -} - -require("tpl/deck/view.php"); diff --git a/lib/list/addbatch.php b/lib/list/addbatch.php deleted file mode 100644 index 5cb5fb6..0000000 --- a/lib/list/addbatch.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -require("lib/list/inc_process.php"); - -assert_redir(count($args) == 3, 'list'); -$listid = intval($args[2]); - -$list = mysql_fetch_assoc(sql( - "SELECT lists.id AS id, lists.name AS name, lists.owner AS owner_id ". - "FROM lists WHERE lists.id = $listid")); -assert_error($list && $list['owner_id'] == $user['id'], - "This list does not exist, or you are not allowed to edit it."); - -$batch_name = ""; -$batch_model = ""; -$batch_contents = ""; -if (isset($_POST['name']) && isset($_POST['model']) && isset($_POST['contents'])) { - $batch_name = esca($_POST['name']); - $batch_model = esca($_POST['model']); - $batch_contents = esca($_POST['contents']); - $batch_json = mk_batch_json($batch_model, $batch_contents); - if ($batch_name == "") { - $error = "You must give a name to this batch."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM batches WHERE list = $listid AND name = '" . escs($batch_name) . "'"))) { - $error = "You already have a batch using that name."; - } else { - sql( - "INSERT INTO batches(list, name, model, contents, json_data) ". - "VALUES($listid, '" . escs($batch_name) . "', '" . escs($batch_model) . "', '" . escs($batch_contents) . "', '" . escs($batch_json) . "')"); - header("Location: view-list-$listid"); - die(); - } -} - -$title = "Add batch to " . $list['name']; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $batch_name), - array("label" => "Columns : ", "name" => "model", "value" => $batch_model), - array("label" => "Contents : ", "name" => "contents", "type" => "textarea", "value" => $batch_contents) -); -$validate = "Add batch"; - -require("tpl/list/ef.php"); diff --git a/lib/list/edbatch.php b/lib/list/edbatch.php deleted file mode 100644 index 380ecf2..0000000 --- a/lib/list/edbatch.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -require("lib/list/inc_process.php"); - -assert_redir(count($args) == 3, 'list'); -$batchid = intval($args[2]); - -$batch = mysql_fetch_assoc(sql( - "SELECT lists.id AS listid, lists.owner AS listowner, lists.name AS listname, batches.name AS name, ". - "batches.model AS model, batches.contents AS contents ". - "FROM batches LEFT JOIN lists ON lists.id = batches.list ". - "WHERE batches.id = $batchid")); -assert_error($batch && $batch['listowner'] == $user['id'], - "this batch does not exist, or you are not allowed to edit it."); -$list = array("id" => $batch['listid'], 'name' => $batch['listname']); - -$batch_name = $batch['name']; -$batch_model = $batch['model']; -$batch_contents = $batch['contents']; -if (isset($_POST['name']) && isset($_POST['model']) && isset($_POST['contents'])) { - $batch_name = esca($_POST['name']); - $batch_model = esca($_POST['model']); - $batch_contents = esca($_POST['contents']); - $batch_json = mk_batch_json($batch_model, $batch_contents); - if ($batch_name == "") { - $error = "You must give a name to this batch."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM batches WHERE list = " . $list['id'] . " AND name = '" . escs($batch_name) . "' AND id != $batchid"))) { - $error = "You already have a batch using that name."; - } else { - sql( - "UPDATE batches SET name = '" . escs($batch_name) . "', model = '" . escs($batch_model) . "', ". - "contents = '" . escs($batch_contents) . "', json_data = '" . escs($batch_json) . "' WHERE id = $batchid" - ); - header("Location: view-list-" . $list['id']); - die(); - } -} - -$title = "Edit batch in " . $list['name']; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $batch_name), - array("label" => "Columns : ", "name" => "model", "value" => $batch_model), - array("label" => "Contents : ", "name" => "contents", "type" => "textarea", "value" => $batch_contents) -); -$validate = "Edit batch"; - -require("tpl/list/ef.php"); diff --git a/lib/list/edit.php b/lib/list/edit.php deleted file mode 100644 index 64394be..0000000 --- a/lib/list/edit.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -require("lib/markdown.php"); - -assert_redir(count($args) == 3, 'list'); -$listid = intval($args[2]); - -$list = mysql_fetch_assoc(sql( - "SELECT lists.id AS id, lists.name AS name, lists.comment_md AS comment, account.id AS owner_id ". - "FROM lists LEFT JOIN account ON account.id = lists.owner ". - "WHERE lists.id = $listid")); -assert_error($list && $list['owner_id'] == $user['id'], - "This list does not exist, or you are not allowed to edit it."); - -$list_name = $list['name']; -$list_comment = $list['comment']; -if (isset($_POST['name']) && isset($_POST['comment'])) { - $list_name = esca($_POST['name']); - $list_comment = esca($_POST['comment']); - $list_comment_html = Markdown($list_comment); - if ($list_name == "") { - $error = "You must enter a name for your list."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM lists WHERE owner = " . $user['id'] . " AND name = '" . escs($list_name) . "' AND id != $listid"))) { - $error = "You already have a list with that title."; - } else if ($list_comment == "") { - $error = "Please enter a comment on your list."; - } else { - sql("UPDATE lists SET name = '" . escs($list_name) . "', comment_md = '" . escs($list_comment) . - "', comment_html = '" . escs($list_comment_html) . "' WHERE id = $listid"); - header("Location: view-list-" . $listid); - die(); - } -} - -$title = "Edit list : " . $list['name']; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $list_name), - array("label" => "Comment : ", "name" => "comment", "type" => "textarea", "value" => $list_comment), -); -$validate = "Edit list"; - -require("tpl/list/ef.php"); - diff --git a/lib/list/inc_process.php b/lib/list/inc_process.php deleted file mode 100644 index 0c7dd82..0000000 --- a/lib/list/inc_process.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -require("lib/JSON/inc_json.php"); -require("lib/list/list_models.php"); - -function mk_batch_json($models, $contents) { - global $list_models; - - $data = array("columns" => array(), "items" => array(), "questions" => array()); - - if ($models[0] == '*') { - $model = $list_models[substr($models, 1)]; - - $columns = $data['columns'] = $model['columns']; - $data['questions'] = $model['questions']; - } else { - $columns = explode('|', $models); - - foreach ($columns as $k => $c) { - if ($c[0] == '!') { - $data['columns'][] = substr($c, 1); - } else { - $data['columns'][] = $c; - $data['questions'][] = array('col' => $k); - } - } - } - - $items = explode("\n", $contents); - foreach($items as $i) { - $ii = explode('|', str_replace("\r", '', $i)); - if (count($ii) == count($columns)) { - $data['items'][] = $ii; - } - } - - return json_encode($data); -} - - diff --git a/lib/list/index.php b/lib/list/index.php deleted file mode 100644 index cbcad67..0000000 --- a/lib/list/index.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -$filters = array ( - "order" => array ( - "nbUsers" => "popularity", - "name" => "name", - "owner" => "author", - ), - "way" => $ord_ways, -); -$fdefaults = array ( - "order" => "nbUsers", - "way" => "DESC", -); - -$lists = array(); -$n = sql( - "SELECT lists.id AS id, lists.name AS name, account.login AS owner, COUNT(list_study.id) AS nbUsers ". - "FROM lists LEFT JOIN account ON lists.owner = account.id LEFT JOIN list_study ON list_study.list = lists.id ". - "GROUP BY lists.id ORDER BY " . get_filter("order") . " " . get_filter("way") - ); -while ($nn = mysql_fetch_assoc($n)) $lists[] = $nn; - -require("tpl/list/index.php"); - diff --git a/lib/list/list_models.php b/lib/list/list_models.php deleted file mode 100644 index b68b538..0000000 --- a/lib/list/list_models.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php - -$list_models = array( - "RTK-Kanji" => array( - "columns" => array("N#", "Kanji", "Keyword", "Strokes"), - "questions" => array( - array( - 'q' => '<p class="rtk_kr_q_2">%2</p>', - 'a' => '<p class="rtk_kr_a_2">#%0: %2 [%3]<br /><span>%1</span></p>' - ), - array( - 'q' => '<p class="rtk_kr_q_1">%1</p>', - 'a' => '<p class="rtk_kr_a_1">#%0: %1 [%3]<br /><span>%2</span></p>' - ), - ), - ), - "JA-Vocab" => array( - "columns" => array("N#", "Kanji", "Kana", "English"), - "questions" => array( - array( - 'q' => '<p class="vocabqa">%3</p>', - 'a' => '<p class="vocaba"><span class="vocabreading">%2</span><br />%1<br /><span>%3</span></p>', - ), - array( - 'q' => '<p class="vocabqb">%1</p>', - 'a' => '<p class="vocaba"><span class="vocabreading">%2</span><br />%1<br /><span>%3</span></p>', - ), - ), - ), - "JA-Vocab-fr" => array( - "columns" => array("N#", "Kanji", "Kana", "French"), - "questions" => array( - array( - 'q' => '<p class="vocabqb">%1</p>', - 'a' => '<p class="vocaba"><span class="vocabreading">%2</span><br />%1<br /><span>%3</span></p>', - ), - ), - ), -); diff --git a/lib/list/new.php b/lib/list/new.php deleted file mode 100644 index 9a9c801..0000000 --- a/lib/list/new.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -require("lib/markdown.php"); - -$list_name = ""; -$list_comment = ""; -if (isset($_POST["name"]) && isset($_POST['comment'])) { - $list_name = esca($_POST['name']); - $list_comment = esca($_POST['comment']); - $list_comment_html = Markdown($list_comment); - if ($list_name == "") { - $error = "You must enter a name for your list."; - } else if (mysql_fetch_assoc(sql("SELECT id FROM lists WHERE owner = " . $user['id'] . " AND name = '" . escs($list_name) . "'"))) { - $error = "You already have a list with that title."; - } else if ($list_comment == "") { - $error = "Please enter a comment on your list."; - } else { - sql("INSERT INTO lists(owner, name, comment_md, comment_html) ". - "VALUES(" . $user['id'] . ", '" . escs($list_name) . "', '" . escs($list_comment) . "', '" . escs($list_comment_html) . "')"); - header("Location: view-list-" . mysql_insert_id()); - die(); - } -} - -$title = "Create list"; -$fields = array( - array("label" => "Name : ", "name" => "name", "value" => $list_name), - array("label" => "Comment : ", "name" => "comment", "type" => "textarea", "value" => $list_comment), - ); -$validate = "Create list"; - -require("tpl/list/new.php"); - diff --git a/lib/list/rmbatch.php b/lib/list/rmbatch.php deleted file mode 100644 index 90ea370..0000000 --- a/lib/list/rmbatch.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -assert_redir(count($args) >= 3, 'list'); -$batchid = intval($args[2]); - -$batch = mysql_fetch_assoc(sql( - "SELECT lists.id AS listid, lists.owner AS listowner, lists.name AS listname, batches.name AS name, ". - "batches.model AS model, batches.contents AS contents ". - "FROM batches LEFT JOIN lists ON lists.id = batches.list ". - "WHERE batches.id = $batchid")); -assert_error($batch && $batch['listowner'] == $user['id'], - "this batch does not exist, or you are not allowed to edit it."); - -token_validate("Do you really want to delete this batch ?", "view-list-" . $batch['listid']); - -sql("DELETE FROM batches WHERE id = $batchid"); -sql("DELETE FROM batch_study WHERE batch = $batchid"); -sql("DELETE FROM batch_review WHERE batch = $batchid"); -header("Location: view-list-" . $batch['listid']); -die(); diff --git a/lib/list/view.php b/lib/list/view.php deleted file mode 100644 index 2055523..0000000 --- a/lib/list/view.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'list'); -$listid = intval($args[2]); - -$list = mysql_fetch_assoc(sql( - "SELECT lists.id AS id, lists.name AS name, lists.comment_html AS comment, account.login AS owner, ". - "account.id AS owner_id ". - "FROM lists LEFT JOIN account ON account.id = lists.owner ". - "WHERE lists.id = $listid")); -assert_error($list, "This list does not exist."); - -$can_edit = false; -if ($list["owner_id"] == $user['id']) $can_edit = true; - -$batches = array(); -$n = sql( - "SELECT id, name FROM batches WHERE list = $listid ". - "ORDER BY name ASC" - ); -while ($nn = mysql_fetch_assoc($n)) $batches[] = $nn; - -$can_start_study = false; -if ($user['id'] != 0) { - if (!mysql_fetch_assoc(sql("SELECT id FROM list_study WHERE list = $listid AND user = " . $user['id']))) - $can_start_study = true; -} else { - $message = "You should create an account in order to study this list."; -} - -require("tpl/list/view.php"); diff --git a/lib/study/batch.php b/lib/study/batch.php deleted file mode 100644 index 60152f1..0000000 --- a/lib/study/batch.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'study'); -$batchid = intval($args[2]); - -$info = mysql_fetch_assoc(sql( - "SELECT list_study.id AS studyid, batches.name AS bname, ". - "lists.name AS lname, account.login AS uname, ". - "batch_study.id AS bsid, batch_study.notes_json AS notes, ". - "batches.id AS batchid, batches.json_data AS json_data ". - "FROM batches LEFT JOIN list_study ON list_study.list = batches.list AND list_study.user = " . $user['id'] . " " . - "LEFT JOIN batch_study ON batch_study.batch = $batchid AND batch_study.user = " . $user['id'] . " " . - "LEFT JOIN lists ON batches.list = lists.id ". - "LEFT JOIN account ON account.id = lists.owner ". - "WHERE batches.id = $batchid")); -assert_error($info, "This batch does not exist."); -assert_error($info['studyid'] != 0, "You are not studying this list."); - -if ($info["bsid"] == 0) { - sql("INSERT INTO batch_study(user, batch, last_review, notes_json) ". - "VALUES(" . $user['id'] . ", $batchid, 0, '{}')"); - $info['bsid'] = mysql_insert_id(); - $info['notes'] = '{}'; -} - -$reviews = array(); -$d = sql("SELECT results, score, date, batch FROM batch_review WHERE batch = $batchid AND user = " . $user['id'] ." ORDER BY date ASC"); -while ($r = mysql_fetch_assoc($d)) { - $reviews[] = '{"batch": ' . $r['batch'] . ', "date" : "' . $r['date'] . '", '. - '"score": ' . $r['score'] . ', "results": ' . $r['results'] . '}'; -} -$reviews = '[' . implode(', ', $reviews) . ']'; - -require("tpl/study/batch.php"); diff --git a/lib/study/batchreview.php b/lib/study/batchreview.php deleted file mode 100644 index 58fc852..0000000 --- a/lib/study/batchreview.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'study'); -$batchid = intval($args[2]); - -$info = mysql_fetch_assoc(sql( - "SELECT list_study.id AS studyid, batches.name AS bname, ". - "lists.name AS lname, account.login AS uname, ". - "batch_study.id AS bsid, batch_study.notes_json AS notes, ". - "batches.id AS batchid, batches.json_data AS json_data ". - "FROM batches LEFT JOIN list_study ON list_study.list = batches.list AND list_study.user = " . $user['id'] . " " . - "LEFT JOIN batch_study ON batch_study.batch = $batchid AND batch_study.user = " . $user['id'] . " " . - "LEFT JOIN lists ON batches.list = lists.id ". - "LEFT JOIN account ON account.id = lists.owner ". - "WHERE batches.id = $batchid")); -assert_error($info, "This batch does not exist."); -assert_error($info['studyid'] != 0, "You are not studying this list."); - -if ($info["bsid"] == 0) { - sql("INSERT INTO batch_study(user, batch, last_review, notes_json) VALUES(" . $user['id'] . ", $batchid, 0, '{}')"); - $info['bsid'] = mysql_insert_id(); - $info['notes'] = '{}'; -} - -require("tpl/study/batch_review.php"); diff --git a/lib/study/brresults.php b/lib/study/brresults.php deleted file mode 100644 index 93ebfdf..0000000 --- a/lib/study/brresults.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'study'); -$batchid = intval($args[2]); - -$info = mysql_fetch_assoc(sql( - "SELECT list_study.id AS studyid, ". - "batch_study.id AS bsid, batches.id AS batchid, batches.json_data AS json_data ". - "FROM batches LEFT JOIN list_study ON list_study.list = batches.list AND list_study.user = " . $user['id'] . " " . - "LEFT JOIN batch_study ON batch_study.batch = $batchid AND batch_study.user = " . $user['id'] . " " . - "WHERE batches.id = $batchid")); -if (!($info)) { - echo "This batch does not exist"; - die(); -} -if (!($info['studyid'] != 0)) { - echo "You are not studying this list."; - die(); -} - -if ($info["bsid"] == 0) { - sql("INSERT INTO batch_study(user, batch, last_review, notes_json) ". - "VALUES(" . $user['id'] . ", $batchid, 0, '{}')"); - $info['bsid'] = mysql_insert_id(); - $info['notes'] = '{}'; -} - -if (isset($_POST['results']) && isset($_POST['score'])) { - sql("UPDATE batch_study SET before_last_review = last_review WHERE id = " . $info['bsid']); - sql("INSERT INTO batch_review(user, batch, results, score, date) ". - "VALUES(" . $user['id'] . ", $batchid, '" . escs(esca($_POST['results'])) . "', " . intval($_POST['score']) . ", NOW())"); - sql("UPDATE batch_study SET last_review = " . mysql_insert_id() . " WHERE id = " . $info['bsid']); - echo 'Saved'; -} else if (isset($_POST['notes'])) { - sql("UPDATE batch_study SET notes_json = '" . escs(esca($_POST['notes'])) . "' WHERE id = " . $info['bsid']); - echo 'Saved'; -} else { - echo 'Error'; -} - -die(); diff --git a/lib/study/deck.php b/lib/study/deck.php deleted file mode 100644 index 752ff98..0000000 --- a/lib/study/deck.php +++ /dev/null @@ -1,96 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'study'); -$studyid = intval($args[2]); - -$study = mysql_fetch_assoc(sql( - "SELECT decks.id AS deckid, decks.name AS deckname, account.login AS deckowner, ". - " deck_study.learn_rate AS learn_rate, deck_study.user AS learn_user, deck_study.need_check AS need_check, deck_study.last_card AS last_card ". - "FROM deck_study LEFT JOIN decks ON deck_study.deck = decks.id LEFT JOIN account ON account.id = decks.owner ". - "WHERE deck_study.id = $studyid")); -assert_error($study && $study['learn_user'] == $user['id'], "You are not at the right place here."); - -if ($study['need_check']) { - /* Algorithm : - - Delete references to deleted cards - - Check that deck_study.last_card = max(card_study.card.number) - - Check that foreach (card where card.deck = deck_study.deck && card.number < deck_study.last_card), - exists corresponding card_study, if not exist, create level 0 (skipped) - */ - $n = sql("SELECT card_study.id AS id, cards.deck AS d FROM card_study ". - "LEFT JOIN cards ON cards.id = card_study.card WHERE card_study.deck_study = $studyid"); - while ($r = mysql_fetch_assoc($n)) { - if (intval($r['d']) == 0) { - sql("DELETE FROM card_study WHERE id = " . $r['id']); - } - } - $mcn = mysql_fetch_assoc(sql("SELECT MAX(cards.number) AS mcn FROM deck_study ". - "LEFT JOIN card_study ON card_study.deck_study = deck_study.id LEFT JOIN cards ON cards.id = card_study.card ". - "WHERE deck_study.id = $studyid")); - $hasmoar = false; - if ($mcn) { - $mcn = $mcn['mcn']; - if ($study['last_card'] != $mcn) sql('UPDATE deck_study SET last_card = ' . $mcn . ' WHERE id = ' . $studyid); - - $cs = array(); - for($i = 1; $i < $mcn; $i++) $cs[$i] = 0; - - $d = sql("SELECT cards.number AS n, card_study.id AS i FROM card_study LEFT JOIN cards ON cards.id = card_study.card ". - "WHERE card_study.deck_study = $studyid"); - while($r = mysql_fetch_assoc($d)) $cs[$r['n']] = $r['i']; - - for ($i = 1; $i < $mcn; $i++) { - if ($cs[$i] == 0) { - $n = mysql_fetch_assoc(sql("SELECT cards.id AS id FROM deck_study LEFT JOIN cards ON cards.deck = deck_study.deck AND cards.number = $i ". - "WHERE deck_study.id = $studyid")); - assert_error($n, "Fucking deck inconsistency."); - sql("INSERT INTO card_study(deck_study, card, level, next_review) ". - "VALUES($studyid, " . $n['id'] . ", 0, ADDDATE(CURDATE(), INTERVAL 999999 DAY))"); - $hasmoar = true; - } - } - } - sql("UPDATE deck_study SET need_check = 0 WHERE id = $studyid"); - $message = "This deck has been checked. " . ($hasmoar ? "Some cards you hadn't studied before were added to your skipped list." : ""); -} - - -$load = mysql_fetch_assoc(sql("SELECT SUM(4 - level) AS l FROM card_study WHERE deck_study = $studyid AND level < 4 AND level > 0")); -$load = intval($load['l']); - -if ($load < $study['learn_rate']) { - $next_card = mysql_fetch_assoc(sql("SELECT * FROM cards WHERE deck = " . $study['deckid'] . " AND number = " . ($study['last_card'] + 1))); -} - - - -$filters = array( - "what" => array( - "level > 0 AND next_review <= CURDATE()" => "study today", - "level > 0 AND level < 4" => "learning", - "level > 0" => "all except skipped", - "level = 0" => "skipped", - ), - "order" => array( - "level" => "level", - "number" => "card number", - ), - "way" => $ord_ways, -); -$fdefaults = array( - "what" => "level > 0 AND next_review <= CURDATE()", - "order" => "level", - "way" => "ASC", -); - -$study_cards = array(); -$s = sql( - "SELECT cards.id AS id, cards.name AS name, cards.text_html AS text, cards.number AS number, ". - "card_study.level AS level, card_study.next_review <= CURDATE() AS must_study ". - "FROM card_study LEFT JOIN cards ON card_study.card = cards.id WHERE deck_study = $studyid AND " . get_filter("what") . - " ORDER BY " . get_filter("order") . " " . get_filter('way') . (get_filter("order") == "level" ? ", number " . get_filter("way") : "")); -while ($ss = mysql_fetch_assoc($s)) $study_cards[] = $ss; - - - -require("tpl/study/deck.php"); diff --git a/lib/study/deckadd.php b/lib/study/deckadd.php deleted file mode 100644 index b95648c..0000000 --- a/lib/study/deckadd.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'deck'); -$deckid = intval($args[2]); -$deck = mysql_fetch_assoc(sql("SELECT id FROM decks WHERE id = $deckid")); -assert_error($deck, "This deck does not exist."); - -assert_error(!mysql_fetch_assoc(sql("SELECT id FROM deck_study WHERE deck = $deckid AND user = " . $user['id'])), - "You are already studying this deck."); - -sql("INSERT INTO deck_study(user, deck) VALUES(" . $user['id'] . ", $deckid)"); -header("Location: deck-study-".mysql_insert_id()); -die(); diff --git a/lib/study/deckrm.php b/lib/study/deckrm.php deleted file mode 100644 index 6b4e803..0000000 --- a/lib/study/deckrm.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -assert_redir(count($args) >= 3, 'study'); -$studyid = intval($args[2]); - -$study = mysql_fetch_assoc(sql( - "SELECT ". - " deck_study.user AS learn_user ". - "FROM deck_study ". - "WHERE deck_study.id = $studyid")); -assert_error($study && $study['learn_user'] == $user['id'], "You are not at the right place here."); - -token_validate("Do you really want to remove this deck from your studies ? ALL YOUR PROGRESS WILL BE LOST!", "deck-study-$studyid"); -sql("DELETE FROM card_study WHERE deck_study = $studyid"); -sql("DELETE FROM deck_study WHERE id = $studyid"); -header("Location: study"); -die(); diff --git a/lib/study/index.php b/lib/study/index.php deleted file mode 100644 index 6b43d53..0000000 --- a/lib/study/index.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -if ($user['id'] == 0) { - $message = "You must create an account to use this study program."; -} - -require("tpl/study/index.php"); diff --git a/lib/study/list.php b/lib/study/list.php deleted file mode 100644 index bebffa6..0000000 --- a/lib/study/list.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'study'); -$studyid = intval($args[2]); - -$study = mysql_fetch_assoc(sql( - "SELECT lists.id AS listid, lists.name AS listname, account.login AS listowner, ". - " list_study.user AS learn_user ". - "FROM list_study LEFT JOIN lists ON list_study.list = lists.id LEFT JOIN account ON account.id = lists.owner ". - "WHERE list_study.id = $studyid")); -assert_error($study && $study['learn_user'] == $user['id'], "You are not at the right place here."); - -$filters = array( - "order" => array( - "name" => "name", - "lr_score" => "last score", - "lr_date" => "last reviewed" - ), - "way" => $ord_ways, -); -$fdefaults = array( - "order" => "name", - "way" => "ASC", -); - -$batches = array(); -$n = sql( - "SELECT batches.id AS id, batches.name AS name, ". - "batch_study.id AS bs_id, ba.date AS lr_date, TO_DAYS(NOW()) - TO_DAYS(ba.date) AS lr_days, ". - "ba.score AS lr_score, bc.date AS blr_date, bc.score AS blr_score, ". - "COUNT(bb.id) AS num_reviews ". - "FROM batches ". - "LEFT JOIN batch_study ON batch_study.batch = batches.id AND batch_study.user = " . $user['id'] . " " . - "LEFT JOIN batch_review ba ON ba.id = batch_study.last_review ". - "LEFT JOIN batch_review bb ON bb.batch = batches.id AND bb.user = " . $user['id'] . " ". - "LEFT JOIN batch_review bc ON bc.id = batch_study.before_last_review ". - "WHERE batches.list = " . $study['listid'] . " " . - "GROUP BY batches.id ". - "ORDER BY " . get_filter("order") . " " . get_filter("way") - ); -while ($b = mysql_fetch_assoc($n)) $batches[] = $b; - -require("tpl/study/list.php"); diff --git a/lib/study/listadd.php b/lib/study/listadd.php deleted file mode 100644 index 536ab1d..0000000 --- a/lib/study/listadd.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - -assert_redir(count($args) == 3, 'list'); -$listid = intval($args[2]); -$list = mysql_fetch_assoc(sql("SELECT id FROM lists WHERE id = $listid")); -assert_error($list, "This list does not exist."); - -assert_error(!mysql_fetch_assoc(sql("SELECT id FROM list_study WHERE list = $listid AND user = " . $user['id'])), - "You are already studying this list."); - -sql("INSERT INTO list_study(user, list) VALUES(" . $user['id'] . ", $listid)"); -header("Location: list-study-".mysql_insert_id()); -die(); diff --git a/lib/study/listrm.php b/lib/study/listrm.php deleted file mode 100644 index a761e97..0000000 --- a/lib/study/listrm.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php - -assert_redir(count($args) >= 3, 'study'); -$studyid = intval($args[2]); - -$study = mysql_fetch_assoc(sql( - "SELECT ". - " list_study.user AS learn_user ". - "FROM list_study ". - "WHERE list_study.id = $studyid")); -assert_error($study && $study['learn_user'] == $user['id'], "You are not at the right place here."); - -token_validate("Do you really want to remove this list from your studies ? Your progress will not be lost.", "list-study-$studyid"); -sql("DELETE FROM list_study WHERE id = $studyid"); -header("Location: study"); -die(); diff --git a/lib/study/setcard.php b/lib/study/setcard.php deleted file mode 100644 index c71bbfe..0000000 --- a/lib/study/setcard.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -assert_redir(count($args) == 4, 'study'); -$cardid = intval($args[2]); - -$info = mysql_fetch_assoc(sql( - "SELECT deck_study.id AS studyid, deck_study.last_card AS last_card, deck_study.need_check AS need_check, ". - "card_study.id AS csid, cards.id AS cardid, cards.number AS cardnumber ". - "FROM cards LEFT JOIN deck_study ON deck_study.deck = cards.deck AND deck_study.user = " . $user['id'] . " ". - "LEFT JOIN card_study ON card_study.deck_study = deck_study.id AND card_study.card = $cardid ". - "WHERE cards.id = $cardid" - )); -assert_error($info, "This card does not exist."); - -$studyid = intval($info['studyid']); -assert_error($studyid > 0, "You are not studying this deck."); - -assert_error($info['need_check'] == 0, - 'This deck needs checking first. Please return <a href="deck-study-'.$studyid.'">here</a> first, it should do it.'); - -assert_error($info['cardnumber'] <= $info['last_card'] + 1, "You must first add previous cards to your study list."); - -$level = intval($args[3]); -assert_error($level >= 0 && $level <= 7, "That level is invalid."); -$intervals = array(999999, 1, 2, 4, 8, 16, 32, 999999); - -if ($info['cardnumber'] == $info['last_card'] + 1) { - sql("INSERT INTO card_study(deck_study, card, level, next_review) ". - "VALUES($studyid, $cardid, $level, ADDDATE(CURDATE(), INTERVAL " . $intervals[$level] . " DAY))"); - sql("UPDATE deck_study SET last_card = last_card + 1 WHERE id = $studyid"); -} else { - assert_error($info['csid'] > 0, "Deck is inconsistent."); - sql("UPDATE card_study SET level = $level, next_review = ADDDATE(CURDATE(), INTERVAL " . $intervals[$level] . " DAY) WHERE id = " . $info['csid']); -} - -header("Location: deck-study-$studyid"); -die(); diff --git a/lib/study/setrate.php b/lib/study/setrate.php deleted file mode 100644 index f893eb9..0000000 --- a/lib/study/setrate.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -assert_redir(count($args) >= 3, 'study'); -$studyid = intval($args[2]); - -$study = mysql_fetch_assoc(sql( - "SELECT decks.id AS deckid, decks.name AS deckname, account.login AS deckowner, ". - " deck_study.learn_rate AS learn_rate, deck_study.user AS learn_user ". - "FROM deck_study LEFT JOIN decks ON deck_study.deck = decks.id LEFT JOIN account ON account.id = decks.owner ". - "WHERE deck_study.id = $studyid")); -assert_error($study && $study['learn_user'] == $user['id'], "You are not at the right place here."); - -if (isset($args[3]) && ($rate = intval($args[3])) > 0) { - sql("UPDATE deck_study SET learn_rate = $rate WHERE id = $studyid"); - header("Location: deck-study-$studyid"); - die(); -} - -include ("tpl/study/setrate.php"); @@ -40,61 +40,6 @@ CREATE TABLE IF NOT EXISTS `account` ( -- -------------------------------------------------------- -- --- Structure de la table `batches` --- - -CREATE TABLE IF NOT EXISTS `batches` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `list` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `model` text NOT NULL, - `contents` text NOT NULL, - `json_data` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name` (`list`,`name`), - KEY `list` (`list`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `batch_review` --- - -CREATE TABLE IF NOT EXISTS `batch_review` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user` int(11) NOT NULL, - `batch` int(11) NOT NULL, - `results` text NOT NULL, - `score` int(11) NOT NULL, - `date` date NOT NULL, - PRIMARY KEY (`id`), - KEY `batch` (`batch`), - KEY `user_idx` (`user`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `batch_study` --- - -CREATE TABLE IF NOT EXISTS `batch_study` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user` int(11) NOT NULL, - `batch` int(11) NOT NULL, - `last_review` int(11) NOT NULL, - `notes_json` text NOT NULL, - `before_last_review` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `batch_user` (`user`,`batch`), - KEY `user_idx` (`user`), - KEY `batch` (`batch`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- -- Structure de la table `blog_comments` -- @@ -144,77 +89,6 @@ CREATE TABLE IF NOT EXISTS `blog_tags` ( -- -------------------------------------------------------- -- --- Structure de la table `cards` --- - -CREATE TABLE IF NOT EXISTS `cards` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `deck` int(11) NOT NULL, - `number` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `text_md` text NOT NULL, - `text_html` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name` (`deck`,`name`), - UNIQUE KEY `unique_number` (`deck`,`number`), - KEY `deck_idx` (`deck`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `card_study` --- - -CREATE TABLE IF NOT EXISTS `card_study` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `deck_study` int(11) NOT NULL, - `card` int(11) NOT NULL, - `level` int(11) NOT NULL, - `next_review` date NOT NULL, - PRIMARY KEY (`id`), - KEY `deck_study` (`deck_study`,`card`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `decks` --- - -CREATE TABLE IF NOT EXISTS `decks` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `owner` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `comment_md` text NOT NULL, - `comment_html` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name` (`owner`,`name`), - KEY `owner_idx` (`owner`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `deck_study` --- - -CREATE TABLE IF NOT EXISTS `deck_study` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user` int(11) NOT NULL, - `deck` int(11) NOT NULL, - `last_card` int(11) NOT NULL DEFAULT '0', - `learn_rate` int(11) NOT NULL DEFAULT '10', - `need_check` tinyint(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `unique_user_deck` (`user`,`deck`), - KEY `user_idx` (`user`), - KEY `deck_idx` (`deck`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- -- Structure de la table `files` -- @@ -252,39 +126,6 @@ CREATE TABLE IF NOT EXISTS `folders` ( -- -------------------------------------------------------- -- --- Structure de la table `lists` --- - -CREATE TABLE IF NOT EXISTS `lists` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `owner` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `comment_md` text NOT NULL, - `comment_html` text NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_name` (`owner`,`name`), - KEY `owner` (`owner`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- --- Structure de la table `list_study` --- - -CREATE TABLE IF NOT EXISTS `list_study` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `user` int(11) NOT NULL, - `list` int(11) NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `unique_user_list` (`user`,`list`), - KEY `user` (`user`), - KEY `list_idx` (`list`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- -- Structure de la table `notes` -- diff --git a/tpl/deck/ef.php b/tpl/deck/ef.php deleted file mode 100644 index 40d0ecc..0000000 --- a/tpl/deck/ef.php +++ /dev/null @@ -1,16 +0,0 @@ - -<?php -require("tpl/general/top.php"); - -if (isset($fields)) - require("tpl/general/inc_form.php"); - -echo '</div><div class="contents-left">'; - -echo '<h1>' . $deck['name'] . '</h1>'; -echo '<ul><li><a href="view-deck-' . $deck['id'] . '">Back to deck</a></li>'; -echo '<li><a href="edit-deck-' . $deck['id'] . '">Edit deck</a></li>'; -echo '<li><a href="addent-deck-' . $deck['id'] . '">Add card to deck</a></li>'; -echo '</ul>'; - -require("tpl/general/bottom.php"); diff --git a/tpl/deck/index.php b/tpl/deck/index.php deleted file mode 100644 index b8e9a76..0000000 --- a/tpl/deck/index.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -$title = "Study decks"; - -if ($user['id'] == 0) $message = "Hey, you should create an account so that you can study with us!"; - -require("tpl/general/top.php"); - -echo '<div class="ordering_links">' . filters_html_full() . '</div>'; - -echo "<table><tr><th>Name</th><th>Users</th>"; -foreach ($decks as $deck) { - echo '<tr><td><code>' . $deck["owner"] . ':<a href="view-deck-' . $deck['id'] . '">' . $deck["name"] . '</a></code></td>'; - echo '<td>' . $deck["nbUsers"] . '</td></tr>'; -} -echo "</table>"; - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/deck/new.php b/tpl/deck/new.php deleted file mode 100644 index 1f7e81e..0000000 --- a/tpl/deck/new.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -require("tpl/general/top.php"); - -require("tpl/general/inc_form.php"); - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/deck/view.php b/tpl/deck/view.php deleted file mode 100644 index d15de4e..0000000 --- a/tpl/deck/view.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php - -$title = $deck["owner"] . ':' . $deck["name"]; - -require("tpl/general/top.php"); - -if ($can_edit) { - echo '<div class="small_right"><a href="edit-deck-' . $deck['id'] . '">edit</a> | '; - echo '<a href="addent-deck-' . $deck['id'] . '">add card</a></div>'; -} - -echo $deck["comment"]; - -if ($can_start_study) { - echo '<p style="text-align: center; font-size: 1.2em;"><a href="deckadd-study-' . $deckid . '">>> start studying this deck <<</a></p>'; -} - -echo '<div class="ordering_links">' . filters_html_full() . '</div>'; -foreach ($cards as $card) { - echo '<div class="study_card">'; - if ($can_edit) { - echo '<div class="small_right"><a href="edent-deck-' . $card['id'] . '">edit</a> | <a href="rment-deck-' . $card['id'] . '">remove</a> | '; - echo '<a href="#" onclick="if (pos = prompt(\'What position do you want to move this card to ?\', ' . $card['number'] . ')) { window.location = \'mvent-deck-' . $card['id'] . '-\' + pos; }">move</a>'; - echo '</div>'; - } - echo '<code>#' . $card["number"] . ": " . $card["name"] . '</code>'; - echo $card['text']; - echo '</div>'; -} -if ($can_edit) - echo '<a class="tool_link" href="addent-deck-' . $deck['id'] . '">[+] add card</a>'; - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/general/top.php b/tpl/general/top.php index 2e73057..01f7e59 100644 --- a/tpl/general/top.php +++ b/tpl/general/top.php @@ -36,12 +36,10 @@ if ($user['id'] == 0) { if ($user['id'] != 0) { echo '<a href="user-notes-' . $user['id'] . '">notes</a>'; echo '<a href="file">files</a>'; - echo '<a href="study">studies</a>'; } else { if ($user['priv'] >= $apps['file']['upload']) { echo '<a href="upload-file">upload file</a>'; } - echo '<a href="study">studies</a>'; } ?> </div> diff --git a/tpl/list/ef.php b/tpl/list/ef.php deleted file mode 100644 index 1e7387a..0000000 --- a/tpl/list/ef.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -require("tpl/general/top.php"); - -if (isset($fields)) - require("tpl/general/inc_form.php"); - -echo '</div><div class="contents-left">'; - -echo '<h1>' . $list['name'] . '</h1>'; -echo '<ul><li><a href="view-list-' . $list['id'] . '">Back to list</a></li>'; -echo '<li><a href="edit-list-' . $list['id'] . '">Edit list</a></li>'; -echo '<li><a href="addbatch-list-' . $list['id'] . '">Add batch to list</a></li>'; -echo '</ul>'; - -require("tpl/general/bottom.php"); diff --git a/tpl/list/index.php b/tpl/list/index.php deleted file mode 100644 index 85a503c..0000000 --- a/tpl/list/index.php +++ /dev/null @@ -1,20 +0,0 @@ -<?php - -$title = "Study lists"; - -if ($user['id'] == 0) $message = "Hey, you should create an account so that you can study with us!"; - -require("tpl/general/top.php"); - -echo '<div class="ordering_links">' . filters_html_full() . '</div>'; - -echo "<table><tr><th>Name</th><th>Users</th>"; -foreach ($lists as $list) { - echo '<tr><td><code>' . $list["owner"] . ':<a href="view-list-' . $list['id'] . '">' . $list["name"] . '</a></code></td>'; - echo '<td>' . $list["nbUsers"] . '</td></tr>'; -} -echo "</table>"; - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/list/new.php b/tpl/list/new.php deleted file mode 100644 index 1f7e81e..0000000 --- a/tpl/list/new.php +++ /dev/null @@ -1,8 +0,0 @@ -<?php -require("tpl/general/top.php"); - -require("tpl/general/inc_form.php"); - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/list/view.php b/tpl/list/view.php deleted file mode 100644 index 8b2c292..0000000 --- a/tpl/list/view.php +++ /dev/null @@ -1,29 +0,0 @@ -<?php - -$title = $list['owner'] . ':' . $list['name']; -require("tpl/general/top.php"); - -if ($can_edit) { - echo '<div class="small_right"><a href="edit-list-' . $list['id'] . '">edit</a> | '; - echo '<a href="addbatch-list-' . $list['id'] . '">add batch</a></div>'; -} - -echo $list['comment']; - -if ($can_start_study) { - echo '<p style="text-align: center; font-size: 1.2em;"><a href="listadd-study-' . $listid . '">>> start studying this list <<</a></p>'; -} - -echo '<table><tr><th>Batch name</th>' . ($can_edit ? '<th>actions</th>' : '') . '</tr>'; -foreach ($batches as $batch) { - echo '<tr><td>' . $batch['name'] . '</td>'; - if ($can_edit) { - echo '<td><a href="edbatch-list-' . $batch['id'] . '">edit</a> | <a href="rmbatch-list-' . $batch['id'] . '">remove</a></td>'; - } - echo '</tr>'; -} -echo '</table>'; - -require("tpl/study/lib_sidebar.php"); - -require("tpl/general/bottom.php"); diff --git a/tpl/study/batch.php b/tpl/study/batch.php deleted file mode 100644 index 6eaa99c..0000000 --- a/tpl/study/batch.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -$title = $info['uname'] . ':' . $info['lname'] . ' - ' . $info['bname']; - -$javascript = "\nconst batchid = " . $info['batchid'] . "\n\n". - "const batch_data = " . $info['json_data'] . ";\n\n". - "const reviews_data = $reviews;\n\n". - "var notes = " . $info['notes'] . ";\n\n"; -$js_include = array("js/prototype.js", "js/liststudy.js"); -$onload_js = 'show_batch_table();'; - -require("tpl/general/top.php"); - -echo '<div class="small_right"><a href="batchreview-study-' . $info['batchid'] . '">test now</a> | <a href="list-study-' . $info['studyid'] . '#batch_' . $info['batchid'] . '">back</a></div>'; - -echo '<h2>Items in this list</h2>'; -echo '<div id="items">Please wait, processing...</div>'; -echo '<h2>Reviews</h2>'; -echo '<div id="reviews">Please wait, processing...</div>'; - -require("tpl/study/lib_sidebar.php"); -require("tpl/general/bottom.php"); - diff --git a/tpl/study/batch_review.php b/tpl/study/batch_review.php deleted file mode 100644 index abe1944..0000000 --- a/tpl/study/batch_review.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - -$title = "Testing " . $info['uname'] . ':' . $info['lname'] . ' - ' . $info['bname']; - -$javascript = "\n\nconst batchid = " . $info['batchid'] . "\n". - "const batch_data = " . $info['json_data'] . ";\n\n". - "var notes = " . $info['notes'] . ";\n\n"; -$js_include = array("js/prototype.js", "js/reviewdesu.js"); -$onload_js = 'start_review();'; - -require("tpl/general/top.php"); - -echo '<div id="core">Please wait, processing...</div>'; - -require("tpl/general/bottom.php"); diff --git a/tpl/study/deck.php b/tpl/study/deck.php deleted file mode 100644 index 42ef784..0000000 --- a/tpl/study/deck.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php - -$title = "Studying " . $study['deckowner'] . ':' . $study['deckname']; -require("tpl/general/top.php"); - -echo '<div class="small_right"><a href="deckrm-study-' . $studyid . '">stop studying</a> | <a href="view-deck-' . $study['deckid'] . '">view whole deck</a></div>'; - -echo '<div style="margin-top: 20px;text-align: center; font-size: 1.2em;">'; -echo 'Load : ' . $load . '/' . $study['learn_rate'] . ' - <a href="setrate-study-' . $studyid . '">change study rate</a></div>'; - -if (isset($next_card)) { - if ($next_card) { - echo '<div class="study_card">'; - echo '<div class="small_right"><a href="setcard-study-'.$next_card['id'].'-0">skip this card (0)</a><br />'; - echo '<a href="setcard-study-'.$next_card['id'].'-1">learn this card (1)</a><br />'; - echo '<a href="setcard-study-'.$next_card['id'].'-4">I know this already (4)</a><br />'; - echo '<a href="setcard-study-'.$next_card['id'].'-7">I totally know this already (7)</a></div>'; - echo '<code style="font-weight: bold">(next card) #'.$next_card['number'].': '.$next_card['name'].'</code>'; - echo $next_card['text_html']; - echo '<div style="clear: both"></div></div>'; - } else { - echo '<p>No more cards to study !</p>'; - } -} - -echo '<div class="ordering_links">' . filters_html_full() . '</div>'; - -if (count($study_cards) == 0) { - echo '<br /><div class="message">No cards in this view. Switch to another view to see more stuff.</div>'; -} else { - foreach($study_cards as $card) { - echo '<div class="study_card scb'.$card['level'].'">'; - - $l = array(); - if ($card['level'] > 0) { - $l[] = '<a href="setcard-study-'.$card['id'].'-0">'. ($card['level'] >= 4 ? 'put in skip list' : 'skip this card') . '</a>'; - } - if ($card['must_study'] || $card['level'] == 0 || $card['level'] == 7) { - $l[] = '<a href="setcard-study-'.$card['id'].'-1">'. ($card['level'] == 0 ? 'learn this card' : 'I forgot all about this'). ' (1)</a>'; - if ($card['level'] > 0 and $card['level'] < 3) { - $l[] = '<a href="setcard-study-'.$card['id'].'-'.($card['level']+1).'" style="font-weight: bold">I\'m learning this ('.($card['level']+1).')</a>'; - } - if ($card['level'] < 4) { - $l[] = '<a href="setcard-study-'.$card['id'].'-4"'. - ($card['level'] == 3 ? ' style="font-weight: bold"' : '') - .'>I know this (4)</a>'; - } - if ($card['level'] > 3 and $card['level'] < 6) { - $l[] = '<a href="setcard-study-'.$card['id'].'-'.($card['level']+1).'" style="font-weight: bold">I know this ('.($card['level']+1).')</a>'; - } - } - if ($card['level'] < 7) { - $l[] = '<a href="setcard-study-'.$card['id'].'-7"' . - ($card['level'] == 6 && $card['must_study'] ? ' style="font-weight: bold"' : '') - .'>I totally know this (7)</a>'; - } - echo '<div class="small_right">'; - echo implode("<br />\n", $l); - echo '</div>'; - - echo '<code' . ($card['must_study'] ? ' style="font-weight: bold"' : '') . '>(' . ($card['level'] == 0 ? 'skipped' : 'level '.$card['level']) .') #'.$card['number'].': '.$card['name'].'</code>'; - echo $card['text']; - echo '<div style="clear: both"></div></div>'; - } -} - -require ("lib_sidebar.php"); -require("tpl/general/bottom.php"); diff --git a/tpl/study/index.php b/tpl/study/index.php deleted file mode 100644 index 83899e7..0000000 --- a/tpl/study/index.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -$title = "Studies"; -require("tpl/general/top.php"); - -?> - -<p>Welcome to the <em>studies</em> section. This is a simple study program, with two methods of studying available.</p> - -<h3>First method : cards</h3> -<p>The first method is based on -decks of cards, keeping track of your progress and everything.</p> - -<p>The cards you are studying are classified in the following <em>boxes</em> :</p> -<ul> -<li><strong>Skipped cards :</strong> cards you can't really say you know, but you don't want to study right now.</li> -<li><strong>Levels 1 to 3 :</strong> you are reviewing these cards frequently, in order to <em>learn</em> them.</li> -<li><strong>Level 4 to 6 :</strong> we consider you <em>know</em> that card, and you are just reviewing it from times to times, - making sure you didn't forget it.</li> -<li><strong>Level 7 :</strong> you totally know that card and will never be asked about it again.</li> -</ul> -<p>You can freely move cards into different boxes using the links that appear at the right of the card, the number in the parenthesis being - the level that card will have if you click it. -Cards you are supposed to study or review today appear with a bold title : that means that <em>today</em>, - you should decide to put it either in the next box, or somewhere else.</p> -<p>The <em>load</em> is calculated as a function of the number of cards with levels from 1 to 3 : it represents the quantity of - stuff you are <em>learning</em> right now. When the load is smaller than the study rate you ask for, new cards will be suggested for - you to learn (if any are available in the deck).</p> - -<p>Please take a look at the <a href="deck">list of decks</a> and start learning whatever you want to learn. -You can also create your own decks, the editor is pretty intuitive.</p> - -<h3>Second method : study lists</h3> -<p>In this method, we have lists of stuff to learn (like vocabulary), divided into batches (the batches are sorted -for a given list). You will study one batch at a time, and take a test for one batch at a time. All your test results - are kept in storage and are used to display your progress.</p> - -<p>Please take a look at the <a href="list">list of lists</a> and start learning whatever you want to learn.</p> - -<?php - -require ("lib_sidebar.php"); -require("tpl/general/bottom.php"); diff --git a/tpl/study/lib_sidebar.php b/tpl/study/lib_sidebar.php deleted file mode 100644 index c82d0a4..0000000 --- a/tpl/study/lib_sidebar.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php - -if ($user['id'] != 0) { - $studying_decks = array(); - $d = sql("SELECT deck_study.id AS id, decks.name AS name, account.login AS username FROM deck_study ". - "LEFT JOIN decks ON decks.id = deck_study.deck LEFT JOIN account ON account.id = decks.owner ". - "WHERE deck_study.user = ".$user['id']); - while($dd = mysql_fetch_assoc($d)) $studying_decks[] = $dd; - - $my_decks = array(); - $d = sql("SELECT id, name FROM decks WHERE owner = " . $user['id']); - while ($dd = mysql_fetch_assoc($d)) $my_decks[] = $dd; - - $studying_lists = array(); - $d = sql("SELECT list_study.id AS id, lists.name AS name, account.login AS username FROM list_study ". - "LEFT JOIN lists ON lists.id = list_study.list LEFT JOIN account ON account.id = lists.owner ". - "WHERE list_study.user = " . $user['id']); - while($dd = mysql_fetch_assoc($d)) $studying_lists[] = $dd; - - $my_lists = array(); - $d = sql("SELECT id, name FROM lists WHERE owner = " . $user['id']); - while ($dd = mysql_fetch_assoc($d)) $my_lists[] = $dd; - - echo '</div><div class="contents-left">'; - echo '<h1>Studying decks</h1><ul>'; - foreach($studying_decks as $deck) { - echo '<li><code>'.$deck['username'].':<a href="deck-study-' . $deck['id'] . '">' . $deck['name'] . '</a></code></li>'; - } - echo '<li><a class="tool_link" href="deck">[+] Show all decks</a></li></ul>'; - - echo '<h1>My decks</h1><ul>'; - foreach($my_decks as $deck) { - echo '<li><code><a href="view-deck-' . $deck['id'] . '">' . $deck['name'] . '</a></code></li>'; - } - echo '<li><a class="tool_link" href="new-deck">[+] Create deck</a></li></ul>'; - - - echo '<h1>Studying lists</h1><ul>'; - foreach($studying_lists as $list) { - echo '<li><code>'.$list['username'].':<a href="list-study-' . $list['id'] . '">' . $list['name'] . '</a></code></li>'; - } - echo '<li><a class="tool_link" href="list">[+] Show all lists</a></li></ul>'; - - echo '<h1>My lists</h1><ul>'; - foreach($my_lists as $list) { - echo '<li><code><a href="view-list-' . $list['id'] . '">' . $list['name'] . '</a></code></li>'; - } - echo '<li><a class="tool_link" href="new-list">[+] Create list</a></li></ul>'; - -} diff --git a/tpl/study/list.php b/tpl/study/list.php deleted file mode 100644 index 265d8a7..0000000 --- a/tpl/study/list.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php - -$title = "Studying " . $study['listowner'] . ':' . $study['listname']; -require("tpl/general/top.php"); - - -echo '<div class="small_right"><a href="listrm-study-' . $studyid . '">stop studying</a></div>'; - -echo '<div class="ordering_links">' . filters_html_full() . '</div>'; - -echo '<table><tr><th>Batch name</th><th>actions</th><th>tests</th><th>last test</th><th>score</th></tr>'; -foreach ($batches as $batch) { - $color = ""; - if ($batch['lr_date']) { - if ($batch['lr_score'] == 100) - $color = "#00AA00"; - else if ($batch['lr_score'] >= 90) - $color = "#22EE22"; - else if ($batch['lr_score'] >= 80) - $color = "#55FF55"; - else if ($batch['lr_score'] >= 60) - $color = "#EEEE00"; - else if ($batch['lr_score'] >= 40) - $color = "#FFAA22"; - else - $color = "#FF7777"; - - } - if ($color != "") $color = ' style="background-color: ' . $color . '"'; - - $days_color = ($batch['lr_days'] >= 30 ? "#BFBFBF" : - ($batch['lr_days'] >= 20 ? "#C7C7C7" : - ($batch['lr_days'] >= 14 ? "#CFCFCF" : - ($batch['lr_days'] >= 10 ? "#D7D7D7" : - ($batch['lr_days'] >= 7 ? "#DFDFDF" : - ($batch['lr_days'] >= 5 ? "#E7E7E7" : - ($batch['lr_days'] >= 3 ? "#EFEFEF" : - ($batch['lr_days'] >= 1 ? "#F7F7F7" : "#FFFFFF")))))))); - $dc = ($batch['lr_date'] ? ' style="background-color: ' . $days_color .'"' : ''); - - echo '<tr>'; - echo '<td><a id="batch_' . $batch['id'] . '"></a><code>' . $batch['name'] . '</code></td>'; - echo '<td><a href="batch-study-' . $batch['id'] . '">view</a> | <a href="batchreview-study-' . $batch['id'] . '">test</a></td>'; - echo '<td>' . $batch['num_reviews'] . '</td>'; - echo '<td'.$dc.'>' . ($batch['lr_date'] ? $batch['lr_date'] : "never") . '</td>'; - echo '<td'.$color.'>' . ($batch['lr_date'] ? $batch['lr_score'] . '/100' : 'N/A') . - ($batch['blr_date'] ? ($batch['lr_score'] > $batch['blr_score'] ? '<span style="color: green"> ➚</span>' : - ($batch['lr_score'] < $batch['blr_score'] ? '<span style="color: orange;"> ➘</span>' : - '<span style="color: grey"> ➙</span>')) : '') . '</td>'; - echo '</tr>'; -} -echo '</table>'; - -require("lib_sidebar.php"); -require("tpl/general/bottom.php"); diff --git a/tpl/study/setrate.php b/tpl/study/setrate.php deleted file mode 100644 index f632b33..0000000 --- a/tpl/study/setrate.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -$title = "Change learn rate for " . $study['deckowner'] . ':' . $study['deckname']; -require("tpl/general/top.php"); - -echo '<p><strong>Current learn rate :</strong> ' . $study['learn_rate'] . ' - <a href="deck-study-' . $studyid . '">keep this rate</a></p>'; - -echo '<p>Please choose how much you intend on studying :</p><ul>'; -echo '<li><a href="setrate-study-' . $studyid . '-5">Just a tiny bit (5)</a></li>'; -echo '<li><a href="setrate-study-' . $studyid . '-10">A little (10)</a></li>'; -echo '<li><a href="setrate-study-' . $studyid . '-15">Some (15)</a></li>'; -echo '<li><a href="setrate-study-' . $studyid . '-20">A lot (20)</a></li>'; -echo '<li><a href="setrate-study-' . $studyid . '-30">A real lot (30)</a></li>'; -echo '<li><a href="#" onclick="if (rate = prompt(\'Desired learn rate :\', 10)) { window.location = \'setrate-study-' . $studyid . '-\' + rate; }">Custom</a></li>'; -echo '</ul>'; - -require ("lib_sidebar.php"); -require("tpl/general/bottom.php"); |