1# blueimp Gallery
2
3- [Demo](#demo)
4- [Description](#description)
5- [Setup](#setup)
6    - [Controls](#controls)
7    - [Carousel setup](#carousel-setup)
8- [Keyboard shortcuts](#keyboard-shortcuts)
9- [Options](#options)
10    - [Carousel options](#carousel-options)
11    - [Indicator options](#indicator-options)
12    - [Fullscreen options](#fullscreen-options)
13    - [Video factory options](#video-factory-options)
14    - [Container and element options](#container-and-element-options)
15    - [Property options](#property-options)
16- [API](#api)
17    - [API methods](#api-methods)
18    - [Videos](#videos)
19        - [Multiple video sources](#multiple-video-sources)
20    - [Additional content types](#additional-content-types)
21        - [Example HTML text factory implementation](#example-html-text-factory-implementation)
22    - [jQuery plugin](#jquery-plugin)
23        - [HTML5 data-attributes](#html5-data-attributes)
24        - [Container ids and link grouping](#container-ids-and-link-grouping)
25        - [Gallery object](#gallery-object)
26        - [Event callbacks](#event-callbacks)
27- [Requirements](#requirements)
28- [Browsers](#browsers)
29    - [Desktop browsers](#desktop-browsers)
30    - [Mobile browsers](#mobile-browsers)
31- [License](#license)
32- [Credits](#credits)
33
34## Demo
35[blueimp Gallery Demo](http://blueimp.github.io/Gallery/)
36
37## Description
38blueimp Gallery is a touch-enabled, responsive and customizable image and video gallery, carousel and lightbox, optimized for both mobile and desktop web browsers.
39It features swipe, mouse and keyboard navigation, transition effects, slideshow functionality, fullscreen support and on-demand content loading and can be extended to display additional content types.
40
41## Setup
42Copy the **css**, **img** and **js** directories to your website.
43
44Include the Gallery stylesheet in the head section of your webpage:
45
46```html
47<link rel="stylesheet" href="css/blueimp-gallery.min.css">
48```
49
50Add the following HTML snippet with the Gallery widget to the body of your webpage:
51
52```html
53<!-- The Gallery as lightbox dialog, should be a child element of the document body -->
54<div id="blueimp-gallery" class="blueimp-gallery">
55    <div class="slides"></div>
56    <h3 class="title"></h3>
57    <a class="prev">‹</a>
58    <a class="next">›</a>
59    <a class="close">×</a>
60    <a class="play-pause"></a>
61    <ol class="indicator"></ol>
62</div>
63```
64
65Include the Gallery script at the bottom of the body of your webpage:
66
67```html
68<script src="js/blueimp-gallery.min.js"></script>
69```
70
71Create a list of links to image files, optionally with enclosed thumbnails and add them to the body of your webpage, before including the Gallery script:
72
73```html
74<div id="links">
75    <a href="images/banana.jpg" title="Banana">
76        <img src="images/thumbnails/banana.jpg" alt="Banana">
77    </a>
78    <a href="images/apple.jpg" title="Apple">
79        <img src="images/thumbnails/apple.jpg" alt="Apple">
80    </a>
81    <a href="images/orange.jpg" title="Orange">
82        <img src="images/thumbnails/orange.jpg" alt="Orange">
83    </a>
84</div>
85```
86
87Add the following JavaScript code after including the Gallery script, to display the images in the Gallery lightbox on click of the links:
88
89```html
90<script>
91document.getElementById('links').onclick = function (event) {
92    event = event || window.event;
93    var target = event.target || event.srcElement,
94        link = target.src ? target.parentNode : target,
95        options = {index: link, event: event},
96        links = this.getElementsByTagName('a');
97    blueimp.Gallery(links, options);
98};
99</script>
100```
101
102### Controls
103To initialize the Gallery with visible controls, add the CSS class **blueimp-gallery-controls** to the Gallery widget:
104
105```html
106<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls">
107    <div class="slides"></div>
108    <h3 class="title"></h3>
109    <a class="prev">‹</a>
110    <a class="next">›</a>
111    <a class="close">×</a>
112    <a class="play-pause"></a>
113    <ol class="indicator"></ol>
114</div>
115```
116
117### Carousel setup
118To display the images in an inline carousel instead of a lightbox, add the CSS class **blueimp-gallery-carousel** to the Gallery widget and remove the child element with the **close** class, or add a new Gallery widget with a different **id** to your webpage:
119
120```html
121<!-- The Gallery as inline carousel, can be positioned anywhere on the page -->
122<div id="blueimp-gallery-carousel" class="blueimp-gallery blueimp-gallery-carousel">
123    <div class="slides"></div>
124    <h3 class="title"></h3>
125    <a class="prev">‹</a>
126    <a class="next">›</a>
127    <a class="play-pause"></a>
128    <ol class="indicator"></ol>
129</div>
130```
131
132Add the following JavaScript code after including the Gallery script to initialize the carousel:
133
134```html
135<script>
136blueimp.Gallery(
137    document.getElementById('links').getElementsByTagName('a'),
138    {
139        container: '#blueimp-gallery-carousel',
140        carousel: true
141    }
142);
143</script>
144```
145
146## Keyboard shortcuts
147The Gallery can be controlled with the following keyboard shortcuts:
148
149* **Return**: Toggle controls visibility.
150* **Esc**: Close the Gallery lightbox.
151* **Space**: Toggle the slideshow (play/pause).
152* **Left**: Move to the previous slide.
153* **Right**: Move to the next slide.
154
155Please note that setting the **carousel** option to **true** disables the keyboard shortcuts by default.
156
157## Options
158The following are the default options set by the Gallery:
159
160```js
161var options = {
162    // The Id, element or querySelector of the gallery widget:
163    container: '#blueimp-gallery',
164    // The tag name, Id, element or querySelector of the slides container:
165    slidesContainer: 'div',
166    // The tag name, Id, element or querySelector of the title element:
167    titleElement: 'h3',
168    // The class to add when the gallery is visible:
169    displayClass: 'blueimp-gallery-display',
170    // The class to add when the gallery controls are visible:
171    controlsClass: 'blueimp-gallery-controls',
172    // The class to add when the gallery only displays one element:
173    singleClass: 'blueimp-gallery-single',
174    // The class to add when the left edge has been reached:
175    leftEdgeClass: 'blueimp-gallery-left',
176    // The class to add when the right edge has been reached:
177    rightEdgeClass: 'blueimp-gallery-right',
178    // The class to add when the automatic slideshow is active:
179    playingClass: 'blueimp-gallery-playing',
180    // The class for all slides:
181    slideClass: 'slide',
182    // The slide class for loading elements:
183    slideLoadingClass: 'slide-loading',
184    // The slide class for elements that failed to load:
185    slideErrorClass: 'slide-error',
186    // The class for the content element loaded into each slide:
187    slideContentClass: 'slide-content',
188    // The class for the "toggle" control:
189    toggleClass: 'toggle',
190    // The class for the "prev" control:
191    prevClass: 'prev',
192    // The class for the "next" control:
193    nextClass: 'next',
194    // The class for the "close" control:
195    closeClass: 'close',
196    // The class for the "play-pause" toggle control:
197    playPauseClass: 'play-pause',
198    // The list object property (or data attribute) with the object type:
199    typeProperty: 'type',
200    // The list object property (or data attribute) with the object title:
201    titleProperty: 'title',
202    // The list object property (or data attribute) with the object URL:
203    urlProperty: 'href',
204    // Defines if the gallery slides are cleared from the gallery modal,
205    // or reused for the next gallery initialization:
206    clearSlides: true,
207    // Defines if images should be stretched to fill the available space,
208    // while maintaining their aspect ratio (will only be enabled for browsers
209    // supporting background-size="contain", which excludes IE < 9):
210    stretchImages: false,
211    // Toggle the controls on pressing the Return key:
212    toggleControlsOnReturn: true,
213    // Toggle the automatic slideshow interval on pressing the Space key:
214    toggleSlideshowOnSpace: true,
215    // Navigate the gallery by pressing left and right on the keyboard:
216    enableKeyboardNavigation: true,
217    // Close the gallery on pressing the ESC key:
218    closeOnEscape: true,
219    // Close the gallery when clicking on an empty slide area:
220    closeOnSlideClick: true,
221    // Close the gallery by swiping up or down:
222    closeOnSwipeUpOrDown: true,
223    // Emulate touch events on mouse-pointer devices such as desktop browsers:
224    emulateTouchEvents: true,
225    // Hide the page scrollbars:
226    hidePageScrollbars: true,
227    // Stops any touches on the container from scrolling the page:
228    disableScroll: true,
229    // Carousel mode (shortcut for carousel specific options):
230    carousel: false,
231    // Allow continuous navigation, moving from last to first
232    // and from first to last slide:
233    continuous: true,
234    // Remove elements outside of the preload range from the DOM:
235    unloadElements: true,
236    // Start with the automatic slideshow:
237    startSlideshow: false,
238    // Delay in milliseconds between slides for the automatic slideshow:
239    slideshowInterval: 5000,
240    // The starting index as integer.
241    // Can also be an object of the given list,
242    // or an equal object with the same url property:
243    index: 0,
244    // The number of elements to load around the current index:
245    preloadRange: 2,
246    // The transition speed between slide changes in milliseconds:
247    transitionSpeed: 400,
248    // The transition speed for automatic slide changes, set to an integer
249    // greater 0 to override the default transition speed:
250    slideshowTransitionSpeed: undefined,
251    // The event object for which the default action will be canceled
252    // on Gallery initialization (e.g. the click event to open the Gallery):
253    event: undefined,
254    // Callback function executed when the Gallery is initialized.
255    // Is called with the gallery instance as "this" object:
256    onopen: undefined,
257    // Callback function executed on slide change.
258    // Is called with the gallery instance as "this" object and the
259    // current index and slide as arguments:
260    onslide: undefined,
261    // Callback function executed after the slide change transition.
262    // Is called with the gallery instance as "this" object and the
263    // current index and slide as arguments:
264    onslideend: undefined,
265    // Callback function executed on slide content load.
266    // Is called with the gallery instance as "this" object and the
267    // slide index and slide element as arguments:
268    onslidecomplete: undefined,
269    // Callback function executed when the Gallery is closed.
270    // Is called with the gallery instance as "this" object:
271    onclose: undefined
272};
273```
274
275### Carousel options
276
277If the **carousel** option is **true**, the following options are set to different default values:
278
279```js
280var carouselOptions = {
281    hidePageScrollbars: false,
282    toggleControlsOnReturn: false,
283    toggleSlideshowOnSpace: false,
284    enableKeyboardNavigation: false,
285    closeOnEscape: false,
286    closeOnSlideClick: false,
287    closeOnSwipeUpOrDown: false,
288    disableScroll: false,
289    startSlideshow: true
290};
291```
292
293The options object passed to the Gallery function extends the default options and also those options set via **carousel** mode.
294
295### Indicator options
296The following are the additional default options set for the slide position indicator:
297
298```js
299var options = {
300    // The tag name, Id, element or querySelector of the indicator container:
301    indicatorContainer: 'ol',
302    // The class for the active indicator:
303    activeIndicatorClass: 'active',
304    // The list object property (or data attribute) with the thumbnail URL,
305    // used as alternative to a thumbnail child element:
306    thumbnailProperty: 'thumbnail',
307    // Defines if the gallery indicators should display a thumbnail:
308    thumbnailIndicators: true
309};
310```
311
312### Fullscreen options
313The following are the additional default options set for the fullscreen mode:
314
315```js
316var options = {
317    // Defines if the gallery should open in fullscreen mode:
318    fullScreen: false
319};
320```
321
322### Video factory options
323The following are the additional default options set for the video factory:
324
325```js
326var options = {
327    // The class for video content elements:
328    videoContentClass: 'video-content',
329    // The class for video when it is loading:
330    videoLoadingClass: 'video-loading',
331    // The class for video when it is playing:
332    videoPlayingClass: 'video-playing',
333    // The list object property (or data attribute) for the video poster URL:
334    videoPosterProperty: 'poster',
335    // The list object property (or data attribute) for the video sources array:
336    videoSourcesProperty: 'sources'
337};
338```
339
340### Container and element options
341The widget **container** option can be set as id string (with "#" as prefix) or element node, so the following are equivalent:
342
343```js
344var options = {
345    container: '#blueimp-gallery'
346};
347```
348
349```js
350var options = {
351    container: document.getElementById('blueimp-gallery')
352};
353```
354
355The **slidesContainer**, **titleElement** and **indicatorContainer** options can also be defined using a tag name, which selects the first tag of this kind found inside of the widget container:
356
357```js
358var options = {
359    slidesContainer: 'div',
360    titleElement: 'h3',
361    indicatorContainer: 'ol'
362};
363```
364
365It is also possible to define the container and element options with a more complex [querySelector](https://developer.mozilla.org/en-US/docs/Web/API/document.querySelector), which is supported by IE8+ and all modern web browsers.
366
367If the helper script is replaced with [jQuery](http://jquery.com/), the container and element options can be any valid jQuery selector.
368
369### Property options
370The options ending with "Property" define how the properties of each link element are accessed.
371For example, the **urlProperty** is by default set to **href**. This allows to define link elements with **href** or **data-href** attributes:
372
373```html
374<div id="links">
375    <a href="images/banana.jpg">Banana</a>
376    <a data-href="images/apple.jpg">Apple</a>
377</div>
378```
379
380If the links are passed as JavaScript array, it is also possible to define nested property names, by using the native JavaScript accessor syntax for the property string:
381
382```js
383blueimp.Gallery(
384    [
385        {
386            data: {urls: ['http://example.org/images/banana.jpg']}
387        },
388        {
389            data: {urls: ['http://example.org/images/apple.jpg']}
390        }
391    ],
392    {
393        urlProperty: 'data.urls[0]'
394    }
395);
396```
397
398## API
399The blueimp Gallery can be initialized by simply calling it as a function with an array of links as first argument and an optional options object as second argument:
400
401```js
402var gallery = blueimp.Gallery(links, options);
403```
404
405The links array can be a list of URL strings or a list of objects with URL properties.
406The URL property name defined by each list object can be configured via the **urlProperty** option. By default, it is set to **href**, which allows to pass a list of HTML link elements as first argument.
407
408The object returned by executing the Gallery function (the **gallery** variable in the example code above) is a new instance of the Gallery and allows to access the public API methods provided by the Gallery.
409The Gallery initialization function returns **false** if the given list was empty, the Gallery widget is missing, or the browser doesn't pass the functionality test.
410
411### API methods
412
413The Gallery object returned by executing the Gallery function provides the following public API methods:
414
415```js
416// Return the current slide index position:
417var pos = gallery.getIndex();
418
419// Return the total number of slides:
420var count = gallery.getNumber();
421
422// Move to the previous slide:
423gallery.prev();
424
425// Move to the next slide:
426gallery.next();
427
428// Move to the given slide index with the (optional) given duraction speed in milliseconds:
429gallery.slide(index, duration);
430
431// Start an automatic slideshow with the given interval in milliseconds (optional):
432gallery.play(interval);
433
434// Stop the automatic slideshow:
435gallery.pause();
436
437// Add additional slides after Gallery initialization:
438gallery.add(list);
439
440// Close and deinitialize the Gallery:
441gallery.close();
442```
443
444### Videos
445The Gallery can be initialized with a list of videos instead of images, or a combination of both:
446
447```js
448blueimp.Gallery([
449    {
450        title: 'Fruits',
451        href: 'http://example.org/videos/fruits.mp4',
452        type: 'video/mp4',
453        poster: 'http://example.org/images/fruits.jpg'
454    },
455    {
456        title: 'Banana',
457        href: 'http://example.org/images/banana.jpg',
458        type: 'image/jpeg',
459        thumbnail: 'http://example.org/thumbnails/banana.jpg'
460    }
461]);
462```
463
464The Gallery uses the **type** property to determine the content type of the object to display.
465If the type property is empty or doesn't exist, the default type **image** is assumed.
466
467For images, the **thumbnail** property defines the URL of the image thumbnail, which is used for the indicator navigation displayed at the bottom of the Gallery, if the controls are visible.
468
469For videos, the **poster** property defines the URL of the poster image to display, before the video is started.
470
471#### Multiple video sources
472To provide multiple video formats, the **sources** property of a list object can be set to an array of objects with **href** and **type** properties for each video source. The first video format in the list that the browser can play will be displayed:
473
474```js
475blueimp.Gallery([
476    {
477        title: 'Fruits',
478        type: 'video/*',
479        poster: 'http://example.org/images/fruits.jpg',
480        sources: [
481            {
482                href: 'http://example.org/videos/fruits.mp4',
483                type: 'video/mp4'
484            },
485            {
486                href: 'http://example.org/videos/fruits.ogg',
487                type: 'video/ogg'
488            }
489        ]
490    }
491]);
492```
493
494It is also possible to define the video sources as data-attribute on a link element in [JSON](https://developer.mozilla.org/en-US/docs/JSON) array format:
495
496```html
497<div id="links">
498    <a
499        href="http://example.org/videos/fruits.mp4"
500        title="Fruits"
501        type="video/mp4"
502        data-poster="http://example.org/images/fruits.jpg"
503        data-sources='[{"href": "http://example.org/videos/fruits.mp4", "type": "video/mp4"}, {"href": "http://example.org/videos/fruits.ogg", "type": "video/ogg"}]'
504    >Fruits</a>
505</div>
506```
507
508### Additional content types
509By extending the Gallery prototype with new factory methods, additional content types can be displayed.  By default, blueimp Gallery provides the **imageFactory** and **videoFactory** methods for **image** and **video** content types respectively.
510
511The Gallery uses the **type** property of each content object to determine which factory method to use.  The **type** defines the [Internet media type](http://en.wikipedia.org/wiki/Internet_media_type) of the content object and is composed of two or more parts: A type, a subtype, and zero or more optional parameters, e.g. **text/html; charset=UTF-8** for an HTML document with UTF-8 encoding.
512The main type (the string in front of the slash, **text** in the example above) is concatenated with the string **Factory** to create the factory method name, e.g. **textFactory**.
513
514#### Example HTML text factory implementation
515Please note that although blueimp Gallery doesn't require [jQuery](http://jquery.com/), the following example uses it for convenience.
516
517Extend the Gallery prototype with the **textFactory** method:
518
519```js
520blueimp.Gallery.prototype.textFactory = function (obj, callback) {
521    var $element = $('<div>')
522            .addClass('text-content')
523            .attr('title', obj.title);
524    $.get(obj.href)
525        .done(function (result) {
526            $element.html(result);
527            callback({
528                type: 'load',
529                target: $element[0]
530            });
531        })
532        .fail(function () {
533            callback({
534                type: 'error',
535                target: $element[0]
536            });
537        });
538    return $element[0];
539};
540```
541
542Add the **text-content** class to the Gallery CSS:
543
544```css
545.blueimp-gallery > .slides > .slide > .text-content {
546    overflow: auto;
547    margin: 60px auto;
548    padding: 0 60px;
549    max-width: 920px;
550    text-align: left;
551}
552```
553
554With the previous changes in place, the Gallery can now handle HTML content types:
555
556```js
557blueimp.Gallery([
558    {
559        title: 'Noodle soup',
560        href: 'http://example.org/text/noodle-soup.html',
561        type: 'text/html'
562    },
563    {
564        title: 'Tomato salad',
565        href: 'http://example.org/text/tomato-salad.html',
566        type: 'text/html'
567    }
568]);
569```
570
571### jQuery plugin
572The blueimp Gallery jQuery plugin registers a global click handler to open links with **data-gallery** attribute in the Gallery lightbox.
573
574To use it, follow the Setup guide, but replace the minified Gallery script with the jQuery plugin version and include it after including [jQuery](http://jquery.com/):
575
576```html
577<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
578<script src="js/jquery.blueimp-gallery.min.js"></script>
579```
580
581Next, add the attribute **data-gallery** to your Gallery links:
582
583```html
584<div id="links">
585    <a href="images/banana.jpg" title="Banana" data-gallery>
586        <img src="images/thumbnails/banana.jpg" alt="Banana">
587    </a>
588    <a href="images/apple.jpg" title="Apple" data-gallery>
589        <img src="images/thumbnails/apple.jpg" alt="Apple">
590    </a>
591    <a href="images/orange.jpg" title="Orange" data-gallery>
592        <img src="images/thumbnails/orange.jpg" alt="Orange">
593    </a>
594</div>
595```
596
597The onclick handler from the Setup guide is not required and can be removed.
598
599#### HTML5 data-attributes
600Options for the Gallery lightbox opened via the jQuery plugin can be defined as [HTML5 data-attributes](http://api.jquery.com/data/#data-html5) on the Gallery widget container.
601
602The jQuery plugin also introduces the additional **filter** option, which is applied to the Gallery links via [jQuery's filter method](http://api.jquery.com/filter/) and allows to remove duplicates from the list:
603
604```html
605<div id="blueimp-gallery" class="blueimp-gallery" data-start-slideshow="true" data-filter=":even">
606    <div class="slides"></div>
607    <h3 class="title"></h3>
608    <a class="prev">‹</a>
609    <a class="next">›</a>
610    <a class="close">×</a>
611    <a class="play-pause"></a>
612    <ol class="indicator"></ol>
613</div>
614```
615
616This will initialize the Gallery with the option **startSlideshow** set to **true**.
617It will also filter the Gallery links so that only links with an even index number will be included.
618
619#### Container ids and link grouping
620If the **data-gallery** attribute value is a valid id string (e.g. "#blueimp-gallery"), it is used as container option.
621Setting **data-gallery** to a non-empty string also allows to group links into different sets of Gallery images:
622
623```html
624<div id="fruits">
625    <a href="images/banana.jpg" title="Banana" data-gallery="#blueimp-gallery-fruits">
626        <img src="images/thumbnails/banana.jpg" alt="Banana">
627    </a>
628    <a href="images/apple.jpg" title="Apple" data-gallery="#blueimp-gallery-fruits">
629        <img src="images/thumbnails/apple.jpg" alt="Apple">
630    </a>
631</div>
632<div id="vegetables">
633    <a href="images/tomato.jpg" title="Tomato" data-gallery="#blueimp-gallery-vegetables">
634        <img src="images/thumbnails/tomato.jpg" alt="Tomato">
635    </a>
636    <a href="images/onion.jpg" title="Onion" data-gallery="#blueimp-gallery-vegetables">
637        <img src="images/thumbnails/onion.jpg" alt="Onion">
638    </a>
639</div>
640```
641
642This will open the links with the **data-gallery** attribute **#blueimp-gallery-fruits** in the Gallery widget with the id **blueimp-gallery-fruits**, and the links with the **data-gallery** attribute **#blueimp-gallery-vegetables**  in the Gallery widget with the id **blueimp-gallery-vegetables**.
643
644#### Gallery object
645The gallery object is stored via [jQuery data storage](http://api.jquery.com/category/miscellaneous/data-storage/) on the Gallery widget when the Gallery is opened and can be retrieved the following way:
646
647```js
648var gallery = $('#blueimp-gallery').data('gallery');
649```
650
651This gallery object provides all methods outlined in the API methods section.
652
653#### Event callbacks
654The jQuery plugin triggers Gallery events on the widget container, with event names equivalent to the callback options:
655
656```js
657$('#blueimp-gallery')
658    .on('open', function (event) {
659        // Gallery open event handler
660    })
661    .on('slide', function (event, index, slide) {
662        // Gallery slide event handler
663    })
664    .on('slideend', function (event, index, slide) {
665        // Gallery slideend event handler
666    })
667    .on('slidecomplete', function (event, index, slide) {
668        // Gallery slidecomplete event handler
669    })
670    .on('close', function (event) {
671        // Gallery close event handler
672    });
673```
674
675## Requirements
676blueimp Gallery doesn't require any other libraries and can be used standalone without any dependencies.
677
678You can also use the individual source files instead of the standalone minified version:
679
680```html
681<link rel="stylesheet" href="css/blueimp-gallery.css">
682<link rel="stylesheet" href="css/blueimp-gallery-indicator.css">
683<link rel="stylesheet" href="css/blueimp-gallery-video.css">
684<!-- ... -->
685<script src="js/blueimp-helper.js"></script>
686<script src="js/blueimp-gallery.js"></script>
687<script src="js/blueimp-gallery-fullscreen.js"></script>
688<script src="js/blueimp-gallery-indicator.js"></script>
689<script src="js/blueimp-gallery-video.js"></script>
690```
691
692The helper script can be replaced by [jQuery](http://jquery.com/) v. 1.7+.
693The fullscreen, indicator and video source files are optional if their functionality is not required.
694
695The jQuery plugin requires [jQuery](http://jquery.com/) v. 1.7+ and the basic Gallery script, while the fullscreen, indicator and video source files are also optional:
696
697```html
698<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
699<script src="js/blueimp-gallery.js"></script>
700<script src="js/blueimp-gallery-fullscreen.js"></script>
701<script src="js/blueimp-gallery-indicator.js"></script>
702<script src="js/blueimp-gallery-video.js"></script>
703<script src="js/jquery.blueimp-gallery.js"></script>
704```
705
706Please note that the jQuery plugin is an optional extension and not required for the Gallery functionality.
707
708## Browsers
709blueimp Gallery has been tested with and supports the following browsers:
710
711### Desktop browsers
712
713* Google Chrome 14.0+
714* Apple Safari 4.0+
715* Mozilla Firefox 4.0+
716* Opera 10.0+
717* Microsoft Internet Explorer 7.0+
718
719### Mobile browsers
720
721* Apple Safari on iOS 6.0+
722* Google Chrome on iOS 6.0+
723* Google Chrome on Android 4.0+
724* Default Browser on Android 2.3+
725* Opera Mobile 12.0+
726
727## License
728Released under the [MIT license](http://www.opensource.org/licenses/MIT).
729
730## Credits
731The swipe implementation is based on code from the [Swipe](http://swipejs.com/) library.
732