From a79a081a4aee725ca98a4f129be768bafad22312 Mon Sep 17 00:00:00 2001 From: David Laing Date: Sat, 6 Nov 2010 14:56:50 +0000 Subject: [PATCH] import from https://github.com/mrdavidlaing/functional-koans --- KoansRunner.html | 35 + LICENSE | 22 + jasmine/runner_specs/TestJSKoansRunner.html | 24 + .../runner_specs/suites/KoansRunnerSpec.js | 342 +++ koans/AboutApplyingWhatWeHaveLearnt.js | 127 + koans/AboutArrays.js | 97 + koans/AboutExpects.js | 38 + koans/AboutFunctions.js | 115 + koans/AboutHigherOrderFunctions.js | 68 + koans/AboutLambda.js | 22 + koans/AboutMutability.js | 68 + koans/AboutObjects.js | 108 + lib/__.js | 1 + lib/dojo-release-1.5.0/dojo/dojo.js | 14 + .../dojox/lang/functional/array.js | 161 ++ .../dojox/lang/functional/binrec.js | 62 + .../dojox/lang/functional/curry.js | 64 + .../dojox/lang/functional/fold.js | 104 + .../dojox/lang/functional/lambda.js | 89 + .../dojox/lang/functional/linrec.js | 62 + .../dojox/lang/functional/listcomp.js | 33 + .../dojox/lang/functional/multirec.js | 62 + .../dojox/lang/functional/numrec.js | 33 + .../dojox/lang/functional/object.js | 64 + .../dojox/lang/functional/reversed.js | 72 + .../dojox/lang/functional/scan.js | 98 + .../dojox/lang/functional/sequence.js | 32 + .../dojox/lang/functional/tailrec.js | 52 + .../dojox/lang/functional/util.js | 33 + .../dojox/lang/functional/zip.js | 28 + lib/jasmine/jasmine-html.js | 182 ++ lib/jasmine/jasmine.css | 166 ++ lib/jasmine/jasmine.js | 2421 +++++++++++++++++ lib/jasmine/jskoans-jasmine-html.js | 245 ++ lib/jasmine/jskoans-jasmine.css | 210 ++ lib/jsTestDriver/JsTestDriver.jar | Bin 0 -> 3169665 bytes lib/jsTestDriver/capture_browser.sh | 1 + lib/jsTestDriver/jsTestDriver.conf | 16 + lib/jsTestDriver/run_all_koans.sh | 1 + 39 files changed, 5372 insertions(+) create mode 100644 KoansRunner.html create mode 100644 LICENSE create mode 100644 jasmine/runner_specs/TestJSKoansRunner.html create mode 100644 jasmine/runner_specs/suites/KoansRunnerSpec.js create mode 100644 koans/AboutApplyingWhatWeHaveLearnt.js create mode 100644 koans/AboutArrays.js create mode 100644 koans/AboutExpects.js create mode 100644 koans/AboutFunctions.js create mode 100644 koans/AboutHigherOrderFunctions.js create mode 100644 koans/AboutLambda.js create mode 100644 koans/AboutMutability.js create mode 100644 koans/AboutObjects.js create mode 100644 lib/__.js create mode 100644 lib/dojo-release-1.5.0/dojo/dojo.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/array.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/binrec.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/curry.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/fold.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/lambda.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/linrec.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/listcomp.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/multirec.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/numrec.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/object.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/reversed.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/scan.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/sequence.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/tailrec.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/util.js create mode 100644 lib/dojo-release-1.5.0/dojox/lang/functional/zip.js create mode 100644 lib/jasmine/jasmine-html.js create mode 100644 lib/jasmine/jasmine.css create mode 100644 lib/jasmine/jasmine.js create mode 100644 lib/jasmine/jskoans-jasmine-html.js create mode 100644 lib/jasmine/jskoans-jasmine.css create mode 100644 lib/jsTestDriver/JsTestDriver.jar create mode 100755 lib/jsTestDriver/capture_browser.sh create mode 100644 lib/jsTestDriver/jsTestDriver.conf create mode 100755 lib/jsTestDriver/run_all_koans.sh diff --git a/KoansRunner.html b/KoansRunner.html new file mode 100644 index 000000000..3ffffcad0 --- /dev/null +++ b/KoansRunner.html @@ -0,0 +1,35 @@ + + + + Javascript Koans + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..38e1b6dde --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2010 David Laing + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/jasmine/runner_specs/TestJSKoansRunner.html b/jasmine/runner_specs/TestJSKoansRunner.html new file mode 100644 index 000000000..06885ad61 --- /dev/null +++ b/jasmine/runner_specs/TestJSKoansRunner.html @@ -0,0 +1,24 @@ + + + + Jasmine Test Runner + + + + + + + + + + + + + + + + diff --git a/jasmine/runner_specs/suites/KoansRunnerSpec.js b/jasmine/runner_specs/suites/KoansRunnerSpec.js new file mode 100644 index 000000000..9a838c3ca --- /dev/null +++ b/jasmine/runner_specs/suites/KoansRunnerSpec.js @@ -0,0 +1,342 @@ +describe("KoansRunner", function() { + var env; + var reporter; + var body; + var fakeDocument; + + beforeEach(function() { + env = new jasmine.Env(); + env.updateInterval = 0; + + body = document.createElement("body"); + fakeDocument = { body: body, location: { search: "" } }; + reporter = new JsKoansReporter(fakeDocument); + }); + + function fakeSpec(name) { + return { + getFullName: function() { + return name; + } + }; + } + + function fakeSuite(desc) { + return { + parentSuite: null, + description: desc + }; + } + + function findElements(divs, withClass) { + var els = []; + for (var i = 0; i < divs.length; i++) { + if (divs[i].className == withClass) els.push(divs[i]); + } + return els; + } + + function findElement(divs, withClass) { + var els = findElements(divs, withClass); + if (els.length > 0) return els[0]; + throw new Error("couldn't find div with class " + withClass); + } + + it("should run only specs beginning with spec parameter", function() { + fakeDocument.location.search = "?spec=run%20this"; + expect(reporter.specFilter(fakeSpec("run this"))).toBeTruthy(); + expect(reporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy(); + expect(reporter.specFilter(fakeSpec("not run this"))).toBeFalsy(); + }); + + it("should display empty divs for every suite when the runner is starting", function() { + reporter.reportRunnerStarting({ + env: env, + suites: function() { + return [ new jasmine.Suite({}, "suite 1", null, null) ]; + } + }); + + var divs = findElements(body.getElementsByTagName("div"), "suite"); + expect(divs.length).toEqual(1); + expect(divs[0].innerHTML).toContain("suite 1"); + }); + + describe('Matcher reporting', function () { + var getErrorMessageDiv = function (body) { + var divs = body.getElementsByTagName("div"); + for (var i = 0; i < divs.length; i++) { + if (divs[i].className.match(/errorMessage/)) { + return divs[i]; + } + } + }; + + var runner, spec, fakeTimer; + beforeEach(function () { + fakeTimer = new jasmine.FakeTimer(); + env.setTimeout = fakeTimer.setTimeout; + env.clearTimeout = fakeTimer.clearTimeout; + env.setInterval = fakeTimer.setInterval; + env.clearInterval = fakeTimer.clearInterval; + runner = env.currentRunner(); + var suite = new jasmine.Suite(env, 'some suite'); + runner.add(suite); + spec = new jasmine.Spec(env, suite, 'some spec'); + suite.add(spec); + fakeDocument.location.search = "?"; + env.addReporter(reporter); + }); + + describe('toContain', function () { + it('should show actual and expected', function () { + spec.runs(function () { + this.expect('foo').toContain('bar'); + }); + runner.execute(); + fakeTimer.tick(0); + + var resultEl = getErrorMessageDiv(body); + expect(resultEl.innerHTML).toMatch(/foo/); + expect(resultEl.innerHTML).toMatch(/bar/); + }); + }); + }); + + + describe("failure messages (integration)", function () { + var spec, results, expectationResult; + + beforeEach(function() { + results = { + passed: function() { + return false; + }, + getItems: function() { + }}; + + var suite1 = new jasmine.Suite(env, "suite 1", null, null); + + spec = { + suite: suite1, + getFullName: function() { + return "foo"; + }, + results: function() { + return results; + } + }; + + reporter.reportRunnerStarting({ + env: env, + suites: function() { + return [ suite1 ]; + } + }); + }); + + it("should add the failure message to the DOM (non-toEquals matchers)", function() { + expectationResult = new jasmine.ExpectationResult({ + matcherName: "toBeNull", passed: false, message: "Expected 'a' to be null, but it was not" + }); + + spyOn(results, 'getItems').andReturn([expectationResult]); + + reporter.reportSpecResults(spec); + + var divs = body.getElementsByTagName("div"); + var errorDiv = findElement(divs, 'errorMessage'); + expect(errorDiv.innerHTML).toEqual("Expected 'a' to be null, but it was not"); + }); + + it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() { + expectationResult = new jasmine.ExpectationResult({ + matcherName: "toBeNull", passed: false, message: "Expected '1 < 2' to e null, & it was not" + }); + + spyOn(results, 'getItems').andReturn([expectationResult]); + + reporter.reportSpecResults(spec); + + var divs = body.getElementsByTagName("div"); + var errorDiv = findElement(divs, 'errorMessage'); + expect(errorDiv.innerHTML).toEqual("Expected '1 < 2' to <b>e null, & it was not"); + }); + }); + + describe("duplicate example names", function() { + it("should report failures correctly", function() { + var suite1 = env.describe("suite", function() { + env.it("will have log messages", function() { + this.log("this one passes!"); + this.expect(true).toBeTruthy(); + }); + }); + + var suite2 = env.describe("suite", function() { + env.it("will have log messages", function() { + this.log("this one fails!"); + this.expect(true).toBeFalsy(); + }); + }); + + env.addReporter(reporter); + env.execute(); + + var divs = body.getElementsByTagName("div"); + var failedSpecDiv = findElement(divs, 'suite failed'); + expect(failedSpecDiv.className).toEqual('suite failed'); + expect(failedSpecDiv.innerHTML).toContain("damaging your karma"); + expect(failedSpecDiv.innerHTML).not.toContain("has expanded your awareness"); + + var passedSpecDiv = findElement(divs, 'suite passed'); + expect(passedSpecDiv.className).toEqual('suite passed'); + expect(passedSpecDiv.innerHTML).toContain("has expanded your awareness"); + expect(passedSpecDiv.innerHTML).not.toContain("damaging your karma"); + }); + }); + + describe('#reportSpecStarting', function() { + var spec1; + beforeEach(function () { + env.describe("suite 1", function() { + spec1 = env.it("spec 1", function() { + }); + }); + }); + + it('should not log running specs by default', function() { + spyOn(reporter, 'log'); + + reporter.reportSpecStarting(spec1); + + expect(reporter.log).not.toHaveBeenCalled(); + }); + }); + + describe('showing progress', function() { + beforeEach(function() { + env.describe("suite 1", function() { + env.it("spec A"); + env.it("spec B"); + }); + env.describe("suite 2", function() { + env.it("spec C"); + }); + }); + + describe('subjects', function() { + describe("with no failures", function() { + beforeEach(function() { + env.addReporter(reporter); + env.execute(); + }); + + it("should have 2 subjects", function() { + expect(reporter.noOfSubjects).toBe(2); + }); + + it("should not have any failed subjects", function() { + expect(reporter.failedSubjects).toBe(0); + }); + }); + + describe("with 1 failure", function() { + beforeEach(function() { + env.describe("suite with error", function() { + env.it("spec X", function() { + expect(true).toBeFalsey(); + }); + env.it("spec Y", function() { + expect(true).toBeFalsey(); + }); + }); + + env.addReporter(reporter); + env.execute(); + }); + + it("should have 3 subjects", function() { + expect(reporter.noOfSubjects).toBe(3); + }); + + it("should have a failure", function() { + expect(reporter.failedSubjects).toBe(1); + }); + }); + + describe("with 2 failures", function() { + beforeEach(function() { + env.describe("suite with error", function() { + env.it("spec X", function() { + expect(true).toBeFalsey(); + }); + }); + env.describe("suite with error too", function() { + env.it("spec Y", function() { + expect(true).toBeFalsey(); + }); + }); + + env.addReporter(reporter); + env.execute(); + }); + + it("should have 4 subjects", function() { + expect(reporter.noOfSubjects).toBe(4); + }); + + it("should have 2 failures", function() { + expect(reporter.failedSubjects).toBe(2); + }); + }); + + describe("with embedded suites only outer suites count as subjects", function() { + beforeEach(function() { + env.describe("outer suite", function() { + env.it("spec for outer suite", function() { + expect(true).toBeFalsey(); + }); + + env.describe("inner suite", function() { + env.it("spec for inner suite", function() { + expect(true).toBeFalsey(); + }); + }); + }); + + env.addReporter(reporter); + env.execute(); + }); + + it("should have 3 suites", function() { + expect(reporter.noOfSubjects).toBe(3); + }); + + it("should have 1 failure", function() { + expect(reporter.failedSubjects).toBe(1); + }); + + }); + }); + }); + + describe("presentation", function() { + describe("showing the suite description", function() { + it("should prefix outer suite descriptions with 'Thinking'", function() { + suite = fakeSuite("About Pies"); + description = reporter.getSuiteDescription(suite); + + expect(description).toEqual("Thinking About Pies"); + }); + + it("should prefix inner suite descriptions with 'Thinking'", function() { + suite = fakeSuite("cherries"); + suite.parentSuite = "Something"; + description = reporter.getSuiteDescription(suite); + + expect(description).toEqual("Considering cherries"); + }); + }); + }); +}); diff --git a/koans/AboutApplyingWhatWeHaveLearnt.js b/koans/AboutApplyingWhatWeHaveLearnt.js new file mode 100644 index 000000000..85cc2402c --- /dev/null +++ b/koans/AboutApplyingWhatWeHaveLearnt.js @@ -0,0 +1,127 @@ +var dojox; //globals +var df = dojox.lang.functional; + +describe("About Applying What We Have Learnt", function() { + + var operations; + + beforeEach(function () { + operations = [ + { direction: "RT", distance: 200}, + { direction: "FWD", distance: 50}, + { direction: "RT", distance: 100}, + { direction: "RT", distance: 20}, + { direction: "FWD", distance: 200}, + { direction: "RT", distance: 10} + ] + }); + + /*********************************************************************************/ + + it("should find a needle in a haystack (imperative)", function () { + + var findNeedle = function (ops) { + var hasInvalidOperation = false; + for (var i = 0; i < ops.length; i+=1) { + if (ops[i].direction === "FWD" && ops[i].distance > 100) { + hasInvalidOperation = true; + break; + } + } + + return hasInvalidOperation; + }; + + expect(__).toBe(findNeedle(operations)); + }); + + it("should find needle in a haystack (functional)", function () { + expect(__).toBe(df.some(operations, "x.direction === 'FWD' && x.distance > 100")); + }); + + /*********************************************************************************/ + + it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () { + + var sum = 0; + for(var i=1; i<=1000; i+=1) { + if (i % 3 === 0 || i % 5 === 0) { + sum += i; + } + } + + expect(__).toBe(sum); + }); + + it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () { + var sumIfMultipleOf3Or5 = function (sum, next) { + if (next % 3 === 0 || next % 5 === 0) { + return sum + next; + } + return sum; + }; + var numbers = df.repeat(1000, "+1", 1); + + expect(__).toBe(df.reduce(numbers, sumIfMultipleOf3Or5, 0)); + }); + + /*********************************************************************************/ + + it("should find the sum of all the even valued terms in the fibonacci sequence which do not exceed four million (imperative)", function () { + var sum = 0; + var fib = [0,1,1]; + var i = 3; + var currentFib = 0; + + do { + currentFib = fib[i] = fib[i-1] + fib[i-2]; + if (currentFib % 2 === 0) { + sum += currentFib; + } + i+=1; + } while (currentFib < 4000000); + + expect(__).toBe(sum); + }); + + it("should find the sum of all the even valued terms in the fibonacci sequence which do not exceed four million (functional)", function () { + var calcNextFibTuple = function(item, index, array) { + return [item[1], item[0]+item[1]]; + }; + var addEven = function(result, item) { + if (item[0] % 2 === 0) { + return result + item[0]; + } + return result; + }; + var fib = df.until("item[0] > 4000000", calcNextFibTuple, [0,1]); + var sum = df.reduce(fib, addEven, 0); + + expect(__).toBe(sum); + }); + + /*********************************************************************************/ + /* UNCOMMENT FOR EXTRA CREDIT */ + /* + it("should find the largest prime factor of a composite number", function () { + + }); + + it("should find the largest palindrome made from the product of two 3 digit numbers", function () { + + }); + + it("should what is the smallest number divisible by each of the numbers 1 to 20", function () { + + + }); + + it("should what is the difference between the sum of the squares and the square of the sums", function () { + + }); + + it("should find the 10001st prime", function () { + + }); + */ +}); diff --git a/koans/AboutArrays.js b/koans/AboutArrays.js new file mode 100644 index 000000000..e68413e6b --- /dev/null +++ b/koans/AboutArrays.js @@ -0,0 +1,97 @@ +describe("About Arrays", function() { + + //We shall contemplate truth by testing reality, via spec expectations. + it("should create arrays", function() { + var emptyArray = []; + expect(__).toBe(typeof(emptyArray)); //A mistake? - http:javascript.crockford.com/remedial.html + expect(__).toBe(emptyArray.length); + + var multiTypeArray = [0, 1, "two", function () { return 3; }, {value1: 4, value2: 5}, [6, 7]]; + expect(__).toBe(multiTypeArray[0]); + expect(__).toBe(multiTypeArray[2]); + expect(__).toBe(multiTypeArray[3]()); + expect(__).toBe(multiTypeArray[4].value1); + expect(__).toBe(multiTypeArray[4]["value2"]); + expect(__).toBe(multiTypeArray[5][0]); + }); + + it("should understand array literals", function () { + var array = []; + expect([]).toEqual(array); + + array[0] = 1; + expect([1]).toEqual(array); + + array[1] = 2; + expect([1, __]).toEqual(array); + + array.push(3); + expect(__).toEqual(array); + }); + + it("should understand array length", function () { + var fourNumberArray = [1, 2, 3, 4]; + + expect(__).toBe(fourNumberArray.length); + fourNumberArray.push(5, 6); + expect(__).toBe(fourNumberArray.length); + + var tenEmptyElementArray = new Array(10); + expect(__).toBe(tenEmptyElementArray.length); + + tenEmptyElementArray.length = 5; + expect(__).toBe(tenEmptyElementArray.length); + }); + + it("should slice arrays", function () { + var array = ["peanut", "butter", "and", "jelly"]; + + expect(__).toEqual(array.slice(0, 1)); + expect(__).toEqual(array.slice(0, 2)); + expect(__).toEqual(array.slice(2, 2)); + expect(__).toEqual(array.slice(2, 20)); + expect(__).toEqual(array.slice(3, 0)); + expect(__).toEqual(array.slice(3, 100)); + expect(__).toEqual(array.slice(5, 1)); + }); + + it("should know array references", function () { + var array = [ "zero", "one", "two", "three", "four", "five" ]; + + function passedByReference(refArray) { + refArray[1] = "changed in function"; + } + passedByReference(array); + expect(__).toBe(array[1]); + + var assignedArray = array; + assignedArray[5] = "changed in assignedArray"; + expect(__).toBe(array[5]); + + var copyOfArray = array.slice(); + copyOfArray[3] = "changed in copyOfArray"; + expect(__).toBe(array[3]); + }); + + it("should push and pop", function () { + var array = [1, 2]; + array.push(3); + + expect(__).toEqual(array); + + var poppedValue = array.pop(); + expect(__).toBe(poppedValue); + expect(__).toEqual(array); + }); + + it("should shifting arrays", function () { + var array = [1, 2]; + + array.unshift(3); + expect(__).toEqual(array); + + var shiftedValue = array.shift(); + expect(__).toEqual(shiftedValue); + expect(__).toEqual(array); + }); +}); diff --git a/koans/AboutExpects.js b/koans/AboutExpects.js new file mode 100644 index 000000000..a7b196ad6 --- /dev/null +++ b/koans/AboutExpects.js @@ -0,0 +1,38 @@ +describe("About Expects", function() { + + //We shall contemplate truth by testing reality, via spec expectations. + it("should expect true", function() { + expect(false).toBeTruthy(); //This should be true + }); + + //To understand reality, we must compare our expectations against reality. + it("should expect equality", function () { + var expectedValue = __; + var actualValue = 1 + 1; + + expect(expectedValue === actualValue).toBeTruthy(); + }); + + //Some ways of asserting equality are better than others. + it("should assert equality a better way", function () { + var expectedValue = __; + var actualValue = 1 + 1; + + // toEqual() compares using common sense equality + expect(actualValue).toEqual(expectedValue); + }); + + //Sometime you need to be really exact + it("should assert equality with ===", function () { + var expectedValue = __; + var actualValue = 1 + 1; + + // toBe() will always use === to compare + expect(actualValue).toBe(expectedValue); + }); + + //Sometimes we will ask you to fill in the values + it("should have filled in values", function () { + expect(__).toEqual(1 + 1); + }); +}); diff --git a/koans/AboutFunctions.js b/koans/AboutFunctions.js new file mode 100644 index 000000000..b5dc0dde6 --- /dev/null +++ b/koans/AboutFunctions.js @@ -0,0 +1,115 @@ +describe("About Functions", function() { + + it("should declare functions", function() { + + function add(a, b) { + return a + b; + } + + expect(__).toBe(add(1, 2)); + + }); + + it("should know internal wariables override outer variables", function () { + var message = "Outer"; + + function getMessage() { + return message; + } + + function overrideMessage() { + var message = "Inner"; + return message; + } + + expect(__).toBe(getMessage()); + expect(__).toBe(overrideMessage()); + expect(__).toBe(message); + }); + + it("should have lexical scoping", function () { + var variable = "top-level"; + function parentfunction() { + var variable = "local"; + function childfunction() { + return variable; + } + return childfunction(); + } + expect(__).toBe(parentfunction()); + }); + + it("should use lexical scoping to synthesise functions", function () { + + function makeIncreaseByFunction(increaseByAmount) + { + var increaseByFunction = function increaseBy(numberToIncrease) + { + return numberToIncrease + increaseByAmount; + }; + return increaseByFunction; + } + + var increaseBy3 = makeIncreaseByFunction(3); + var increaseBy5 = makeIncreaseByFunction(5); + + expect(__).toBe(increaseBy3(10) + increaseBy5(10)); + }); + + it("should allow extra function arguments", function () { + + function returnFirstArg(firstArg) + { + return firstArg; + } + + expect(__).toBe(returnFirstArg("first", "second", "third")); + + function returnSecondArg(firstArg, secondArg) + { + return secondArg; + } + + expect(__).toBe(returnSecondArg("only give first arg")); + + function returnAllArgs() + { + var argsArray = []; + for (var i = 0; i < arguments.length; i += 1) { + argsArray.push(arguments[i]); + } + return argsArray.join(","); + } + + expect(__).toBe(returnAllArgs("first", "second", "third")); + }); + + it("should pass functions as values", function () { + + var appendRules = function (name) { + return name + " rules!"; + }; + + var appendDoubleRules = function (name) { + return name + " totally rules!"; + }; + + var praiseSinger = { givePraise: appendRules }; + expect(__).toBe(praiseSinger.givePraise("John")); + + praiseSinger.givePraise = appendDoubleRules; + expect(__).toBe(praiseSinger.givePraise("Mary")); + + }); + + it("should use function body as a string", function () { + var add = new Function("a", "b", "return a + b;"); + expect(__).toBe(add(1, 2)); + + var multiply = function (a, b) { + //An internal comment + return a * b; + }; + expect(__).toBe(multiply.toString()); + }); +}); diff --git a/koans/AboutHigherOrderFunctions.js b/koans/AboutHigherOrderFunctions.js new file mode 100644 index 000000000..740241592 --- /dev/null +++ b/koans/AboutHigherOrderFunctions.js @@ -0,0 +1,68 @@ +var dojox; //globals +var df = dojox.lang.functional; + +describe("About Higher Order Functions", function () { + + it("should use filter to return array items that meet a criteria", function () { + var numbers = [1,2,3]; + var odd = df.filter(numbers, "x % 2 !== 0"); + + expect(__).toEqual(odd); + expect(__).toBe(odd.length); + expect(__).toBe(numbers.length); + }); + + it("should use 'map' to transform each element", function () { + var numbers = [1, 2, 3]; + var numbersPlus1 = df.map(numbers, "x + 1"); + + expect(__).toEqual(numbersPlus1); + expect(__).toEqual(numbers); + }); + + it("should use 'reduce' to update the same result on each iteration ", function () { + var numbers = [1, 2, 3]; + var reduction = df.reduce(numbers, "result + x"); + + expect(__).toBe(reduction); + expect(__).toEqual(numbers); + }); + + it("should use 'forEach' for simple iteration", function () { + var numbers = [1,2,3]; + var msg = ""; + var isEven = function (item) { + msg += (item % 2) === 0; + }; + + df.forEach(numbers, isEven); + + expect(__).toEqual(msg); + expect(__).toEqual(numbers); + }); + + it("should use 'some' to apply until true", function () { + var numbers = [1,2,3]; + var msg = ""; + var isEven = function (item) { + msg += item + ";"; + return (item % 2) === 0; + }; + + expect(numbers.some(isEven)).toBeTruthy(); + expect(__).toEqual(msg); + }); + + it("should use 'every' to applies until first false" , function () { + var numbers = [1,2,3]; + var msg = ""; + var isEven = function (item) { + msg += item + ";"; + return (item % 2) === 0; + }; + + expect(numbers.every(isEven)).toBeFalsy(); + expect(__).toBe(msg); + }); +}); + diff --git a/koans/AboutLambda.js b/koans/AboutLambda.js new file mode 100644 index 000000000..03e91d0ce --- /dev/null +++ b/koans/AboutLambda.js @@ -0,0 +1,22 @@ +var dojox; //global variables +var df = dojox.lang.functional; + +describe("About Lambdas", function () { + + it("should turn an expression string into a function that returns a value of the expression", function () { + expect(__).toBe(df.lambda("1 + 2")()); + }); + + it("should confirm that an expression string can contain parameters", function () { + expect(__).toBe(df.lambda("x + 2")(3)); + }); + + it("should separate parameters from the expression", function () { + expect(__).toBe(df.lambda("x, y -> y*2 + x*3")(2, 3)); + }); + + it("should demonstrate a string passed to higher order functions assumed to be lambdas", function () { + expect(__).toEqual(df.map([1, 2, 3], "x + 1")); + }); + +}); diff --git a/koans/AboutMutability.js b/koans/AboutMutability.js new file mode 100644 index 000000000..622d06604 --- /dev/null +++ b/koans/AboutMutability.js @@ -0,0 +1,68 @@ +describe("About Mutability", function() { + + it("should expect object properties to be public and mutable", function () { + var aPerson = {firstname: "John", lastname: "Smith" }; + aPerson.firstname = "Alan"; + + expect(__).toBe(aPerson.firstname); + }); + + it("should understand that constructed properties are public and mutable", function () { + function Person(firstname, lastname) + { + this.firstname = firstname; + this.lastname = lastname; + } + var aPerson = new Person ("John", "Smith"); + aPerson.firstname = "Alan"; + + expect(__).toBe(aPerson.firstname); + }); + + it("should expect prototype properties to be public and mutable", function () { + function Person(firstname, lastname) + { + this.firstname = firstname; + this.lastname = lastname; + } + Person.prototype.getFullName = function () { + return this.firstname + " " + this.lastname; + }; + + var aPerson = new Person ("John", "Smith"); + expect(__).toBe(aPerson.getFullName()); + + aPerson.getFullName = function () { + return this.lastname + ", " + this.firstname; + }; + + expect(__).toBe(aPerson.getFullName()); + }); + + it("should know that variables inside constructor and constructor args are private", function () { + function Person(firstname, lastname) + { + var fullName = firstname + " " + lastname; + + this.getFirstName = function () { return firstname; }; + this.getLastName = function () { return lastname; }; + this.getFullName = function () { return fullName; }; + } + var aPerson = new Person ("John", "Smith"); + + aPerson.firstname = "Penny"; + aPerson.lastname = "Andrews"; + aPerson.fullName = "Penny Andrews"; + + expect(__).toBe(aPerson.getFirstName()); + expect(__).toBe(aPerson.getLastName()); + expect(__).toBe(aPerson.getFullName()); + + aPerson.getFullName = function () { + return aPerson.lastname + ", " + aPerson.firstname; + }; + + expect(__).toBe(aPerson.getFullName()); + }); + +}); diff --git a/koans/AboutObjects.js b/koans/AboutObjects.js new file mode 100644 index 000000000..71021f856 --- /dev/null +++ b/koans/AboutObjects.js @@ -0,0 +1,108 @@ +describe("About Objects", function () { + + describe("Properties", function () { + var meglomaniac; + + beforeEach(function () { + meglomaniac = { mastermind: "Joker", henchwoman: "Harley" }; + }); + + it("should confirm objects are collections of properties", function () { + expect(__).toBe(meglomaniac.mastermind); + }); + + it("should confirm that properties are case sensitive", function () { + expect(__).toBe(meglomaniac.henchwoman); + expect(__).toBe(meglomaniac.henchWoman); + }); + }); + + + it("should know properties that are functions act like methods", function () { + var meglomaniac = { + mastermind : "Brain", + henchman: "Pinky", + battleCry: function (noOfBrains) { + return "They are " + this.henchman + " and the" + + Array(noOfBrains + 1).join(" " + this.mastermind); + } + }; + + battleCry = meglomaniac.battleCry(4); + expect(battleCry).toMatch(__); + }); + + it("should confirm that when a function is attached to an object, 'this' refers to the object", function () { + var currentYear = 2010; // Update me! + var meglomaniac = { + mastermind: "James Wood", + henchman: "Adam West", + birthYear: 1970, + calculateAge: function () { + return currentYear - this.birthYear; + } + }; + + expect(__).toBe(currentYear); + expect(__).toBe(meglomaniac.calculateAge()); + }); + + describe("'in' keyword", function () { + var meglomaniac; + beforeEach(function () { + meglomaniac = { + mastermind: "The Monarch", + henchwoman: "Dr Girlfriend", + theBomb: true + }; + }); + + it("should have the bomb", function () { + + hasBomb = "theBomb" in meglomaniac; + + expect(__).toBe(hasBomb); + }); + + it("should not have the detonator however", function () { + + hasDetonator = "theDetonator" in meglomaniac; + + expect(__).toBe(hasDetonator); + }); + }); + + it("should know that properties can be added and deleted", function () { + var meglomaniac = { mastermind : "Agent Smith", henchman: "Agent Smith" }; + + expect(__).toBe(("secretary" in meglomaniac)); + + meglomaniac.secretary = "Agent Smith"; + expect(__).toBe(("secretary" in meglomaniac)); + + delete meglomaniac.henchman; + expect(__).toBe(("henchman" in meglomaniac)); + }); + + + it("should use prototype to add to all objects", function () { + function Circle(radius) + { + this.radius = radius; + } + + var simpleCircle = new Circle(10); + var colouredCircle = new Circle(5); + colouredCircle.colour = "red"; + + expect(__).toBe(simpleCircle.colour); + expect(__).toBe(colouredCircle.colour); + + Circle.prototype.describe = function () { + return "This circle has a radius of: " + this.radius; + }; + + expect(__).toBe(simpleCircle.describe()); + expect(__).toBe(colouredCircle.describe()); + }); +}); diff --git a/lib/__.js b/lib/__.js new file mode 100644 index 000000000..2c29e6bc1 --- /dev/null +++ b/lib/__.js @@ -0,0 +1 @@ +var __ = "Fill this value in"; diff --git a/lib/dojo-release-1.5.0/dojo/dojo.js b/lib/dojo-release-1.5.0/dojo/dojo.js new file mode 100644 index 000000000..665870c62 --- /dev/null +++ b/lib/dojo-release-1.5.0/dojo/dojo.js @@ -0,0 +1,14 @@ +/* + Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +(function(){var _1=null;if((_1||(typeof djConfig!="undefined"&&djConfig.scopeMap))&&(typeof window!="undefined")){var _2="",_3="",_4="",_5={},_6={};_1=_1||djConfig.scopeMap;for(var i=0;i<_1.length;i++){var _7=_1[i];_2+="var "+_7[0]+" = {}; "+_7[1]+" = "+_7[0]+";"+_7[1]+"._scopeName = '"+_7[1]+"';";_3+=(i==0?"":",")+_7[0];_4+=(i==0?"":",")+_7[1];_5[_7[0]]=_7[1];_6[_7[1]]=_7[0];}eval(_2+"dojo._scopeArgs = ["+_4+"];");dojo._scopePrefixArgs=_3;dojo._scopePrefix="(function("+_3+"){";dojo._scopeSuffix="})("+_4+")";dojo._scopeMap=_5;dojo._scopeMapRev=_6;}(function(){if(typeof this["loadFirebugConsole"]=="function"){this["loadFirebugConsole"]();}else{this.console=this.console||{};var cn=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","profile","profileEnd","time","timeEnd","trace","warn","log"];var i=0,tn;while((tn=cn[i++])){if(!console[tn]){(function(){var _8=tn+"";console[_8]=("log" in console)?function(){var a=Array.apply({},arguments);a.unshift(_8+":");console["log"](a.join(" "));}:function(){};console[_8]._fake=true;})();}}}if(typeof dojo=="undefined"){dojo={_scopeName:"dojo",_scopePrefix:"",_scopePrefixArgs:"",_scopeSuffix:"",_scopeMap:{},_scopeMapRev:{}};}var d=dojo;if(typeof dijit=="undefined"){dijit={_scopeName:"dijit"};}if(typeof dojox=="undefined"){dojox={_scopeName:"dojox"};}if(!d._scopeArgs){d._scopeArgs=[dojo,dijit,dojox];}d.global=this;d.config={isDebug:false,debugAtAllCosts:false};if(typeof djConfig!="undefined"){for(var _9 in djConfig){d.config[_9]=djConfig[_9];}}dojo.locale=d.config.locale;var _a="$Rev: 22487 $".match(/\d+/);dojo.version={major:1,minor:5,patch:0,flag:"",revision:_a?+_a[0]:NaN,toString:function(){with(d.version){return major+"."+minor+"."+patch+flag+" ("+revision+")";}}};if(typeof OpenAjax!="undefined"){OpenAjax.hub.registerLibrary(dojo._scopeName,"http://dojotoolkit.org",d.version.toString());}var _b,_c,_d={};for(var i in {toString:1}){_b=[];break;}dojo._extraNames=_b=_b||["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];_c=_b.length;dojo._mixin=function(_e,_f){var _10,s,i;for(_10 in _f){s=_f[_10];if(!(_10 in _e)||(_e[_10]!==s&&(!(_10 in _d)||_d[_10]!==s))){_e[_10]=s;}}if(_c&&_f){for(i=0;i<_c;++i){_10=_b[i];s=_f[_10];if(!(_10 in _e)||(_e[_10]!==s&&(!(_10 in _d)||_d[_10]!==s))){_e[_10]=s;}}}return _e;};dojo.mixin=function(obj,_11){if(!obj){obj={};}for(var i=1,l=arguments.length;i0){console.warn("files still in flight!");return;}d._callLoaded();};dojo._callLoaded=function(){if(typeof setTimeout=="object"||(d.config.useXDomain&&d.isOpera)){setTimeout(d.isAIR?function(){d.loaded();}:d._scopeName+".loaded();",0);}else{d.loaded();}};dojo._getModuleSymbols=function(_27){var _28=_27.split(".");for(var i=_28.length;i>0;i--){var _29=_28.slice(0,i).join(".");if(i==1&&!d._moduleHasPrefix(_29)){_28[0]="../"+_28[0];}else{var _2a=d._getModulePrefix(_29);if(_2a!=_29){_28.splice(0,i,_2a);break;}}}return _28;};dojo._global_omit_module_check=false;dojo.loadInit=function(_2b){_2b();};dojo._loadModule=dojo.require=function(_2c,_2d){_2d=d._global_omit_module_check||_2d;var _2e=d._loadedModules[_2c];if(_2e){return _2e;}var _2f=d._getModuleSymbols(_2c).join("/")+".js";var _30=!_2d?_2c:null;var ok=d._loadPath(_2f,_30);if(!ok&&!_2d){throw new Error("Could not load '"+_2c+"'; last tried '"+_2f+"'");}if(!_2d&&!d._isXDomain){_2e=d._loadedModules[_2c];if(!_2e){throw new Error("symbol '"+_2c+"' is not defined after loading '"+_2f+"'");}}return _2e;};dojo.provide=function(_31){_31=_31+"";return (d._loadedModules[_31]=d.getObject(_31,true));};dojo.platformRequire=function(_32){var _33=_32.common||[];var _34=_33.concat(_32[d._name]||_32["default"]||[]);for(var x=0;x<_34.length;x++){var _35=_34[x];if(_35.constructor==Array){d._loadModule.apply(d,_35);}else{d._loadModule(_35);}}};dojo.requireIf=function(_36,_37){if(_36===true){var _38=[];for(var i=1;i0&&!(j==1&&_43[0]=="")&&_43[j]==".."&&_43[j-1]!=".."){if(j==(_43.length-1)){_43.splice(j,1);_43[j-1]="";}else{_43.splice(j-1,2);j-=2;}}}}_40.path=_43.join("/");}}}}uri=[];if(_40.scheme){uri.push(_40.scheme,":");}if(_40.authority){uri.push("//",_40.authority);}uri.push(_40.path);if(_40.query){uri.push("?",_40.query);}if(_40.fragment){uri.push("#",_40.fragment);}}this.uri=uri.join("");var r=this.uri.match(ore);this.scheme=r[2]||(r[1]?"":n);this.authority=r[4]||(r[3]?"":n);this.path=r[5];this.query=r[7]||(r[6]?"":n);this.fragment=r[9]||(r[8]?"":n);if(this.authority!=n){r=this.authority.match(ire);this.user=r[3]||n;this.password=r[4]||n;this.host=r[6]||r[7];this.port=r[9]||n;}};dojo._Url.prototype.toString=function(){return this.uri;};dojo.moduleUrl=function(_44,url){var loc=d._getModuleSymbols(_44).join("/");if(!loc){return null;}if(loc.lastIndexOf("/")!=loc.length-1){loc+="/";}var _45=loc.indexOf(":");if(loc.charAt(0)!="/"&&(_45==-1||_45>loc.indexOf("/"))){loc=d.baseUrl+loc;}return new d._Url(loc,url);};})();if(typeof window!="undefined"){dojo.isBrowser=true;dojo._name="browser";(function(){var d=dojo;if(document&&document.getElementsByTagName){var _46=document.getElementsByTagName("script");var _47=/dojo(\.xd)?\.js(\W|$)/i;for(var i=0;i<_46.length;i++){var src=_46[i].getAttribute("src");if(!src){continue;}var m=src.match(_47);if(m){if(!d.config.baseUrl){d.config.baseUrl=src.substring(0,m.index);}var cfg=_46[i].getAttribute("djConfig");if(cfg){var _48=eval("({ "+cfg+" })");for(var x in _48){dojo.config[x]=_48[x];}}break;}}}d.baseUrl=d.config.baseUrl;var n=navigator;var dua=n.userAgent,dav=n.appVersion,tv=parseFloat(dav);if(dua.indexOf("Opera")>=0){d.isOpera=tv;}if(dua.indexOf("AdobeAIR")>=0){d.isAIR=1;}d.isKhtml=(dav.indexOf("Konqueror")>=0)?tv:0;d.isWebKit=parseFloat(dua.split("WebKit/")[1])||undefined;d.isChrome=parseFloat(dua.split("Chrome/")[1])||undefined;d.isMac=dav.indexOf("Macintosh")>=0;var _49=Math.max(dav.indexOf("WebKit"),dav.indexOf("Safari"),0);if(_49&&!dojo.isChrome){d.isSafari=parseFloat(dav.split("Version/")[1]);if(!d.isSafari||parseFloat(dav.substr(_49+7))<=419.3){d.isSafari=2;}}if(dua.indexOf("Gecko")>=0&&!d.isKhtml&&!d.isWebKit){d.isMozilla=d.isMoz=tv;}if(d.isMoz){d.isFF=parseFloat(dua.split("Firefox/")[1]||dua.split("Minefield/")[1])||undefined;}if(document.all&&!d.isOpera){d.isIE=parseFloat(dav.split("MSIE ")[1])||undefined;var _4a=document.documentMode;if(_4a&&_4a!=5&&Math.floor(d.isIE)!=_4a){d.isIE=_4a;}}if(dojo.isIE&&window.location.protocol==="file:"){dojo.config.ieForceActiveXXhr=true;}d.isQuirks=document.compatMode=="BackCompat";d.locale=dojo.config.locale||(d.isIE?n.userLanguage:n.language).toLowerCase();d._XMLHTTP_PROGIDS=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"];d._xhrObj=function(){var _4b,_4c;if(!dojo.isIE||!dojo.config.ieForceActiveXXhr){try{_4b=new XMLHttpRequest();}catch(e){}}if(!_4b){for(var i=0;i<3;++i){var _4d=d._XMLHTTP_PROGIDS[i];try{_4b=new ActiveXObject(_4d);}catch(e){_4c=e;}if(_4b){d._XMLHTTP_PROGIDS=[_4d];break;}}}if(!_4b){throw new Error("XMLHTTP not available: "+_4c);}return _4b;};d._isDocumentOk=function(_4e){var _4f=_4e.status||0,lp=location.protocol;return (_4f>=200&&_4f<300)||_4f==304||_4f==1223||(!_4f&&(lp=="file:"||lp=="chrome:"||lp=="chrome-extension:"||lp=="app:"));};var _50=window.location+"";var _51=document.getElementsByTagName("base");var _52=(_51&&_51.length>0);d._getText=function(uri,_53){var _54=d._xhrObj();if(!_52&&dojo._Url){uri=(new dojo._Url(_50,uri)).toString();}if(d.config.cacheBust){uri+="";uri+=(uri.indexOf("?")==-1?"?":"&")+String(d.config.cacheBust).replace(/\W+/g,"");}_54.open("GET",uri,false);try{_54.send(null);if(!d._isDocumentOk(_54)){var err=Error("Unable to load "+uri+" status:"+_54.status);err.status=_54.status;err.responseText=_54.responseText;throw err;}}catch(e){if(_53){return null;}throw e;}return _54.responseText;};var _55=window;var _56=function(_57,fp){var _58=_55.attachEvent||_55.addEventListener;_57=_55.attachEvent?_57:_57.substring(2);_58(_57,function(){fp.apply(_55,arguments);},false);};d._windowUnloaders=[];d.windowUnloaded=function(){var mll=d._windowUnloaders;while(mll.length){(mll.pop())();}d=null;};var _59=0;d.addOnWindowUnload=function(obj,_5a){d._onto(d._windowUnloaders,obj,_5a);if(!_59){_59=1;_56("onunload",d.windowUnloaded);}};var _5b=0;d.addOnUnload=function(obj,_5c){d._onto(d._unloaders,obj,_5c);if(!_5b){_5b=1;_56("onbeforeunload",dojo.unloaded);}};})();dojo._initFired=false;dojo._loadInit=function(e){if(dojo._scrollIntervalId){clearInterval(dojo._scrollIntervalId);dojo._scrollIntervalId=0;}if(!dojo._initFired){dojo._initFired=true;if(!dojo.config.afterOnLoad&&window.detachEvent){window.detachEvent("onload",dojo._loadInit);}if(dojo._inFlightCount==0){dojo._modulesLoaded();}}};if(!dojo.config.afterOnLoad){if(document.addEventListener){document.addEventListener("DOMContentLoaded",dojo._loadInit,false);window.addEventListener("load",dojo._loadInit,false);}else{if(window.attachEvent){window.attachEvent("onload",dojo._loadInit);if(!dojo.config.skipIeDomLoaded&&self===self.top){dojo._scrollIntervalId=setInterval(function(){try{if(document.body){document.documentElement.doScroll("left");dojo._loadInit();}}catch(e){}},30);}}}}if(dojo.isIE){try{(function(){document.namespaces.add("v","urn:schemas-microsoft-com:vml");var _5d=["*","group","roundrect","oval","shape","rect","imagedata","path","textpath","text"],i=0,l=1,s=document.createStyleSheet();if(dojo.isIE>=8){i=1;l=_5d.length;}for(;i2){return d._hitchArgs.apply(d,arguments);}if(!_67){_67=_66;_66=null;}if(d.isString(_67)){_66=_66||d.global;if(!_66[_67]){throw (["dojo.hitch: scope[\"",_67,"\"] is null (scope=\"",_66,"\")"].join(""));}return function(){return _66[_67].apply(_66,arguments||[]);};}return !_66?_67:function(){return _67.apply(_66,arguments||[]);};};dojo.delegate=dojo._delegate=(function(){function TMP(){};return function(obj,_68){TMP.prototype=obj;var tmp=new TMP();TMP.prototype=null;if(_68){d._mixin(tmp,_68);}return tmp;};})();var _69=function(obj,_6a,_6b){return (_6b||[]).concat(Array.prototype.slice.call(obj,_6a||0));};var _6c=function(obj,_6d,_6e){var arr=_6e||[];for(var x=_6d||0;xend)||i=0;--j){_a1=lin[j].prototype;if(!_a1.hasOwnProperty("declaredClass")){_a1.declaredClass="uniqName_"+(_98++);}_a2=_a1.declaredClass;if(!_9e.hasOwnProperty(_a2)){_9e[_a2]={count:0,refs:[],cls:lin[j]};++_9f;}rec=_9e[_a2];if(top&&top!==rec){rec.refs.push(top);++top.count;}top=rec;}++top.count;_9d[0].refs.push(top);}while(_9d.length){top=_9d.pop();_9c.push(top.cls);--_9f;while(_a3=top.refs,_a3.length==1){top=_a3[0];if(!top||--top.count){top=0;break;}_9c.push(top.cls);--_9f;}if(top){for(i=0,l=_a3.length;i=0;--i){f=_be[i];m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,_c1?_c1[i]:a);}}f=this.postscript;if(f){f.apply(this,_c0);}};};function _c3(_c4,_c5){return function(){var a=arguments,t=a,a0=a[0],f;if(!(this instanceof a.callee)){return _c2(a);}if(_c5){if(a0){f=a0.preamble;if(f){t=f.apply(this,t)||t;}}f=this.preamble;if(f){f.apply(this,t);}}if(_c4){_c4.apply(this,a);}f=this.postscript;if(f){f.apply(this,a);}};};function _c6(_c7){return function(){var a=arguments,i=0,f,m;if(!(this instanceof a.callee)){return _c2(a);}for(;f=_c7[i];++i){m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,a);break;}}f=this.postscript;if(f){f.apply(this,a);}};};function _c8(_c9,_ca,_cb){return function(){var b,m,f,i=0,_cc=1;if(_cb){i=_ca.length-1;_cc=-1;}for(;b=_ca[i];i+=_cc){m=b._meta;f=(m?m.hidden:b.prototype)[_c9];if(f){f.apply(this,arguments);}}};};function _cd(_ce){_97.prototype=_ce.prototype;var t=new _97;_97.prototype=null;return t;};function _c2(_cf){var _d0=_cf.callee,t=_cd(_d0);_d0.apply(t,_cf);return t;};d.declare=function(_d1,_d2,_d3){if(typeof _d1!="string"){_d3=_d2;_d2=_d1;_d1="";}_d3=_d3||{};var _d4,i,t,_d5,_d6,_d7,_d8,_d9=1,_da=_d2;if(_96.call(_d2)=="[object Array]"){_d7=_9a(_d2);t=_d7[0];_d9=_d7.length-t;_d2=_d7[_d9];}else{_d7=[0];if(_d2){if(_96.call(_d2)=="[object Function]"){t=_d2._meta;_d7=_d7.concat(t?t.bases:_d2);}else{err("base class is not a callable constructor.");}}else{if(_d2!==null){err("unknown base class. Did you use dojo.require to pull it in?");}}}if(_d2){for(i=_d9-1;;--i){_d4=_cd(_d2);if(!i){break;}t=_d7[i];(t._meta?_b3:mix)(_d4,t.prototype);_d5=new Function;_d5.superclass=_d2;_d5.prototype=_d4;_d2=_d4.constructor=_d5;}}else{_d4={};}_b7(_d4,_d3);t=_d3.constructor;if(t!==op.constructor){t.nom=_99;_d4.constructor=t;}for(i=_d9-1;i;--i){t=_d7[i]._meta;if(t&&t.chains){_d8=mix(_d8||{},t.chains);}}if(_d4["-chains-"]){_d8=mix(_d8||{},_d4["-chains-"]);}t=!_d8||!_d8.hasOwnProperty(_99);_d7[0]=_d5=(_d8&&_d8.constructor==="manual")?_c6(_d7):(_d7.length==1?_c3(_d3.constructor,t):_bd(_d7,t));_d5._meta={bases:_d7,hidden:_d3,chains:_d8,parents:_da,ctor:_d3.constructor};_d5.superclass=_d2&&_d2.prototype;_d5.extend=_bb;_d5.prototype=_d4;_d4.constructor=_d5;_d4.getInherited=_ae;_d4.inherited=_a4;_d4.isInstanceOf=_b1;if(_d1){_d4.declaredClass=_d1;d.setObject(_d1,_d5);}if(_d8){for(_d6 in _d8){if(_d4[_d6]&&typeof _d8[_d6]=="string"&&_d6!=_99){t=_d4[_d6]=_c8(_d6,_d7,_d8[_d6]==="after");t.nom=_d6;}}}return _d5;};d.safeMixin=_b7;})();}if(!dojo._hasResource["dojo._base.connect"]){dojo._hasResource["dojo._base.connect"]=true;dojo.provide("dojo._base.connect");dojo._listener={getDispatcher:function(){return function(){var ap=Array.prototype,c=arguments.callee,ls=c._listeners,t=c.target;var r=t&&t.apply(this,arguments);var i,lls;lls=[].concat(ls);for(i in lls){if(!(i in ap)){lls[i].apply(this,arguments);}}return r;};},add:function(_db,_dc,_dd){_db=_db||dojo.global;var f=_db[_dc];if(!f||!f._listeners){var d=dojo._listener.getDispatcher();d.target=f;d._listeners=[];f=_db[_dc]=d;}return f._listeners.push(_dd);},remove:function(_de,_df,_e0){var f=(_de||dojo.global)[_df];if(f&&f._listeners&&_e0--){delete f._listeners[_e0];}}};dojo.connect=function(obj,_e1,_e2,_e3,_e4){var a=arguments,_e5=[],i=0;_e5.push(dojo.isString(a[0])?null:a[i++],a[i++]);var a1=a[i+1];_e5.push(dojo.isString(a1)||dojo.isFunction(a1)?a[i++]:null,a[i++]);for(var l=a.length;i>=bits;t[x]=bits==4?17*c:c;});t.a=1;return t;};dojo.colorFromArray=function(a,obj){var t=obj||new d.Color();t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));if(isNaN(t.a)){t.a=1;}return t.sanitize();};dojo.colorFromString=function(str,obj){var a=d.Color.named[str];return a&&d.colorFromArray(a,obj)||d.colorFromRgb(str,obj)||d.colorFromHex(str,obj);};})();}if(!dojo._hasResource["dojo._base"]){dojo._hasResource["dojo._base"]=true;dojo.provide("dojo._base");}if(!dojo._hasResource["dojo._base.window"]){dojo._hasResource["dojo._base.window"]=true;dojo.provide("dojo._base.window");dojo.doc=window["document"]||null;dojo.body=function(){return dojo.doc.body||dojo.doc.getElementsByTagName("body")[0];};dojo.setContext=function(_12b,_12c){dojo.global=_12b;dojo.doc=_12c;};dojo.withGlobal=function(_12d,_12e,_12f,_130){var _131=dojo.global;try{dojo.global=_12d;return dojo.withDoc.call(null,_12d.document,_12e,_12f,_130);}finally{dojo.global=_131;}};dojo.withDoc=function(_132,_133,_134,_135){var _136=dojo.doc,_137=dojo._bodyLtr,oldQ=dojo.isQuirks;try{dojo.doc=_132;delete dojo._bodyLtr;dojo.isQuirks=dojo.doc.compatMode=="BackCompat";if(_134&&typeof _133=="string"){_133=_134[_133];}return _133.apply(_134,_135||[]);}finally{dojo.doc=_136;delete dojo._bodyLtr;if(_137!==undefined){dojo._bodyLtr=_137;}dojo.isQuirks=oldQ;}};}if(!dojo._hasResource["dojo._base.event"]){dojo._hasResource["dojo._base.event"]=true;dojo.provide("dojo._base.event");(function(){var del=(dojo._event_listener={add:function(node,name,fp){if(!node){return;}name=del._normalizeEventName(name);fp=del._fixCallback(name,fp);var _138=name;if(!dojo.isIE&&(name=="mouseenter"||name=="mouseleave")){var ofp=fp;name=(name=="mouseenter")?"mouseover":"mouseout";fp=function(e){if(!dojo.isDescendant(e.relatedTarget,node)){return ofp.call(this,e);}};}node.addEventListener(name,fp,false);return fp;},remove:function(node,_139,_13a){if(node){_139=del._normalizeEventName(_139);if(!dojo.isIE&&(_139=="mouseenter"||_139=="mouseleave")){_139=(_139=="mouseenter")?"mouseover":"mouseout";}node.removeEventListener(_139,_13a,false);}},_normalizeEventName:function(name){return name.slice(0,2)=="on"?name.slice(2):name;},_fixCallback:function(name,fp){return name!="keypress"?fp:function(e){return fp.call(this,del._fixEvent(e,this));};},_fixEvent:function(evt,_13b){switch(evt.type){case "keypress":del._setKeyChar(evt);break;}return evt;},_setKeyChar:function(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;},_punctMap:{106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39}});dojo.fixEvent=function(evt,_13c){return del._fixEvent(evt,_13c);};dojo.stopEvent=function(evt){evt.preventDefault();evt.stopPropagation();};var _13d=dojo._listener;dojo._connect=function(obj,_13e,_13f,_140,_141){var _142=obj&&(obj.nodeType||obj.attachEvent||obj.addEventListener);var lid=_142?(_141?2:1):0,l=[dojo._listener,del,_13d][lid];var h=l.add(obj,_13e,dojo.hitch(_13f,_140));return [obj,_13e,h,lid];};dojo._disconnect=function(obj,_143,_144,_145){([dojo._listener,del,_13d][_145]).remove(obj,_143,_144);};dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,META:dojo.isSafari?91:224,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUMPAD_DIVIDE:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,NUM_LOCK:144,SCROLL_LOCK:145,copyKey:dojo.isMac&&!dojo.isAIR?(dojo.isSafari?91:224):17};var _146=dojo.isMac?"metaKey":"ctrlKey";dojo.isCopyKey=function(e){return e[_146];};if(dojo.isIE){dojo.mouseButtons={LEFT:1,MIDDLE:4,RIGHT:2,isButton:function(e,_147){return e.button&_147;},isLeft:function(e){return e.button&1;},isMiddle:function(e){return e.button&4;},isRight:function(e){return e.button&2;}};}else{dojo.mouseButtons={LEFT:0,MIDDLE:1,RIGHT:2,isButton:function(e,_148){return e.button==_148;},isLeft:function(e){return e.button==0;},isMiddle:function(e){return e.button==1;},isRight:function(e){return e.button==2;}};}if(dojo.isIE){var _149=function(e,code){try{return (e.keyCode=code);}catch(e){return 0;}};var iel=dojo._listener;var _14a=(dojo._ieListenersName="_"+dojo._scopeName+"_listeners");if(!dojo.config._allow_leaks){_13d=iel=dojo._ie_listener={handlers:[],add:function(_14b,_14c,_14d){_14b=_14b||dojo.global;var f=_14b[_14c];if(!f||!f[_14a]){var d=dojo._getIeDispatcher();d.target=f&&(ieh.push(f)-1);d[_14a]=[];f=_14b[_14c]=d;}return f[_14a].push(ieh.push(_14d)-1);},remove:function(_14e,_14f,_150){var f=(_14e||dojo.global)[_14f],l=f&&f[_14a];if(f&&l&&_150--){delete ieh[l[_150]];delete l[_150];}}};var ieh=iel.handlers;}dojo.mixin(del,{add:function(node,_151,fp){if(!node){return;}_151=del._normalizeEventName(_151);if(_151=="onkeypress"){var kd=node.onkeydown;if(!kd||!kd[_14a]||!kd._stealthKeydownHandle){var h=del.add(node,"onkeydown",del._stealthKeyDown);kd=node.onkeydown;kd._stealthKeydownHandle=h;kd._stealthKeydownRefs=1;}else{kd._stealthKeydownRefs++;}}return iel.add(node,_151,del._fixCallback(fp));},remove:function(node,_152,_153){_152=del._normalizeEventName(_152);iel.remove(node,_152,_153);if(_152=="onkeypress"){var kd=node.onkeydown;if(--kd._stealthKeydownRefs<=0){iel.remove(node,"onkeydown",kd._stealthKeydownHandle);delete kd._stealthKeydownHandle;}}},_normalizeEventName:function(_154){return _154.slice(0,2)!="on"?"on"+_154:_154;},_nop:function(){},_fixEvent:function(evt,_155){if(!evt){var w=_155&&(_155.ownerDocument||_155.document||_155).parentWindow||window;evt=w.event;}if(!evt){return (evt);}evt.target=evt.srcElement;evt.currentTarget=(_155||evt.srcElement);evt.layerX=evt.offsetX;evt.layerY=evt.offsetY;var se=evt.srcElement,doc=(se&&se.ownerDocument)||document;var _156=((dojo.isIE<6)||(doc["compatMode"]=="BackCompat"))?doc.body:doc.documentElement;var _157=dojo._getIeDocumentElementOffset();evt.pageX=evt.clientX+dojo._fixIeBiDiScrollLeft(_156.scrollLeft||0)-_157.x;evt.pageY=evt.clientY+(_156.scrollTop||0)-_157.y;if(evt.type=="mouseover"){evt.relatedTarget=evt.fromElement;}if(evt.type=="mouseout"){evt.relatedTarget=evt.toElement;}evt.stopPropagation=del._stopPropagation;evt.preventDefault=del._preventDefault;return del._fixKeys(evt);},_fixKeys:function(evt){switch(evt.type){case "keypress":var c=("charCode" in evt?evt.charCode:evt.keyCode);if(c==10){c=0;evt.keyCode=13;}else{if(c==13||c==27){c=0;}else{if(c==3){c=99;}}}evt.charCode=c;del._setKeyChar(evt);break;}return evt;},_stealthKeyDown:function(evt){var kp=evt.currentTarget.onkeypress;if(!kp||!kp[_14a]){return;}var k=evt.keyCode;var _158=k!=13&&k!=32&&k!=27&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);if(_158||evt.ctrlKey){var c=_158?0:k;if(evt.ctrlKey){if(k==3||k==13){return;}else{if(c>95&&c<106){c-=48;}else{if((!evt.shiftKey)&&(c>=65&&c<=90)){c+=32;}else{c=del._punctMap[c]||c;}}}}var faux=del._synthesizeEvent(evt,{type:"keypress",faux:true,charCode:c});kp.call(evt.currentTarget,faux);evt.cancelBubble=faux.cancelBubble;evt.returnValue=faux.returnValue;_149(evt,faux.keyCode);}},_stopPropagation:function(){this.cancelBubble=true;},_preventDefault:function(){this.bubbledKeyCode=this.keyCode;if(this.ctrlKey){_149(this,0);}this.returnValue=false;}});dojo.stopEvent=function(evt){evt=evt||window.event;del._stopPropagation.call(evt);del._preventDefault.call(evt);};}del._synthesizeEvent=function(evt,_159){var faux=dojo.mixin({},evt,_159);del._setKeyChar(faux);faux.preventDefault=function(){evt.preventDefault();};faux.stopPropagation=function(){evt.stopPropagation();};return faux;};if(dojo.isOpera){dojo.mixin(del,{_fixEvent:function(evt,_15a){switch(evt.type){case "keypress":var c=evt.which;if(c==3){c=99;}c=c<41&&!evt.shiftKey?0:c;if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){c+=32;}return del._synthesizeEvent(evt,{charCode:c});}return evt;}});}if(dojo.isWebKit){del._add=del.add;del._remove=del.remove;dojo.mixin(del,{add:function(node,_15b,fp){if(!node){return;}var _15c=del._add(node,_15b,fp);if(del._normalizeEventName(_15b)=="keypress"){_15c._stealthKeyDownHandle=del._add(node,"keydown",function(evt){var k=evt.keyCode;var _15d=k!=13&&k!=32&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222);if(_15d||evt.ctrlKey){var c=_15d?0:k;if(evt.ctrlKey){if(k==3||k==13){return;}else{if(c>95&&c<106){c-=48;}else{if(!evt.shiftKey&&c>=65&&c<=90){c+=32;}else{c=del._punctMap[c]||c;}}}}var faux=del._synthesizeEvent(evt,{type:"keypress",faux:true,charCode:c});fp.call(evt.currentTarget,faux);}});}return _15c;},remove:function(node,_15e,_15f){if(node){if(_15f._stealthKeyDownHandle){del._remove(node,"keydown",_15f._stealthKeyDownHandle);}del._remove(node,_15e,_15f);}},_fixEvent:function(evt,_160){switch(evt.type){case "keypress":if(evt.faux){return evt;}var c=evt.charCode;c=c>=32?c:0;return del._synthesizeEvent(evt,{charCode:c,faux:true});}return evt;}});}})();if(dojo.isIE){dojo._ieDispatcher=function(args,_161){var ap=Array.prototype,h=dojo._ie_listener.handlers,c=args.callee,ls=c[dojo._ieListenersName],t=h[c.target];var r=t&&t.apply(_161,args);var lls=[].concat(ls);for(var i in lls){var f=h[lls[i]];if(!(i in ap)&&f){f.apply(_161,args);}}return r;};dojo._getIeDispatcher=function(){return new Function(dojo._scopeName+"._ieDispatcher(arguments, this)");};dojo._event_listener._fixCallback=function(fp){var f=dojo._event_listener._fixEvent;return function(e){return fp.call(this,f(e,this));};};}}if(!dojo._hasResource["dojo._base.html"]){dojo._hasResource["dojo._base.html"]=true;dojo.provide("dojo._base.html");try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}if(dojo.isIE||dojo.isOpera){dojo.byId=function(id,doc){if(typeof id!="string"){return id;}var _162=doc||dojo.doc,te=_162.getElementById(id);if(te&&(te.attributes.id.value==id||te.id==id)){return te;}else{var eles=_162.all[id];if(!eles||eles.nodeName){eles=[eles];}var i=0;while((te=eles[i++])){if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){return te;}}}};}else{dojo.byId=function(id,doc){return (typeof id=="string")?(doc||dojo.doc).getElementById(id):id;};}(function(){var d=dojo;var byId=d.byId;var _163=null,_164;d.addOnWindowUnload(function(){_163=null;});dojo._destroyElement=dojo.destroy=function(node){node=byId(node);try{var doc=node.ownerDocument;if(!_163||_164!=doc){_163=doc.createElement("div");_164=doc;}_163.appendChild(node.parentNode?node.parentNode.removeChild(node):node);_163.innerHTML="";}catch(e){}};dojo.isDescendant=function(node,_165){try{node=byId(node);_165=byId(_165);while(node){if(node==_165){return true;}node=node.parentNode;}}catch(e){}return false;};dojo.setSelectable=function(node,_166){node=byId(node);if(d.isMozilla){node.style.MozUserSelect=_166?"":"none";}else{if(d.isKhtml||d.isWebKit){node.style.KhtmlUserSelect=_166?"auto":"none";}else{if(d.isIE){var v=(node.unselectable=_166?"":"on");d.query("*",node).forEach("item.unselectable = '"+v+"'");}}}};var _167=function(node,ref){var _168=ref.parentNode;if(_168){_168.insertBefore(node,ref);}};var _169=function(node,ref){var _16a=ref.parentNode;if(_16a){if(_16a.lastChild==ref){_16a.appendChild(node);}else{_16a.insertBefore(node,ref.nextSibling);}}};dojo.place=function(node,_16b,_16c){_16b=byId(_16b);if(typeof node=="string"){node=node.charAt(0)=="<"?d._toDom(node,_16b.ownerDocument):byId(node);}if(typeof _16c=="number"){var cn=_16b.childNodes;if(!cn.length||cn.length<=_16c){_16b.appendChild(node);}else{_167(node,cn[_16c<0?0:_16c]);}}else{switch(_16c){case "before":_167(node,_16b);break;case "after":_169(node,_16b);break;case "replace":_16b.parentNode.replaceChild(node,_16b);break;case "only":d.empty(_16b);_16b.appendChild(node);break;case "first":if(_16b.firstChild){_167(node,_16b.firstChild);break;}default:_16b.appendChild(node);}}return node;};dojo.boxModel="content-box";if(d.isIE){d.boxModel=document.compatMode=="BackCompat"?"border-box":"content-box";}var gcs;if(d.isWebKit){gcs=function(node){var s;if(node.nodeType==1){var dv=node.ownerDocument.defaultView;s=dv.getComputedStyle(node,null);if(!s&&node.style){node.style.display="";s=dv.getComputedStyle(node,null);}}return s||{};};}else{if(d.isIE){gcs=function(node){return node.nodeType==1?node.currentStyle:{};};}else{gcs=function(node){return node.nodeType==1?node.ownerDocument.defaultView.getComputedStyle(node,null):{};};}}dojo.getComputedStyle=gcs;if(!d.isIE){d._toPixelValue=function(_16d,_16e){return parseFloat(_16e)||0;};}else{d._toPixelValue=function(_16f,_170){if(!_170){return 0;}if(_170=="medium"){return 4;}if(_170.slice&&_170.slice(-2)=="px"){return parseFloat(_170);}with(_16f){var _171=style.left;var _172=runtimeStyle.left;runtimeStyle.left=currentStyle.left;try{style.left=_170;_170=style.pixelLeft;}catch(e){_170=0;}style.left=_171;runtimeStyle.left=_172;}return _170;};}var px=d._toPixelValue;var astr="DXImageTransform.Microsoft.Alpha";var af=function(n,f){try{return n.filters.item(astr);}catch(e){return f?{}:null;}};dojo._getOpacity=d.isIE?function(node){try{return af(node).Opacity/100;}catch(e){return 1;}}:function(node){return gcs(node).opacity;};dojo._setOpacity=d.isIE?function(node,_173){var ov=_173*100,_174=_173==1;node.style.zoom=_174?"":1;if(!af(node)){if(_174){return _173;}node.style.filter+=" progid:"+astr+"(Opacity="+ov+")";}else{af(node,1).Opacity=ov;}af(node,1).Enabled=!_174;if(node.nodeName.toLowerCase()=="tr"){d.query("> td",node).forEach(function(i){d._setOpacity(i,_173);});}return _173;}:function(node,_175){return node.style.opacity=_175;};var _176={left:true,top:true};var _177=/margin|padding|width|height|max|min|offset/;var _178=function(node,type,_179){type=type.toLowerCase();if(d.isIE){if(_179=="auto"){if(type=="height"){return node.offsetHeight;}if(type=="width"){return node.offsetWidth;}}if(type=="fontweight"){switch(_179){case 700:return "bold";case 400:default:return "normal";}}}if(!(type in _176)){_176[type]=_177.test(type);}return _176[type]?px(node,_179):_179;};var _17a=d.isIE?"styleFloat":"cssFloat",_17b={"cssFloat":_17a,"styleFloat":_17a,"float":_17a};dojo.style=function(node,_17c,_17d){var n=byId(node),args=arguments.length,op=(_17c=="opacity");_17c=_17b[_17c]||_17c;if(args==3){return op?d._setOpacity(n,_17d):n.style[_17c]=_17d;}if(args==2&&op){return d._getOpacity(n);}var s=gcs(n);if(args==2&&typeof _17c!="string"){for(var x in _17c){d.style(node,x,_17c[x]);}return s;}return (args==1)?s:_178(n,_17c,s[_17c]||n.style[_17c]);};dojo._getPadExtents=function(n,_17e){var s=_17e||gcs(n),l=px(n,s.paddingLeft),t=px(n,s.paddingTop);return {l:l,t:t,w:l+px(n,s.paddingRight),h:t+px(n,s.paddingBottom)};};dojo._getBorderExtents=function(n,_17f){var ne="none",s=_17f||gcs(n),bl=(s.borderLeftStyle!=ne?px(n,s.borderLeftWidth):0),bt=(s.borderTopStyle!=ne?px(n,s.borderTopWidth):0);return {l:bl,t:bt,w:bl+(s.borderRightStyle!=ne?px(n,s.borderRightWidth):0),h:bt+(s.borderBottomStyle!=ne?px(n,s.borderBottomWidth):0)};};dojo._getPadBorderExtents=function(n,_180){var s=_180||gcs(n),p=d._getPadExtents(n,s),b=d._getBorderExtents(n,s);return {l:p.l+b.l,t:p.t+b.t,w:p.w+b.w,h:p.h+b.h};};dojo._getMarginExtents=function(n,_181){var s=_181||gcs(n),l=px(n,s.marginLeft),t=px(n,s.marginTop),r=px(n,s.marginRight),b=px(n,s.marginBottom);if(d.isWebKit&&(s.position!="absolute")){r=l;}return {l:l,t:t,w:l+r,h:t+b};};dojo._getMarginBox=function(node,_182){var s=_182||gcs(node),me=d._getMarginExtents(node,s);var l=node.offsetLeft-me.l,t=node.offsetTop-me.t,p=node.parentNode;if(d.isMoz){var sl=parseFloat(s.left),st=parseFloat(s.top);if(!isNaN(sl)&&!isNaN(st)){l=sl,t=st;}else{if(p&&p.style){var pcs=gcs(p);if(pcs.overflow!="visible"){var be=d._getBorderExtents(p,pcs);l+=be.l,t+=be.t;}}}}else{if(d.isOpera||(d.isIE>7&&!d.isQuirks)){if(p){be=d._getBorderExtents(p);l-=be.l;t-=be.t;}}}return {l:l,t:t,w:node.offsetWidth+me.w,h:node.offsetHeight+me.h};};dojo._getContentBox=function(node,_183){var s=_183||gcs(node),pe=d._getPadExtents(node,s),be=d._getBorderExtents(node,s),w=node.clientWidth,h;if(!w){w=node.offsetWidth,h=node.offsetHeight;}else{h=node.clientHeight,be.w=be.h=0;}if(d.isOpera){pe.l+=be.l;pe.t+=be.t;}return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};};dojo._getBorderBox=function(node,_184){var s=_184||gcs(node),pe=d._getPadExtents(node,s),cb=d._getContentBox(node,s);return {l:cb.l-pe.l,t:cb.t-pe.t,w:cb.w+pe.w,h:cb.h+pe.h};};dojo._setBox=function(node,l,t,w,h,u){u=u||"px";var s=node.style;if(!isNaN(l)){s.left=l+u;}if(!isNaN(t)){s.top=t+u;}if(w>=0){s.width=w+u;}if(h>=0){s.height=h+u;}};dojo._isButtonTag=function(node){return node.tagName=="BUTTON"||node.tagName=="INPUT"&&(node.getAttribute("type")||"").toUpperCase()=="BUTTON";};dojo._usesBorderBox=function(node){var n=node.tagName;return d.boxModel=="border-box"||n=="TABLE"||d._isButtonTag(node);};dojo._setContentSize=function(node,_185,_186,_187){if(d._usesBorderBox(node)){var pb=d._getPadBorderExtents(node,_187);if(_185>=0){_185+=pb.w;}if(_186>=0){_186+=pb.h;}}d._setBox(node,NaN,NaN,_185,_186);};dojo._setMarginBox=function(node,_188,_189,_18a,_18b,_18c){var s=_18c||gcs(node),bb=d._usesBorderBox(node),pb=bb?_18d:d._getPadBorderExtents(node,s);if(d.isWebKit){if(d._isButtonTag(node)){var ns=node.style;if(_18a>=0&&!ns.width){ns.width="4px";}if(_18b>=0&&!ns.height){ns.height="4px";}}}var mb=d._getMarginExtents(node,s);if(_18a>=0){_18a=Math.max(_18a-pb.w-mb.w,0);}if(_18b>=0){_18b=Math.max(_18b-pb.h-mb.h,0);}d._setBox(node,_188,_189,_18a,_18b);};var _18d={l:0,t:0,w:0,h:0};dojo.marginBox=function(node,box){var n=byId(node),s=gcs(n),b=box;return !b?d._getMarginBox(n,s):d._setMarginBox(n,b.l,b.t,b.w,b.h,s);};dojo.contentBox=function(node,box){var n=byId(node),s=gcs(n),b=box;return !b?d._getContentBox(n,s):d._setContentSize(n,b.w,b.h,s);};var _18e=function(node,prop){if(!(node=(node||0).parentNode)){return 0;}var val,_18f=0,_190=d.body();while(node&&node.style){if(gcs(node).position=="fixed"){return 0;}val=node[prop];if(val){_18f+=val-0;if(node==_190){break;}}node=node.parentNode;}return _18f;};dojo._docScroll=function(){var n=d.global;return "pageXOffset" in n?{x:n.pageXOffset,y:n.pageYOffset}:(n=d.doc.documentElement,n.clientHeight?{x:d._fixIeBiDiScrollLeft(n.scrollLeft),y:n.scrollTop}:(n=d.body(),{x:n.scrollLeft||0,y:n.scrollTop||0}));};dojo._isBodyLtr=function(){return "_bodyLtr" in d?d._bodyLtr:d._bodyLtr=(d.body().dir||d.doc.documentElement.dir||"ltr").toLowerCase()=="ltr";};dojo._getIeDocumentElementOffset=function(){var de=d.doc.documentElement;if(d.isIE<8){var r=de.getBoundingClientRect();var l=r.left,t=r.top;if(d.isIE<7){l+=de.clientLeft;t+=de.clientTop;}return {x:l<0?0:l,y:t<0?0:t};}else{return {x:0,y:0};}};dojo._fixIeBiDiScrollLeft=function(_191){var dd=d.doc;if(d.isIE<8&&!d._isBodyLtr()){var de=d.isQuirks?dd.body:dd.documentElement;return _191+de.clientWidth-de.scrollWidth;}return _191;};dojo._abs=dojo.position=function(node,_192){var db=d.body(),dh=db.parentNode,ret;node=byId(node);if(node["getBoundingClientRect"]){ret=node.getBoundingClientRect();ret={x:ret.left,y:ret.top,w:ret.right-ret.left,h:ret.bottom-ret.top};if(d.isIE){var _193=d._getIeDocumentElementOffset();ret.x-=_193.x+(d.isQuirks?db.clientLeft+db.offsetLeft:0);ret.y-=_193.y+(d.isQuirks?db.clientTop+db.offsetTop:0);}else{if(d.isFF==3){var cs=gcs(dh);ret.x-=px(dh,cs.marginLeft)+px(dh,cs.borderLeftWidth);ret.y-=px(dh,cs.marginTop)+px(dh,cs.borderTopWidth);}}}else{ret={x:0,y:0,w:node.offsetWidth,h:node.offsetHeight};if(node["offsetParent"]){ret.x-=_18e(node,"scrollLeft");ret.y-=_18e(node,"scrollTop");var _194=node;do{var n=_194.offsetLeft,t=_194.offsetTop;ret.x+=isNaN(n)?0:n;ret.y+=isNaN(t)?0:t;cs=gcs(_194);if(_194!=node){if(d.isMoz){ret.x+=2*px(_194,cs.borderLeftWidth);ret.y+=2*px(_194,cs.borderTopWidth);}else{ret.x+=px(_194,cs.borderLeftWidth);ret.y+=px(_194,cs.borderTopWidth);}}if(d.isMoz&&cs.position=="static"){var _195=_194.parentNode;while(_195!=_194.offsetParent){var pcs=gcs(_195);if(pcs.position=="static"){ret.x+=px(_194,pcs.borderLeftWidth);ret.y+=px(_194,pcs.borderTopWidth);}_195=_195.parentNode;}}_194=_194.offsetParent;}while((_194!=dh)&&_194);}else{if(node.x&&node.y){ret.x+=isNaN(node.x)?0:node.x;ret.y+=isNaN(node.y)?0:node.y;}}}if(_192){var _196=d._docScroll();ret.x+=_196.x;ret.y+=_196.y;}return ret;};dojo.coords=function(node,_197){var n=byId(node),s=gcs(n),mb=d._getMarginBox(n,s);var abs=d.position(n,_197);mb.x=abs.x;mb.y=abs.y;return mb;};var _198={"class":"className","for":"htmlFor",tabindex:"tabIndex",readonly:"readOnly",colspan:"colSpan",frameborder:"frameBorder",rowspan:"rowSpan",valuetype:"valueType"},_199={classname:"class",htmlfor:"for",tabindex:"tabIndex",readonly:"readOnly"},_19a={innerHTML:1,className:1,htmlFor:d.isIE,value:1};var _19b=function(name){return _199[name.toLowerCase()]||name;};var _19c=function(node,name){var attr=node.getAttributeNode&&node.getAttributeNode(name);return attr&&attr.specified;};dojo.hasAttr=function(node,name){var lc=name.toLowerCase();return _19a[_198[lc]||name]||_19c(byId(node),_199[lc]||name);};var _19d={},_19e=0,_19f=dojo._scopeName+"attrid",_1a0={col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1};dojo.attr=function(node,name,_1a1){node=byId(node);var args=arguments.length,prop;if(args==2&&typeof name!="string"){for(var x in name){d.attr(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_1a2=_198[lc]||name,_1a3=_19a[_1a2],_1a4=_199[lc]||name;if(args==3){do{if(_1a2=="style"&&typeof _1a1!="string"){d.style(node,_1a1);break;}if(_1a2=="innerHTML"){if(d.isIE&&node.tagName.toLowerCase() in _1a0){d.empty(node);node.appendChild(d._toDom(_1a1,node.ownerDocument));}else{node[_1a2]=_1a1;}break;}if(d.isFunction(_1a1)){var _1a5=d.attr(node,_19f);if(!_1a5){_1a5=_19e++;d.attr(node,_19f,_1a5);}if(!_19d[_1a5]){_19d[_1a5]={};}var h=_19d[_1a5][_1a2];if(h){d.disconnect(h);}else{try{delete node[_1a2];}catch(e){}}_19d[_1a5][_1a2]=d.connect(node,_1a2,_1a1);break;}if(_1a3||typeof _1a1=="boolean"){node[_1a2]=_1a1;break;}node.setAttribute(_1a4,_1a1);}while(false);return node;}_1a1=node[_1a2];if(_1a3&&typeof _1a1!="undefined"){return _1a1;}if(_1a2!="href"&&(typeof _1a1=="boolean"||d.isFunction(_1a1))){return _1a1;}return _19c(node,_1a4)?node.getAttribute(_1a4):null;};dojo.removeAttr=function(node,name){byId(node).removeAttribute(_19b(name));};dojo.getNodeProp=function(node,name){node=byId(node);var lc=name.toLowerCase(),_1a6=_198[lc]||name;if((_1a6 in node)&&_1a6!="href"){return node[_1a6];}var _1a7=_199[lc]||name;return _19c(node,_1a7)?node.getAttribute(_1a7):null;};dojo.create=function(tag,_1a8,_1a9,pos){var doc=d.doc;if(_1a9){_1a9=byId(_1a9);doc=_1a9.ownerDocument;}if(typeof tag=="string"){tag=doc.createElement(tag);}if(_1a8){d.attr(tag,_1a8);}if(_1a9){d.place(tag,_1a9,pos);}return tag;};d.empty=d.isIE?function(node){node=byId(node);for(var c;c=node.lastChild;){d.destroy(c);}}:function(node){byId(node).innerHTML="";};var _1aa={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_1ab=/<\s*([\w\:]+)/,_1ac={},_1ad=0,_1ae="__"+d._scopeName+"ToDomId";for(var _1af in _1aa){var tw=_1aa[_1af];tw.pre=_1af=="option"?"