summaryrefslogtreecommitdiffstats
path: root/o3d
diff options
context:
space:
mode:
authorluchen@chromium.org <luchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-11 21:30:08 +0000
committerluchen@chromium.org <luchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-11 21:30:08 +0000
commit64fd176302087ad4de3d88770cf948479a1e9852 (patch)
tree26b25c5cfccea633b0f572531e2e7b839ffde5ec /o3d
parentc60939a4fc1a23caa5777937912e69decbf5266f (diff)
downloadchromium_src-64fd176302087ad4de3d88770cf948479a1e9852.zip
chromium_src-64fd176302087ad4de3d88770cf948479a1e9852.tar.gz
chromium_src-64fd176302087ad4de3d88770cf948479a1e9852.tar.bz2
WebGL bubble demo. Based off of: http://code.google.com/p/o3d/source/browse/trunk/googleclient/o3d/?r=55#o3d/command_buffer/samples/bubble
This demo adds dynamic ability to change the iridescence/noise textures, turn on/off the environment mapping, change the number of bubbles, bubble size/spin/thickness/etc. I also added a third texture that modulates the bubble geometry to get a pulsing effect (this could use some improvement but it's not bad). Review URL: http://codereview.chromium.org/3050048 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55787 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'o3d')
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/bubble.html235
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/css/style.css163
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/negx.pngbin0 -> 8952 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/negy.pngbin0 -> 9353 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/negz.pngbin0 -> 8635 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/posx.pngbin0 -> 8805 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/posy.pngbin0 -> 7478 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/cubemap/posz.pngbin0 -> 8616 bytes
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/bubbledemo.js583
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/controls.js336
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/environment.js61
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/iridescence.js223
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/main.js260
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/modulation.js97
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/js/noise.js210
-rwxr-xr-xo3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/AUTHORS.txt30
-rwxr-xr-xo3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/MIT-LICENSE.txt25
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/README.o3d7
-rw-r--r--o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/css/jquery-ui-1.8.4.custom.css124
-rwxr-xr-xo3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-1.4.2.min.js154
-rwxr-xr-xo3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-ui-1.8.4.custom.min.js83
21 files changed, 2591 insertions, 0 deletions
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/bubble.html b/o3d/samples/o3d-webgl-samples/bubbles/bubble.html
new file mode 100644
index 0000000..80570f7
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/bubble.html
@@ -0,0 +1,235 @@
+<!--
+Copyright 2010, Google Inc.
+All rights reserved.
+
+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.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"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 THE COPYRIGHT
+OWNER OR 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.
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Bubbles Demo</title>
+
+<link type="text/css" href="css/style.css" rel="stylesheet" />
+
+<!-- Use jQuery UI for the sliders. -->
+<link type="text/css"
+ href="third_party/jquery/css/jquery-ui-1.8.4.custom.css" rel="stylesheet" />
+<script type="text/javascript"
+ src="third_party/jquery/jquery-1.4.2.min.js"></script>
+<script type="text/javascript"
+ src="third_party/jquery/jquery-ui-1.8.4.custom.min.js"></script>
+
+<!-- Our javascript code -->
+<script type="text/javascript" src="../../o3d-webgl/base.js"></script>
+<script type="text/javascript" src="../../o3djs/base.js"></script>
+<script type="text/javascript" src="js/bubbledemo.js"></script>
+<script type="text/javascript" src="js/environment.js"></script>
+<script type="text/javascript" src="js/noise.js"></script>
+<script type="text/javascript" src="js/iridescence.js"></script>
+<script type="text/javascript" src="js/modulation.js"></script>
+<script type="text/javascript" src="js/controls.js"></script>
+<script type="text/javascript" src="js/main.js"></script>
+
+<!--
+
+This demo is based off of the bubble demo created for o3d command buffers:
+http://code.google.com/p/o3d/source/browse/trunk/googleclient/o3d/?r=55#o3d/command_buffer/samples/bubble
+
+ -->
+
+</head>
+<body>
+ <!-- The o3d container. -->
+ <div id="o3d"></div>
+
+ <div id="floatControls">
+ <b>Options:</b>
+ <ul>
+ <li>
+ <label>
+ Bubble Options?
+ <input type="checkbox" onclick="toggle(0, this); void(0);" />
+ </label>
+ </li>
+ <li>
+ <label>
+ Iridescence Texture?
+ <input type="checkbox" onclick="toggle(1, this); void(0);" />
+ </label>
+ </li>
+ <li>
+ <label>
+ Noise Texture?
+ <input type="checkbox" onclick="toggle(2, this); void(0);" />
+ </label>
+ </li>
+ <li>
+ <label>Modulation Texture?
+ <input type="checkbox" onclick="toggle(3, this); void(0);" />
+ </label>
+ </li>
+ <li>
+ <label>Environment Map?
+ <input type="checkbox" onclick="toggle(4, this); void(0);" />
+ </label>
+ </li>
+ </ul>
+ <br />
+ <b>Background Color (0-255, rgb):</b>
+ <p></p>
+ <form onSubmit="updateClearColor(); void(0); return false;">
+ <input type="text" id="bg-red" size="3" maxLength="3" value="0" />
+ <input type="text" id="bg-green" size="3" maxLength="3" value="0" />
+ <input type="text" id="bg-blue" size="3" maxLength="3" value="0" />
+ <input type="submit" value="Go!" />
+ </form>
+ <br />
+ <b>Controls:</b>
+ Drag to rotate. Mousewheel to zoom. 'q' to exit all options.
+ <p id="loading">Loading...</p>
+ </div>
+
+ <!-- The option panels. -->
+ <div id="controls">
+ <div id="opt-bubble" class="option">
+ <a href="#close" class="closer">close</a>
+ </div>
+ <div id="tex-iridescence" class="option">
+ <a href="#close" class="closer">close</a>
+ </div>
+ <div id="tex-perlin" class="option">
+ <a href="#close" class="closer">close</a>
+ </div>
+ <div id="tex-modulation" class="option">
+ <a href="#close" class="closer">close</a>
+ </div>
+ <div id="tex-environment" class="option">
+ <img src="cubemap/posx.png" />
+ <img src="cubemap/negx.png" />
+ <img src="cubemap/posy.png" />
+ <img src="cubemap/negy.png" />
+ <img src="cubemap/posz.png" />
+ <img src="cubemap/negz.png" />
+ <p>Using environment map:
+ <a id="toggle-env" href="#toggle-env">On. Turn off?</a>
+ </p>
+ <a href="#close" class="closer">close</a>
+ </div>
+ </div>
+
+ <!-- Define the vertex shader -->
+ <textarea id="shader" name="shader" style="display: none;">
+ #ifdef GL_ES
+ precision highp float;
+ #endif
+
+ attribute vec3 position;
+ attribute vec3 normal;
+ attribute vec2 texCoord0;
+ attribute float texCoord1;
+
+
+ varying vec4 v_position;
+ varying vec2 v_uv;
+ varying vec2 v_params;
+ varying vec3 v_reflected;
+
+ uniform mat4 worldViewProjection;
+ uniform mat4 world;
+ uniform mat4 worldInverseTranspose;
+ uniform vec3 eye;
+ uniform vec4 thickness_params;
+ uniform float timer;
+ uniform float bubbleNumber;
+ uniform float distortion;
+
+ void main() {
+ vec4 object_position = vec4(position.xyz, 1);
+ vec4 object_normal = vec4(normal.xyz, 0);
+
+ // texCoord1 is the sampled value from the modulation texture.
+ float modulation_factor = sin(timer + bubbleNumber) *
+ (distortion * texCoord1);
+ vec4 unit_normal = normalize(object_normal);
+ object_position.xyz += unit_normal.xyz * modulation_factor;
+
+ vec3 tmp_normal = normalize((worldInverseTranspose * object_normal).xyz);
+ vec4 tmp_position = world * object_position;
+ vec4 center = world * vec4(0, 0, 0, 1);
+ vec3 eye_vector = normalize(tmp_position.xyz - eye);
+
+ // Absolute value for the back faces.
+ float cos_i = abs(dot(tmp_normal, eye_vector));
+ float thickness = exp(-(tmp_position.y - center.y) * thickness_params.x) *
+ thickness_params.y / 2.0;
+
+ gl_Position = worldViewProjection * object_position;
+ v_position = world * object_position;
+ v_uv = texCoord0;
+ v_params = vec2(cos_i, thickness);
+ v_reflected = reflect(eye_vector, tmp_normal);
+ }
+
+ // #o3d SplitMarker
+
+ #ifdef GL_ES
+ precision highp float;
+ #endif
+
+ uniform sampler2D noise_sampler;
+ uniform sampler2D iridescence_sampler;
+ uniform samplerCube env_sampler;
+ uniform vec4 thickness_params;
+ uniform bool useCubeMap;
+
+ varying vec4 v_position;
+ varying vec2 v_uv;
+ varying vec2 v_params;
+ varying vec3 v_reflected;
+
+ void main() {
+ // Noise: remap [0.. 1] to [-0.5, -.5]
+ float noise = (texture2D(noise_sampler, v_uv).x - 0.5);
+ float thickness = v_params.y - noise * thickness_params.z;
+ float cos_i = v_params.x;
+
+ // Modulate iridescence color by the environment looked up along the
+ // reflected ray.
+ vec4 color = texture2D(iridescence_sampler, vec2(cos_i, thickness));
+ if (useCubeMap) {
+ color.xyz *= textureCube(env_sampler, v_reflected).xyz;
+ }
+
+ // Modulate by per-face attenuation
+ color.rgb *= thickness_params.w;
+ gl_FragColor = color;
+ }
+ </textarea>
+</body>
+</html>
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/css/style.css b/o3d/samples/o3d-webgl-samples/bubbles/css/style.css
new file mode 100644
index 0000000..b6f0efa
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/css/style.css
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: #000;
+}
+
+body, b, a, td, p {
+ font-family: Verdana, Arial, Tahoma, sans-serif;
+ font-size: 8pt;
+}
+
+#o3d {
+ height: 100%;
+ width: 100%;
+}
+
+p {
+ margin: 5px 0;
+}
+
+/** Parent to all the option divs. **/
+#controls {
+ left: 30%;
+ margin: 30px auto;
+ min-width: 50%;
+ position: absolute;
+ top: 0;
+}
+
+#controls > div {
+ display: none;
+}
+
+/** Applies to all the options divs. **/
+.option {
+ background-color: rgba(0, 0, 0, 0.8);
+ border-radius: 10px;
+ -moz-border-radius: 10px;
+ margin: 10px;
+ padding: 20px;
+}
+
+.slider-set {
+ padding: 15px;
+}
+
+.slider-set span {
+ color: #FFF;
+ font-size: 10pt;
+}
+
+.slider-set .value {
+ color: #F5CA84;
+ float: right;
+ font-weight: bold;
+ font-size: 14pt;
+}
+
+/** Closes an option block. **/
+a.closer {
+ color: #FFF;
+ display: block;
+ margin-top: 15px;
+}
+
+.slider-wrap {
+ margin-top: 15px;
+}
+
+/** Floating box on the top left **/
+#floatControls {
+ background-color: rgba(255, 255, 255, 0.5);
+ border-radius: 10px;
+ -moz-border-radius: 10px;
+ left: 15px;
+ padding: 10px;
+ position: absolute;
+ top: 15px;
+ width: 25%;
+ z-index: 1;
+}
+
+/** Space out the environment maps a little. */
+#tex-environment img {
+ margin: 15px 10px;
+}
+
+#tex-environment p {
+ color: #F5CA84;
+ font-size: 14pt;
+ font-weight: bold;
+}
+
+/** Toggle environment map link. */
+#tex-environment a#toggle-env {
+ color: #FFF;
+ font-size: 14pt;
+ padding: 4px;
+ text-decoration: none;
+}
+
+#tex-environment a#toggle-env:hover {
+ color: #666;
+}
+
+ul {
+ list-style-type: none;
+}
+
+li {
+ margin-top: 5px;
+}
+
+#bg-red {
+ background-color: rgb(255, 200, 200);
+}
+
+#bg-green {
+ background-color: rgb(200, 255, 200);
+}
+
+#bg-blue {
+ background-color: rgb(200, 200, 255);
+}
+
+#loading {
+ color: red;
+ font-size: 18pt;
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negx.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negx.png
new file mode 100644
index 0000000..3dabb64
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negx.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negy.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negy.png
new file mode 100644
index 0000000..9fdc1ff
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negy.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negz.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negz.png
new file mode 100644
index 0000000..5e71d3e
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/negz.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posx.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posx.png
new file mode 100644
index 0000000..ddf4afc
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posx.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posy.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posy.png
new file mode 100644
index 0000000..b46330d
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posy.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posz.png b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posz.png
new file mode 100644
index 0000000..0efd837
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/cubemap/posz.png
Binary files differ
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/bubbledemo.js b/o3d/samples/o3d-webgl-samples/bubbles/js/bubbledemo.js
new file mode 100644
index 0000000..6cde798
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/bubbledemo.js
@@ -0,0 +1,583 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+/**
+ * A namespace to contain all the BubbleShader related methods and functions.
+ */
+var bsh = bsh || {};
+
+/**
+ * Define pi globally.
+ * @type {number}
+ */
+var kPi = 3.14159265359;
+
+/**
+ * Generates a random number between min and max.
+ * @param {number} min
+ * @param {number} max
+ * @return {number}
+ */
+function randf(min, max) {
+ return min + (Math.random() * (max - min));
+}
+
+/**
+ * Clamps a decimal value to [0, 1] and then converts it to range [0, 255].
+ * @param {number} x Input value.
+ * @return {number}
+ */
+bsh.clamp = function(x) {
+ x = Math.min(1.0, Math.max(0.0, x));
+ return Math.floor(x * 255.0);
+}
+
+/**
+ * Applies a cubic Hermite interpolation: x^2 * (3 - 2x)
+ * @param {number} x
+ * @return {number}
+ */
+bsh.smoothStep = function(x) {
+ return (3.0 - (2.0 * x)) * x * x;
+}
+
+/**
+ * Does a linear interpolation between a and b at time t.
+ * @param {number} t
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+bsh.lerp = function(t, a, b) {
+ return a + ((b - a) * t);
+}
+
+/**
+ * Samples a canvas at the given (u, v) coordinates and returns the red value
+ * of that pixel as a float in range [0, 1]. Wraps the texture coordinates (u,v)
+ * if they exceed the range [0, 1].
+ * @param {Canvas} canvas The canvas to sample from.
+ * @param {number} u The u texture coordinate.
+ * @param {number} v The v texture coordinate.
+ */
+bsh.Sample = function(canvas, u, v) {
+ var width = canvas.width;
+ var height = canvas.height;
+ var x = Math.floor((u % 1.0) * width);
+ var y = Math.floor((v % 1.0) * height);
+ var pixel = canvas.getContext('2d').getImageData(x, y, 1, 1);
+ return pixel.data[0] / 255; // Return the red value of the pixel in [0, 1].
+}
+
+/**
+ * Computes the vertices and indices for a sphere shape. The vertices and
+ * indices array will be overwritten with the computed values. Assumes that all
+ * bubbles share the same sphere shape.
+ *
+ * @param {number} rows Number of rows to subdivide the sphere in to.
+ * @param {number} cols Number of cols to subdivide the sphere in to.
+ * @param {Canvas} canvas A canvas to sample modulation from.
+ * @param {!Array.<Object>} vertices Array of vertices (as objects).
+ * @param {!Array.<number>} indices The index buffer array for the triangles.
+ */
+bsh.MakeSphereCoordinates = function(rows, cols, canvas, vertices, indices) {
+ var counter = 0;
+ for (var y = 0; y < rows + 1; ++y) {
+ var phi = y * kPi / rows;
+ var y1 = Math.cos(phi);
+ var r = Math.sin(phi);
+ for (var x = 0; x < cols + 1; ++x) {
+ var theta = x * 2.0 * kPi / cols;
+ var x1 = Math.cos(theta) * r;
+ var z1 = Math.sin(theta) * r;
+ var index = x + y * (cols + 1);
+ var vertex = {};
+ vertices.push(vertex);
+ vertex.x = x1;
+ vertex.y = y1;
+ vertex.z = z1;
+ vertex.nx = x1;
+ vertex.ny = y1;
+ vertex.nz = z1;
+ vertex.u = x * 1.0 / cols;
+ vertex.v = y * 1.0 / rows;
+ vertex.mod = bsh.Sample(canvas, vertex.u, vertex.v);
+
+ if (x != cols && y != rows) {
+ // For each vertex, we add indices for 2 triangles representing the
+ // quad using this vertex as the upper left corner:
+ // [(x, y), (x+1, y), (x+1, y+1)] and
+ // [(x, y), (x+1, y+1), (x, y+1)].
+ // Note that we don't create triangles for the last row and the last
+ // column of vertices.
+ indices[counter++] = index;
+ indices[counter++] = index + 1;
+ indices[counter++] = index + cols + 2;
+ indices[counter++] = index;
+ indices[counter++] = index + cols + 2;
+ indices[counter++] = index + cols + 1;
+ }
+ }
+ }
+}
+
+/**
+ * Globals values.
+ * @type {Object}
+ */
+bsh.Globals = {
+ kRows: 50,
+ kCols: 100,
+ kTexWidth: 512,
+ kTexHeight: 512,
+ kRefractionIndex: 1.33,
+ kBubbleCount: 10,
+ kRedWavelength: 680,
+ kGreenWavelength: 530,
+ kBlueWavelength: 440,
+ kMaxWavelength: 680,
+ kFrequency: 8,
+ kNoiseRatio: [0.2, 0.5],
+ kBubbleThickness: [0.3, 0.6],
+ kBubbleScale: [0.5, 2.0],
+ kBubbleSpin: 0.05,
+ kNumBlips: 4,
+ kBlipSize: [150, 200],
+ kBlipDistortion: 0.25,
+ kMaxBlips: 15
+};
+
+/**
+ * An instance of the demo.
+ * @param {string} shaderString The bubble's shader string.
+ */
+var BubbleDemo = function(shaderString) {
+ this.indices_ = [];
+ this.vertices_ = [];
+
+ var g = bsh.Globals;
+
+ // Make the modulation canvas before making sphere coordinates.
+ this.mod_source = new bsh.Modulation(g.kTexWidth, g.kTexHeight, g.kBlipSize,
+ g.kNumBlips);
+
+ bsh.MakeSphereCoordinates(g.kRows, g.kCols, this.mod_source.canvas,
+ this.vertices_, this.indices_);
+
+ var effect = g_pack.createObject('Effect');
+ var material = g_pack.createObject('Material');
+ effect.loadFromFXString(shaderString);
+ material.drawList = g_viewInfo.performanceDrawList;
+ material.effect = effect;
+ effect.createUniformParameters(material);
+
+ material.getParam("noise_sampler").value = this.MakeNoiseTexture_();
+ material.getParam("iridescence_sampler").value =
+ this.MakeIridescenceTexture_();
+ material.getParam("env_sampler").value = this.MakeCubeMap_();
+ material.getParam("eye").bind(g_eyeParam);
+ material.getParam("timer").bind(g_clock);
+ material.getParam("useCubeMap").bind(g_useCubeMap);
+ material.getParam("distortion").bind(g_blipDistortion);
+
+ this.shape = this.makeShape_(material);
+ this.bubbles_ = [];
+ this.regenerateBubbles();
+}
+
+/**
+ * Creates the perlin noise texture.
+ * @return {o3d.Sampler}
+ * @private
+ */
+BubbleDemo.prototype.MakeNoiseTexture_ = function() {
+ var g = bsh.Globals;
+ this.noise_source = new bsh.Perlin(g.kFrequency,
+ 98576, // This is supposed to be a random \cough seed.
+ g.kTexWidth,
+ g.kTexHeight);
+ this.noise_texture = g_pack.createTexture2D(g.kTexWidth,
+ g.kTexHeight,
+ g_o3d.Texture.ARGB8,
+ 1,
+ false);
+ this.noise_source.refresh(this.noise_texture);
+ var noise_sampler = g_pack.createObject('Sampler');
+ noise_sampler.name = "noise";
+ noise_sampler.addressModeU = g_o3d.Sampler.WRAP;
+ noise_sampler.addressModeV = g_o3d.Sampler.WRAP;
+ noise_sampler.addressModeW = g_o3d.Sampler.WRAP;
+ noise_sampler.magFilter = g_o3d.Sampler.LINEAR;
+ noise_sampler.minFilter = g_o3d.Sampler.LINEAR;
+ noise_sampler.mipFilter = g_o3d.Sampler.NONE;
+ noise_sampler.maxAnisotropy = 1;
+ noise_sampler.texture = this.noise_texture;
+ return noise_sampler;
+}
+
+/**
+ * Creates the iridescence texture.
+ * @return {o3d.Sampler}
+ * @private
+ */
+BubbleDemo.prototype.MakeIridescenceTexture_ = function() {
+ var g = bsh.Globals;
+ this.iridescence_source = new bsh.Iridescence(g.kTexWidth,
+ g.kTexHeight,
+ g.kRefractionIndex,
+ g.kMaxWavelength);
+ this.iridescence_texture = g_pack.createTexture2D(g.kTexWidth,
+ g.kTexHeight,
+ g_o3d.Texture.ARGB8,
+ 1,
+ false);
+ this.iridescence_source.refresh(this.iridescence_texture);
+ var iri_sampler = g_pack.createObject('Sampler');
+ iri_sampler.name = "iridescence";
+ iri_sampler.addressModeU = g_o3d.Sampler.CLAMP;
+ iri_sampler.addressModeV = g_o3d.Sampler.CLAMP;
+ iri_sampler.addressModeW = g_o3d.Sampler.CLAMP;
+ iri_sampler.magFilter = g_o3d.Sampler.LINEAR;
+ iri_sampler.minFilter = g_o3d.Sampler.LINEAR;
+ iri_sampler.mipFilter = g_o3d.Sampler.NONE;
+ iri_sampler.maxAnisotropy = 1;
+ iri_sampler.texture = this.iridescence_texture;
+ return iri_sampler;
+}
+
+
+/**
+ * Creates a cube/environment map.
+ * @return {o3d.TextureCUBE}
+ * @private
+ */
+BubbleDemo.prototype.MakeCubeMap_ = function() {
+ this.env_source = new bsh.Environment($("#tex-environment img"));
+ return this.env_source.texture;
+}
+
+
+/**
+ * A list of indices used to create geometry.
+ * @type {!Array.<number>}
+ * @private
+ */
+BubbleDemo.prototype.indices_ = [];
+
+/**
+ * A list of vertices used to create geometry.
+ * @type {!Array.<number>}
+ * @private
+ */
+BubbleDemo.prototype.vertices_ = [];
+
+/**
+ * The noise texture source.
+ * @type {bsh.Perlin}
+ */
+BubbleDemo.prototype.noise_source = null;
+
+/**
+ * The noise texture object.
+ * @type {o3d.Texture}
+ */
+BubbleDemo.prototype.noise_texture = null;
+
+/**
+ * The iridescence texture source.
+ * @type {bsh.Iridescence}
+ */
+BubbleDemo.prototype.iridescence_source = null;
+
+/**
+ * The iridescence texture object.
+ * @type {o3d.Texture}
+ */
+BubbleDemo.prototype.iridescence_texture = null;
+
+/**
+ * The modulation texture source.
+ * @type {bsh.Modulation}
+ */
+BubbleDemo.prototype.mod_source = null;
+
+/**
+ * The environment map source.
+ * @type {bsh.Environment}
+ */
+BubbleDemo.prototype.env_source = null;
+
+/**
+ * A list of bubbles in the demo.
+ * @type {!Array.<Object>}
+ */
+BubbleDemo.prototype.bubbles_ = [];
+
+/**
+ * The shape object shared by all bubble instances.
+ * @type {o3d.Shape}
+ */
+BubbleDemo.prototype.shape = null;
+
+/**
+ * The streambank backing the shape primitive.
+ * @type {o3d.StreamBank}
+ */
+BubbleDemo.prototype.streamBank = null;
+
+
+/**
+ * Updates the iridescence texture using the latest global parameters.
+ */
+BubbleDemo.prototype.regenerateIridescence = function() {
+ var g = bsh.Globals;
+ this.iridescence_source.init(g.kRefractionIndex, g.kMaxWavelength);
+ this.iridescence_source.refresh(this.iridescence_texture);
+}
+
+/**
+ * Updates the noise texture using the latest global parameters.
+ */
+BubbleDemo.prototype.regenerateNoise = function() {
+ var g = bsh.Globals;
+ var seed = Math.floor(new Date().getTime() % 100000);
+ this.noise_source.init(g.kFrequency, seed);
+ this.noise_source.refresh(this.noise_texture);
+}
+
+/**
+ * Updates the modulation vertex stream using the latest global parameters.
+ */
+BubbleDemo.prototype.regenerateModulation = function() {
+ var g = bsh.Globals;
+ this.mod_source.init(g.kBlipSize, g.kNumBlips);
+
+ // Update the stream to sample from the new texture.
+ var modulationStream =
+ this.streamBank.getVertexStream(g_o3d.Stream.TEXCOORD, 1);
+ var newModulationCoords = [];
+ for (var i = 0; i < this.vertices_.length; ++i) {
+ var vertex = this.vertices_[i];
+ var value = bsh.Sample(this.mod_source.canvas, vertex.u, vertex.v);
+ vertex.mod = value;
+ newModulationCoords.push(value);
+ }
+ modulationStream.field.setAt(0, newModulationCoords);
+}
+
+/**
+ * Updates the set of bubbles to use the latest global parameters.
+ */
+BubbleDemo.prototype.regenerateBubbles = function() {
+ var g = bsh.Globals;
+ var i = 0;
+
+ // Update existing bubbles and create new ones if necessary.
+ for (i = 0; i < g.kBubbleCount; ++i) {
+ var bubble = this.bubbles_[i] || {};
+ bubble.position = [randf(-6, 6), randf(-6, 6), randf(-6, 6)];
+ bubble.rotation_speed = [randf(-g.kBubbleSpin, g.kBubbleSpin),
+ randf(-g.kBubbleSpin, g.kBubbleSpin),
+ randf(-g.kBubbleSpin, g.kBubbleSpin)];
+ bubble.scale = randf(g.kBubbleScale[0], g.kBubbleScale[1]);
+
+ var max_thickness = randf(g.kBubbleThickness[0], g.kBubbleThickness[1]);
+ var min_thickness = randf(g.kBubbleThickness[0], max_thickness);
+
+ // thickness = base * e^(-y*falloff) for y in [-scale..scale].
+ bubble.thickness_falloff =
+ Math.log(max_thickness / min_thickness) / (2 * bubble.scale);
+ bubble.base_thickness =
+ max_thickness * Math.exp(-bubble.scale * bubble.thickness_falloff);
+ bubble.noise_ratio = randf(g.kNoiseRatio[0], g.kNoiseRatio[1]);
+
+ if (!bubble.transform) {
+ // The parent transform for this one bubble.
+ bubble.transform = g_pack.createObject("Transform");
+ bubble.transform.name = "Bubble" + i;
+
+ // One child transform for the back faces.
+ bubble.back = g_pack.createObject("Transform");
+ bubble.back.createParam('thickness_params', 'ParamFloat4');
+ bubble.back.parent = bubble.transform;
+ bubble.back.addShape(this.shape);
+ bubble.back.state = g_pack.createObject('State');
+ bubble.back.state.getStateParam('FillMode').value = g_o3d.State.SOLID;
+ bubble.back.state.getStateParam('CullMode').value = g_o3d.State.CULL_CW;
+
+ // And another child for the front faces.
+ bubble.front = g_pack.createObject("Transform");
+ bubble.front.createParam('thickness_params', 'ParamFloat4');
+ bubble.front.parent = bubble.transform;
+ bubble.front.addShape(this.shape);
+ bubble.front.state = g_pack.createObject('State');
+ bubble.front.state.getStateParam('FillMode').value = g_o3d.State.SOLID;
+ bubble.front.state.getStateParam('CullMode').value = g_o3d.State.CULL_CCW;
+
+ // This adds a little modulation so that the bubbles grow/shrink at
+ // different rates and times.
+ var bNumber = kPi * i * 0.5;
+ bubble.back.createParam('bubbleNumber', 'ParamFloat').value = bNumber;
+ bubble.front.createParam('bubbleNumber', 'ParamFloat').value = bNumber;
+ }
+
+ bubble.transform.visible = true;
+ this.bubbles_[i] = bubble;
+ this.updateParams_(bubble);
+ }
+
+ // Hide the rest of the bubbles.
+ for (i; i < this.bubbles_.length; ++i) {
+ this.bubbles_[i].transform.visible = false;
+ }
+}
+
+/**
+ * Updates the uniform parameters for a bubble.
+ * @param {Object} bubble
+ * @private
+ */
+BubbleDemo.prototype.updateParams_ = function(bubble) {
+ bubble.back.getParam('thickness_params').value =
+ [bubble.thickness_falloff, bubble.base_thickness, bubble.noise_ratio, 0.5];
+ bubble.front.getParam('thickness_params').value =
+ [bubble.thickness_falloff, bubble.base_thickness, bubble.noise_ratio, 1.0];
+}
+
+/**
+ * Creates a bubble shape that uses the material. Also sets the streambank
+ * variable to the bank that was used for the primitive that was created.
+ *
+ * @param {o3d.Material} material
+ * @return {o3d.Shape}
+ * @private
+ */
+BubbleDemo.prototype.makeShape_ = function(material) {
+ var shape = g_pack.createObject('Shape');
+ var shapePrimitive = g_pack.createObject('Primitive');
+ var streamBank = g_pack.createObject('StreamBank');
+
+ shapePrimitive.material = material;
+ shapePrimitive.owner = shape;
+ shapePrimitive.streamBank = this.streamBank = streamBank;
+
+ var g = bsh.Globals;
+ shapePrimitive.primitiveType = g_o3d.Primitive.TRIANGLELIST;
+ shapePrimitive.numberPrimitives = this.indices_.length / 3;
+ shapePrimitive.numberVertices = this.vertices_.length;
+ shapePrimitive.createDrawElement(g_pack, null);
+
+ var positionArray = [];
+ var normalArray = [];
+ var uvArray = [];
+ var modulationArray = [];
+
+ for (var i = 0; i < this.vertices_.length; ++i) {
+ var vertex = this.vertices_[i];
+ positionArray.push(vertex.x, vertex.y, vertex.z);
+ normalArray.push(vertex.nx, vertex.ny, vertex.nz);
+ uvArray.push(vertex.u, vertex.v);
+ modulationArray.push(vertex.mod);
+ }
+
+ var indicesArray = this.indices_;
+
+ // Create buffers containing the vertex data.
+ var positionsBuffer = g_pack.createObject('VertexBuffer');
+ var positionsField = positionsBuffer.createField('FloatField', 3);
+ positionsBuffer.set(positionArray);
+
+ var texCoordsBuffer = g_pack.createObject('VertexBuffer');
+ var texCoordsField = texCoordsBuffer.createField('FloatField', 2);
+ texCoordsBuffer.set(uvArray);
+
+ var modulationBuffer = g_pack.createObject('VertexBuffer');
+ var modulationField = modulationBuffer.createField('FloatField', 1);
+ modulationBuffer.set(modulationArray);
+
+ var normalBuffer = g_pack.createObject('VertexBuffer');
+ var normalField = normalBuffer.createField('FloatField', 3);
+ normalBuffer.set(normalArray);
+
+ var indexBuffer = g_pack.createObject('IndexBuffer');
+ indexBuffer.set(indicesArray);
+
+ // Add buffers to the StreamBank.
+ streamBank.setVertexStream(
+ g_o3d.Stream.POSITION,
+ 0,
+ positionsField,
+ 0);
+ streamBank.setVertexStream(
+ g_o3d.Stream.TEXCOORD,
+ 0,
+ texCoordsField,
+ 0);
+ streamBank.setVertexStream(
+ g_o3d.Stream.TEXCOORD,
+ 1,
+ modulationField,
+ 0);
+ streamBank.setVertexStream(
+ g_o3d.Stream.NORMAL,
+ 0,
+ normalField,
+ 0);
+ shapePrimitive.indexBuffer = indexBuffer;
+ return shape;
+}
+
+/**
+ * Updates all the bubbles managed by this demo object.
+ */
+BubbleDemo.prototype.update = function() {
+ for (var i = 0; i < this.bubbles_.length; ++i) {
+ this.updateBubble_(this.bubbles_[i]);
+ }
+}
+
+/**
+ * Updates the position and scale of a single bubble.
+ * @param {Object} bubble
+ * @private
+ */
+BubbleDemo.prototype.updateBubble_ = function(bubble) {
+ if (!bubble.transform.parent) {
+ bubble.transform.parent = g_dataroot;
+ }
+ bubble.transform.identity();
+ var rotation = bubble.rotation_speed;
+ bubble.transform.rotateX(rotation[0] * 2 * kPi * g_clock.value);
+ bubble.transform.rotateY(rotation[1] * 2 * kPi * g_clock.value);
+ bubble.transform.rotateZ(rotation[2] * 2 * kPi * g_clock.value);
+ bubble.transform.scale(bubble.scale, bubble.scale, bubble.scale);
+ bubble.transform.translate(bubble.position);
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/controls.js b/o3d/samples/o3d-webgl-samples/bubbles/js/controls.js
new file mode 100644
index 0000000..22d3bf8
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/controls.js
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+/**
+ * Creates a jQuery UI Slider and stores associated options and callbacks.
+ * @param {Object} options Options for the slider. See jQuery documentation.
+ * @param {function} cb Callback to run when value is changed.
+ */
+var SliderSet = function(options, cb) {
+ this.parent = $('<div class="slider-set"></div>');
+
+ // Span for the title of this option.
+ this.parent.append('<span>' + options.name + '</span>');
+
+ // Span for the value of this option.
+ this.valueWrite = $('<span class="value"></span>');
+ this.parent.append(this.valueWrite);
+
+ // Make the slider.
+ var slider = $('<div></div>');
+ var that = this;
+ options.slide = function(ev, ui) {
+ that.updateValue(ui.values ? ui.values : ui.value);
+ };
+ options.stop = function(ev, ui) {
+ cb(ui.values ? ui.values : ui.value);
+ }
+ slider.slider(options);
+
+ // Wrap slider in div and append to parent.
+ var sliderWrapper = $('<div class="slider-wrap" />');
+ sliderWrapper.append(slider);
+ this.parent.append(sliderWrapper);
+}
+
+/**
+ * The parent div of this particular option set.
+ * @type {DOMElement}
+ */
+SliderSet.prototype.parent = null;
+
+/**
+ * Container the displays the current value of the slider.
+ * @type {DOMElement}
+ */
+SliderSet.prototype.valueWrite = null;
+
+
+/**
+ * Updates the value being shown to the user.
+ * @param {Number|!Array.<number>} values The value(s) of the slider.
+ */
+SliderSet.prototype.updateValue = function(values) {
+ var print = '';
+ if (values.length) { // is Array
+ print = 'Range: ' + values[0] + ' to ' + values[1];
+ } else {
+ print = values + '';
+ }
+ this.valueWrite.html(print);
+}
+
+
+/**
+ * Creates and appends the controls.
+ */
+function buildControls() {
+ var bubblePanel = $("#opt-bubble");
+ var iridescencePanel = $("#tex-iridescence");
+ var noisePanel = $("#tex-perlin");
+ var modPanel = $("#tex-modulation")
+ var g = bsh.Globals;
+
+ var sliders = [
+ { name: 'Number of Bubbles',
+ min: 1,
+ max: 15,
+ value: g.kBubbleCount,
+ step: 1,
+ range: false,
+ parent: bubblePanel,
+ cb: function(values) {
+ bsh.Globals.kBubbleCount = values;
+ g_demo.regenerateBubbles();
+ }
+ },
+ { name: 'Bubble Size',
+ min: 0.3,
+ max: 2.5,
+ step: 0.2,
+ values: g.kBubbleScale,
+ range: true,
+ parent: bubblePanel,
+ cb: function(values) {
+ bsh.Globals.kBubbleScale = values;
+ g_demo.regenerateBubbles();
+ }
+ },
+ { name: 'Bubble Thickness',
+ min: 0.1,
+ max: 1.0,
+ step: 0.1,
+ values: g.kBubbleThickness,
+ range: true,
+ parent: bubblePanel,
+ cb: function(values) {
+ bsh.Globals.kBubbleThickness = values;
+ g_demo.regenerateBubbles();
+ }
+ },
+ { name: 'Bubble Movement',
+ min: 0,
+ max: 0.2,
+ step: 0.01,
+ value: g.kBubbleSpin,
+ range: false,
+ parent: bubblePanel,
+ cb: function(values) {
+ bsh.Globals.kBubbleSpin = values;
+ g_demo.regenerateBubbles();
+ }
+ },
+ { name: 'Pattern Distortion',
+ min: 0,
+ max: 1.5,
+ step: 0.1,
+ values: g.kNoiseRatio,
+ range: true,
+ parent: bubblePanel,
+ cb: function(values) {
+ bsh.Globals.kNoiseRatio = values;
+ g_demo.regenerateBubbles();
+ }
+ },
+ { name: 'Iridescence Frequency',
+ min: 500,
+ max: 1000,
+ step: 20,
+ value: g.kMaxWavelength,
+ range: false,
+ parent: iridescencePanel,
+ cb: function(values) {
+ bsh.Globals.kMaxWavelength = values;
+ g_demo.regenerateIridescence();
+ }
+ },
+ { name: 'Iridescence Refraction Index',
+ min: 1,
+ max: 2,
+ step: 0.01,
+ value: g.kRefractionIndex,
+ range: false,
+ parent: iridescencePanel,
+ cb: function(values) {
+ bsh.Globals.kRefractionIndex = values;
+ g_demo.regenerateIridescence();
+ }
+ },
+ { name: 'Noise Frequency',
+ min: 4,
+ max: 12,
+ step: 1,
+ value: g.kFrequency,
+ range: false,
+ parent: noisePanel,
+ cb: function(values) {
+ bsh.Globals.kFrequency = values;
+ g_demo.regenerateNoise();
+ }
+ },
+ { name: 'Blip Size',
+ min: 50,
+ max: 400,
+ step: 25,
+ values: g.kBlipSize,
+ range: true,
+ parent: modPanel,
+ cb: function(values) {
+ bsh.Globals.kBlipSize = values;
+ g_demo.regenerateModulation();
+ }
+ },
+ { name: 'Number of Blips',
+ min: 0,
+ max: g.kMaxBlips,
+ step: 1,
+ value: g.kNumBlips,
+ range: false,
+ parent: modPanel,
+ cb: function(values) {
+ bsh.Globals.kNumBlips = values;
+ g_demo.regenerateModulation();
+ }
+ },
+ { name: 'Distortion Factor',
+ min: 0,
+ max: 1,
+ step: 0.05,
+ value: g.kBlipDistortion,
+ range: false,
+ parent: modPanel,
+ cb: function(values) {
+ g_blipDistortion.value = values;
+ }
+ }
+ ];
+
+ // Append textures to their divs.
+ $("#tex-iridescence").prepend(g_demo.iridescence_source.canvas);
+ $("#tex-perlin").prepend(g_demo.noise_source.canvas);
+ $("#tex-modulation").prepend(g_demo.mod_source.canvas);
+
+ // Make the sliders.
+ for (var i = 0; i < sliders.length; i++) {
+ var specs = sliders[i];
+ var s = new SliderSet(specs, specs.cb);
+ specs.parent.prepend(s.parent);
+ s.updateValue(specs.value ? specs.value : specs.values);
+ }
+
+ // Add event listeners to specific links.
+ $("#toggle-env").click(function() {
+ g_useCubeMap.value = !g_useCubeMap.value;
+ if (g_useCubeMap.value) {
+ $(this).html("On. Turn off?");
+ } else {
+ $(this).html("Off. Turn on?");
+ }
+ return false;
+ });
+
+ $(".closer").each(function(i) {
+ var index = i;
+ $(this).click(function() {
+ $(this).parent().slideUp();
+ var checkboxes = $("input[type=checkbox]");
+ $(checkboxes[index]).attr("checked", false);
+ return false;
+ });
+ });
+
+ // 'q' closes all the open panels.
+ window.document.onkeypress = function(e) {
+ event = event || window.event;
+ if (event.metaKey)
+ return;
+ var keyChar = String.fromCharCode(o3djs.event.getEventKeyChar(event));
+ keyChar = keyChar.toLowerCase();
+ if (keyChar == 'q') {
+ hideAll();
+ }
+ };
+}
+
+/**
+ * Hides any open option panels.
+ */
+function hideAll() {
+ $(".closer").click();
+}
+
+/**
+ * Toggles which option panel is being shown.
+ * @param {number} type Index of the associated option panel in #controls.
+ * @param {DOMElement} checkbox The checkbox element.
+ */
+function toggle(type, checkbox) {
+ var options = $("#controls").children();
+
+ if (! $(checkbox).attr('checked')) {
+ $(options[type]).slideUp();
+ } else {
+ var target = $(options[type]);
+ if (target.css("display") == "block") {
+ return; // Already showing.
+ }
+ $("#controls").children().slideUp();
+ target.slideDown();
+ $("#floatControls input").each(function(i) {
+ if (i != type) {
+ $(this).attr("checked", false);
+ }
+ });
+ }
+}
+
+/**
+ * Changes the background color of the o3d container based on the current values
+ * of the input fields bg-red, bg-green and bg-blue.
+ */
+function updateClearColor() {
+ function to255(a) {
+ a = parseInt(a);
+ if (isNaN(a)) {
+ a = 0;
+ }
+ return Math.max(0, Math.min(255, a));
+ }
+ var red = to255($("#bg-red").val());
+ var green = to255($("#bg-green").val());
+ var blue = to255($("#bg-blue").val());
+ $("#bg-red").val(red);
+ $("#bg-green").val(green);
+ $("#bg-blue").val(blue);
+
+ // Convert back to [0, 1] for o3d.
+ g_viewInfo.clearBuffer.clearColor = [red / 255, green / 255, blue / 255, 1.0];
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/environment.js b/o3d/samples/o3d-webgl-samples/bubbles/js/environment.js
new file mode 100644
index 0000000..773f625
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/environment.js
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+var bsh = bsh || {};
+
+/**
+ * Creates a cubemap texture object given six faces of the cube.
+ * @param {!Array.<HTMLElementImage>} images An array of 6 HTML image elements,
+ * representing the six faces of the cubemap. Should be in X+, X-, Y+, Y-, Z+,
+ * Z- order.
+ * @constructor
+ */
+bsh.Environment = function(images) {
+ if (images.length != 6) {
+ throw 'Expecting six cube map faces.';
+ }
+ var rawDataArray = [];
+ for (var i = 0; i < 6; ++i) {
+ var rawData = g_pack.createObject('RawData');
+ // TODO(luchen): Change this once textureCUBE set() is implemented
+ rawData.image_ = images[i];
+ rawData.width = 64;
+ rawData.height = 64;
+ rawDataArray.push(rawData);
+ }
+ this.texture =
+ o3djs.texture.createTextureFromRawDataArray(g_pack, rawDataArray, true);
+}
+
+/**
+ * The created texture.
+ * @type {o3d.TextureCUBE}
+ */
+bsh.Environment.prototype.texture = null;
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/iridescence.js b/o3d/samples/o3d-webgl-samples/bubbles/js/iridescence.js
new file mode 100644
index 0000000..61eee5b
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/iridescence.js
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+var bsh = bsh || {};
+
+
+/**
+ * Creates a canvas element that contains the interference pattern colors, to
+ * be used as a texture. Once set, the width and height cannot be changed.
+ *
+ * @param {number} width The width of the texture (should be power-of-two).
+ * @param {number} height The height of the texture (should be power-of-two).
+ * @param {number} refraction_index The refraction index of the medium.
+ * @param {number} thickness The thickness of the medium between the interfaces.
+ * @constructor
+ */
+bsh.Iridescence = function(width, height, refraction_index, thickness) {
+ this.canvas = document.createElement('canvas');
+ this.canvas.width = width;
+ this.canvas.height = height;
+ this.init(refraction_index, thickness);
+};
+
+
+/**
+ * The canvas element that is written to.
+ * @type {Canvas}
+ */
+bsh.Iridescence.prototype.canvas = null;
+
+
+/**
+ * Computes the fresnel coefficients for amplitude.
+ * http://physics.tamuk.edu/~suson/html/4323/prop-em.html has them.
+ * @param {number} n
+ * @param {number} cos_i
+ * @param {number} cos_t
+ * @return {Object} object containing reflection and transmitted values.
+ */
+bsh.Iridescence.ComputeFresnel = function(n, cos_i, cos_t) {
+ var coeff = {};
+ coeff.reflected_perp = (cos_i - n*cos_t)/(cos_i + n*cos_t);
+ coeff.transmitted_perp = 2.0*cos_i/(cos_i + n*cos_t);
+ coeff.reflected_para = (n*cos_i - cos_t)/(n*cos_i + cos_t);
+ coeff.transmitted_para = 2.0*cos_i/(n*cos_i + cos_t);
+ return coeff;
+}
+
+
+/**
+ * Uses Snell-Descartes' Law: sin_i = n * sin_t
+ * @param {number} n
+ * @param {number} cos_i
+ * @return {number}
+ */
+bsh.Iridescence.RefractedRay = function(n, cos_i) {
+ var sin2_i = 1 - cos_i * cos_i;
+ var sin2_t = sin2_i / (n*n);
+ var cos2_t = 1 - sin2_t;
+ var cos_t = Math.sqrt(Math.max(0, cos2_t));
+ return cos_t;
+}
+
+
+/**
+ * Understanding the notations in the following two functions.
+ *
+ * \ A \ A' / B i = incident angle.
+ * incident ray \ \ / t = transmitted angle.
+ * \ i| \ i|i /
+ * \| \|/ air (n = 1) outside the bubble
+ * -outer-interface----P---------R---------------------------------------
+ * |\ /| ^
+ * |t\ /t| |thin layer (e.g. water, n > 1)
+ * transmitted ray \t|t/ |thickness
+ * \|/ v
+ * -inner-interface---------Q--------------------------------------------
+ * |\ air (n = 1) inside the bubble
+ * |i \
+ * \ C
+ *
+ * Incident ray A gets refracted by the outer interface at point P, then
+ * reflected by the inner interface at point Q, then refracted into B at point
+ * R ("trt" ray). At the same time, incident ray A', coherent with A, gets
+ * directly reflected into B ("r" ray) at point R, so it interferes with the
+ * "trt" ray.
+ * At point Q the ray also gets refracted inside the bubble, leading to the
+ * "tt" ray C.
+ */
+
+/**
+ * Computes the interference between the reflected ray ('r' - one reflection
+ * one the outer interface) and the reflection of the transmitted ray ('trt' -
+ * transmitted through the outer interface, reflected on the inner interface,
+ * then transmitted again through the outer interface).
+ * @param {number} thickness The thickness of the medium between the interfaces.
+ * @param {number} wavelength The wavelength of the incident light.
+ * @param {number} n The refraction index of the medium (relative to the outer
+ * medium).
+ * @param {number} r_perp The amplitude coefficient for the r ray for
+ * perpendicular polarization.
+ * @param {number} r_para The amplitude coefficient for the r ray for parallel
+ * polarization.
+ * @param {number} trt_perp The amplitude coefficient for the trt ray for
+ * perpendicular polarization.
+ * @param {number} trt_para The amplitude coefficient for the trt ray for
+ * parallel polarization.
+ * @param {number} cos_t The cosine of the refracted angle.
+ * @return {number} The reflected power after interference.
+ */
+bsh.Iridescence.Interference = function(thickness,
+ wavelength,
+ n,
+ r_perp,
+ r_para,
+ trt_perp,
+ trt_para,
+ cos_t) {
+ // Difference in wave propagation between the trt ray and the r ray.
+ var delta_phase = 2.0 * thickness/wavelength * n * cos_t;
+ // For a given polarization, power = ||r + trt * e^(i*2*pi*delta_phase)||^2
+ var cos_delta = Math.cos(2.0 * kPi * delta_phase);
+ var power_perp =
+ r_perp*r_perp + trt_perp*trt_perp + 2.0 * r_perp*trt_perp*cos_delta;
+ var power_para =
+ r_para*r_para + trt_para*trt_para + 2.0 * r_para*trt_para*cos_delta;
+ // Total power is the average between 2 polarization modes (for non-polarized
+ // light).
+ return (power_perp+power_para)/2.0;
+}
+
+
+/**
+ * Regenerates and writes iridescence map to the canvas element.
+ * @param {number} refraction_index The refraction index of the medium.
+ * @param {number} thickness The thickness of the medium between the interfaces.
+ */
+bsh.Iridescence.prototype.init = function(refraction_index, thickness) {
+ var kRedWavelength = bsh.Globals.kRedWavelength;
+ var kGreenWavelength = bsh.Globals.kGreenWavelength;
+ var kBlueWavelength = bsh.Globals.kBlueWavelength;
+ var width = this.canvas.width;
+ var height = this.canvas.height;
+ var n = refraction_index;
+ var max_thickness = thickness * 1.5;
+ var ctx = this.canvas.getContext('2d');
+
+ var counter = 0;
+ var imageData = ctx.getImageData(0, 0, width, height);
+ for (var y = 0; y < height; ++y) {
+ var thickness = (y + .5) * max_thickness / height;
+ for (var x = 0; x < width; ++x) {
+ var cos_i = (x + .5) * 1.0 / width;
+ var cos_t = bsh.Iridescence.RefractedRay(n, cos_i);
+ // Fresnel coefficient for the "outer" interface (outside->inside).
+ var outer = bsh.Iridescence.ComputeFresnel(n, cos_i, cos_t);
+ // Fresnel coefficient for the "inner" interface (inside->outside).
+ var inner = bsh.Iridescence.ComputeFresnel(1.0/n, cos_t, cos_i);
+ var r_perp = outer.reflected_perp;
+ var r_para = outer.reflected_para;
+ var trt_perp = outer.transmitted_perp * inner.reflected_perp *
+ inner.transmitted_perp;
+ var trt_para = outer.transmitted_para * inner.reflected_para *
+ inner.transmitted_para;
+ var red = bsh.Iridescence.Interference(thickness, kRedWavelength, n,
+ r_perp, r_para, trt_perp, trt_para, cos_t);
+ var green = bsh.Iridescence.Interference(thickness, kGreenWavelength, n,
+ r_perp, r_para, trt_perp, trt_para, cos_t);
+ var blue = bsh.Iridescence.Interference(thickness, kBlueWavelength, n,
+ r_perp, r_para, trt_perp, trt_para, cos_t);
+ var tt_perp = outer.transmitted_perp * inner.transmitted_perp;
+ var tt_para = outer.transmitted_para * inner.transmitted_para;
+ var alpha = (tt_perp*tt_perp + tt_para*tt_para)/2.0;
+ imageData.data[counter++] = bsh.clamp(red);
+ imageData.data[counter++] = bsh.clamp(green);
+ imageData.data[counter++] = bsh.clamp(blue);
+ imageData.data[counter++] = bsh.clamp(alpha);
+ }
+ }
+ ctx.putImageData(imageData, 0, 0);
+}
+
+
+/**
+ * Copies the data from the canvas into the texture.
+ * @param {o3d.Texture} texture The texture to write to. Should be same size.
+ */
+bsh.Iridescence.prototype.refresh = function(texture) {
+ var data = this.canvas.getContext('2d').getImageData(0, 0, this.canvas.width,
+ this.canvas.height).data;
+ var pixels = [];
+ for (var i = 0; i < data.length; ++i) {
+ pixels[i] = data[i] / 255.0;
+ }
+ texture.set(0, pixels);
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/main.js b/o3d/samples/o3d-webgl-samples/bubbles/js/main.js
new file mode 100644
index 0000000..a8fa92f
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/main.js
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+
+o3djs.base.o3d = o3d;
+o3djs.require('o3djs.webgl');
+o3djs.require('o3djs.math');
+o3djs.require('o3djs.rendergraph');
+o3djs.require('o3djs.primitives');
+o3djs.require('o3djs.quaternions');
+o3djs.require('o3djs.arcball');
+
+// Events
+// Run the init() function once the page has finished loading.
+// unload() when the page is unloaded.
+window.onload = init;
+window.onunload = unload;
+
+// Global variables.
+var g_o3d;
+var g_math;
+var g_quaternions;
+var g_client;
+var g_o3dElement;
+var g_viewInfo;
+var g_pack;
+var g_o3dWidth = -1;
+var g_o3dHeight = -1;
+var g_dataroot;
+var g_camera = {};
+var g_aball;
+var g_demo;
+var g_clock = null;
+var g_dragging = false;
+var g_eyeParam;
+var g_controls;
+var g_done = false;
+var g_useCubeMap;
+var g_blipDistortion;
+
+/**
+ * Initializes the o3d clients.
+ */
+function init() {
+ o3djs.webgl.makeClients(initStep2);
+}
+
+
+/**
+ * Initializes O3D and sets up an instance of BubbleDemo.
+ * @param {Array} clientElements Array of o3d object elements.
+ */
+function initStep2(clientElements) {
+ // Initializes global variables and libraries.
+ g_o3dElement = clientElements[0];
+ g_o3d = g_o3dElement.o3d;
+ g_math = o3djs.math;
+ g_client = g_o3dElement.client;
+
+ // Create a g_pack to manage our resources/assets
+ g_pack = g_client.createPack();
+ g_quaternions = o3djs.quaternions;
+
+ // Create the render graph for a view.
+ g_viewInfo = o3djs.rendergraph.createBasicView(
+ g_pack,
+ g_client.root,
+ g_client.renderGraphRoot,
+ [0.93, 0.93, 0.93, 1]
+ );
+
+ // Set the clear color to the default set in the HTML input fields.
+ updateClearColor();
+
+ // Use Z-Sorting to draw bubbles back-to-front.
+ g_viewInfo.performanceDrawPass.sortMethod = g_o3d.DrawList.BY_Z_ORDER;
+
+ // Set some blending states.
+ var state = g_viewInfo.performanceDrawPassInfo.state;
+ state.getStateParam('SourceBlendFunction').value = g_o3d.State.BLENDFUNC_ONE;
+ state.getStateParam('DestinationBlendFunction').value =
+ g_o3d.State.BLENDFUNC_SOURCE_ALPHA;
+ state.getStateParam('BlendEquation').value = g_o3d.State.BLEND_ADD;
+ state.getStateParam('SeparateAlphaBlendEnable').value = false;
+ state.getStateParam('AlphaBlendEnable').value = true;
+
+ // Creates a transform to put our data in.
+ g_dataroot = g_pack.createObject('Transform');
+ g_dataroot.parent = g_client.root;
+
+ // Create some of the uniforms for the shaders.
+ var paramObject = g_pack.createObject('ParamObject');
+ g_eyeParam = paramObject.createParam('eye', 'ParamFloat4');
+ g_camera.target = [0, 0, 0];
+ g_camera.eye = [0, 0, 5];
+ updateCamera();
+ // Create a timer/clock.
+ g_clock = paramObject.createParam('timer', 'ParamFloat');
+ g_clock.value = 0;
+ // Use the environment map?
+ g_useCubeMap = paramObject.createParam('useCubeMap', 'ParamBoolean');
+ g_useCubeMap.value = true;
+ // Number, location and overall effect of the modulation map.
+ g_blipDistortion = paramObject.createParam('distortion', 'ParamFloat');
+ g_blipDistortion.value = bsh.Globals.kBlipDistortion;
+
+ // Create an arcball for scene rotations.
+ g_lastRot = g_math.matrix4.identity();
+ g_thisRot = g_math.matrix4.identity();
+ g_aball = o3djs.arcball.create(100, 100);
+ setClientSize();
+
+ // Create the demo - all the geometry and shaders get set up here.
+ var shaderString = document.getElementById('shader').value;
+ g_demo = new BubbleDemo(shaderString);
+ buildControls();
+
+ // Add event listeners.
+ o3djs.event.addEventListener(g_o3dElement, 'mousedown', startDragging);
+ o3djs.event.addEventListener(g_o3dElement, 'mousemove', drag);
+ o3djs.event.addEventListener(g_o3dElement, 'mouseup', stopDragging);
+ o3djs.event.addEventListener(g_o3dElement, 'wheel', scrollMe);
+
+ g_client.setRenderCallback(onRender);
+}
+
+
+/**
+ * Generates the projection matrix based on the size of the o3d plugin
+ * and calculates the view-projection matrix.
+ */
+function onRender(event) {
+ g_clock.value += (event.elapsedTime);
+ g_demo.update();
+ setClientSize();
+ if (!g_done) {
+ g_done = true;
+ // Hide the loading label.
+ $("#loading").slideUp(1000);
+ }
+}
+
+
+/**
+ * Checks to see if the o3d container size has changed, and if so, adjusts
+ * the projection matrix accordingaly.
+ */
+function setClientSize() {
+ var newWidth = parseInt(g_client.width);
+ var newHeight = parseInt(g_client.height);
+
+ if (newWidth != g_o3dWidth || newHeight != g_o3dHeight) {
+ g_o3dWidth = newWidth;
+ g_o3dHeight = newHeight;
+
+ // Update the projection matrix.
+ g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
+ g_math.degToRad(45), g_o3dWidth / g_o3dHeight, 0.1, 1000);
+
+ // Sets a new area size for arcball.
+ g_aball.setAreaSize(g_o3dWidth, g_o3dHeight);
+ }
+}
+
+
+/**
+ * Called on mousedown to signify a drag.
+ */
+function startDragging(e) {
+ g_lastRot = g_thisRot;
+ g_aball.click([e.x, e.y]);
+ g_dragging = true;
+}
+
+
+/**
+ * Rotates the scene as the user is dragging the mouse.
+ */
+function drag(e) {
+ if (g_dragging) {
+ var rotationQuat = g_aball.drag([e.x, e.y]);
+ var rot_mat = g_quaternions.quaternionToRotation(rotationQuat);
+ g_thisRot = g_math.matrix4.mul(g_lastRot, rot_mat);
+
+ var m = g_dataroot.localMatrix;
+ g_math.matrix4.setUpper3x3(m, g_thisRot);
+ g_dataroot.localMatrix = m;
+ }
+}
+
+
+/**
+ * Called on mouseup.
+ */
+function stopDragging(e) {
+ g_dragging = false;
+}
+
+
+/**
+ * Zooms in and out of the scene on scrollwheel event.
+ */
+function scrollMe(e) {
+ var t = (e.deltaY > 0) ? 11 / 12 : 13 /12;
+ if (e.deltaY) {
+ var t = (e.deltaY > 0) ? 11 / 12 : 13 /12;
+ g_camera.eye = g_math.lerpVector(g_camera.target, g_camera.eye, t);
+ updateCamera();
+ }
+}
+
+
+/**
+ * Updates the view matrix. Should be called whenever the camera position or
+ * target has changed.
+ */
+function updateCamera() {
+ var up = [0, 1, 0];
+ g_viewInfo.drawContext.view = g_math.matrix4.lookAt(g_camera.eye,
+ g_camera.target,
+ up);
+ g_eyeParam.value = g_camera.eye;
+}
+
+
+/**
+ * Removes any callbacks so they don't get called after the page has unloaded.
+ */
+function unload() {
+ if (g_client) {
+ g_client.cleanup();
+ }
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/modulation.js b/o3d/samples/o3d-webgl-samples/bubbles/js/modulation.js
new file mode 100644
index 0000000..bb9ce3a
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/modulation.js
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+var bsh = bsh || {};
+
+/**
+ * Creates a canvas element that contains the geometry modulations. Modulations
+ * are represented as radial gradient "blips" drawn on the canvas. Once set,
+ * the width and height of the texture cannot be changed.
+ *
+ * @param {number} width The width of the texture (should be power-of-two).
+ * @param {number} height The height of the texture (should be power-of-two).
+ * @param {!Array.<number>} bounds An array [min, max] for blip radius.
+ * @param {number} blips The number of spots to modulate.
+ * @constructor
+ */
+bsh.Modulation = function(width, height, bounds, blips) {
+ this.canvas = document.createElement('canvas');
+ this.canvas.width = width;
+ this.canvas.height = height;
+ this.init(bounds, blips);
+};
+
+/**
+ * The canvas element that is written to.
+ * @type {Canvas}
+ */
+bsh.Modulation.prototype.canvas = null;
+
+/**
+ * Creates a gradient with the provided position and radius.
+ * @param {number} x x-coordinate of the blip center.
+ * @param {number} y y-coordinate of the blip center.
+ * @param {number} r Radius of the blip.
+ * @param {CanvasRenderingContext2D} ctx The 2d drawing context.
+ * @return {CanvasGradient}
+ */
+bsh.Modulation.makeGradient = function(x, y, r, ctx) {
+ var radgrad = ctx.createRadialGradient(x, y, 0, x, y, r);
+ radgrad.addColorStop(0, '#FFFFFF');
+ radgrad.addColorStop(1, 'rgba(0, 0, 0, 0)');
+ return radgrad;
+}
+
+/**
+ * Regenerates the texture and writes to the canvas element.
+ * @param {!Array.<number>} bounds An array containing [min, max] of the radius
+ * of the blips.
+ * @param {number} blips Number of blips.
+ */
+bsh.Modulation.prototype.init = function(bounds, blips) {
+ var ctx = this.canvas.getContext('2d');
+ var width = this.canvas.width;
+ var height = this.canvas.height;
+
+ // Reset to opaque black first.
+ ctx.fillStyle = "rgba(0, 0, 0, 1)";
+ ctx.fillRect(0, 0, width, height);
+ var r = bounds;
+ var x = [r[1] / 1.5, width - r[1] / 1.5];
+ var y = x;
+
+ for (var i = 0; i < blips; ++i) {
+ var posX = randf(x[0], x[1]);
+ var posY = randf(y[0], y[1]);
+ var radius = randf(r[0], r[1]);
+ ctx.fillStyle = bsh.Modulation.makeGradient(posX, posY, radius, ctx);
+ ctx.fillRect(0, 0, width, height);
+ }
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/js/noise.js b/o3d/samples/o3d-webgl-samples/bubbles/js/noise.js
new file mode 100644
index 0000000..add6934
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/js/noise.js
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2010, Google Inc.
+ * All rights reserved.
+ *
+ * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE COPYRIGHT
+ * OWNER OR 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.
+ */
+var bsh = bsh || {};
+
+
+/**
+ * Generates a perlin noise texture. The width and height cannot be changed
+ * after construction.
+ *
+ * @param {number} frequency Frequency of the texture.
+ * @param {number} seed A seed for random values.
+ * @param {number} width The width of the texture (should be power-of-two).
+ * @param {number} height The height of the texture (should be power-of-two).
+ * @constructor
+ */
+bsh.Perlin = function(frequency, seed, width, height) {
+ this.canvas = document.createElement('canvas');
+ this.canvas.width = width;
+ this.canvas.height = height;
+ this.init(frequency, seed);
+}
+
+
+/**
+ * The canvas that stores the texture.
+ * @type {Canvas}
+ */
+bsh.Perlin.prototype.canvas = null;
+
+
+/**
+ * The frequency
+ * @type {number}
+ */
+bsh.Perlin.prototype.frequency = null;
+
+
+/**
+ * An array that contains the perlin noise values before adding attenuation at
+ * the poles.
+ * @type {!Array.<number>}
+ * @private
+ */
+bsh.Perlin.prototype.values_ = [];
+
+
+/**
+ * Permutation array.
+ * @type {!Array.<number>}
+ * @private
+ */
+bsh.Perlin.prototype.permutation_ = [];
+
+
+/**
+ * Gradient array.
+ * @type {!Array.<number>}
+ * @private
+ */
+bsh.Perlin.prototype.gradients_ = [];
+
+
+/**
+ * Generates and writes the perlin noise into the canvas element.
+ * @param {number} frequency Frequency of the texture.
+ * @param {number} seed A seed for random values.
+ */
+bsh.Perlin.prototype.init = function(frequency, seed) {
+ this.frequency = frequency;
+ this.values_ = [];
+ this.permutation_ = [];
+ this.gradients_ = [];
+
+ this.prep_(seed);
+ this.generate_();
+
+ var ctx = this.canvas.getContext('2d');
+ var width = this.canvas.width;
+ var height = this.canvas.height;
+ var imageData = ctx.getImageData(0, 0, width, height);
+ var counter = 0;
+ for (var y = 0; y < height; ++y) {
+ // Attenuate the noise value with a function that goes to 0 on the poles to
+ // avoid discontinuities.
+ // Note: it'd be better to have a 3D noise texture, but they are way
+ // too expensive.
+ var attenuation = Math.sin(y * kPi / height);
+ for (var x = 0; x < width; ++x) {
+ var attenuated_value = this.values_[y * width + x] * attenuation;
+ // remap [-1..1] to [0..1] and convert to color values.
+ var value = bsh.clamp(attenuated_value * 0.5 + 0.5);
+ imageData.data[counter++] = value;
+ imageData.data[counter++] = value;
+ imageData.data[counter++] = value;
+ imageData.data[counter++] = value;
+ }
+ }
+ ctx.putImageData(imageData, 0, 0);
+}
+
+
+/**
+ * Initializes the values, permutation and gradients arrays that are used by the
+ * generate method.
+ * @param {number} seed A seed for random values.
+ * @private
+ */
+bsh.Perlin.prototype.prep_ = function(seed) {
+ //Initialize the gradients table with a random unit direction.
+ // Initialize the permutation table to be the identity.
+ for (var i = 0; i < this.frequency; ++i) {
+ var theta = Math.random() * (2.0 * kPi);
+ this.gradients_[i] = [Math.cos(theta), Math.sin(theta)];
+ this.permutation_[i] = i;
+ }
+ // Generate the permutation table by switching each element with a further
+ // element. Also duplicate the permutation table so that constructs like
+ // permutation[x + permutation[y]] work without additional modulo.
+ for (var i = 0; i < this.frequency; ++i) {
+ var j = i + (Math.floor(Math.random() * seed) % (this.frequency - i));
+ var tmp = this.permutation_[j];
+ this.permutation_[j] = this.permutation_[i];
+ this.permutation_[i] = tmp;
+ this.permutation_[i + this.frequency] = tmp;
+ }
+}
+
+/**
+ * Generates the perlin noise texture into the values_ array.
+ * @private
+ */
+bsh.Perlin.prototype.generate_ = function() {
+ var width = this.canvas.width;
+ var height = this.canvas.height;
+ var counter = 0;
+ for (var y = 0; y < height; ++y) {
+ for (var x = 0; x < width; ++x) {
+ // The texture is decomposed into a lattice of frequency_ points in each
+ // direction. A (x, y) point falls between 4 lattice vertices.
+ // (xx, yy) are the coordinate of the bottom left lattice vertex
+ // corresponding to an (x, y) image point.
+ var xx = Math.floor((x * this.frequency) / width);
+ var yy = Math.floor((y * this.frequency) / height);
+ // xt and yt are the barycentric coordinates of the (x, y) point relative
+ // to the vertices (between 0 and 1).
+ var xt = 1.0/width * ((x * this.frequency) % width);
+ var yt = 1.0/height * ((y * this.frequency) % height);
+ // contribution of each lattice vertex to the point value.
+ var contrib = [];
+ for (var y_offset = 0; y_offset < 2; ++y_offset) {
+ for (var x_offset = 0; x_offset < 2; ++x_offset) {
+ var index = this.permutation_[xx + x_offset] + y_offset + yy;
+ var gradient = this.gradients_[this.permutation_[index]];
+ contrib[y_offset*2+x_offset] = gradient[0] * (xt - x_offset) +
+ gradient[1] * (yt - y_offset);
+ }
+ }
+ // We interpolate between the vertex contributions using a smooth step
+ // function of the barycentric coordinates.
+ var xt_smooth = bsh.smoothStep(xt);
+ var yt_smooth = bsh.smoothStep(yt);
+ var contrib_bottom = bsh.lerp(xt_smooth, contrib[0], contrib[1]);
+ var contrib_top = bsh.lerp(xt_smooth, contrib[2], contrib[3]);
+ var sq = bsh.lerp(yt_smooth, contrib_bottom, contrib_top);
+ this.values_[counter++] = sq;
+ }
+ }
+}
+
+/**
+ * Copies the data from the canvas into the texture.
+ * @param {o3d.Texture} texture The texture to. Should be same size.
+ */
+bsh.Perlin.prototype.refresh = function(texture) {
+ var data = this.canvas.getContext('2d').getImageData(0, 0, this.canvas.width,
+ this.canvas.height).data;
+ var pixels = [];
+ for (var i = 0; i < data.length; ++i) {
+ pixels[i] = data[i] / 255.0;
+ }
+ texture.set(0, pixels);
+}
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/AUTHORS.txt b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/AUTHORS.txt
new file mode 100755
index 0000000..b216865
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/AUTHORS.txt
@@ -0,0 +1,30 @@
+jQuery UI Authors (http://jqueryui.com/about)
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+and logs, available at http://github.com/jquery/jquery-ui
+
+Brandon Aaron
+Paul Bakaus (paulbakaus.com)
+David Bolter
+Rich Caloggero
+Chi Cheng (cloudream@gmail.com)
+Colin Clark (http://colin.atrc.utoronto.ca/)
+Michelle D'Souza
+Aaron Eisenberger (aaronchi@gmail.com)
+Ariel Flesler
+Bohdan Ganicky
+Scott González
+Marc Grabanski (m@marcgrabanski.com)
+Klaus Hartl (stilbuero.de)
+Scott Jehl
+Cody Lindley
+Eduardo Lundgren (eduardolundgren@gmail.com)
+Todd Parker
+John Resig
+Patty Toland
+Ca-Phun Ung (yelotofu.com)
+Keith Wood (kbwood@virginbroadband.com.au)
+Maggie Costello Wachs
+Richard D. Worth (rdworth.org)
+Jörn Zaefferer (bassistance.de)
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/MIT-LICENSE.txt b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/MIT-LICENSE.txt
new file mode 100755
index 0000000..2585de2
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/MIT-LICENSE.txt
@@ -0,0 +1,25 @@
+Copyright (c) 2010 Paul Bakaus, http://jqueryui.com/
+
+This software consists of voluntary contributions made by many
+individuals (AUTHORS.txt, http://jqueryui.com/about) For exact
+contribution history, see the revision history and logs, available
+at http://jquery-ui.googlecode.com/svn/
+
+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/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/README.o3d b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/README.o3d
new file mode 100644
index 0000000..949a42a
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/README.o3d
@@ -0,0 +1,7 @@
+This directory contains the jQuery library and a customized subset of the
+jQuery UI library, available at http://jquery.com and http://jqueryui.com/,
+licensed under the General Public License (GPL) Version 2 and MIT licenses.
+
+The provided CSS stylesheet(s) (css/*.css) have been modified to remove
+unneeded style rules and image dependencies. The remaining code is otherwise
+unmodified.
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/css/jquery-ui-1.8.4.custom.css b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/css/jquery-ui-1.8.4.custom.css
new file mode 100644
index 0000000..550eb93
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/css/jquery-ui-1.8.4.custom.css
@@ -0,0 +1,124 @@
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
+
+
+/*
+ * jQuery UI CSS Framework @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Theming/API
+ *
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+ */
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
+.ui-widget .ui-widget { font-size: 1em; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
+.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee; color: #333333; }
+.ui-widget-content a { color: #333333; }
+.ui-widget-header { border: 1px solid #e78f08; background: #f6a828; color: #ffffff; font-weight: bold; }
+.ui-widget-header a { color: #ffffff; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6; font-weight: bold; color: #1c94c4; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce; font-weight: bold; color: #c77405; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }
+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff; font-weight: bold; color: #eb8f00; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }
+.ui-widget :active { outline: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }
+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }
+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }
+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }
+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }
+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }
+/*
+ * jQuery UI Slider @VERSION
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider#theming
+ */
+.ui-slider { position: relative; text-align: left; }
+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
+
+.ui-slider-horizontal { height: .8em; }
+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
+.ui-slider-horizontal .ui-slider-range-min { left: 0; }
+.ui-slider-horizontal .ui-slider-range-max { right: 0; }
+
+.ui-slider-vertical { width: .8em; height: 100px; }
+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }
+.ui-slider-vertical .ui-slider-range-max { top: 0; }
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-1.4.2.min.js b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-1.4.2.min.js
new file mode 100755
index 0000000..7c24308
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-1.4.2.min.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.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\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-ui-1.8.4.custom.min.js b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-ui-1.8.4.custom.min.js
new file mode 100755
index 0000000..6cab644
--- /dev/null
+++ b/o3d/samples/o3d-webgl-samples/bubbles/third_party/jquery/jquery-ui-1.8.4.custom.min.js
@@ -0,0 +1,83 @@
+/*!
+ * jQuery UI 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI
+ */
+(function(c,j){function k(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.4",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e<b.length;e++)a.options[b[e][0]]&&b[e][1].apply(a.element,d)}},contains:function(a,
+b){return document.compareDocumentPosition?a.compareDocumentPosition(b)&16:a!==b&&a.contains(b)},hasScroll:function(a,b){if(c(a).css("overflow")==="hidden")return false;b=b&&b==="left"?"scrollLeft":"scrollTop";var d=false;if(a[b]>0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a<b+d},isOver:function(a,b,d,e,h,i){return c.ui.isOverAxis(a,d,h)&&c.ui.isOverAxis(b,e,i)},keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,
+CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d=this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable",
+"off").css("MozUserSelect","")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none")},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this,
+"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"));if(!isNaN(b)&&b!=0)return b}a=a.parent()}}return 0}});c.each(["Width","Height"],function(a,b){function d(f,g,l,m){c.each(e,function(){g-=
+parseFloat(c.curCSS(f,"padding"+this,true))||0;if(l)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(m)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight,outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c.style(this,h,d(this,f)+"px")})};c.fn["outer"+
+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c.style(this,h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){var b=a.nodeName.toLowerCase(),d=c.attr(a,"tabindex");if("area"===b){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&k(a)}return(/input|select|textarea|button|object/.test(b)?!a.disabled:"a"==
+b?a.href||!isNaN(d):!isNaN(d))&&k(a)},tabbable:function(a){var b=c.attr(a,"tabindex");return(isNaN(b)||b>=0)&&c(a).is(":focusable")}})}})(jQuery);
+;/*!
+ * jQuery UI Widget 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Widget
+ */
+(function(b,j){var k=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add([this]).each(function(){b(this).triggerHandler("remove")});return k.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend(true,{},c.options);
+b[e][a].prototype=b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==j){h=i;return false}}):
+this.each(function(){var g=b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){b.data(c,this.widgetName,this);this.element=b(c);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});
+this._create();this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===j)return this.options[a];d={};d[a]=c}b.each(d,function(f,
+h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a=
+b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery);
+;/*!
+ * jQuery UI Mouse 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Mouse
+ *
+ * Depends:
+ * jquery.ui.widget.js
+ */
+(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&&
+this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault();
+return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&
+this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-
+a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery);
+;/*
+ * jQuery UI Slider 1.8.4
+ *
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ * jquery.ui.core.js
+ * jquery.ui.mouse.js
+ * jquery.ui.widget.js
+ */
+(function(d){d.widget("ui.slider",d.ui.mouse,{widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var a=this,b=this.options;this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");b.disabled&&this.element.addClass("ui-slider-disabled ui-disabled");
+this.range=d([]);if(b.range){if(b.range===true){this.range=d("<div></div>");if(!b.values)b.values=[this._valueMin(),this._valueMin()];if(b.values.length&&b.values.length!==2)b.values=[b.values[0],b.values[0]]}else this.range=d("<div></div>");this.range.appendTo(this.element).addClass("ui-slider-range");if(b.range==="min"||b.range==="max")this.range.addClass("ui-slider-range-"+b.range);this.range.addClass("ui-widget-header")}d(".ui-slider-handle",this.element).length===0&&d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");
+if(b.values&&b.values.length)for(;d(".ui-slider-handle",this.element).length<b.values.length;)d("<a href='#'></a>").appendTo(this.element).addClass("ui-slider-handle");this.handles=d(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(c){c.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();
+else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(c){d(this).data("index.ui-slider-handle",c)});this.handles.keydown(function(c){var e=true,f=d(this).data("index.ui-slider-handle"),h,g,i;if(!a.options.disabled){switch(c.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:e=
+false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");h=a._start(c,f);if(h===false)return}break}i=a.options.step;h=a.options.values&&a.options.values.length?(g=a.values(f)):(g=a.value());switch(c.keyCode){case d.ui.keyCode.HOME:g=a._valueMin();break;case d.ui.keyCode.END:g=a._valueMax();break;case d.ui.keyCode.PAGE_UP:g=a._trimAlignValue(h+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:g=a._trimAlignValue(h-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(h===
+a._valueMax())return;g=a._trimAlignValue(h+i);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(h===a._valueMin())return;g=a._trimAlignValue(h-i);break}a._slide(c,f,g);return e}}).keyup(function(c){var e=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(c,e);a._change(c,e);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");
+this._mouseDestroy();return this},_mouseCapture:function(a){var b=this.options,c,e,f,h,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});e=this._valueMax()-this._valueMin()+1;h=this;this.handles.each(function(i){var j=Math.abs(c-h.values(i));if(e>j){e=j;f=d(this);g=i}});if(b.range===true&&this.values(1)===b.min){g+=1;f=d(this.handles[g])}if(this._start(a,
+g)===false)return false;this._mouseSliding=true;h._handleIndex=g;f.addClass("ui-state-active").focus();b=f.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-f.width()/2,top:a.pageY-b.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b=
+this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b=
+this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);
+c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var e;if(this.options.values&&this.options.values.length){e=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>e||b===1&&c<e))c=e;if(c!==this.values(b)){e=this.values();e[b]=c;a=this._trigger("slide",a,{handle:this.handles[b],value:c,values:e});this.values(b?0:1);a!==false&&this.values(b,c,true)}}else if(c!==this.value()){a=this._trigger("slide",a,{handle:this.handles[b],value:c});
+a!==false&&this.value(c)}},_stop:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("stop",a,c)},_change:function(a,b){if(!this._keySliding&&!this._mouseSliding){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b);c.values=this.values()}this._trigger("change",a,c)}},value:function(a){if(arguments.length){this.options.value=
+this._trimAlignValue(a);this._refreshValue();this._change(null,0)}return this._value()},values:function(a,b){var c,e,f;if(arguments.length>1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f<c.length;f+=1){c[f]=this._trimAlignValue(e[f]);this._change(null,f)}this._refreshValue()}else return this.options.values&&this.options.values.length?this._values(a):this.value();
+else return this._values()},_setOption:function(a,b){var c,e=0;if(d.isArray(this.options.values))e=this.options.values.length;d.Widget.prototype._setOption.apply(this,arguments);switch(a){case "disabled":if(b){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled");this.element.addClass("ui-disabled")}else{this.handles.removeAttr("disabled");this.element.removeClass("ui-disabled")}break;case "orientation":this._detectOrientation();
+this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue();break;case "value":this._animateOff=true;this._refreshValue();this._change(null,0);this._animateOff=false;break;case "values":this._animateOff=true;this._refreshValue();for(c=0;c<e;c+=1)this._change(null,c);this._animateOff=false;break}},_value:function(){var a=this.options.value;return a=this._trimAlignValue(a)},_values:function(a){var b,c;if(arguments.length){b=this.options.values[a];
+return b=this._trimAlignValue(b)}else{b=this.options.values.slice();for(c=0;c<b.length;c+=1)b[c]=this._trimAlignValue(b[c]);return b}},_trimAlignValue:function(a){if(a<this._valueMin())return this._valueMin();if(a>this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=a%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a=
+this.options.range,b=this.options,c=this,e=!this._animateOff?b.animate:false,f,h={},g,i,j,l;if(this.options.values&&this.options.values.length)this.handles.each(function(k){f=(c.values(k)-c._valueMin())/(c._valueMax()-c._valueMin())*100;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";d(this).stop(1,1)[e?"animate":"css"](h,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(k===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},b.animate);if(k===1)c.range[e?"animate":"css"]({width:f-
+g+"%"},{queue:false,duration:b.animate})}else{if(k===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},b.animate);if(k===1)c.range[e?"animate":"css"]({height:f-g+"%"},{queue:false,duration:b.animate})}g=f});else{i=this.value();j=this._valueMin();l=this._valueMax();f=l!==j?(i-j)/(l-j)*100:0;h[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](h,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"},
+b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.4"})})(jQuery);
+; \ No newline at end of file