SHOW:
|
|
- or go back to the newest paste.
| 1 | /* | |
| 2 | * Slides, A Slideshow Plugin for jQuery | |
| 3 | * Intructions: http://slidesjs.com | |
| 4 | * By: Nathan Searles, http://nathansearles.com | |
| 5 | * Version: 1.1.9 | |
| 6 | * Updated: September 5th, 2011 | |
| 7 | * | |
| 8 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
| 9 | * you may not use this file except in compliance with the License. | |
| 10 | * You may obtain a copy of the License at | |
| 11 | * | |
| 12 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 13 | * | |
| 14 | * Unless required by applicable law or agreed to in writing, software | |
| 15 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 17 | * See the License for the specific language governing permissions and | |
| 18 | * limitations under the License. | |
| 19 | */ | |
| 20 | (function($){
| |
| 21 | $.fn.slides = function( option ) {
| |
| 22 | // override defaults with specified option | |
| 23 | option = $.extend( {}, $.fn.slides.option, option );
| |
| 24 | ||
| 25 | return this.each(function(){
| |
| 26 | // wrap slides in control container, make sure slides are block level | |
| 27 | $('.' + option.container, $(this)).children().wrapAll('<div class="slides_control"/>');
| |
| 28 | ||
| 29 | var elem = $(this), | |
| 30 | control = $('.slides_control',elem),
| |
| 31 | total = control.children().size(), | |
| 32 | width = control.children().outerWidth(), | |
| 33 | height = control.children().outerHeight(), | |
| 34 | start = option.start - 1, | |
| 35 | effect = option.effect.indexOf(',') < 0 ? option.effect : option.effect.replace(' ', '').split(',')[0],
| |
| 36 | paginationEffect = option.effect.indexOf(',') < 0 ? effect : option.effect.replace(' ', '').split(',')[1],
| |
| 37 | next = 0, prev = 0, number = 0, current = 0, loaded, active, clicked, position, direction, imageParent, pauseTimeout, playInterval; | |
| 38 | ||
| 39 | // is there only one slide? | |
| 40 | if (total < 2) {
| |
| 41 | // Fade in .slides_container | |
| 42 | $('.' + option.container, $(this)).fadeIn(option.fadeSpeed, option.fadeEasing, function(){
| |
| 43 | // let the script know everything is loaded | |
| 44 | loaded = true; | |
| 45 | // call the loaded funciton | |
| 46 | option.slidesLoaded(); | |
| 47 | }); | |
| 48 | // Hide the next/previous buttons | |
| 49 | $('.' + option.next + ', .' + option.prev).fadeOut(0);
| |
| 50 | return false; | |
| 51 | } | |
| 52 | ||
| 53 | // animate slides | |
| 54 | function animate(direction, effect, clicked) {
| |
| 55 | if (!active && loaded) {
| |
| 56 | active = true; | |
| 57 | // start of animation | |
| 58 | option.animationStart(current + 1); | |
| 59 | switch(direction) {
| |
| 60 | case 'prev': | |
| 61 | // change current slide to previous | |
| 62 | prev = current; | |
| 63 | // get next from current + 1 | |
| 64 | next = current + 1; | |
| 65 | // if last slide, set next to first slide | |
| 66 | next = total === next ? 0 : next; | |
| 67 | // set position of next slide to right of previous | |
| 68 | position = width*2; | |
| 69 | // distance to slide based on width of slides | |
| 70 | direction = -width*2; | |
| 71 | // store new current slide | |
| 72 | current = next; | |
| 73 | break; | |
| 74 | case 'next': | |
| 75 | // change current slide to previous | |
| 76 | prev = current; | |
| 77 | // get next from current - 1 | |
| 78 | next = current - 1; | |
| 79 | // if first slide, set next to last slide | |
| 80 | next = next === -1 ? total-1 : next; | |
| 81 | // set position of next slide to left of previous | |
| 82 | position = 0; | |
| 83 | // distance to slide based on width of slides | |
| 84 | direction = 0; | |
| 85 | // store new current slide | |
| 86 | current = next; | |
| 87 | break; | |
| 88 | case 'pagination': | |
| 89 | // get next from pagination item clicked, convert to number | |
| 90 | next = parseInt(clicked,10); | |
| 91 | // get previous from pagination item with class of current | |
| 92 | prev = $('.' + option.paginationClass + ' li.'+ option.currentClass +' a', elem).attr('href').match('[^#/]+$');
| |
| 93 | // if next is greater then previous set position of next slide to right of previous | |
| 94 | - | if (next > prev) {
|
| 94 | + | if (next < prev) {
|
| 95 | position = width*2; | |
| 96 | direction = -width*2; | |
| 97 | } else {
| |
| 98 | // if next is less then previous set position of next slide to left of previous | |
| 99 | position = 0; | |
| 100 | direction = 0; | |
| 101 | } | |
| 102 | // store new current slide | |
| 103 | current = next; | |
| 104 | break; | |
| 105 | } | |
| 106 | ||
| 107 | // fade animation | |
| 108 | if (effect === 'fade') {
| |
| 109 | // fade animation with crossfade | |
| 110 | if (option.crossfade) {
| |
| 111 | // put hidden next above current | |
| 112 | control.children(':eq('+ next +')', elem).css({
| |
| 113 | zIndex: 10 | |
| 114 | // fade in next | |
| 115 | }).fadeIn(option.fadeSpeed, option.fadeEasing, function(){
| |
| 116 | if (option.autoHeight) {
| |
| 117 | // animate container to height of next | |
| 118 | control.animate({
| |
| 119 | height: control.children(':eq('+ next +')', elem).outerHeight()
| |
| 120 | }, option.autoHeightSpeed, function(){
| |
| 121 | // hide previous | |
| 122 | control.children(':eq('+ prev +')', elem).css({
| |
| 123 | display: 'none', | |
| 124 | zIndex: 0 | |
| 125 | }); | |
| 126 | // reset z index | |
| 127 | control.children(':eq('+ next +')', elem).css({
| |
| 128 | zIndex: 0 | |
| 129 | }); | |
| 130 | // end of animation | |
| 131 | option.animationComplete(next + 1); | |
| 132 | active = false; | |
| 133 | }); | |
| 134 | } else {
| |
| 135 | // hide previous | |
| 136 | control.children(':eq('+ prev +')', elem).css({
| |
| 137 | display: 'none', | |
| 138 | zIndex: 0 | |
| 139 | }); | |
| 140 | // reset zindex | |
| 141 | control.children(':eq('+ next +')', elem).css({
| |
| 142 | zIndex: 0 | |
| 143 | }); | |
| 144 | // end of animation | |
| 145 | option.animationComplete(next + 1); | |
| 146 | active = false; | |
| 147 | } | |
| 148 | }); | |
| 149 | } else {
| |
| 150 | // fade animation with no crossfade | |
| 151 | control.children(':eq('+ prev +')', elem).fadeOut(option.fadeSpeed, option.fadeEasing, function(){
| |
| 152 | // animate to new height | |
| 153 | if (option.autoHeight) {
| |
| 154 | control.animate({
| |
| 155 | // animate container to height of next | |
| 156 | height: control.children(':eq('+ next +')', elem).outerHeight()
| |
| 157 | }, option.autoHeightSpeed, | |
| 158 | // fade in next slide | |
| 159 | function(){
| |
| 160 | control.children(':eq('+ next +')', elem).fadeIn(option.fadeSpeed, option.fadeEasing);
| |
| 161 | }); | |
| 162 | } else {
| |
| 163 | // if fixed height | |
| 164 | control.children(':eq('+ next +')', elem).fadeIn(option.fadeSpeed, option.fadeEasing, function(){
| |
| 165 | // fix font rendering in ie, lame | |
| 166 | if($.browser.msie) {
| |
| 167 | $(this).get(0).style.removeAttribute('filter');
| |
| 168 | } | |
| 169 | }); | |
| 170 | } | |
| 171 | // end of animation | |
| 172 | option.animationComplete(next + 1); | |
| 173 | active = false; | |
| 174 | }); | |
| 175 | } | |
| 176 | // slide animation | |
| 177 | } else {
| |
| 178 | // move next slide to right of previous | |
| 179 | control.children(':eq('+ next +')').css({
| |
| 180 | left: position, | |
| 181 | display: 'block' | |
| 182 | }); | |
| 183 | // animate to new height | |
| 184 | if (option.autoHeight) {
| |
| 185 | control.animate({
| |
| 186 | left: direction, | |
| 187 | height: control.children(':eq('+ next +')').outerHeight()
| |
| 188 | },option.slideSpeed, option.slideEasing, function(){
| |
| 189 | control.css({
| |
| 190 | left: -width | |
| 191 | }); | |
| 192 | control.children(':eq('+ next +')').css({
| |
| 193 | left: width, | |
| 194 | zIndex: 5 | |
| 195 | }); | |
| 196 | // reset previous slide | |
| 197 | control.children(':eq('+ prev +')').css({
| |
| 198 | left: width, | |
| 199 | display: 'none', | |
| 200 | zIndex: 0 | |
| 201 | }); | |
| 202 | // end of animation | |
| 203 | option.animationComplete(next + 1); | |
| 204 | active = false; | |
| 205 | }); | |
| 206 | // if fixed height | |
| 207 | } else {
| |
| 208 | // animate control | |
| 209 | control.animate({
| |
| 210 | left: direction | |
| 211 | },option.slideSpeed, option.slideEasing, function(){
| |
| 212 | // after animation reset control position | |
| 213 | control.css({
| |
| 214 | left: -width | |
| 215 | }); | |
| 216 | // reset and show next | |
| 217 | control.children(':eq('+ next +')').css({
| |
| 218 | left: width, | |
| 219 | zIndex: 5 | |
| 220 | }); | |
| 221 | // reset previous slide | |
| 222 | control.children(':eq('+ prev +')').css({
| |
| 223 | left: width, | |
| 224 | display: 'none', | |
| 225 | zIndex: 0 | |
| 226 | }); | |
| 227 | // end of animation | |
| 228 | option.animationComplete(next + 1); | |
| 229 | active = false; | |
| 230 | }); | |
| 231 | } | |
| 232 | } | |
| 233 | // set current state for pagination | |
| 234 | if (option.pagination) {
| |
| 235 | // remove current class from all | |
| 236 | $('.'+ option.paginationClass +' li.' + option.currentClass, elem).removeClass(option.currentClass);
| |
| 237 | // add current class to next | |
| 238 | $('.' + option.paginationClass + ' li:eq('+ next +')', elem).addClass(option.currentClass);
| |
| 239 | } | |
| 240 | } | |
| 241 | } // end animate function | |
| 242 | ||
| 243 | function stop() {
| |
| 244 | // clear interval from stored id | |
| 245 | clearInterval(elem.data('interval'));
| |
| 246 | } | |
| 247 | ||
| 248 | function pause() {
| |
| 249 | if (option.pause) {
| |
| 250 | // clear timeout and interval | |
| 251 | clearTimeout(elem.data('pause'));
| |
| 252 | clearInterval(elem.data('interval'));
| |
| 253 | // pause slide show for option.pause amount | |
| 254 | pauseTimeout = setTimeout(function() {
| |
| 255 | // clear pause timeout | |
| 256 | clearTimeout(elem.data('pause'));
| |
| 257 | // start play interval after pause | |
| 258 | playInterval = setInterval( function(){
| |
| 259 | animate("next", effect);
| |
| 260 | },option.play); | |
| 261 | // store play interval | |
| 262 | elem.data('interval',playInterval);
| |
| 263 | },option.pause); | |
| 264 | // store pause interval | |
| 265 | elem.data('pause',pauseTimeout);
| |
| 266 | } else {
| |
| 267 | // if no pause, just stop | |
| 268 | stop(); | |
| 269 | } | |
| 270 | } | |
| 271 | ||
| 272 | // 2 or more slides required | |
| 273 | if (total < 2) {
| |
| 274 | return; | |
| 275 | } | |
| 276 | ||
| 277 | // error corection for start slide | |
| 278 | if (start < 0) {
| |
| 279 | start = 0; | |
| 280 | } | |
| 281 | ||
| 282 | if (start > total) {
| |
| 283 | start = total - 1; | |
| 284 | } | |
| 285 | ||
| 286 | // change current based on start option number | |
| 287 | if (option.start) {
| |
| 288 | current = start; | |
| 289 | } | |
| 290 | ||
| 291 | // randomizes slide order | |
| 292 | if (option.randomize) {
| |
| 293 | control.randomize(); | |
| 294 | } | |
| 295 | ||
| 296 | // make sure overflow is hidden, width is set | |
| 297 | $('.' + option.container, elem).css({
| |
| 298 | overflow: 'hidden', | |
| 299 | // fix for ie | |
| 300 | position: 'relative' | |
| 301 | }); | |
| 302 | ||
| 303 | // set css for slides | |
| 304 | control.children().css({
| |
| 305 | position: 'absolute', | |
| 306 | top: 0, | |
| 307 | left: control.children().outerWidth(), | |
| 308 | zIndex: 0, | |
| 309 | display: 'none' | |
| 310 | }); | |
| 311 | ||
| 312 | // set css for control div | |
| 313 | control.css({
| |
| 314 | position: 'relative', | |
| 315 | // size of control 3 x slide width | |
| 316 | width: (width * 3), | |
| 317 | // set height to slide height | |
| 318 | height: height, | |
| 319 | // center control to slide | |
| 320 | left: -width | |
| 321 | }); | |
| 322 | ||
| 323 | // show slides | |
| 324 | $('.' + option.container, elem).css({
| |
| 325 | display: 'block' | |
| 326 | }); | |
| 327 | ||
| 328 | // if autoHeight true, get and set height of first slide | |
| 329 | if (option.autoHeight) {
| |
| 330 | control.children().css({
| |
| 331 | height: 'auto' | |
| 332 | }); | |
| 333 | control.animate({
| |
| 334 | height: control.children(':eq('+ start +')').outerHeight()
| |
| 335 | },option.autoHeightSpeed); | |
| 336 | } | |
| 337 | ||
| 338 | // checks if image is loaded | |
| 339 | if (option.preload && control.find('img:eq(' + start + ')').length) {
| |
| 340 | // adds preload image | |
| 341 | $('.' + option.container, elem).css({
| |
| 342 | background: 'url(' + option.preloadImage + ') no-repeat 50% 50%'
| |
| 343 | }); | |
| 344 | ||
| 345 | // gets image src, with cache buster | |
| 346 | var img = control.find('img:eq(' + start + ')').attr('src') + '?' + (new Date()).getTime();
| |
| 347 | ||
| 348 | // check if the image has a parent | |
| 349 | if ($('img', elem).parent().attr('class') != 'slides_control') {
| |
| 350 | // If image has parent, get tag name | |
| 351 | imageParent = control.children(':eq(0)')[0].tagName.toLowerCase();
| |
| 352 | } else {
| |
| 353 | // Image doesn't have parent, use image tag name | |
| 354 | imageParent = control.find('img:eq(' + start + ')');
| |
| 355 | } | |
| 356 | ||
| 357 | // checks if image is loaded | |
| 358 | control.find('img:eq(' + start + ')').attr('src', img).load(function() {
| |
| 359 | // once image is fully loaded, fade in | |
| 360 | control.find(imageParent + ':eq(' + start + ')').fadeIn(option.fadeSpeed, option.fadeEasing, function(){
| |
| 361 | $(this).css({
| |
| 362 | zIndex: 5 | |
| 363 | }); | |
| 364 | // removes preload image | |
| 365 | $('.' + option.container, elem).css({
| |
| 366 | background: '' | |
| 367 | }); | |
| 368 | // let the script know everything is loaded | |
| 369 | loaded = true; | |
| 370 | // call the loaded funciton | |
| 371 | option.slidesLoaded(); | |
| 372 | }); | |
| 373 | }); | |
| 374 | } else {
| |
| 375 | // if no preloader fade in start slide | |
| 376 | control.children(':eq(' + start + ')').fadeIn(option.fadeSpeed, option.fadeEasing, function(){
| |
| 377 | // let the script know everything is loaded | |
| 378 | loaded = true; | |
| 379 | // call the loaded funciton | |
| 380 | option.slidesLoaded(); | |
| 381 | }); | |
| 382 | } | |
| 383 | ||
| 384 | // click slide for next | |
| 385 | if (option.bigTarget) {
| |
| 386 | // set cursor to pointer | |
| 387 | control.children().css({
| |
| 388 | cursor: 'pointer' | |
| 389 | }); | |
| 390 | // click handler | |
| 391 | control.children().click(function(){
| |
| 392 | // animate to next on slide click | |
| 393 | animate('next', effect);
| |
| 394 | return false; | |
| 395 | }); | |
| 396 | } | |
| 397 | ||
| 398 | // pause on mouseover | |
| 399 | if (option.hoverPause && option.play) {
| |
| 400 | control.bind('mouseover',function(){
| |
| 401 | // on mouse over stop | |
| 402 | stop(); | |
| 403 | }); | |
| 404 | control.bind('mouseleave',function(){
| |
| 405 | // on mouse leave start pause timeout | |
| 406 | pause(); | |
| 407 | }); | |
| 408 | } | |
| 409 | ||
| 410 | // generate next/prev buttons | |
| 411 | if (option.generateNextPrev) {
| |
| 412 | $('.' + option.container, elem).after('<a href="#" class="'+ option.prev +'">Prev</a>');
| |
| 413 | $('.' + option.prev, elem).after('<a href="#" class="'+ option.next +'">Next</a>');
| |
| 414 | } | |
| 415 | ||
| 416 | // next button | |
| 417 | $('.' + option.next ,elem).click(function(e){
| |
| 418 | e.preventDefault(); | |
| 419 | if (option.play) {
| |
| 420 | pause(); | |
| 421 | } | |
| 422 | animate('next', effect);
| |
| 423 | }); | |
| 424 | ||
| 425 | // previous button | |
| 426 | $('.' + option.prev, elem).click(function(e){
| |
| 427 | e.preventDefault(); | |
| 428 | if (option.play) {
| |
| 429 | pause(); | |
| 430 | } | |
| 431 | animate('prev', effect);
| |
| 432 | }); | |
| 433 | ||
| 434 | // generate pagination | |
| 435 | if (option.generatePagination) {
| |
| 436 | // create unordered list | |
| 437 | if (option.prependPagination) {
| |
| 438 | elem.prepend('<ul class='+ option.paginationClass +'></ul>');
| |
| 439 | } else {
| |
| 440 | elem.append('<ul class='+ option.paginationClass +'></ul>');
| |
| 441 | } | |
| 442 | // for each slide create a list item and link | |
| 443 | control.children().each(function(){
| |
| 444 | $('.' + option.paginationClass, elem).append('<li><a href="#'+ number +'">'+ (number+1) +'</a></li>');
| |
| 445 | number++; | |
| 446 | }); | |
| 447 | } else {
| |
| 448 | // if pagination exists, add href w/ value of item number to links | |
| 449 | $('.' + option.paginationClass + ' li a', elem).each(function(){
| |
| 450 | $(this).attr('href', '#' + number);
| |
| 451 | number++; | |
| 452 | }); | |
| 453 | } | |
| 454 | ||
| 455 | // add current class to start slide pagination | |
| 456 | $('.' + option.paginationClass + ' li:eq('+ start +')', elem).addClass(option.currentClass);
| |
| 457 | ||
| 458 | // click handling | |
| 459 | $('.' + option.paginationClass + ' li a', elem ).click(function(){
| |
| 460 | // pause slideshow | |
| 461 | if (option.play) {
| |
| 462 | pause(); | |
| 463 | } | |
| 464 | // get clicked, pass to animate function | |
| 465 | clicked = $(this).attr('href').match('[^#/]+$');
| |
| 466 | // if current slide equals clicked, don't do anything | |
| 467 | if (current != clicked) {
| |
| 468 | animate('pagination', paginationEffect, clicked);
| |
| 469 | } | |
| 470 | return false; | |
| 471 | }); | |
| 472 | ||
| 473 | // click handling | |
| 474 | $('a.link', elem).click(function(){
| |
| 475 | // pause slideshow | |
| 476 | if (option.play) {
| |
| 477 | pause(); | |
| 478 | } | |
| 479 | // get clicked, pass to animate function | |
| 480 | clicked = $(this).attr('href').match('[^#/]+$') - 1;
| |
| 481 | // if current slide equals clicked, don't do anything | |
| 482 | if (current != clicked) {
| |
| 483 | animate('pagination', paginationEffect, clicked);
| |
| 484 | } | |
| 485 | return false; | |
| 486 | }); | |
| 487 | ||
| 488 | if (option.play) {
| |
| 489 | // set interval | |
| 490 | playInterval = setInterval(function() {
| |
| 491 | animate('next', effect);
| |
| 492 | }, option.play); | |
| 493 | // store interval id | |
| 494 | elem.data('interval',playInterval);
| |
| 495 | } | |
| 496 | }); | |
| 497 | }; | |
| 498 | ||
| 499 | // default options | |
| 500 | $.fn.slides.option = {
| |
| 501 | preload: false, // boolean, Set true to preload images in an image based slideshow | |
| 502 | preloadImage: '/img/loading.gif', // string, Name and location of loading image for preloader. Default is "/img/loading.gif" | |
| 503 | container: 'slides_container', // string, Class name for slides container. Default is "slides_container" | |
| 504 | generateNextPrev: false, // boolean, Auto generate next/prev buttons | |
| 505 | next: 'next', // string, Class name for next button | |
| 506 | prev: 'prev', // string, Class name for previous button | |
| 507 | pagination: true, // boolean, If you're not using pagination you can set to false, but don't have to | |
| 508 | generatePagination: true, // boolean, Auto generate pagination | |
| 509 | prependPagination: false, // boolean, prepend pagination | |
| 510 | paginationClass: 'pagination', // string, Class name for pagination | |
| 511 | currentClass: 'current', // string, Class name for current class | |
| 512 | fadeSpeed: 350, // number, Set the speed of the fading animation in milliseconds | |
| 513 | fadeEasing: '', // string, must load jQuery's easing plugin before http://gsgd.co.uk/sandbox/jquery/easing/ | |
| 514 | slideSpeed: 350, // number, Set the speed of the sliding animation in milliseconds | |
| 515 | slideEasing: '', // string, must load jQuery's easing plugin before http://gsgd.co.uk/sandbox/jquery/easing/ | |
| 516 | start: 1, // number, Set the speed of the sliding animation in milliseconds | |
| 517 | effect: 'slide', // string, '[next/prev], [pagination]', e.g. 'slide, fade' or simply 'fade' for both | |
| 518 | crossfade: false, // boolean, Crossfade images in a image based slideshow | |
| 519 | randomize: false, // boolean, Set to true to randomize slides | |
| 520 | play: 0, // number, Autoplay slideshow, a positive number will set to true and be the time between slide animation in milliseconds | |
| 521 | pause: 0, // number, Pause slideshow on click of next/prev or pagination. A positive number will set to true and be the time of pause in milliseconds | |
| 522 | hoverPause: false, // boolean, Set to true and hovering over slideshow will pause it | |
| 523 | autoHeight: false, // boolean, Set to true to auto adjust height | |
| 524 | autoHeightSpeed: 350, // number, Set auto height animation time in milliseconds | |
| 525 | bigTarget: false, // boolean, Set to true and the whole slide will link to next slide on click | |
| 526 | animationStart: function(){}, // Function called at the start of animation
| |
| 527 | animationComplete: function(){}, // Function called at the completion of animation
| |
| 528 | slidesLoaded: function() {} // Function is called when slides is fully loaded
| |
| 529 | }; | |
| 530 | ||
| 531 | // Randomize slide order on load | |
| 532 | $.fn.randomize = function(callback) {
| |
| 533 | function randomizeOrder() { return(Math.round(Math.random())-0.5); }
| |
| 534 | return($(this).each(function() {
| |
| 535 | var $this = $(this); | |
| 536 | var $children = $this.children(); | |
| 537 | var childCount = $children.length; | |
| 538 | if (childCount > 1) {
| |
| 539 | $children.hide(); | |
| 540 | var indices = []; | |
| 541 | for (i=0;i<childCount;i++) { indices[indices.length] = i; }
| |
| 542 | indices = indices.sort(randomizeOrder); | |
| 543 | $.each(indices,function(j,k) {
| |
| 544 | var $child = $children.eq(k); | |
| 545 | var $clone = $child.clone(true); | |
| 546 | $clone.show().appendTo($this); | |
| 547 | if (callback !== undefined) {
| |
| 548 | callback($child, $clone); | |
| 549 | } | |
| 550 | $child.remove(); | |
| 551 | }); | |
| 552 | } | |
| 553 | })); | |
| 554 | }; | |
| 555 | })(jQuery); |