, this is not supported by this loader, mesh ignored", ColladaLoader2.messageError);
+ return null;
+ }
+ _ref6 = this._createGeometryAndMaterial(daeSkinGeometry, daeInstanceController.materials), threejsGeometry = _ref6[0], threejsMaterial = _ref6[1];
+ if (this._options["convertSkinsToMorphs"]) {
+ if (this._addSkinMorphTargets(threejsGeometry, daeSkin, bones, threejsMaterial)) {
+ return new THREE.MorphAnimMesh(threejsGeometry, threejsMaterial);
+ } else {
+ return new THREE.Mesh(threejsGeometry, threejsMaterial);
+ }
+ } else {
+ if (this._addSkinBones(threejsGeometry, daeSkin, bones, threejsMaterial)) {
+ mesh = new THREE.SkinnedMesh(threejsGeometry, threejsMaterial);
+ mesh.boneInverses = [];
+ _ref7 = threejsGeometry.bones;
+ for (_l = 0, _len4 = _ref7.length; _l < _len4; _l++) {
+ bone = _ref7[_l];
+ mesh.boneInverses.push(bone.inverse);
+ }
+ return mesh;
+ } else {
+ return new THREE.Mesh(threejsGeometry, threejsMaterial);
+ }
+ }
+ return null;
+ };
+
+ ColladaFile.prototype._findJointNode = function(jointSid, skeletonRootNodes) {
+ var jointNode, skeleton, _i, _len;
+ jointNode = null;
+ for (_i = 0, _len = skeletonRootNodes.length; _i < _len; _i++) {
+ skeleton = skeletonRootNodes[_i];
+ jointNode = this._findSidTarget(skeleton, jointSid);
+ if (jointNode != null) break;
+ }
+ if (jointNode instanceof ColladaVisualSceneNode) {
+ return jointNode;
+ } else {
+ return null;
+ }
+ };
+
+ ColladaFile.prototype._createBone = function(boneNode, jointSid, bones) {
+ var bone, transform, _i, _len, _ref;
+ bone = new ThreejsSkeletonBone;
+ bone.sid = jointSid;
+ bone.node = boneNode;
+ _ref = boneNode.transformations;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ transform = _ref[_i];
+ if (transform.animTarget.channels.length > 0) {
+ bone.isAnimated = true;
+ break;
+ }
+ }
+ bone.matrix = new THREE.Matrix4;
+ boneNode.getTransformMatrix(bone.matrix);
+ bone.index = bones.length;
+ bones.push(bone);
+ return bone;
+ };
+
+ ColladaFile.prototype._addSkinMorphTargets = function(threejsGeometry, daeSkin, bones, threejsMaterial) {
+ var bindShapeMatrix, bone, boneIndex, boneWeight, boneWeightIndex, enableWarningInvalidWeight, enableWarningNoBones, i, material, sourceVertex, sourceVertices, srcVertex, tempVertex, timesteps, totalWeight, vertex, vertexCount, vertices, vindex, vwJoints, vwJointsSource, vwV, vwVcount, vwWeights, vwWeightsSource, w, weights, _i, _j, _len, _len2, _len3, _ref, _ref2, _ref3;
+ timesteps = this._prepareAnimations(bones);
+ if (!timesteps > 0) return null;
+ sourceVertices = threejsGeometry.vertices;
+ vertexCount = sourceVertices.length;
+ vwV = daeSkin.vertexWeights.v;
+ vwVcount = daeSkin.vertexWeights.vcount;
+ vwJointsSource = this._getLinkTarget(daeSkin.vertexWeights.joints.source);
+ vwWeightsSource = this._getLinkTarget(daeSkin.vertexWeights.weights.source);
+ vwJoints = vwJointsSource != null ? vwJointsSource.data : void 0;
+ vwWeights = vwWeightsSource != null ? vwWeightsSource.data : void 0;
+ if (!(vwWeights != null)) {
+ this._log("Skin has no weights data, no morph targets added for mesh", ColladaLoader2.messageError);
+ return null;
+ }
+ bindShapeMatrix = new THREE.Matrix4;
+ if (daeSkin.bindShapeMatrix != null) {
+ bindShapeMatrix = _floatsToMatrix4RowMajor(daeSkin.bindShapeMatrix, 0);
+ }
+ tempVertex = new THREE.Vector3;
+ enableWarningNoBones = true;
+ enableWarningInvalidWeight = true;
+ for (i = 0, _ref = timesteps - 1; i <= _ref; i += 1) {
+ this._updateSkinMatrices(bones, bindShapeMatrix, i);
+ vertices = [];
+ for (_i = 0, _len = sourceVertices.length; _i < _len; _i++) {
+ srcVertex = sourceVertices[_i];
+ vertices.push(new THREE.Vector3());
+ }
+ vindex = 0;
+ for (i = 0, _len2 = vertices.length; i < _len2; i++) {
+ vertex = vertices[i];
+ sourceVertex = sourceVertices[i];
+ weights = vwVcount[i];
+ totalWeight = 0;
+ for (w = 0, _ref2 = weights - 1; w <= _ref2; w += 1) {
+ boneIndex = vwV[vindex];
+ boneWeightIndex = vwV[vindex + 1];
+ vindex += 2;
+ boneWeight = vwWeights[boneWeightIndex];
+ totalWeight += boneWeight;
+ if (boneIndex >= 0) {
+ bone = bones[boneIndex];
+ tempVertex.copy(sourceVertex);
+ tempVertex.applyMatrix4(bone.skinMatrix);
+ tempVertex.multiplyScalar(boneWeight);
+ vertex.add(tempVertex);
+ } else {
+ tempVertex.copy(sourceVertex);
+ tempVertex.applyMatrix4(bindShapeMatrix);
+ tempVertex.multiplyScalar(boneWeight);
+ vertex.add(tempVertex);
+ }
+ }
+ if (weights === 0) {
+ vertex.copy(sourceVertex);
+ if (enableWarningNoBones) {
+ this._log("Skinned vertex not influenced by any bone, some vertices will be unskinned", ColladaLoader2.messageWarning);
+ enableWarningNoBones = false;
+ }
+ } else if (!((0.01 < totalWeight && totalWeight < 1e6))) {
+ vertex.copy(sourceVertex);
+ if (enableWarningInvalidWeight) {
+ this._log("Zero or infinite total weight for skinned vertex, some vertices will be unskinned", ColladaLoader2.messageWarning);
+ enableWarningInvalidWeight = false;
+ }
+ } else {
+ vertex.multiplyScalar(1 / totalWeight);
+ }
+ }
+ if (vindex !== vwV.length) {
+ this._log("Skinning did not consume all weights", ColladaLoader2.messageError);
+ }
+ threejsGeometry.morphTargets.push({
+ name: "target",
+ vertices: vertices
+ });
+ }
+ threejsGeometry.computeMorphNormals();
+ threejsMaterial.morphTargets = true;
+ threejsMaterial.morphNormals = true;
+ if (threejsMaterial.materials != null) {
+ _ref3 = threejsMaterial.materials;
+ for (_j = 0, _len3 = _ref3.length; _j < _len3; _j++) {
+ material = _ref3[_j];
+ material.morphTargets = true;
+ material.morphNormals = true;
+ }
+ }
+ return true;
+ };
+
+ ColladaFile.prototype._prepareAnimations = function(bones) {
+ var bone, channel, channelTimesteps, hasAnimation, timesteps, transform, _i, _j, _k, _len, _len2, _len3, _ref, _ref2;
+ timesteps = null;
+ for (_i = 0, _len = bones.length; _i < _len; _i++) {
+ bone = bones[_i];
+ hasAnimation = false;
+ _ref = bone.node.transformations;
+ for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
+ transform = _ref[_j];
+ transform.resetAnimation();
+ transform.selectAllAnimations();
+ _ref2 = transform.animTarget.activeChannels;
+ for (_k = 0, _len3 = _ref2.length; _k < _len3; _k++) {
+ channel = _ref2[_k];
+ hasAnimation = true;
+ channelTimesteps = channel.inputData.length;
+ if ((timesteps != null) && channelTimesteps !== timesteps) {
+ this._log("Inconsistent number of time steps, no morph targets added for mesh. Resample all animations to fix this.", ColladaLoader2.messageError);
+ return null;
+ }
+ timesteps = channelTimesteps;
+ }
+ }
+ if (this._options["verboseMessages"] && !hasAnimation) {
+ this._log("Joint '" + bone.sid + "' has no animation channel", ColladaLoader2.messageWarning);
+ }
+ }
+ return timesteps;
+ };
+
+ ColladaFile.prototype._updateSkinMatrices = function(bones, bindShapeMatrix, keyframe) {
+ var bone, _i, _j, _len, _len2;
+ for (_i = 0, _len = bones.length; _i < _len; _i++) {
+ bone = bones[_i];
+ bone.applyAnimation(keyframe);
+ }
+ for (_j = 0, _len2 = bones.length; _j < _len2; _j++) {
+ bone = bones[_j];
+ bone.updateSkinMatrix(bindShapeMatrix);
+ }
+ return null;
+ };
+
+ ColladaFile.prototype._addSkinBones = function(threejsGeometry, daeSkin, bones, threejsMaterial) {
+ var bindShapeMatrix, bone, boneIndex, boneWeight, boneWeightIndex, bonesPerVertex, enableWarningInvalidWeight, enableWarningTooManyBones, i, indices, key, keyframe, material, pos, rot, scl, sourceVertices, threejsAnimation, threejsBone, threejsBoneAnimation, threejsBones, threejsSkinIndices, threejsSkinWeights, timesteps, totalWeight, vertex, vertexCount, vindex, vwJoints, vwJointsSource, vwV, vwVcount, vwWeights, vwWeightsSource, w, weightCount, weights, _i, _j, _k, _len, _len2, _len3, _len4, _ref, _ref2, _ref3, _ref4, _ref5;
+ timesteps = this._prepareAnimations(bones);
+ if (!timesteps > 0) return null;
+ sourceVertices = threejsGeometry.vertices;
+ vertexCount = sourceVertices.length;
+ vwV = daeSkin.vertexWeights.v;
+ vwVcount = daeSkin.vertexWeights.vcount;
+ vwJointsSource = this._getLinkTarget(daeSkin.vertexWeights.joints.source);
+ vwWeightsSource = this._getLinkTarget(daeSkin.vertexWeights.weights.source);
+ vwJoints = vwJointsSource != null ? vwJointsSource.data : void 0;
+ vwWeights = vwWeightsSource != null ? vwWeightsSource.data : void 0;
+ if (!(vwWeights != null)) {
+ this._log("Skin has no weights data, no skin added for mesh", ColladaLoader2.messageError);
+ return null;
+ }
+ bindShapeMatrix = new THREE.Matrix4;
+ if (daeSkin.bindShapeMatrix != null) {
+ bindShapeMatrix = _floatsToMatrix4RowMajor(daeSkin.bindShapeMatrix, 0);
+ }
+ pos = new THREE.Vector3();
+ rot = new THREE.Quaternion();
+ scl = new THREE.Vector3();
+ enableWarningTooManyBones = true;
+ enableWarningInvalidWeight = true;
+ threejsSkinIndices = [];
+ threejsSkinWeights = [];
+ vindex = 0;
+ bonesPerVertex = 4;
+ indices = [0, 0, 0, 0];
+ weights = [0, 0, 0, 0];
+ for (i = 0, _len = sourceVertices.length; i < _len; i++) {
+ vertex = sourceVertices[i];
+ weightCount = vwVcount[i];
+ if (weightCount > bonesPerVertex) {
+ if (enableWarningTooManyBones) {
+ this._log("Too many bones influence a vertex, some influences will be discarded. Threejs supports only " + bonesPerVertex + " bones per vertex.", ColladaLoader2.messageWarning);
+ enableWarningTooManyBones = false;
+ }
+ weightCount = bonesPerVertex;
+ }
+ totalWeight = 0;
+ for (w = 0, _ref = weightCount - 1; w <= _ref; w += 1) {
+ boneIndex = vwV[vindex];
+ boneWeightIndex = vwV[vindex + 1];
+ vindex += 2;
+ boneWeight = vwWeights[boneWeightIndex];
+ totalWeight += boneWeight;
+ indices[w] = boneIndex;
+ weights[w] = boneWeight;
+ }
+ for (w = weights, _ref2 = bonesPerVertex - 1; w <= _ref2; w += 1) {
+ indices[w] = 0;
+ weights[w] = 0;
+ }
+ if (!((0.01 < totalWeight && totalWeight < 1e6))) {
+ if (enableWarningInvalidWeight) {
+ this._log("Zero or infinite total weight for skinned vertex, skin will be broken", ColladaLoader2.messageWarning);
+ enableWarningInvalidWeight = false;
+ }
+ } else {
+ for (w = 0, _ref3 = bonesPerVertex - 1; w <= _ref3; w += 1) {
+ weights[w] /= totalWeight;
+ }
+ }
+ threejsSkinIndices.push(new THREE.Vector4(indices[0], indices[1], indices[2], indices[3]));
+ threejsSkinWeights.push(new THREE.Vector4(weights[0], weights[1], weights[2], weights[3]));
+ }
+ threejsGeometry.skinIndices = threejsSkinIndices;
+ threejsGeometry.skinWeights = threejsSkinWeights;
+ threejsBones = [];
+ for (_i = 0, _len2 = bones.length; _i < _len2; _i++) {
+ bone = bones[_i];
+ threejsBone = {};
+ if (bone.parent != null) {
+ threejsBone.parent = bone.parent.index;
+ } else {
+ threejsBone.parent = -1;
+ }
+ threejsBone.name = bone.node.name;
+ bone.matrix.decompose(pos, rot, scl);
+ threejsBone.pos = [pos.x, pos.y, pos.z];
+ threejsBone.scl = [scl.x, scl.y, scl.z];
+ threejsBone.rotq = [rot.x, rot.y, rot.z, rot.w];
+ threejsBone.rot = null;
+ threejsBone.inverse = new THREE.Matrix4;
+ threejsBone.inverse.multiplyMatrices(bone.invBindMatrix, bindShapeMatrix);
+ threejsBones.push(threejsBone);
+ }
+ threejsGeometry.bones = threejsBones;
+ threejsAnimation = {};
+ threejsAnimation.name = "animation";
+ threejsAnimation.hierarchy = [];
+ for (_j = 0, _len3 = bones.length; _j < _len3; _j++) {
+ bone = bones[_j];
+ threejsBoneAnimation = {};
+ threejsBoneAnimation.parent = bone.index;
+ threejsBoneAnimation.keys = [];
+ for (keyframe = 0, _ref4 = timesteps - 1; keyframe <= _ref4; keyframe += 1) {
+ bone.applyAnimation(keyframe);
+ bone.updateSkinMatrix(bindShapeMatrix);
+ key = {};
+ key.time = keyframe;
+ bone.matrix.decompose(pos, rot, scl);
+ key.pos = [pos.x, pos.y, pos.z];
+ key.scl = [scl.x, scl.y, scl.z];
+ key.rot = [rot.x, rot.y, rot.z, rot.w];
+ threejsBoneAnimation.keys.push(key);
+ }
+ threejsAnimation.hierarchy.push(threejsBoneAnimation);
+ }
+ threejsAnimation.fps = 30;
+ threejsAnimation.length = timesteps - 1;
+ threejsGeometry.animation = threejsAnimation;
+ threejsMaterial.skinning = true;
+ if (threejsMaterial.materials != null) {
+ _ref5 = threejsMaterial.materials;
+ for (_k = 0, _len4 = _ref5.length; _k < _len4; _k++) {
+ material = _ref5[_k];
+ material.skinning = true;
+ }
+ }
+ return true;
+ };
+
+ ColladaFile.prototype._createMorphMesh = function(daeInstanceController, daeController) {
+ this._log("Morph animated meshes not supported, mesh ignored", ColladaLoader2.messageError);
+ return null;
+ };
+
+ ColladaFile.prototype._createGeometry = function(daeGeometry, materials) {
+ var materialIndex, threejsGeometry, triangles, _i, _len, _ref;
+ threejsGeometry = new THREE.Geometry();
+ _ref = daeGeometry.triangles;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ triangles = _ref[_i];
+ materialIndex = materials.indices[triangles.material];
+ if (!(materialIndex != null)) {
+ this._log("Material symbol " + triangles.material + " has no bound material instance", ColladaLoader2.messageError);
+ materialIndex = 0;
+ }
+ this._addTrianglesToGeometry(daeGeometry, triangles, materialIndex, threejsGeometry);
+ }
+ threejsGeometry.computeFaceNormals();
+ threejsGeometry.computeCentroids();
+ if (materials.needtangents) threejsGeometry.computeTangents();
+ threejsGeometry.computeBoundingBox();
+ return threejsGeometry;
+ };
+
+ ColladaFile.prototype._addTrianglesToGeometry = function(daeGeometry, triangles, materialIndex, threejsGeometry) {
+ var baseOffset0, baseOffset1, baseOffset2, c, color, data, dataTriColor, dataTriNormal, dataTriTexcoord, dataVertColor, dataVertNormal, dataVertPos, dataVertTexcoord, face, faceVertexUvs, i, indices, input, inputTriColor, inputTriNormal, inputTriTexcoord, inputTriVertices, inputVertColor, inputVertNormal, inputVertPos, inputVertTexcoord, missingFaces, n0, n1, n2, normal, numExistingFaces, numExistingTexcoordSets, numNewFaces, numNewTexcoordSets, srcTriColor, srcTriNormal, srcTriTexcoord, srcTriVertices, srcVertColor, srcVertNormal, srcVertPos, srcVertTexcoord, t0, t1, t2, texcoord, triangleBaseOffset, triangleStride, v0, v1, v2, vcount, vertexStride, _i, _j, _k, _len, _len2, _len3, _len4, _len5, _len6, _len7, _ref, _ref2, _ref3, _ref4, _step, _unused,
+ _this = this;
+ inputTriVertices = null;
+ inputTriNormal = null;
+ inputTriColor = null;
+ inputTriTexcoord = [];
+ _ref = triangles.inputs;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ input = _ref[_i];
+ switch (input.semantic) {
+ case "VERTEX":
+ inputTriVertices = input;
+ break;
+ case "NORMAL":
+ inputTriNormal = input;
+ break;
+ case "COLOR":
+ inputTriColor = input;
+ break;
+ case "TEXCOORD":
+ inputTriTexcoord.push(input);
+ break;
+ default:
+ this._log("Unknown triangles input semantic " + input.semantic + " ignored", ColladaLoader2.messageWarning);
+ }
+ }
+ srcTriVertices = this._getLinkTarget(inputTriVertices.source, ColladaVertices);
+ if (!(srcTriVertices != null)) {
+ this._log("Geometry " + daeGeometry.id + " has no vertices", ColladaLoader2.messageError);
+ return;
+ }
+ srcTriNormal = this._getLinkTarget(inputTriNormal != null ? inputTriNormal.source : void 0, ColladaSource);
+ srcTriColor = this._getLinkTarget(inputTriColor != null ? inputTriColor.source : void 0, ColladaSource);
+ srcTriTexcoord = inputTriTexcoord.map(function(x) {
+ return _this._getLinkTarget(x != null ? x.source : void 0, ColladaSource);
+ });
+ inputVertPos = null;
+ inputVertNormal = null;
+ inputVertColor = null;
+ inputVertTexcoord = [];
+ _ref2 = srcTriVertices.inputs;
+ for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+ input = _ref2[_j];
+ switch (input.semantic) {
+ case "POSITION":
+ inputVertPos = input;
+ break;
+ case "NORMAL":
+ inputVertNormal = input;
+ break;
+ case "COLOR":
+ inputVertColor = input;
+ break;
+ case "TEXCOORD":
+ inputVertTexcoord.push(input);
+ break;
+ default:
+ this._log("Unknown vertices input semantic " + input.semantic + " ignored", ColladaLoader2.messageWarning);
+ }
+ }
+ srcVertPos = this._getLinkTarget(inputVertPos.source, ColladaSource);
+ if (!(srcVertPos != null)) {
+ this._log("Geometry " + daeGeometry.id + " has no vertex positions", ColladaLoader2.messageError);
+ return;
+ }
+ srcVertNormal = this._getLinkTarget(inputVertNormal != null ? inputVertNormal.source : void 0, ColladaSource);
+ srcVertColor = this._getLinkTarget(inputVertColor != null ? inputVertColor.source : void 0, ColladaSource);
+ srcVertTexcoord = inputVertTexcoord.map(function(x) {
+ return _this._getLinkTarget(x != null ? x.source : void 0, ColladaSource);
+ });
+ dataVertPos = this._createVector3Array(srcVertPos);
+ dataVertNormal = this._createVector3Array(srcVertNormal);
+ dataTriNormal = this._createVector3Array(srcTriNormal);
+ dataVertColor = this._createColorArray(srcVertColor);
+ dataTriColor = this._createColorArray(srcTriColor);
+ dataVertTexcoord = srcVertTexcoord.map(function(x) {
+ return _this._createUVArray(x);
+ });
+ dataTriTexcoord = srcTriTexcoord.map(function(x) {
+ return _this._createUVArray(x);
+ });
+ threejsGeometry.vertices = dataVertPos;
+ numNewTexcoordSets = dataVertTexcoord.length + dataTriTexcoord.length;
+ numExistingTexcoordSets = threejsGeometry.faceVertexUvs.length;
+ numNewFaces = triangles.count;
+ numExistingFaces = threejsGeometry.faces.count;
+ _ref3 = threejsGeometry.faceVertexUvs;
+ for (i = 0, _len3 = _ref3.length; i < _len3; i++) {
+ faceVertexUvs = _ref3[i];
+ if (i < numNewTexcoordSets) {
+ missingFaces = faceVertexUvs.length - threejsGeometry.faces.length;
+ this._addEmptyUVs(faceVertexUvs, missingFaces);
+ } else {
+ missingFaces = faceVertexUvs.length - threejsGeometry.faces.length + numNewFaces;
+ this._addEmptyUVs(faceVertexUvs, missingFaces);
+ }
+ }
+ while (threejsGeometry.faceVertexUvs.length < numNewTexcoordSets) {
+ faceVertexUvs = [];
+ this._addEmptyUVs(faceVertexUvs, numExistingFaces);
+ threejsGeometry.faceVertexUvs.push(faceVertexUvs);
+ }
+ if (triangles.type !== "triangles") {
+ vcount = triangles.vcount;
+ for (_k = 0, _len4 = vcount.length; _k < _len4; _k++) {
+ c = vcount[_k];
+ if (c !== 3) {
+ this._log("Geometry " + daeGeometry.id + " has non-triangle polygons, geometry ignored", ColladaLoader2.messageError);
+ return;
+ }
+ }
+ }
+ indices = triangles.indices;
+ triangleStride = indices.length / triangles.count;
+ vertexStride = triangleStride / 3;
+ _ref4 = triangles.indices;
+ for (triangleBaseOffset = 0, _len5 = _ref4.length, _step = triangleStride; triangleBaseOffset < _len5; triangleBaseOffset += _step) {
+ _unused = _ref4[triangleBaseOffset];
+ baseOffset0 = triangleBaseOffset + 0 * vertexStride;
+ baseOffset1 = triangleBaseOffset + 1 * vertexStride;
+ baseOffset2 = triangleBaseOffset + 2 * vertexStride;
+ v0 = indices[baseOffset0 + inputTriVertices.offset];
+ v1 = indices[baseOffset1 + inputTriVertices.offset];
+ v2 = indices[baseOffset2 + inputTriVertices.offset];
+ if (dataVertNormal != null) {
+ normal = [dataVertNormal[v0], dataVertNormal[v1], dataVertNormal[v2]];
+ } else if (dataTriNormal != null) {
+ n0 = indices[baseOffset0 + inputTriNormal.offset];
+ n1 = indices[baseOffset1 + inputTriNormal.offset];
+ n2 = indices[baseOffset2 + inputTriNormal.offset];
+ normal = [dataTriNormal[n0], dataTriNormal[n1], dataTriNormal[n2]];
+ } else {
+ normal = null;
+ }
+ if (dataVertColor != null) {
+ color = [dataVertColor[v0], dataVertColor[v1], dataVertColor[v2]];
+ } else if (dataTriColor != null) {
+ n0 = indices[baseOffset0 + inputTriColor.offset];
+ n1 = indices[baseOffset1 + inputTriColor.offset];
+ n2 = indices[baseOffset2 + inputTriColor.offset];
+ color = [dataTriColor[n0], dataTriColor[n1], dataTriColor[n2]];
+ } else {
+ color = null;
+ }
+ face = new THREE.Face3(v0, v1, v2, normal, color);
+ if (materialIndex != null) face.materialIndex = materialIndex;
+ threejsGeometry.faces.push(face);
+ for (i = 0, _len6 = dataVertTexcoord.length; i < _len6; i++) {
+ data = dataVertTexcoord[i];
+ if (!(data != null)) {
+ geometry.faceVertexUvs[i].push([new THREE.Vector2(0, 0), new THREE.Vector2(0, 0), new THREE.Vector2(0, 0)]);
+ } else {
+ texcoord = [data[v0], data[v1], data[v2]];
+ geometry.faceVertexUvs[i].push(texcoord);
+ }
+ }
+ for (i = 0, _len7 = dataTriTexcoord.length; i < _len7; i++) {
+ data = dataTriTexcoord[i];
+ if (!(data != null)) {
+ geometry.faceVertexUvs[i].push([new THREE.Vector2(0, 0), new THREE.Vector2(0, 0), new THREE.Vector2(0, 0)]);
+ } else {
+ t0 = indices[baseOffset0 + inputTriTexcoord[i].offset];
+ t1 = indices[baseOffset1 + inputTriTexcoord[i].offset];
+ t2 = indices[baseOffset2 + inputTriTexcoord[i].offset];
+ texcoord = [data[t0], data[t1], data[t2]];
+ threejsGeometry.faceVertexUvs[i].push(texcoord);
+ }
+ }
+ }
+ };
+
+ ColladaFile.prototype._addEmptyUVs = function(faceVertexUvs, count) {
+ var i, _ref;
+ for (i = 0, _ref = count - 1; i <= _ref; i += 1) {
+ faceVertexUvs.push(new THREE.Vector2(0, 0));
+ }
+ };
+
+ ColladaFile.prototype._createVector3Array = function(source) {
+ var data, i, srcData, _ref;
+ if (!(source != null)) return null;
+ if (source.stride !== 3) {
+ this._log("Vector source data does not contain 3D vectors", ColladaLoader2.messageError);
+ return null;
+ }
+ data = [];
+ srcData = source.data;
+ for (i = 0, _ref = srcData.length - 1; i <= _ref; i += 3) {
+ data.push(new THREE.Vector3(srcData[i], srcData[i + 1], srcData[i + 2]));
+ }
+ return data;
+ };
+
+ ColladaFile.prototype._createColorArray = function(source) {
+ var data, i, srcData, _ref, _ref2;
+ if (!(source != null)) return null;
+ if (source.stride < 3) {
+ this._log("Color source data does not contain 3+D vectors", ColladaLoader2.messageError);
+ return null;
+ }
+ data = [];
+ srcData = source.data;
+ for (i = 0, _ref = srcData.length - 1, _ref2 = source.stride; 0 <= _ref ? i <= _ref : i >= _ref; i += _ref2) {
+ data.push(new THREE.Color().setRGB(srcData[i], srcData[i + 1], srcData[i + 2]));
+ }
+ return data;
+ };
+
+ ColladaFile.prototype._createUVArray = function(source) {
+ var data, i, srcData, _ref, _ref2;
+ if (!(source != null)) return null;
+ if (source.stride < 2) {
+ this._log("UV source data does not contain 2+D vectors", ColladaLoader2.messageError);
+ return null;
+ }
+ data = [];
+ srcData = source.data;
+ for (i = 0, _ref = srcData.length - 1, _ref2 = source.stride; 0 <= _ref ? i <= _ref : i >= _ref; i += _ref2) {
+ data.push(new THREE.Vector2(srcData[i], 1.0 - srcData[i + 1]));
+ }
+ return data;
+ };
+
+ ColladaFile.prototype._createMaterials = function(daeInstanceMaterials) {
+ var daeInstanceMaterial, numMaterials, result, symbol, threejsMaterial, _i, _len;
+ result = new ThreejsMaterialMap;
+ numMaterials = 0;
+ for (_i = 0, _len = daeInstanceMaterials.length; _i < _len; _i++) {
+ daeInstanceMaterial = daeInstanceMaterials[_i];
+ symbol = daeInstanceMaterial.symbol;
+ if (!(symbol != null)) {
+ this._log("Material instance has no symbol, material skipped.", ColladaLoader2.messageError);
+ continue;
+ }
+ if (result.indices[symbol] != null) {
+ this._log("Geometry instance tried to map material symbol " + symbol + " multiple times", ColladaLoader2.messageError);
+ continue;
+ }
+ threejsMaterial = this._createMaterial(daeInstanceMaterial);
+ if ((threejsMaterial.bumpMap != null) || (threejsMaterial.normalMap != null)) {
+ result.needtangents = true;
+ }
+ this.threejs.materials.push(threejsMaterial);
+ result.materials.push(threejsMaterial);
+ result.indices[symbol] = numMaterials++;
+ }
+ return result;
+ };
+
+ ColladaFile.prototype._createMaterial = function(daeInstanceMaterial) {
+ var daeEffect, daeMaterial;
+ daeMaterial = this._getLinkTarget(daeInstanceMaterial.material, ColladaMaterial);
+ if (!(daeMaterial != null)) return this._createDefaultMaterial;
+ daeEffect = this._getLinkTarget(daeMaterial.effect, ColladaEffect);
+ if (!(daeEffect != null)) return this._createDefaultMaterial;
+ return this._createBuiltInMaterial(daeEffect);
+ };
+
+ ColladaFile.prototype._createShaderMaterial = function(daeEffect) {
+ var materialNormalMap, shader, technique, textureDiffuse, textureLight, textureNormal, textureSpecular, uniforms, _ref, _ref2, _ref3;
+ technique = daeEffect.technique;
+ shader = THREE.ShaderUtils.lib["normal"];
+ uniforms = THREE.UniformsUtils.clone(shader.uniforms);
+ textureNormal = this._loadThreejsTexture(technique.bump);
+ if (textureNormal != null) {
+ uniforms["tNormal"].texture = textureNormal;
+ uniforms["uNormalScale"].value = 0.85;
+ }
+ textureDiffuse = this._loadThreejsTexture(technique.diffuse);
+ if (textureDiffuse != null) {
+ uniforms["tDiffuse"].texture = textureDiffuse;
+ uniforms["enableDiffuse"].value = true;
+ } else {
+ uniforms["enableDiffuse"].value = false;
+ }
+ textureSpecular = this._loadThreejsTexture(technique.specular);
+ if (textureSpecular != null) {
+ uniforms["tSpecular"].texture = textureSpecular;
+ uniforms["enableSpecular"].value = true;
+ } else {
+ uniforms["enableSpecular"].value = false;
+ }
+ textureLight = this._loadThreejsTexture(technique.emission);
+ if (textureLight != null) {
+ uniforms["tAO"].texture = textureLight;
+ uniforms["enableAO"].value = true;
+ } else {
+ uniforms["enableAO"].value = false;
+ }
+ if (((_ref = technique.diffuse) != null ? _ref.color : void 0) != null) {
+ uniforms["uDiffuseColor"].value.setHex(_colorToHex(technique.diffuse.color));
+ }
+ if (((_ref2 = technique.specular) != null ? _ref2.color : void 0) != null) {
+ uniforms["uSpecularColor"].value.setHex(_colorToHex(technique.specular.color));
+ }
+ if (((_ref3 = technique.ambient) != null ? _ref3.color : void 0) != null) {
+ uniforms["uAmbientColor"].value.setHex(_colorToHex(technique.ambient.color));
+ }
+ if (technique.shininess != null) {
+ uniforms["uShininess"].value = technique.shininess;
+ }
+ if (technique.transparency != null) {
+ uniforms["uOpacity"].value = this._getOpacity(daeEffect);
+ }
+ materialNormalMap = new THREE.ShaderMaterial({
+ fragmentShader: shader.fragmentShader,
+ vertexShader: shader.vertexShader,
+ uniforms: uniforms,
+ lights: true
+ });
+ return materialNormalMap;
+ };
+
+ ColladaFile.prototype._getOpacity = function(daeEffect) {
+ var opacityMode, technique, transparency, transparent, transparentA, _ref;
+ technique = daeEffect.technique;
+ transparent = technique.transparent;
+ opacityMode = transparent != null ? transparent.opaque : void 0;
+ if ((opacityMode != null) && opacityMode !== "A_ONE") {
+ this._log("Opacity mode " + opacityMode + " not supported, transparency will be broken", ColladaLoader2.messageWarning);
+ }
+ if ((transparent != null ? transparent.textureSampler : void 0) != null) {
+ this._log("Separate transparency texture not supported, transparency will be broken", ColladaLoader2.messageWarning);
+ }
+ transparentA = (transparent != null ? (_ref = transparent.color) != null ? _ref[3] : void 0 : void 0) || 1;
+ transparency = technique.transparency || 1;
+ return transparentA * transparency;
+ };
+
+ ColladaFile.prototype._hasTransparency = function(daeEffect) {
+ var technique, _ref, _ref2;
+ technique = daeEffect.technique;
+ return (((_ref = technique.transparent) != null ? _ref.textureSampler : void 0) != null) || ((0 >= (_ref2 = technique.transparency) && _ref2 >= 1));
+ };
+
+ ColladaFile.prototype._createBuiltInMaterial = function(daeEffect) {
+ var hasTransparency, opacity, params, technique;
+ technique = daeEffect.technique;
+ params = {};
+ this._setThreejsMaterialParam(params, technique.diffuse, "diffuse", "map", false);
+ this._setThreejsMaterialParam(params, technique.emission, "emissive", null, false);
+ this._setThreejsMaterialParam(params, technique.ambient, "ambient", "lightMap", false);
+ this._setThreejsMaterialParam(params, technique.specular, "specular", "specularMap", false);
+ this._setThreejsMaterialParam(params, technique.bump, null, "normalMap", false);
+ if (params["bumpMap"]) params["bumpScale"] = 1.0;
+ if (params["normalMap"]) params["normalScale"] = new THREE.Vector2(1.0, 1.0);
+ if (params["map"] != null) params["diffuse"] = 0xffffff;
+ if (params["specularMap"] != null) params["specular"] = 0xffffff;
+ if (!(params["diffuse"] != null)) params["diffuse"] = 0xffffff;
+ if (technique.shininess != null) params["shininess"] = technique.shininess;
+ if (technique.reflectivity != null) {
+ params["reflectivity"] = technique.reflectivity;
+ }
+ hasTransparency = this._hasTransparency(daeEffect);
+ if (hasTransparency) {
+ params["transparent"] = true;
+ opacity = this._getOpacity(daeEffect);
+ params["opacity"] = opacity;
+ params["alphaTest"] = 0.001;
+ }
+ if (technique.doubleSided) params["side"] = THREE.DoubleSide;
+ params["shading"] = THREE.SmoothShading;
+ params["perPixel"] = true;
+ switch (technique.shading) {
+ case "blinn":
+ case "phong":
+ params["color"] = params["diffuse"];
+ return new THREE.MeshPhongMaterial(params);
+ case "lambert":
+ params["color"] = params["diffuse"];
+ return new THREE.MeshLambertMaterial(params);
+ case "constant":
+ params["color"] = params["emission"];
+ return new THREE.MeshBasicMaterial(params);
+ default:
+ return this._createDefaultMaterial;
+ }
+ };
+
+ ColladaFile.prototype._createDefaultMaterial = function() {
+ return new THREE.MeshLambertMaterial({
+ color: 0xdddddd,
+ shading: THREE.FlatShading
+ });
+ };
+
+ ColladaFile.prototype._setThreejsMaterialParam = function(params, colorOrTexture, nameColor, nameTexture, replace) {
+ var threejsTexture;
+ if (!(colorOrTexture != null)) return;
+ if ((colorOrTexture.color != null) && (nameColor != null)) {
+ if (!replace && (params[nameColor] != null)) return;
+ params[nameColor] = _colorToHex(colorOrTexture.color);
+ } else if ((colorOrTexture.textureSampler != null) && (nameTexture != null)) {
+ if (!replace && (params[nameTexture] != null)) return;
+ threejsTexture = this._loadThreejsTexture(colorOrTexture);
+ if (threejsTexture != null) params[nameTexture] = threejsTexture;
+ }
+ };
+
+ ColladaFile.prototype._loadThreejsTexture = function(colorOrTexture) {
+ var imageURL, texture, textureImage, textureSampler, textureSurface;
+ if (!(colorOrTexture.textureSampler != null)) return null;
+ textureSampler = this._getLinkTarget(colorOrTexture.textureSampler, ColladaEffectSampler);
+ if (!(textureSampler != null)) return null;
+ textureImage = null;
+ if (textureSampler.image != null) {
+ textureImage = this._getLinkTarget(textureSampler.image, ColladaImage);
+ } else if (textureSampler.surface != null) {
+ textureSurface = this._getLinkTarget(textureSampler.surface, ColladaEffectSurface);
+ textureImage = this._getLinkTarget(textureSurface.initFrom, ColladaImage);
+ }
+ if (!(textureImage != null)) return null;
+ imageURL = this._baseUrl + textureImage.initFrom;
+ texture = this._loader._loadTextureFromURL(imageURL);
+ return texture;
+ };
+
+ return ColladaFile;
+
+ })();
+
+ ColladaLoader2 = (function() {
+
+ ColladaLoader2.messageTrace = 0;
+
+ ColladaLoader2.messageInfo = 1;
+
+ ColladaLoader2.messageWarning = 2;
+
+ ColladaLoader2.messageError = 3;
+
+ ColladaLoader2.messageTypes = ["TRACE", "INFO", "WARNING", "ERROR"];
+
+ function ColladaLoader2() {
+ this.log = ColladaLoader2.logConsole;
+ this._imageCache = {};
+ this.options = {
+ "useAnimations": true,
+ "convertSkinsToMorphs": false,
+ "verboseMessages": false,
+ "localImageMode": false
+ };
+ }
+
+ ColladaLoader2.logConsole = function(msg, type) {
+ console.log("ColladaLoader2 " + ColladaLoader2.messageTypes[type] + ": " + msg);
+ };
+
+ ColladaLoader2.prototype.setLog = function(logCallback) {
+ this.log = logCallback || this.logConsole;
+ };
+
+ ColladaLoader2.prototype.addChachedTextures = function(textures) {
+ var key, value;
+ for (key in textures) {
+ value = textures[key];
+ this._imageCache[key] = value;
+ }
+ };
+
+ ColladaLoader2.prototype.load = function(url, readyCallback, progressCallback) {
+ var length, req, _ref,
+ _this = this;
+ length = 0;
+ if ((_ref = document.implementation) != null ? _ref.createDocument : void 0) {
+ req = new XMLHttpRequest();
+ if (typeof req.overrideMimeType === "function") {
+ req.overrideMimeType("text/xml");
+ }
+ req.onreadystatechange = function() {
+ if (req.readyState === 4) {
+ if (req.status === 0 || req.status === 200) {
+ if (req.responseXML) {
+ return _this.parse(req.responseXML, readyCallback, url);
+ } else {
+ return _this.log("Empty or non-existing file " + url + ".", ColladaLoader2.messageError);
+ }
+ }
+ } else if (req.readyState === 3) {
+ if (progressCallback) {
+ if (length === 0) length = req.getResponseHeader("Content-Length");
+ return progressCallback({
+ total: length,
+ loaded: req.responseText.length
+ });
+ }
+ }
+ };
+ req.open("GET", url, true);
+ req.send(null);
+ } else {
+ this.log("Don't know how to parse XML!", ColladaLoader2.messageError);
+ }
+ };
+
+ ColladaLoader2.prototype.parse = function(doc, readyCallback, url) {
+ var file;
+ file = new ColladaFile(this);
+ file.setUrl(url);
+ file._readyCallback = readyCallback;
+ file._parseXml(doc);
+ file._linkAnimations();
+ file._createSceneGraph();
+ if (file._readyCallback) file._readyCallback(file);
+ return file;
+ };
+
+ ColladaLoader2.prototype._loadTextureFromURL = function(imageURL) {
+ var texture;
+ texture = this._imageCache[imageURL];
+ if (texture != null) return texture;
+ if (this.options.localImageMode) texture = this._loadImageLocal(imageURL);
+ if (!(texture != null)) texture = this._loadImageSimple(imageURL);
+ if (texture != null) {
+ this._imageCache[imageURL] = texture;
+ } else {
+ this.log("Texture " + imageURL + " could not be loaded, texture will be ignored.", ColladaLoader2.messageError);
+ }
+ return texture;
+ };
+
+ ColladaLoader2.prototype._loadImageThreejs = function(imageURL) {
+ var texture;
+ texture = THREE.ImageUtils.loadTexture(imageURL);
+ texture.flipY = false;
+ return texture;
+ };
+
+ ColladaLoader2.prototype._loadImageSimple = function(imageURL) {
+ var image, texture;
+ image = new Image();
+ texture = new THREE.Texture(image);
+ texture.flipY = false;
+ texture.wrapS = THREE.RepeatWrapping;
+ texture.wrapT = THREE.RepeatWrapping;
+ image.onload = function() {
+ return texture.needsUpdate = true;
+ };
+ image.crossOrigin = 'anonymous';
+ image.src = imageURL;
+ return texture;
+ };
+
+ ColladaLoader2.prototype._loadImageLocal = function(imageURL) {
+ var cachedURLBase, imageURLBase, key, texture, value, _ref, _ref2;
+ imageURLBase = this._removeSameDirectoryPath(imageURL);
+ _ref = this._imageCache;
+ for (key in _ref) {
+ value = _ref[key];
+ cachedURLBase = this._removeSameDirectoryPath(key);
+ if (imageURLBase.indexOf(cachedURLBase) >= 0) {
+ texture = value;
+ break;
+ }
+ }
+ imageURLBase = this._removeSameDirectoryPath(this._removeFileExtension(imageURL));
+ if (!(texture != null)) {
+ _ref2 = this._imageCache;
+ for (key in _ref2) {
+ value = _ref2[key];
+ cachedURLBase = this._removeSameDirectoryPath(this._removeFileExtension(key));
+ if (imageURLBase.indexOf(cachedURLBase) >= 0) {
+ texture = value;
+ break;
+ }
+ }
+ }
+ return texture;
+ };
+
+ ColladaLoader2.prototype._removeFileExtension = function(filePath) {
+ return filePath.substr(0, filePath.lastIndexOf(".")) || filePath;
+ };
+
+ ColladaLoader2.prototype._removeSameDirectoryPath = function(filePath) {
+ return filePath.replace(/^.\//, "");
+ };
+
+ return ColladaLoader2;
+
+ })();
+
+ _strToStrings = function(str) {
+ var trimmed;
+ if (str.length > 0) {
+ trimmed = str.trim();
+ return trimmed.split(/\s+/);
+ } else {
+ return [];
+ }
+ };
+
+ _strToFloats = function(str) {
+ var data, i, string, strings, _len;
+ strings = _strToStrings(str);
+ data = new Float32Array(strings.length);
+ for (i = 0, _len = strings.length; i < _len; i++) {
+ string = strings[i];
+ data[i] = parseFloat(string);
+ }
+ return data;
+ };
+
+ _strToInts = function(str) {
+ var data, i, string, strings, _len;
+ strings = _strToStrings(str);
+ data = new Int32Array(strings.length);
+ for (i = 0, _len = strings.length; i < _len; i++) {
+ string = strings[i];
+ data[i] = parseInt(string, 10);
+ }
+ return data;
+ };
+
+ _strToBools = function(str) {
+ var data, i, string, strings, _len, _ref;
+ strings = _strToStrings(str);
+ data = new Uint8Array(strings.length);
+ for (i = 0, _len = strings.length; i < _len; i++) {
+ string = strings[i];
+ data[i] = (_ref = string === "true" || string === "1") != null ? _ref : {
+ 1: 0
+ };
+ }
+ return data;
+ };
+
+ _strToColor = function(str) {
+ var rgba;
+ rgba = _strToFloats(str);
+ if (rgba.length === 4) {
+ return rgba;
+ } else {
+ return null;
+ }
+ };
+
+ _colorToHex = function(rgba) {
+ if (rgba != null) {
+ return Math.floor(rgba[0] * 255) << 16 ^ Math.floor(rgba[1] * 255) << 8 ^ Math.floor(rgba[2] * 255);
+ } else {
+ return null;
+ }
+ };
+
+ _floatsToMatrix4ColumnMajor = function(data, offset) {
+ return new THREE.Matrix4(data[0 + offset], data[4 + offset], data[8 + offset], data[12 + offset], data[1 + offset], data[5 + offset], data[9 + offset], data[13 + offset], data[2 + offset], data[6 + offset], data[10 + offset], data[14 + offset], data[3 + offset], data[7 + offset], data[11 + offset], data[15 + offset]);
+ };
+
+ _floatsToMatrix4RowMajor = function(data, offset) {
+ return new THREE.Matrix4(data[0 + offset], data[1 + offset], data[2 + offset], data[3 + offset], data[4 + offset], data[5 + offset], data[6 + offset], data[7 + offset], data[8 + offset], data[9 + offset], data[10 + offset], data[11 + offset], data[12 + offset], data[13 + offset], data[14 + offset], data[15 + offset]);
+ };
+
+ _fillMatrix4ColumnMajor = function(data, offset, matrix) {
+ return matrix.set(data[0 + offset], data[4 + offset], data[8 + offset], data[12 + offset], data[1 + offset], data[5 + offset], data[9 + offset], data[13 + offset], data[2 + offset], data[6 + offset], data[10 + offset], data[14 + offset], data[3 + offset], data[7 + offset], data[11 + offset], data[15 + offset]);
+ };
+
+ _fillMatrix4RowMajor = function(data, offset, matrix) {
+ return matrix.set(data[0 + offset], data[1 + offset], data[2 + offset], data[3 + offset], data[4 + offset], data[5 + offset], data[6 + offset], data[7 + offset], data[8 + offset], data[9 + offset], data[10 + offset], data[11 + offset], data[12 + offset], data[13 + offset], data[14 + offset], data[15 + offset]);
+ };
+
+ _checkMatrix4 = function(matrix) {
+ var col1len, col2len, col3len, me;
+ me = matrix.elements;
+ if (me[3] !== 0 || me[7] !== 0 || me[11] !== 0 || me[15] !== 1) {
+ throw new Error("Last row isnt [0,0,0,1]");
+ }
+ col1len = Math.sqrt(me[0] * me[0] + me[1] * me[1] + me[2] * me[2]);
+ col2len = Math.sqrt(me[4] * me[4] + me[5] * me[5] + me[6] * me[6]);
+ col3len = Math.sqrt(me[8] * me[8] + me[9] * me[9] + me[10] * me[10]);
+ if (col1len < 0.9 || col1len > 1.1) {
+ throw new Error("First column has significant scaling");
+ }
+ if (col2len < 0.9 || col2len > 1.1) {
+ throw new Error("Second column has significant scaling");
+ }
+ if (col3len < 0.9 || col3len > 1.1) {
+ throw new Error("Third column has significant scaling");
+ }
+ };
+
+ _floatsToVec3 = function(data) {
+ return new THREE.Vector3(data[0], data[1], data[2]);
+ };
+
+ TO_RADIANS = Math.PI / 180.0;
+
+ ColladaLoader2.prototype['setLog'] = ColladaLoader2.prototype.setLog;
+
+ ColladaLoader2.prototype['addChachedTextures'] = ColladaLoader2.prototype.addChachedTextures;
+
+ ColladaLoader2.prototype['load'] = ColladaLoader2.prototype.load;
+
+ ColladaLoader2.prototype['parse'] = ColladaLoader2.prototype.parse;
+
+ if (typeof module !== "undefined" && module !== null) {
+ module['exports'] = ColladaLoader2;
+ } else if (typeof window !== "undefined" && window !== null) {
+ window['ColladaLoader2'] = ColladaLoader2;
+ }
+
+}).call(this);
diff --git a/vulcano_web/javascript_libraries/Ros3D.js b/vulcano_web/javascript_libraries/Ros3D.js
new file mode 100755
index 0000000..604c9c6
--- /dev/null
+++ b/vulcano_web/javascript_libraries/Ros3D.js
@@ -0,0 +1,169 @@
+/**
+ * @author Russell Toris - rctoris@wpi.edu
+ * @author David Gossow - dgossow@willowgarage.com
+ */
+
+var ROS3D = ROS3D || {
+ REVISION : '8-devel'
+};
+
+// Marker types
+ROS3D.MARKER_ARROW = 0;
+ROS3D.MARKER_CUBE = 1;
+ROS3D.MARKER_SPHERE = 2;
+ROS3D.MARKER_CYLINDER = 3;
+ROS3D.MARKER_LINE_STRIP = 4;
+ROS3D.MARKER_LINE_LIST = 5;
+ROS3D.MARKER_CUBE_LIST = 6;
+ROS3D.MARKER_SPHERE_LIST = 7;
+ROS3D.MARKER_POINTS = 8;
+ROS3D.MARKER_TEXT_VIEW_FACING = 9;
+ROS3D.MARKER_MESH_RESOURCE = 10;
+ROS3D.MARKER_TRIANGLE_LIST = 11;
+
+// Interactive marker feedback types
+ROS3D.INTERACTIVE_MARKER_KEEP_ALIVE = 0;
+ROS3D.INTERACTIVE_MARKER_POSE_UPDATE = 1;
+ROS3D.INTERACTIVE_MARKER_MENU_SELECT = 2;
+ROS3D.INTERACTIVE_MARKER_BUTTON_CLICK = 3;
+ROS3D.INTERACTIVE_MARKER_MOUSE_DOWN = 4;
+ROS3D.INTERACTIVE_MARKER_MOUSE_UP = 5;
+
+// Interactive marker control types
+ROS3D.INTERACTIVE_MARKER_NONE = 0;
+ROS3D.INTERACTIVE_MARKER_MENU = 1;
+ROS3D.INTERACTIVE_MARKER_BUTTON = 2;
+ROS3D.INTERACTIVE_MARKER_MOVE_AXIS = 3;
+ROS3D.INTERACTIVE_MARKER_MOVE_PLANE = 4;
+ROS3D.INTERACTIVE_MARKER_ROTATE_AXIS = 5;
+ROS3D.INTERACTIVE_MARKER_MOVE_ROTATE = 6;
+
+// Interactive marker rotation behavior
+ROS3D.INTERACTIVE_MARKER_INHERIT = 0;
+ROS3D.INTERACTIVE_MARKER_FIXED = 1;
+ROS3D.INTERACTIVE_MARKER_VIEW_FACING = 2;
+
+/**
+ * Create a THREE material based on the given RGBA values.
+ *
+ * @param r - the red value
+ * @param g - the green value
+ * @param b - the blue value
+ * @param a - the alpha value
+ * @returns the THREE material
+ */
+ROS3D.makeColorMaterial = function(r, g, b, a) {
+ var color = new THREE.Color();
+ color.setRGB(r, g, b);
+ if (a <= 0.99) {
+ return new THREE.MeshBasicMaterial({
+ color : color.getHex(),
+ opacity : a + 0.1,
+ transparent : true,
+ depthWrite : true,
+ blendSrc : THREE.SrcAlphaFactor,
+ blendDst : THREE.OneMinusSrcAlphaFactor,
+ blendEquation : THREE.ReverseSubtractEquation,
+ blending : THREE.NormalBlending
+ });
+ } else {
+ return new THREE.MeshLambertMaterial({
+ color : color.getHex(),
+ opacity : a,
+ blending : THREE.NormalBlending
+ });
+ }
+};
+
+/**
+ * Return the intersection between the mouseray and the plane.
+ *
+ * @param mouseRay - the mouse ray
+ * @param planeOrigin - the origin of the plane
+ * @param planeNormal - the normal of the plane
+ * @returns the intersection point
+ */
+ROS3D.intersectPlane = function(mouseRay, planeOrigin, planeNormal) {
+ var vector = new THREE.Vector3();
+ var intersectPoint = new THREE.Vector3();
+ vector.subVectors(planeOrigin, mouseRay.origin);
+ var dot = mouseRay.direction.dot(planeNormal);
+
+ // bail if ray and plane are parallel
+ if (Math.abs(dot) < mouseRay.precision) {
+ return undefined;
+ }
+
+ // calc distance to plane
+ var scalar = planeNormal.dot(vector) / dot;
+
+ intersectPoint.addVectors(mouseRay.origin, mouseRay.direction.clone().multiplyScalar(scalar));
+ return intersectPoint;
+};
+
+/**
+ * Find the closest point on targetRay to any point on mouseRay. Math taken from
+ * http://paulbourke.net/geometry/lineline3d/
+ *
+ * @param targetRay - the target ray to use
+ * @param mouseRay - the mouse ray
+ * @param the closest point between the two rays
+ */
+ROS3D.findClosestPoint = function(targetRay, mouseRay) {
+ var v13 = new THREE.Vector3();
+ v13.subVectors(targetRay.origin, mouseRay.origin);
+ var v43 = mouseRay.direction.clone();
+ var v21 = targetRay.direction.clone();
+ var d1343 = v13.dot(v43);
+ var d4321 = v43.dot(v21);
+ var d1321 = v13.dot(v21);
+ var d4343 = v43.dot(v43);
+ var d2121 = v21.dot(v21);
+
+ var denom = d2121 * d4343 - d4321 * d4321;
+ // check within a delta
+ if (Math.abs(denom) <= 0.0001) {
+ return undefined;
+ }
+ var numer = d1343 * d4321 - d1321 * d4343;
+
+ var mua = numer / denom;
+ return mua;
+};
+
+/**
+ * Find the closest point between the axis and the mouse.
+ *
+ * @param axisRay - the ray from the axis
+ * @param camera - the camera to project from
+ * @param mousePos - the mouse position
+ * @returns the closest axis point
+ */
+ROS3D.closestAxisPoint = function(axisRay, camera, mousePos) {
+ var projector = new THREE.Projector();
+
+ // project axis onto screen
+ var o = axisRay.origin.clone();
+ projector.projectVector(o, camera);
+ var o2 = axisRay.direction.clone().add(axisRay.origin);
+ projector.projectVector(o2, camera);
+
+ // d is the axis vector in screen space (d = o2-o)
+ var d = o2.clone().sub(o);
+
+ // t is the 2d ray param of perpendicular projection of mousePos onto o
+ var tmp = new THREE.Vector2();
+ // (t = (mousePos - o) * d / (d*d))
+ var t = tmp.subVectors(mousePos, o).dot(d) / d.dot(d);
+
+ // mp is the final 2d-projected mouse pos (mp = o + d*t)
+ var mp = new THREE.Vector2();
+ mp.addVectors(o, d.clone().multiplyScalar(t));
+
+ // go back to 3d by shooting a ray
+ var vector = new THREE.Vector3(mp.x, mp.y, 0.5);
+ projector.unprojectVector(vector, camera);
+ var mpRay = new THREE.Ray(camera.position, vector.sub(camera.position).normalize());
+
+ return ROS3D.findClosestPoint(axisRay, mpRay);
+};
diff --git a/vulcano_web/javascript_libraries/depthcloud/DepthCloud.js b/vulcano_web/javascript_libraries/depthcloud/DepthCloud.js
new file mode 100755
index 0000000..b13cc05
--- /dev/null
+++ b/vulcano_web/javascript_libraries/depthcloud/DepthCloud.js
@@ -0,0 +1,305 @@
+/**
+ * @author Julius Kammerl - jkammerl@willowgarage.com
+ */
+
+/**
+ * The DepthCloud object.
+ *
+ * @constructor
+ * @param options - object with following keys:
+ * * url - the URL of the stream
+ * * f (optional) - the camera's focal length (defaults to standard Kinect calibration)
+ * * pointSize (optional) - point size (pixels) for rendered point cloud
+ * * width (optional) - width of the video stream
+ * * height (optional) - height of the video stream
+ * * whiteness (optional) - blends rgb values to white (0..100)
+ * * varianceThreshold (optional) - threshold for variance filter, used for compression artifact removal
+ */
+ROS3D.DepthCloud = function(options) {
+ options = options || {};
+ THREE.Object3D.call(this);
+
+ this.url = options.url;
+ this.f = options.f || 526;
+ this.pointSize = options.pointSize || 3;
+ this.width = options.width || 1024;
+ this.height = options.height || 1024;
+ this.whiteness = options.whiteness || 0;
+ this.varianceThreshold = options.varianceThreshold || 0.000016667;
+
+ var metaLoaded = false;
+ this.video = document.createElement('video');
+
+ this.video.addEventListener('loadedmetadata', this.metaLoaded.bind(this), false);
+
+ this.video.loop = true;
+ this.video.src = this.url;
+ this.video.crossOrigin = 'Anonymous';
+ this.video.setAttribute('crossorigin', 'Anonymous');
+
+ // define custom shaders
+ this.vertex_shader = [
+ 'uniform sampler2D map;',
+ '',
+ 'uniform float width;',
+ 'uniform float height;',
+ 'uniform float nearClipping, farClipping;',
+ '',
+ 'uniform float pointSize;',
+ 'uniform float zOffset;',
+ '',
+ 'uniform float focallength;',
+ '',
+ 'varying vec2 vUvP;',
+ 'varying vec2 colorP;',
+ '',
+ 'varying float depthVariance;',
+ 'varying float maskVal;',
+ '',
+ 'float sampleDepth(vec2 pos)',
+ ' {',
+ ' float depth;',
+ ' ',
+ ' vec2 vUv = vec2( pos.x / (width*2.0), pos.y / (height*2.0)+0.5 );',
+ ' vec2 vUv2 = vec2( pos.x / (width*2.0)+0.5, pos.y / (height*2.0)+0.5 );',
+ ' ',
+ ' vec4 depthColor = texture2D( map, vUv );',
+ ' ',
+ ' depth = ( depthColor.r + depthColor.g + depthColor.b ) / 3.0 ;',
+ ' ',
+ ' if (depth>0.99)',
+ ' {',
+ ' vec4 depthColor2 = texture2D( map, vUv2 );',
+ ' float depth2 = ( depthColor2.r + depthColor2.g + depthColor2.b ) / 3.0 ;',
+ ' depth = 0.99+depth2;',
+ ' }',
+ ' ',
+ ' return depth;',
+ ' }',
+ '',
+ 'float median(float a, float b, float c)',
+ ' {',
+ ' float r=a;',
+ ' ',
+ ' if ( (a0.5) || (vUvP.y<0.5) || (vUvP.y>0.0))',
+ ' {',
+ ' vec2 smp = decodeDepth(vec2(position.x, position.y));',
+ ' float depth = smp.x;',
+ ' depthVariance = smp.y;',
+ ' ',
+ ' float z = -depth;',
+ ' ',
+ ' pos = vec4(',
+ ' ( position.x / width - 0.5 ) * z * (1000.0/focallength) * -1.0,',
+ ' ( position.y / height - 0.5 ) * z * (1000.0/focallength),',
+ ' (- z + zOffset / 1000.0) * 2.0,',
+ ' 1.0);',
+ ' ',
+ ' vec2 maskP = vec2( position.x / (width*2.0), position.y / (height*2.0) );',
+ ' vec4 maskColor = texture2D( map, maskP );',
+ ' maskVal = ( maskColor.r + maskColor.g + maskColor.b ) / 3.0 ;',
+ ' }',
+ ' ',
+ ' gl_PointSize = pointSize;',
+ ' gl_Position = projectionMatrix * modelViewMatrix * pos;',
+ ' ',
+ '}'
+ ].join('\n');
+
+ this.fragment_shader = [
+ 'uniform sampler2D map;',
+ 'uniform float varianceThreshold;',
+ 'uniform float whiteness;',
+ '',
+ 'varying vec2 vUvP;',
+ 'varying vec2 colorP;',
+ '',
+ 'varying float depthVariance;',
+ 'varying float maskVal;',
+ '',
+ '',
+ 'void main() {',
+ ' ',
+ ' vec4 color;',
+ ' ',
+ ' if ( (depthVariance>varianceThreshold) || (maskVal>0.5) ||(vUvP.x<0.0)|| (vUvP.x>0.5) || (vUvP.y<0.5) || (vUvP.y>1.0))',
+ ' { ',
+ ' discard;',
+ ' }',
+ ' else ',
+ ' {',
+ ' color = texture2D( map, colorP );',
+ ' ',
+ ' float fader = whiteness /100.0;',
+ ' ',
+ ' color.r = color.r * (1.0-fader)+ fader;',
+ ' ',
+ ' color.g = color.g * (1.0-fader)+ fader;',
+ ' ',
+ ' color.b = color.b * (1.0-fader)+ fader;',
+ ' ',
+ ' color.a = 1.0;//smoothstep( 20000.0, -20000.0, gl_FragCoord.z / gl_FragCoord.w );',
+ ' }',
+ ' ',
+ ' gl_FragColor = vec4( color.r, color.g, color.b, color.a );',
+ ' ',
+ '}'
+ ].join('\n');
+};
+ROS3D.DepthCloud.prototype.__proto__ = THREE.Object3D.prototype;
+
+/**
+ * Callback called when video metadata is ready
+ */
+ROS3D.DepthCloud.prototype.metaLoaded = function() {
+ this.metaLoaded = true;
+ this.initStreamer();
+};
+
+/**
+ * Callback called when video metadata is ready
+ */
+ROS3D.DepthCloud.prototype.initStreamer = function() {
+
+ if (this.metaLoaded) {
+ this.texture = new THREE.Texture(this.video);
+ this.geometry = new THREE.Geometry();
+
+ for (var i = 0, l = this.width * this.height; i < l; i++) {
+
+ var vertex = new THREE.Vector3();
+ vertex.x = (i % this.width);
+ vertex.y = Math.floor(i / this.width);
+
+ this.geometry.vertices.push(vertex);
+ }
+
+ this.material = new THREE.ShaderMaterial({
+ uniforms : {
+ 'map' : {
+ type : 't',
+ value : this.texture
+ },
+ 'width' : {
+ type : 'f',
+ value : this.width
+ },
+ 'height' : {
+ type : 'f',
+ value : this.height
+ },
+ 'focallength' : {
+ type : 'f',
+ value : this.f
+ },
+ 'pointSize' : {
+ type : 'f',
+ value : this.pointSize
+ },
+ 'zOffset' : {
+ type : 'f',
+ value : 0
+ },
+ 'whiteness' : {
+ type : 'f',
+ value : this.whiteness
+ },
+ 'varianceThreshold' : {
+ type : 'f',
+ value : this.varianceThreshold
+ }
+ },
+ vertexShader : this.vertex_shader,
+ fragmentShader : this.fragment_shader
+ });
+
+ this.mesh = new THREE.ParticleSystem(this.geometry, this.material);
+ this.mesh.position.x = 0;
+ this.mesh.position.y = 0;
+ this.add(this.mesh);
+
+ var that = this;
+
+ setInterval(function() {
+ if (that.video.readyState === that.video.HAVE_ENOUGH_DATA) {
+ that.texture.needsUpdate = true;
+ }
+ }, 1000 / 30);
+ }
+};
+
+/**
+ * Start video playback
+ */
+ROS3D.DepthCloud.prototype.startStream = function() {
+ this.video.play();
+};
+
+/**
+ * Stop video playback
+ */
+ROS3D.DepthCloud.prototype.stopStream = function() {
+ this.video.stop();
+};
diff --git a/vulcano_web/javascript_libraries/eventemitter2.min.js b/vulcano_web/javascript_libraries/eventemitter2.min.js
new file mode 100755
index 0000000..5acfdaf
--- /dev/null
+++ b/vulcano_web/javascript_libraries/eventemitter2.min.js
@@ -0,0 +1 @@
+!function(d,b){var e=Array.isArray?Array.isArray:function h(k){return Object.prototype.toString.call(k)==="[object Array]"};var f=10;function i(){this._events={};if(this._conf){a.call(this,this._conf)}}function a(k){if(k){this._conf=k;k.delimiter&&(this.delimiter=k.delimiter);k.maxListeners&&(this._events.maxListeners=k.maxListeners);k.wildcard&&(this.wildcard=k.wildcard);k.newListener&&(this.newListener=k.newListener);if(this.wildcard){this.listenerTree={}}}}function j(k){this._events={};this.newListener=false;a.call(this,k)}function c(l,t,y,n){if(!y){return[]}var u=[],q,p,w,x,s,r,m,k=t.length,o=t[n],v=t[n+1];if(n===k&&y._listeners){if(typeof y._listeners==="function"){l&&l.push(y._listeners);return[y]}else{for(q=0,p=y._listeners.length;q0&&l._listeners.length>k){l._listeners.warned=true;console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",l._listeners.length);console.trace()}}}}}return true}o=q.shift()}return true}j.prototype.delimiter=".";j.prototype.setMaxListeners=function(k){this._events||i.call(this);this._events.maxListeners=k;if(!this._conf){this._conf={}}this._conf.maxListeners=k};j.prototype.event="";j.prototype.once=function(l,k){this.many(l,1,k);return this};j.prototype.many=function(n,k,m){var l=this;if(typeof m!=="function"){throw new Error("many only accepts instances of Function")}function o(){if(--k===0){l.off(n,o)}m.apply(this,arguments)}o._origin=m;this.on(n,o);return l};j.prototype.emit=function(){this._events||i.call(this);var r=arguments[0];if(r==="newListener"&&!this.newListener){if(!this._events.newListener){return false}}if(this._all){var k=arguments.length;var m=new Array(k-1);for(var n=1;n1){switch(arguments.length){case 2:q.call(this,arguments[1]);break;case 3:q.call(this,arguments[1],arguments[2]);break;default:var k=arguments.length;var m=new Array(k-1);for(var n=1;n0)||this._all}else{return this._all}}};j.prototype.on=function(l,n){if(typeof l==="function"){this.onAny(l);return this}if(typeof n!=="function"){throw new Error("on only accepts instances of Function")}this._events||i.call(this);this.emit("newListener",l,n);if(this.wildcard){g.call(this,l,n);return this}if(!this._events[l]){this._events[l]=n}else{if(typeof this._events[l]==="function"){this._events[l]=[this._events[l],n]}else{if(e(this._events[l])){this._events[l].push(n);if(!this._events[l].warned){var k=f;if(typeof this._events.maxListeners!=="undefined"){k=this._events.maxListeners}if(k>0&&this._events[l].length>k){this._events[l].warned=true;console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[l].length);console.trace()}}}}}return this};j.prototype.onAny=function(k){if(!this._all){this._all=[]}if(typeof k!=="function"){throw new Error("onAny only accepts instances of Function")}this._all.push(k);return this};j.prototype.addListener=j.prototype.on;j.prototype.off=function(q,l){if(typeof l!=="function"){throw new Error("removeListener only takes instances of Function")}var m,t=[];if(this.wildcard){var r=typeof q==="string"?q.split(this.delimiter):q.slice();t=c.call(this,null,r,this.listenerTree,0)}else{if(!this._events[q]){return this}m=this._events[q];t.push({_listeners:m})}for(var s=0;s0){m=this._all;for(n=0,k=m.length;n 0) {
+ this.menu = new ROS3D.InteractiveMarkerMenu({
+ menuEntries : handle.menuEntries
+ });
+
+ // forward menu select events
+ this.menu.addEventListener('menu-select', function(event) {
+ that.dispatchEvent(event);
+ });
+ }
+};
+ROS3D.InteractiveMarker.prototype.__proto__ = THREE.Object3D.prototype;
+
+/**
+ * Show the interactive marker menu associated with this marker.
+ *
+ * @param control - the control to use
+ * @param event - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.showMenu = function(control, event) {
+ if (this.menu) {
+ this.menu.show(control, event);
+ }
+};
+
+/**
+ * Move the axis based on the given event information.
+ *
+ * @param control - the control to use
+ * @param origAxis - the origin of the axis
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.moveAxis = function(control, origAxis, event3d) {
+ if (this.dragging) {
+ var currentControlOri = control.currentControlOri;
+ var axis = origAxis.clone().applyQuaternion(currentControlOri);
+ // get move axis in world coords
+ var originWorld = this.dragStart.event3d.intersection.point;
+ var axisWorld = axis.clone().applyQuaternion(this.dragStart.orientationWorld.clone());
+
+ var axisRay = new THREE.Ray(originWorld, axisWorld);
+
+ // find closest point to mouse on axis
+ var t = ROS3D.closestAxisPoint(axisRay, event3d.camera, event3d.mousePos);
+
+ // offset from drag start position
+ var p = new THREE.Vector3();
+ p.addVectors(this.dragStart.position, axis.clone().applyQuaternion(this.dragStart.orientation)
+ .multiplyScalar(t));
+ this.setPosition(control, p);
+
+ event3d.stopPropagation();
+ }
+};
+
+/**
+ * Move with respect to the plane based on the contorl and event.
+ *
+ * @param control - the control to use
+ * @param origNormal - the normal of the origin
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.movePlane = function(control, origNormal, event3d) {
+ if (this.dragging) {
+ var currentControlOri = control.currentControlOri;
+ var normal = origNormal.clone().applyQuaternion(currentControlOri);
+ // get plane params in world coords
+ var originWorld = this.dragStart.event3d.intersection.point;
+ var normalWorld = normal.clone().applyQuaternion(this.dragStart.orientationWorld);
+
+ // intersect mouse ray with plane
+ var intersection = ROS3D.intersectPlane(event3d.mouseRay, originWorld, normalWorld);
+
+ // offset from drag start position
+ var p = new THREE.Vector3();
+ p.subVectors(intersection, originWorld);
+ p.add(this.dragStart.positionWorld);
+ this.setPosition(control, p);
+ event3d.stopPropagation();
+ }
+};
+
+/**
+ * Rotate based on the control and event given.
+ *
+ * @param control - the control to use
+ * @param origOrientation - the orientation of the origin
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.rotateAxis = function(control, origOrientation, event3d) {
+ if (this.dragging) {
+ control.updateMatrixWorld();
+
+ var currentControlOri = control.currentControlOri;
+ var orientation = currentControlOri.clone().multiply(origOrientation.clone());
+
+ var normal = (new THREE.Vector3(1, 0, 0)).applyQuaternion(orientation);
+
+ // get plane params in world coords
+ var originWorld = this.dragStart.event3d.intersection.point;
+ var normalWorld = normal.applyQuaternion(this.dragStart.orientationWorld);
+
+ // intersect mouse ray with plane
+ var intersection = ROS3D.intersectPlane(event3d.mouseRay, originWorld, normalWorld);
+
+ // offset local origin to lie on intersection plane
+ var normalRay = new THREE.Ray(this.dragStart.positionWorld, normalWorld);
+ var rotOrigin = ROS3D.intersectPlane(normalRay, originWorld, normalWorld);
+
+ // rotates from world to plane coords
+ var orientationWorld = this.dragStart.orientationWorld.clone().multiply(orientation);
+ var orientationWorldInv = orientationWorld.clone().inverse();
+
+ // rotate original and current intersection into local coords
+ intersection.sub(rotOrigin);
+ intersection.applyQuaternion(orientationWorldInv);
+
+ var origIntersection = this.dragStart.event3d.intersection.point.clone();
+ origIntersection.sub(rotOrigin);
+ origIntersection.applyQuaternion(orientationWorldInv);
+
+ // compute relative 2d angle
+ var a1 = Math.atan2(intersection.y, intersection.z);
+ var a2 = Math.atan2(origIntersection.y, origIntersection.z);
+ var a = a2 - a1;
+
+ var rot = new THREE.Quaternion();
+ rot.setFromAxisAngle(normal, a);
+
+ // rotate
+ this.setOrientation(control, rot.multiply(this.dragStart.orientationWorld));
+
+ // offset from drag start position
+ event3d.stopPropagation();
+ }
+};
+
+/**
+ * Dispatch the given event type.
+ *
+ * @param type - the type of event
+ * @param control - the control to use
+ */
+ROS3D.InteractiveMarker.prototype.feedbackEvent = function(type, control) {
+ this.dispatchEvent({
+ type : type,
+ position : this.position.clone(),
+ orientation : this.quaternion.clone(),
+ controlName : control.name
+ });
+};
+
+/**
+ * Start a drag action.
+ *
+ * @param control - the control to use
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.startDrag = function(control, event3d) {
+ if (event3d.domEvent.button === 0) {
+ event3d.stopPropagation();
+ this.dragging = true;
+ this.updateMatrixWorld(true);
+ var scale = new THREE.Vector3();
+ this.matrixWorld
+ .decompose(this.dragStart.positionWorld, this.dragStart.orientationWorld, scale);
+ this.dragStart.position = this.position.clone();
+ this.dragStart.orientation = this.quaternion.clone();
+ this.dragStart.event3d = event3d;
+
+ this.feedbackEvent('user-mousedown', control);
+ }
+};
+
+/**
+ * Stop a drag action.
+ *
+ * @param control - the control to use
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.stopDrag = function(control, event3d) {
+ if (event3d.domEvent.button === 0) {
+ event3d.stopPropagation();
+ this.dragging = false;
+ this.dragStart.event3d = {};
+ this.onServerSetPose(this.bufferedPoseEvent);
+ this.bufferedPoseEvent = undefined;
+
+ this.feedbackEvent('user-mouseup', control);
+ }
+};
+
+/**
+ * Handle a button click.
+ *
+ * @param control - the control to use
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.buttonClick = function(control, event3d) {
+ event3d.stopPropagation();
+ this.feedbackEvent('user-button-click', control);
+};
+
+/**
+ * Handle a user pose change for the position.
+ *
+ * @param control - the control to use
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.setPosition = function(control, position) {
+ this.position = position;
+ this.feedbackEvent('user-pose-change', control);
+};
+
+/**
+ * Handle a user pose change for the orientation.
+ *
+ * @param control - the control to use
+ * @param event3d - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.setOrientation = function(control, orientation) {
+ orientation.normalize();
+ this.quaternion = orientation;
+ this.feedbackEvent('user-pose-change', control);
+};
+
+/**
+ * Update the marker based when the pose is set from the server.
+ *
+ * @param event - the event that caused this
+ */
+ROS3D.InteractiveMarker.prototype.onServerSetPose = function(event) {
+ if (event !== undefined) {
+ // don't update while dragging
+ if (this.dragging) {
+ this.bufferedPoseEvent = event;
+ } else {
+ var pose = event.pose;
+
+ this.position.x = pose.position.x;
+ this.position.y = pose.position.y;
+ this.position.z = pose.position.z;
+
+ this.useQuaternion = true;
+ this.quaternion = new THREE.Quaternion(pose.orientation.x, pose.orientation.y,
+ pose.orientation.z, pose.orientation.w);
+
+ this.updateMatrixWorld(true);
+ }
+ }
+};
diff --git a/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerClient.js b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerClient.js
new file mode 100755
index 0000000..d2fe338
--- /dev/null
+++ b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerClient.js
@@ -0,0 +1,183 @@
+/**
+ * @author David Gossow - dgossow@willowgarage.com
+ */
+
+/**
+ * A client for an interactive marker topic.
+ *
+ * @constructor
+ * @param options - object with following keys:
+ * * ros - a handle to the ROS connection
+ * * tfClient - a handle to the TF client
+ * * topic (optional) - the topic to subscribe to, like '/basic_controls'
+ * * path (optional) - the base path to any meshes that will be loaded
+ * * camera - the main camera associated with the viewer for this marker client
+ * * rootObject (optional) - the root THREE 3D object to render to
+ */
+ROS3D.InteractiveMarkerClient = function(options) {
+ var that = this;
+ options = options || {};
+ this.ros = options.ros;
+ this.tfClient = options.tfClient;
+ this.topic = options.topic;
+ this.path = options.path || '/';
+ this.camera = options.camera;
+ this.rootObject = options.rootObject || new THREE.Object3D();
+
+ this.interactiveMarkers = {};
+ this.updateTopic = null;
+ this.feedbackTopic = null;
+
+ // check for an initial topic
+ if (this.topic) {
+ this.subscribe(this.topic);
+ }
+};
+
+/**
+ * Subscribe to the given interactive marker topic. This will unsubscribe from any current topics.
+ *
+ * @param topic - the topic to subscribe to, like '/basic_controls'
+ */
+ROS3D.InteractiveMarkerClient.prototype.subscribe = function(topic) {
+ // unsubscribe to the other topics
+ this.unsubscribe();
+
+ this.updateTopic = new ROSLIB.Topic({
+ ros : this.ros,
+ name : topic + '/tunneled/update',
+ messageType : 'visualization_msgs/InteractiveMarkerUpdate',
+ compression : 'png'
+ });
+ this.updateTopic.subscribe(this.processUpdate.bind(this));
+
+ this.feedbackTopic = new ROSLIB.Topic({
+ ros : this.ros,
+ name : topic + '/feedback',
+ messageType : 'visualization_msgs/InteractiveMarkerFeedback',
+ compression : 'png'
+ });
+ this.feedbackTopic.advertise();
+
+ this.initService = new ROSLIB.Service({
+ ros : this.ros,
+ name : topic + '/tunneled/get_init',
+ serviceType : 'demo_interactive_markers/GetInit'
+ });
+ var request = new ROSLIB.ServiceRequest({});
+ this.initService.callService(request, this.processInit.bind(this));
+};
+
+/**
+ * Unsubscribe from the current interactive marker topic.
+ */
+ROS3D.InteractiveMarkerClient.prototype.unsubscribe = function() {
+ if (this.updateTopic) {
+ this.updateTopic.unsubscribe();
+ }
+ if (this.feedbackTopic) {
+ this.feedbackTopic.unadvertise();
+ }
+ // erase all markers
+ for (var intMarkerName in this.interactiveMarkers) {
+ this.eraseIntMarker(intMarkerName);
+ }
+ this.interactiveMarkers = {};
+};
+
+/**
+ * Process the given interactive marker initialization message.
+ *
+ * @param initMessage - the interactive marker initialization message to process
+ */
+ROS3D.InteractiveMarkerClient.prototype.processInit = function(initMessage) {
+ var message = initMessage.msg;
+
+ // erase any old markers
+ message.erases = [];
+ for (var intMarkerName in this.interactiveMarkers) {
+ message.erases.push(intMarkerName);
+ }
+ message.poses = [];
+
+ // treat it as an update
+ this.processUpdate(message);
+};
+
+/**
+ * Process the given interactive marker update message.
+ *
+ * @param initMessage - the interactive marker update message to process
+ */
+ROS3D.InteractiveMarkerClient.prototype.processUpdate = function(message) {
+ var that = this;
+
+ // erase any markers
+ message.erases.forEach(function(name) {
+ that.eraseIntMarker(name);
+ });
+
+ // updates marker poses
+ message.poses.forEach(function(poseMessage) {
+ var marker = that.interactiveMarkers[poseMessage.name];
+ if (marker) {
+ marker.setPoseFromServer(poseMessage.pose);
+ }
+ });
+
+ // add new markers
+ message.markers.forEach(function(msg) {
+ // get rid of anything with the same name
+ var oldhandle = that.interactiveMarkers[msg.name];
+ if (oldhandle) {
+ that.eraseIntMarker(oldhandle.name);
+ }
+
+ // create the handle
+ var handle = new ROS3D.InteractiveMarkerHandle({
+ message : msg,
+ feedbackTopic : that.feedbackTopic,
+ tfClient : that.tfClient
+ });
+ that.interactiveMarkers[msg.name] = handle;
+
+ // create the actual marker
+ var intMarker = new ROS3D.InteractiveMarker({
+ handle : handle,
+ camera : that.camera,
+ path : that.path
+ });
+ // add it to the scene
+ intMarker.name = msg.name;
+ that.rootObject.add(intMarker);
+
+ // listen for any pose updates from the server
+ handle.on('pose', function(pose) {
+ intMarker.onServerSetPose({
+ pose : pose
+ });
+ });
+
+ intMarker.addEventListener('user-pose-change', handle.setPoseFromClient.bind(handle));
+ intMarker.addEventListener('user-mousedown', handle.onMouseDown.bind(handle));
+ intMarker.addEventListener('user-mouseup', handle.onMouseUp.bind(handle));
+ intMarker.addEventListener('user-button-click', handle.onButtonClick.bind(handle));
+ intMarker.addEventListener('menu-select', handle.onMenuSelect.bind(handle));
+
+ // now list for any TF changes
+ handle.subscribeTf();
+ });
+};
+
+/**
+ * Erase the interactive marker with the given name.
+ *
+ * @param intMarkerName - the interactive marker name to delete
+ */
+ROS3D.InteractiveMarkerClient.prototype.eraseIntMarker = function(intMarkerName) {
+ if (this.interactiveMarkers[intMarkerName]) {
+ // remove the object
+ this.rootObject.remove(this.rootObject.getChildByName(intMarkerName));
+ delete this.interactiveMarkers[intMarkerName];
+ }
+};
diff --git a/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerControl.js b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerControl.js
new file mode 100755
index 0000000..b9ec195
--- /dev/null
+++ b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerControl.js
@@ -0,0 +1,181 @@
+/**
+ * @author David Gossow - dgossow@willowgarage.com
+ */
+
+/**
+ * The main marker control object for an interactive marker.
+ *
+ * @constructor
+ * @param options - object with following keys:
+ * * parent - the parent of this control
+ * * message - the interactive marker control message
+ * * camera - the main camera associated with the viewer for this marker client
+ * * path (optional) - the base path to any meshes that will be loaded
+ */
+ROS3D.InteractiveMarkerControl = function(options) {
+ var that = this;
+ THREE.Object3D.call(this);
+ THREE.EventDispatcher.call(this);
+
+ options = options || {};
+ this.parent = options.parent;
+ var message = options.message;
+ this.name = message.name;
+ this.camera = options.camera;
+ this.path = options.path || '/';
+ this.dragging = false;
+
+ // orientation for the control
+ var controlOri = new THREE.Quaternion(message.orientation.x, message.orientation.y,
+ message.orientation.z, message.orientation.w);
+ controlOri.normalize();
+
+ // transform x axis into local frame
+ var controlAxis = new THREE.Vector3(1, 0, 0);
+ controlAxis.applyQuaternion(controlOri);
+
+ this.currentControlOri = new THREE.Quaternion();
+
+ // determine mouse interaction
+ switch (message.interaction_mode) {
+ case ROS3D.INTERACTIVE_MARKER_MOVE_AXIS:
+ this.addEventListener('mousemove', this.parent.moveAxis.bind(this.parent, this, controlAxis));
+ this.addEventListener('touchmove', this.parent.moveAxis.bind(this.parent, this, controlAxis));
+ break;
+ case ROS3D.INTERACTIVE_MARKER_ROTATE_AXIS:
+ this
+ .addEventListener('mousemove', this.parent.rotateAxis.bind(this.parent, this, controlOri));
+ break;
+ case ROS3D.INTERACTIVE_MARKER_MOVE_PLANE:
+ this
+ .addEventListener('mousemove', this.parent.movePlane.bind(this.parent, this, controlAxis));
+ break;
+ case ROS3D.INTERACTIVE_MARKER_BUTTON:
+ this.addEventListener('click', this.parent.buttonClick.bind(this.parent, this));
+ break;
+ default:
+ break;
+ }
+
+ /**
+ * Install default listeners for highlighting / dragging.
+ *
+ * @param event - the event to stop
+ */
+ function stopPropagation(event) {
+ event.stopPropagation();
+ }
+
+ // check the mode
+ if (message.interaction_mode !== ROS3D.INTERACTIVE_MARKER_NONE) {
+ this.addEventListener('mousedown', this.parent.startDrag.bind(this.parent, this));
+ this.addEventListener('mouseup', this.parent.stopDrag.bind(this.parent, this));
+ this.addEventListener('contextmenu', this.parent.showMenu.bind(this.parent, this));
+ this.addEventListener('mouseover', stopPropagation);
+ this.addEventListener('mouseout', stopPropagation);
+ this.addEventListener('click', stopPropagation);
+
+ // touch support
+ this.addEventListener('touchstart', function(event3d) {
+ console.log(event3d.domEvent);
+ if (event3d.domEvent.touches.length === 1) {
+ event3d.type = 'mousedown';
+ event3d.domEvent.button = 0;
+ that.dispatchEvent(event3d);
+ }
+ });
+ this.addEventListener('touchmove', function(event3d) {
+ if (event3d.domEvent.touches.length === 1) {
+ console.log(event3d.domEvent);
+ event3d.type = 'mousemove';
+ event3d.domEvent.button = 0;
+ that.dispatchEvent(event3d);
+ }
+ });
+ this.addEventListener('touchend', function(event3d) {
+ if (event3d.domEvent.touches.length === 0) {
+ event3d.domEvent.button = 0;
+ event3d.type = 'mouseup';
+ that.dispatchEvent(event3d);
+ event3d.type = 'click';
+ that.dispatchEvent(event3d);
+ }
+ });
+ }
+
+ // rotation behavior
+ var rotInv = new THREE.Quaternion();
+ var posInv = this.parent.position.clone().multiplyScalar(-1);
+ switch (message.orientation_mode) {
+ case ROS3D.INTERACTIVE_MARKER_INHERIT:
+ rotInv = this.parent.quaternion.clone().inverse();
+ this.updateMatrixWorld = function(force) {
+ ROS3D.InteractiveMarkerControl.prototype.updateMatrixWorld.call(that, force);
+ that.currentControlOri.copy(that.quaternion);
+ that.currentControlOri.normalize();
+ };
+ break;
+ case ROS3D.INTERACTIVE_MARKER_FIXED:
+ this.updateMatrixWorld = function(force) {
+ that.useQuaternion = true;
+ that.quaternion = that.parent.quaternion.clone().inverse();
+ that.updateMatrix();
+ that.matrixWorldNeedsUpdate = true;
+ ROS3D.InteractiveMarkerControl.prototype.updateMatrixWorld.call(that, force);
+ that.currentControlOri.copy(that.quaternion);
+ };
+ break;
+ case ROS3D.INTERACTIVE_MARKER_VIEW_FACING:
+ var independentMarkerOrientation = message.independentMarkerOrientation;
+ this.updateMatrixWorld = function(force) {
+ that.camera.updateMatrixWorld();
+ var cameraRot = new THREE.Matrix4().extractRotation(that.camera.matrixWorld);
+
+ var ros2Gl = new THREE.Matrix4();
+ var r90 = Math.PI * 0.5;
+ var rv = new THREE.Vector3(-r90, 0, r90);
+ ros2Gl.setRotationFromEuler(rv);
+
+ var worldToLocal = new THREE.Matrix4();
+ worldToLocal.getInverse(that.parent.matrixWorld);
+
+ cameraRot.multiplyMatrices(cameraRot, ros2Gl);
+ cameraRot.multiplyMatrices(worldToLocal, cameraRot);
+
+ that.currentControlOri.setFromRotationMatrix(cameraRot);
+
+ // check the orientation
+ if (!independentMarkerOrientation) {
+ that.useQuaternion = true;
+ that.quaternion.copy(that.currentControlOri);
+ that.updateMatrix();
+ that.matrixWorldNeedsUpdate = true;
+ }
+ ROS3D.InteractiveMarkerControl.prototype.updateMatrixWorld.call(that, force);
+ };
+ break;
+ default:
+ console.error('Unkown orientation mode: ' + message.orientation_mode);
+ break;
+ }
+
+ // create visuals (markers)
+ message.markers.forEach(function(markerMsg) {
+ var markerHelper = new ROS3D.Marker({
+ message : markerMsg,
+ path : that.path
+ });
+
+ if (markerMsg.header.frame_id !== '') {
+ // if the marker lives in its own coordinate frame, convert position into IM's local frame
+ markerHelper.position.add(posInv);
+ markerHelper.position.applyQuaternion(rotInv);
+ markerHelper.quaternion.multiplyQuaternions(rotInv, markerHelper.quaternion);
+ markerHelper.updateMatrixWorld();
+ }
+
+ // add the marker
+ that.add(markerHelper);
+ });
+};
+ROS3D.InteractiveMarkerControl.prototype.__proto__ = THREE.Object3D.prototype;
diff --git a/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerHandle.js b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerHandle.js
new file mode 100755
index 0000000..2022792
--- /dev/null
+++ b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerHandle.js
@@ -0,0 +1,176 @@
+/**
+ * @author David Gossow - dgossow@willowgarage.com
+ */
+
+/**
+ * Handle with signals for a single interactive marker.
+ *
+ * Emits the following events:
+ * * 'pose' - emitted when a new pose comes from the server
+ *
+ * @constructor
+ * @param options - object with following keys:
+ * * message - the interactive marker message
+ * * feedbackTopic - the ROSLIB.Topic associated with the feedback
+ * * tfClient - a handle to the TF client to use
+ */
+ROS3D.InteractiveMarkerHandle = function(options) {
+ options = options || {};
+ this.message = options.message;
+ this.feedbackTopic = options.feedbackTopic;
+ this.tfClient = options.tfClient;
+ this.name = this.message.name;
+ this.header = this.message.header;
+ this.controls = this.message.controls;
+ this.menuEntries = this.message.menu_entries;
+ this.dragging = false;
+ this.timeoutHandle = null;
+ this.tfTransform = new ROSLIB.Transform();
+ this.pose = new ROSLIB.Pose();
+
+ // start by setting the pose
+ this.setPoseFromServer(this.message.pose);
+};
+ROS3D.InteractiveMarkerHandle.prototype.__proto__ = EventEmitter2.prototype;
+
+/**
+ * Subscribe to the TF associated with this interactive marker.
+ */
+ROS3D.InteractiveMarkerHandle.prototype.subscribeTf = function() {
+ // subscribe to tf updates if frame-fixed
+ if (this.message.header.stamp.secs === 0.0 && this.message.header.stamp.nsecs === 0.0) {
+ this.tfClient.subscribe(this.message.header.frame_id, this.tfUpdate.bind(this));
+ }
+};
+
+/**
+ * Emit the new pose that has come from the server.
+ */
+ROS3D.InteractiveMarkerHandle.prototype.emitServerPoseUpdate = function() {
+ var poseTransformed = new ROSLIB.Pose(this.pose);
+ poseTransformed.applyTransform(this.tfTransform);
+ this.emit('pose', poseTransformed);
+};
+
+/**
+ * Update the pose based on the pose given by the server.
+ *
+ * @param poseMsg - the pose given by the server
+ */
+ROS3D.InteractiveMarkerHandle.prototype.setPoseFromServer = function(poseMsg) {
+ this.pose = new ROSLIB.Pose(poseMsg);
+ this.emitServerPoseUpdate();
+};
+
+/**
+ * Update the pose based on the TF given by the server.
+ *
+ * @param transformMsg - the TF given by the server
+ */
+ROS3D.InteractiveMarkerHandle.prototype.tfUpdate = function(transformMsg) {
+ this.tfTransform = new ROSLIB.Transform(transformMsg);
+ this.emitServerPoseUpdate();
+};
+
+/**
+ * Set the pose from the client based on the given event.
+ *
+ * @param event - the event to base the change off of
+ */
+ROS3D.InteractiveMarkerHandle.prototype.setPoseFromClient = function(event) {
+ // apply the transform
+ this.pose = new ROSLIB.Pose(event);
+ var inv = this.tfTransform.clone();
+ inv.rotation.invert();
+ inv.translation.multiplyQuaternion(inv.rotation);
+ inv.translation.x *= -1;
+ inv.translation.y *= -1;
+ inv.translation.z *= -1;
+ this.pose.applyTransform(inv);
+
+ // send feedback to the server
+ this.sendFeedback(ROS3D.INTERACTIVE_MARKER_POSE_UPDATE, undefined, 0, event.controlName);
+
+ // keep sending pose feedback until the mouse goes up
+ if (this.dragging) {
+ if (this.timeoutHandle) {
+ clearTimeout(this.timeoutHandle);
+ }
+ this.timeoutHandle = setTimeout(this.setPoseFromClient.bind(this, event), 250);
+ }
+};
+
+/**
+ * Send the button click feedback to the server.
+ *
+ * @param event - the event associated with the button click
+ */
+ROS3D.InteractiveMarkerHandle.prototype.onButtonClick = function(event) {
+ this.sendFeedback(ROS3D.INTERACTIVE_MARKER_BUTTON_CLICK, event.clickPosition, 0,
+ event.controlName);
+};
+
+/**
+ * Send the mousedown feedback to the server.
+ *
+ * @param event - the event associated with the mousedown
+ */
+ROS3D.InteractiveMarkerHandle.prototype.onMouseDown = function(event) {
+ this.sendFeedback(ROS3D.INTERACTIVE_MARKER_MOUSE_DOWN, event.clickPosition, 0, event.controlName);
+ this.dragging = true;
+};
+
+/**
+ * Send the mouseup feedback to the server.
+ *
+ * @param event - the event associated with the mouseup
+ */
+ROS3D.InteractiveMarkerHandle.prototype.onMouseUp = function(event) {
+ this.sendFeedback(ROS3D.INTERACTIVE_MARKER_MOUSE_UP, event.clickPosition, 0, event.controlName);
+ this.dragging = false;
+ if (this.timeoutHandle) {
+ clearTimeout(this.timeoutHandle);
+ }
+};
+
+/**
+ * Send the menu select feedback to the server.
+ *
+ * @param event - the event associated with the menu select
+ */
+ROS3D.InteractiveMarkerHandle.prototype.onMenuSelect = function(event) {
+ this.sendFeedback(ROS3D.INTERACTIVE_MARKER_MENU_SELECT, undefined, event.id, event.controlName);
+};
+
+/**
+ * Send feedback to the interactive marker server.
+ *
+ * @param eventType - the type of event that happened
+ * @param clickPosition (optional) - the position in ROS space the click happened
+ * @param menuEntryID (optional) - the menu entry ID that is associated
+ * @param controlName - the name of the control
+ */
+ROS3D.InteractiveMarkerHandle.prototype.sendFeedback = function(eventType, clickPosition,
+ menuEntryID, controlName) {
+
+ // check for the click position
+ var mousePointValid = clickPosition !== undefined;
+ clickPosition = clickPosition || {
+ x : 0,
+ y : 0,
+ z : 0
+ };
+
+ var feedback = {
+ header : this.header,
+ client_id : this.clientID,
+ marker_name : this.name,
+ control_name : controlName,
+ event_type : eventType,
+ pose : this.pose,
+ mouse_point : clickPosition,
+ mouse_point_valid : mousePointValid,
+ menu_entry_id : menuEntryID
+ };
+ this.feedbackTopic.publish(feedback);
+};
diff --git a/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerMenu.js b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerMenu.js
new file mode 100755
index 0000000..7b808f1
--- /dev/null
+++ b/vulcano_web/javascript_libraries/interactivemarkers/InteractiveMarkerMenu.js
@@ -0,0 +1,166 @@
+/**
+ * @author David Gossow - dgossow@willowgarage.com
+ */
+
+/**
+ * A menu for an interactive marker. This will be overlayed on the canvas.
+ *
+ * @constructor
+ * @param options - object with following keys:
+ * * menuEntries - the menu entries to add
+ * * className (optional) - a custom CSS class for the menu div
+ * * entryClassName (optional) - a custom CSS class for the menu entry
+ * * overlayClassName (optional) - a custom CSS class for the menu overlay
+ */
+ROS3D.InteractiveMarkerMenu = function(options) {
+ var that = this;
+ options = options || {};
+ var menuEntries = options.menuEntries;
+ var className = options.className || 'default-interactive-marker-menu';
+ var entryClassName = options.entryClassName || 'default-interactive-marker-menu-entry';
+ var overlayClassName = options.overlayClassName || 'default-interactive-marker-overlay';
+
+ // holds the menu tree
+ var allMenus = [];
+ allMenus[0] = {
+ children : []
+ };
+
+ THREE.EventDispatcher.call(this);
+
+ // create the CSS for this marker if it has not been created
+ if (document.getElementById('default-interactive-marker-menu-css') === null) {
+ var style = document.createElement('style');
+ style.id = 'default-interactive-marker-menu-css';
+ style.type = 'text/css';
+ style.innerHTML = '.default-interactive-marker-menu {' + 'background-color: #444444;'
+ + 'border: 1px solid #888888;' + 'border: 1px solid #888888;' + 'padding: 0px 0px 0px 0px;'
+ + 'color: #FFFFFF;' + 'font-family: sans-serif;' + 'font-size: 0.8em;' + 'z-index: 1002;'
+ + '}' + '.default-interactive-marker-menu ul {' + 'padding: 0px 0px 5px 0px;'
+ + 'margin: 0px;' + 'list-style-type: none;' + '}'
+ + '.default-interactive-marker-menu ul li div {' + '-webkit-touch-callout: none;'
+ + '-webkit-user-select: none;' + '-khtml-user-select: none;' + '-moz-user-select: none;'
+ + '-ms-user-select: none;' + 'user-select: none;' + 'cursor: default;'
+ + 'padding: 3px 10px 3px 10px;' + '}' + '.default-interactive-marker-menu-entry:hover {'
+ + ' background-color: #666666;' + ' cursor: pointer;' + '}'
+ + '.default-interactive-marker-menu ul ul {' + ' font-style: italic;'
+ + ' padding-left: 10px;' + '}' + '.default-interactive-marker-overlay {'
+ + ' position: absolute;' + ' top: 0%;' + ' left: 0%;' + ' width: 100%;'
+ + ' height: 100%;' + ' background-color: black;' + ' z-index: 1001;'
+ + ' -moz-opacity: 0.0;' + ' opacity: .0;' + ' filter: alpha(opacity = 0);' + '}';
+ document.getElementsByTagName('head')[0].appendChild(style);
+ }
+
+ // place the menu in a div
+ this.menuDomElem = document.createElement('div');
+ this.menuDomElem.style.position = 'absolute';
+ this.menuDomElem.className = className;
+ this.menuDomElem.addEventListener('contextmenu', function(event) {
+ event.preventDefault();
+ });
+
+ // create the overlay DOM
+ this.overlayDomElem = document.createElement('div');
+ this.overlayDomElem.className = overlayClassName;
+
+ this.hideListener = this.hide.bind(this);
+ this.overlayDomElem.addEventListener('contextmenu', this.hideListener);
+ this.overlayDomElem.addEventListener('click', this.hideListener);
+
+ // parse all entries and link children to parents
+ var i, entry, id;
+ for ( i = 0; i < menuEntries.length; i++) {
+ entry = menuEntries[i];
+ id = entry.id;
+ allMenus[id] = {
+ title : entry.title,
+ id : id,
+ children : []
+ };
+ }
+ for ( i = 0; i < menuEntries.length; i++) {
+ entry = menuEntries[i];
+ id = entry.id;
+ var menu = allMenus[id];
+ var parent = allMenus[entry.parent_id];
+ parent.children.push(menu);
+ }
+
+ function emitMenuSelect(menuEntry, domEvent) {
+ this.dispatchEvent({
+ type : 'menu-select',
+ domEvent : domEvent,
+ id : menuEntry.id,
+ controlName : this.controlName
+ });
+ this.hide(domEvent);
+ }
+
+ /**
+ * Create the HTML UL element for the menu and link it to the parent.
+ *
+ * @param parentDomElem - the parent DOM element
+ * @param parentMenu - the parent menu
+ */
+ function makeUl(parentDomElem, parentMenu) {
+
+ var ulElem = document.createElement('ul');
+ parentDomElem.appendChild(ulElem);
+
+ var children = parentMenu.children;
+
+ for ( var i = 0; i < children.length; i++) {
+ var liElem = document.createElement('li');
+ var divElem = document.createElement('div');
+ divElem.appendChild(document.createTextNode(children[i].title));
+ ulElem.appendChild(liElem);
+ liElem.appendChild(divElem);
+
+ if (children[i].children.length > 0) {
+ makeUl(liElem, children[i]);
+ divElem.addEventListener('click', that.hide.bind(that));
+ } else {
+ divElem.addEventListener('click', emitMenuSelect.bind(that, children[i]));
+ divElem.className = 'default-interactive-marker-menu-entry';
+ }
+ }
+
+ }
+
+ // construct DOM element
+ makeUl(this.menuDomElem, allMenus[0]);
+};
+
+/**
+ * Shoe the menu DOM element.
+ *
+ * @param control - the control for the menu
+ * @param event - the event that caused this
+ */
+ROS3D.InteractiveMarkerMenu.prototype.show = function(control, event) {
+ if (event && event.preventDefault) {
+ event.preventDefault();
+ }
+
+ this.controlName = control.name;
+
+ // position it on the click
+ this.menuDomElem.style.left = event.domEvent.clientX + 'px';
+ this.menuDomElem.style.top = event.domEvent.clientY + 'px';
+ document.body.appendChild(this.overlayDomElem);
+ document.body.appendChild(this.menuDomElem);
+};
+
+/**
+ * Hide the menu DOM element.
+ *
+ * @param event (optional) - the event that caused this
+ */
+ROS3D.InteractiveMarkerMenu.prototype.hide = function(event) {
+ if (event && event.preventDefault) {
+ event.preventDefault();
+ }
+
+ document.body.removeChild(this.overlayDomElem);
+ document.body.removeChild(this.menuDomElem);
+};
diff --git a/vulcano_web/javascript_libraries/jquery-2.1.0.min.js b/vulcano_web/javascript_libraries/jquery-2.1.0.min.js
new file mode 100755
index 0000000..cbe6abe
--- /dev/null
+++ b/vulcano_web/javascript_libraries/jquery-2.1.0.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v2.1.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m=a.document,n="2.1.0",o=function(a,b){return new o.fn.init(a,b)},p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};o.fn=o.prototype={jquery:n,constructor:o,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=o.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return o.each(this,a,b)},map:function(a){return this.pushStack(o.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},o.extend=o.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||o.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=o.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},o.extend({expando:"jQuery"+(n+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isPlainObject:function(a){if("object"!==o.type(a)||a.nodeType||o.isWindow(a))return!1;try{if(a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=o.trim(a),a&&(1===a.indexOf("use strict")?(b=m.createElement("script"),b.text=a,m.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":k.call(a)},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?o.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),o.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||o.guid++,f):void 0},now:Date.now,support:l}),o.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=o.type(a);return"function"===c||o.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);o.find=t,o.expr=t.selectors,o.expr[":"]=o.expr.pseudos,o.unique=t.uniqueSort,o.text=t.getText,o.isXMLDoc=t.isXML,o.contains=t.contains;var u=o.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(o.isFunction(b))return o.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return o.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return o.filter(b,a,c);b=o.filter(b,a)}return o.grep(a,function(a){return g.call(b,a)>=0!==c})}o.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?o.find.matchesSelector(d,a)?[d]:[]:o.find.matches(a,o.grep(b,function(a){return 1===a.nodeType}))},o.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(o(a).filter(function(){for(b=0;c>b;b++)if(o.contains(e[b],this))return!0}));for(b=0;c>b;b++)o.find(a,e[b],d);return d=this.pushStack(c>1?o.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?o(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=o.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof o?b[0]:b,o.merge(this,o.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:m,!0)),v.test(c[1])&&o.isPlainObject(b))for(c in b)o.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=m.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=m,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):o.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(o):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),o.makeArray(a,this))};A.prototype=o.fn,y=o(m);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};o.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&o(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),o.fn.extend({has:function(a){var b=o(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(o.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?o(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&o.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?o.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(o(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(o.unique(o.merge(this.get(),o(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}o.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return o.dir(a,"parentNode")},parentsUntil:function(a,b,c){return o.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return o.dir(a,"nextSibling")},prevAll:function(a){return o.dir(a,"previousSibling")},nextUntil:function(a,b,c){return o.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return o.dir(a,"previousSibling",c)},siblings:function(a){return o.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return o.sibling(a.firstChild)},contents:function(a){return a.contentDocument||o.merge([],a.childNodes)}},function(a,b){o.fn[a]=function(c,d){var e=o.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=o.filter(d,e)),this.length>1&&(C[a]||o.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return o.each(a.match(E)||[],function(a,c){b[c]=!0}),b}o.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):o.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){o.each(b,function(b,c){var d=o.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&o.each(arguments,function(a,b){var c;while((c=o.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?o.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},o.extend({Deferred:function(a){var b=[["resolve","done",o.Callbacks("once memory"),"resolved"],["reject","fail",o.Callbacks("once memory"),"rejected"],["notify","progress",o.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return o.Deferred(function(c){o.each(b,function(b,f){var g=o.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&o.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?o.extend(a,d):d}},e={};return d.pipe=d.then,o.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&o.isFunction(a.promise)?e:0,g=1===f?a:o.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&o.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;o.fn.ready=function(a){return o.ready.promise().done(a),this},o.extend({isReady:!1,readyWait:1,holdReady:function(a){a?o.readyWait++:o.ready(!0)},ready:function(a){(a===!0?--o.readyWait:o.isReady)||(o.isReady=!0,a!==!0&&--o.readyWait>0||(H.resolveWith(m,[o]),o.fn.trigger&&o(m).trigger("ready").off("ready")))}});function I(){m.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),o.ready()}o.ready.promise=function(b){return H||(H=o.Deferred(),"complete"===m.readyState?setTimeout(o.ready):(m.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},o.ready.promise();var J=o.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===o.type(c)){e=!0;for(h in c)o.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,o.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(o(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};o.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=o.expando+Math.random()}K.uid=1,K.accepts=o.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,o.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(o.isEmptyObject(f))o.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,o.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{o.isArray(b)?d=b.concat(b.map(o.camelCase)):(e=o.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!o.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?o.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}o.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),o.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;
+while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=o.camelCase(d.slice(5)),P(f,d,e[d]));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=o.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),o.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||o.isArray(c)?d=L.access(a,b,o.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=o.queue(a,b),d=c.length,e=c.shift(),f=o._queueHooks(a,b),g=function(){o.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:o.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),o.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";l.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return m.activeElement}catch(a){}}o.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=o.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof o!==U&&o.event.triggered!==b.type?o.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n&&(l=o.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=o.event.special[n]||{},k=o.extend({type:n,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&o.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(n,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),o.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],n=q=h[1],p=(h[2]||"").split(".").sort(),n){l=o.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||o.removeEvent(a,n,r.handle),delete i[n])}else for(n in i)o.event.remove(a,n+b[j],c,d,!0);o.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,p=[d||m],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||m,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+o.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[o.expando]?b:new o.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:o.makeArray(c,[b]),n=o.event.special[q]||{},e||!n.trigger||n.trigger.apply(d,c)!==!1)){if(!e&&!n.noBubble&&!o.isWindow(d)){for(i=n.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||m)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:n.bindType||q,l=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),l&&l.apply(g,c),l=k&&g[k],l&&l.apply&&o.acceptData(g)&&(b.result=l.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||n._default&&n._default.apply(p.pop(),c)!==!1||!o.acceptData(d)||k&&o.isFunction(d[q])&&!o.isWindow(d)&&(h=d[k],h&&(d[k]=null),o.event.triggered=q,d[q](),o.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=o.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=o.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=o.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((o.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?o(e,this).index(i)>=0:o.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return o.nodeName(a,"table")&&o.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)o.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=o.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&o.nodeName(a,b)?o.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}o.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=o.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||o.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,n=a.length;n>m;m++)if(e=a[m],e||0===e)if("object"===o.type(e))o.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>$2>")+h[2],j=h[0];while(j--)f=f.lastChild;o.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===o.inArray(e,d))&&(i=o.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f,g,h=o.event.special,i=0;void 0!==(c=a[i]);i++){if(o.acceptData(c)&&(f=c[L.expando],f&&(b=L.cache[f]))){if(d=Object.keys(b.events||{}),d.length)for(g=0;void 0!==(e=d[g]);g++)h[e]?o.event.remove(c,e):o.removeEvent(c,e,b.handle);L.cache[f]&&delete L.cache[f]}delete M.cache[c[M.expando]]}}}),o.fn.extend({text:function(a){return J(this,function(a){return void 0===a?o.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?o.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||o.cleanData(ob(c)),c.parentNode&&(b&&o.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(o.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return o.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(o.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,o.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,n=k-1,p=a[0],q=o.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(c=o.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=o.map(ob(c,"script"),kb),g=f.length;k>j;j++)h=c,j!==n&&(h=o.clone(h,!0,!0),g&&o.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,o.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&o.contains(i,h)&&(h.src?o._evalUrl&&o._evalUrl(h.src):o.globalEval(h.textContent.replace(hb,"")))}return this}}),o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){o.fn[a]=function(a){for(var c,d=[],e=o(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),o(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d=o(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:o.css(d[0],"display");return d.detach(),e}function tb(a){var b=m,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||o("")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||o.contains(a.ownerDocument,a)||(g=o.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d="padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",e=m.documentElement,f=m.createElement("div"),g=m.createElement("div");g.style.backgroundClip="content-box",g.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===g.style.backgroundClip,f.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",f.appendChild(g);function h(){g.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%",e.appendChild(f);var d=a.getComputedStyle(g,null);b="1%"!==d.top,c="4px"===d.width,e.removeChild(f)}a.getComputedStyle&&o.extend(l,{pixelPosition:function(){return h(),b},boxSizingReliable:function(){return null==c&&h(),c},reliableMarginRight:function(){var b,c=g.appendChild(m.createElement("div"));return c.style.cssText=g.style.cssText=d,c.style.marginRight=c.style.width="0",g.style.width="1px",e.appendChild(f),b=!parseFloat(a.getComputedStyle(c,null).marginRight),e.removeChild(f),g.innerHTML="",b}})}(),o.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:0,fontWeight:400},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=o.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=o.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=o.css(a,"border"+R[f]+"Width",!0,e))):(g+=o.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=o.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===o.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):f[g]||(e=S(d),(c&&"none"!==c||!e)&&L.set(d,"olddisplay",e?c:o.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}o.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=o.camelCase(b),i=a.style;return b=o.cssProps[h]||(o.cssProps[h]=Fb(i,h)),g=o.cssHooks[b]||o.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(o.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||o.cssNumber[h]||(c+="px"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]="",i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=o.camelCase(b);return b=o.cssProps[h]||(o.cssProps[h]=Fb(a.style,h)),g=o.cssHooks[b]||o.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||o.isNumeric(f)?f||0:e):e}}),o.each(["height","width"],function(a,b){o.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&zb.test(o.css(a,"display"))?o.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===o.css(a,"boxSizing",!1,e),e):0)}}}),o.cssHooks.marginRight=yb(l.reliableMarginRight,function(a,b){return b?o.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),o.each({margin:"",padding:"",border:"Width"},function(a,b){o.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(o.cssHooks[a+b].set=Gb)}),o.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(o.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=o.css(a,b[g],!1,d);return f}return void 0!==c?o.style(a,b,c):o.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?o(this).show():o(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}o.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(o.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?o.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=o.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){o.fx.step[a.prop]?o.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[o.cssProps[a.prop]]||o.cssHooks[a.prop])?o.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},o.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},o.fx=Kb.prototype.init,o.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(o.cssNumber[a]?"":"px"),g=(o.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(o.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,o.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=o.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k=this,l={},m=a.style,n=a.nodeType&&S(a),p=L.get(a,"fxshow");c.queue||(h=o._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,k.always(function(){k.always(function(){h.unqueued--,o.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[m.overflow,m.overflowX,m.overflowY],j=o.css(a,"display"),"none"===j&&(j=tb(a.nodeName)),"inline"===j&&"none"===o.css(a,"float")&&(m.display="inline-block")),c.overflow&&(m.overflow="hidden",k.always(function(){m.overflow=c.overflow[0],m.overflowX=c.overflow[1],m.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(n?"hide":"show")){if("show"!==e||!p||void 0===p[d])continue;n=!0}l[d]=p&&p[d]||o.style(a,d)}if(!o.isEmptyObject(l)){p?"hidden"in p&&(n=p.hidden):p=L.access(a,"fxshow",{}),f&&(p.hidden=!n),n?o(a).show():k.done(function(){o(a).hide()}),k.done(function(){var b;L.remove(a,"fxshow");for(b in l)o.style(a,b,l[b])});for(d in l)g=Ub(n?p[d]:0,d,k),d in p||(p[d]=g.start,n&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=o.camelCase(c),e=b[d],f=a[c],o.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=o.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=o.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:o.extend({},b),opts:o.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=o.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return o.map(k,Ub,j),o.isFunction(j.opts.start)&&j.opts.start.call(a,j),o.fx.timer(o.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}o.Animation=o.extend(Xb,{tweener:function(a,b){o.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),o.speed=function(a,b,c){var d=a&&"object"==typeof a?o.extend({},a):{complete:c||!c&&b||o.isFunction(a)&&a,duration:a,easing:c&&b||b&&!o.isFunction(b)&&b};return d.duration=o.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in o.fx.speeds?o.fx.speeds[d.duration]:o.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){o.isFunction(d.old)&&d.old.call(this),d.queue&&o.dequeue(this,d.queue)},d},o.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=o.isEmptyObject(a),f=o.speed(b,c,d),g=function(){var b=Xb(this,o.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=o.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&o.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=o.timers,g=d?d.length:0;for(c.finish=!0,o.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),o.each(["toggle","show","hide"],function(a,b){var c=o.fn[b];o.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),o.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){o.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),o.timers=[],o.fx.tick=function(){var a,b=0,c=o.timers;for(Lb=o.now();b1)},removeAttr:function(a){return this.each(function(){o.removeAttr(this,a)})}}),o.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?o.prop(a,b,c):(1===f&&o.isXMLDoc(a)||(b=b.toLowerCase(),d=o.attrHooks[b]||(o.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=o.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void o.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=o.propFix[c]||c,o.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&o.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?o.removeAttr(a,c):a.setAttribute(c,c),c}},o.each(o.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||o.find.attr;$b[b]=function(a,b,d){var e,f;
+return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;o.fn.extend({prop:function(a,b){return J(this,o.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[o.propFix[a]||a]})}}),o.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!o.isXMLDoc(a),f&&(b=o.propFix[b]||b,e=o.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),l.optSelected||(o.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),o.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){o.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;o.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=o.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(o.isFunction(a))return this.each(function(b){o(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?o.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(o.isFunction(a)?function(c){o(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=o(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;o.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=o.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,o(this).val()):a,null==e?e="":"number"==typeof e?e+="":o.isArray(e)&&(e=o.map(e,function(a){return null==a?"":a+""})),b=o.valHooks[this.type]||o.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=o.valHooks[e.type]||o.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),o.extend({valHooks:{select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(l.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&o.nodeName(c.parentNode,"optgroup"))){if(b=o(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=o.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=o.inArray(o(d).val(),f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),o.each(["radio","checkbox"],function(){o.valHooks[this]={set:function(a,b){return o.isArray(b)?a.checked=o.inArray(o(a).val(),b)>=0:void 0}},l.checkOn||(o.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),o.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){o.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),o.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=o.now(),dc=/\?/;o.parseJSON=function(a){return JSON.parse(a+"")},o.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&o.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=m.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(o.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,o.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=o.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&o.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}o.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":o.parseJSON,"text xml":o.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,o.ajaxSettings),b):tc(o.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=o.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?o(l):o.event,n=o.Deferred(),p=o.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(n.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=o.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=o.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===o.active++&&o.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(o.lastModified[d]&&v.setRequestHeader("If-Modified-Since",o.lastModified[d]),o.etag[d]&&v.setRequestHeader("If-None-Match",o.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(o.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(o.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?n.resolveWith(l,[r,x,v]):n.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--o.active||o.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return o.get(a,b,c,"json")},getScript:function(a,b){return o.get(a,void 0,b,"script")}}),o.each(["get","post"],function(a,b){o[b]=function(a,c,d,e){return o.isFunction(c)&&(e=e||d,d=c,c=void 0),o.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),o.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){o.fn[b]=function(a){return this.on(b,a)}}),o._evalUrl=function(a){return o.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},o.fn.extend({wrapAll:function(a){var b;return o.isFunction(a)?this.each(function(b){o(this).wrapAll(a.call(this,b))}):(this[0]&&(b=o(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(o.isFunction(a)?function(b){o(this).wrapInner(a.call(this,b))}:function(){var b=o(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=o.isFunction(a);return this.each(function(c){o(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){o.nodeName(this,"body")||o(this).replaceWith(this.childNodes)}).end()}}),o.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},o.expr.filters.visible=function(a){return!o.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(o.isArray(b))o.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==o.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}o.param=function(a,b){var c,d=[],e=function(a,b){b=o.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=o.ajaxSettings&&o.ajaxSettings.traditional),o.isArray(a)||a.jquery&&!o.isPlainObject(a))o.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},o.fn.extend({serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=o.prop(this,"elements");return a?o.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!o(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=o(this).val();return null==c?null:o.isArray(c)?o.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),o.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=o.ajaxSettings.xhr();a.ActiveXObject&&o(a).on("unload",function(){for(var a in Dc)Dc[a]()}),l.cors=!!Fc&&"withCredentials"in Fc,l.ajax=Fc=!!Fc,o.ajaxTransport(function(a){var b;return l.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort"),f.send(a.hasContent&&a.data||null)},abort:function(){b&&b()}}:void 0}),o.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return o.globalEval(a),a}}}),o.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),o.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=o("
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Simple URDF Example
+
+
+