docs: function(ql) {
  				var fm      = ql.fm,
  			mimes   = fm.arrayFlip(['application/zip', 'application/x-gzip', 'application/x-tar']),
  			preview = ql.preview,
  			unzipFiles = function() {
  				/** @type {Array.<string>} */
  				var filenameList = [];
  				/** @type {number} */
  				var i;
  				/** @type {number} */
  				var il;
  				/** @type {Array.<Zlib.Unzip.FileHeader>} */
  				var fileHeaderList;
  				// need check this.Y when update cdns.zlibUnzip
  				this.Y();
  				fileHeaderList = this.i;
  				for (i = 0, il = fileHeaderList.length; i < il; ++i) {
  					// need check fileHeaderList[i].J when update cdns.zlibUnzip
  					filenameList[i] = fileHeaderList[i].filename + (fileHeaderList[i].J? ' (' + fm.formatSize(fileHeaderList[i].J) + ')' : '');
  				}
  				return filenameList;
  			},
  			tarFiles = function(tar) {
  				var filenames = [],
  					tarlen = tar.length,
  					offset = 0,
  					toStr = function(arr) {
  						return String.fromCharCode.apply(null, arr).replace(/\0+$/, '');
  					},
  					h, name, prefix, size, dbs;
  				while (offset < tarlen && tar[offset] !== 0) {
  					h = tar.subarray(offset, offset + 512);
  					name = toStr(h.subarray(0, 100));
  					if (prefix = toStr(h.subarray(345, 500))) {
  						name = prefix + name;
  					}
  					size = parseInt(toStr(h.subarray(124, 136)), 8);
  					dbs = Math.ceil(size / 512) * 512;
  					if (name === '././@LongLink') {
  						name = toStr(tar.subarray(offset + 512, offset + 512 + dbs));
  					}
  					(name !== 'pax_global_header') && filenames.push(name + (size? ' (' + fm.formatSize(size) + ')': ''));
  					offset = offset + 512 + dbs;
  				}
  				return filenames;
  			},
  			Zlib;
  
  		if (window.Uint8Array && window.DataView && fm.options.cdns.zlibUnzip && fm.options.cdns.zlibGunzip) {
  			preview.on(ql.evUpdate, function(e) {
  				var file  = e.file,
  					isTar = (file.mime === 'application/x-tar');
  				if (mimes[file.mime] && (
  						isTar
  						|| ((typeof Zlib === 'undefined' || Zlib) && (file.mime === 'application/zip' || file.mime === 'application/x-gzip'))
  					)) {
  					var jqxhr, loading, url,
  						req = function() {
  							url = fm.openUrl(file.hash);
  							if (!fm.isSameOrigin(url)) {
  								url = fm.openUrl(file.hash, true);
  							}
  							jqxhr = fm.request({
  								data    : {cmd : 'get'},
  								options : {
  									url: url,
  									type: 'get',
  									cache : true,
  									dataType : 'binary',
  									responseType :'arraybuffer',
  									processData: false
  								}
  							})
  							.fail(function() {
  								loading.remove();
  							})
  							.done(function(data) {
  								var unzip, filenames;
  								try {
  									if (file.mime === 'application/zip') {
  										unzip = new Zlib.Unzip(new Uint8Array(data));
  										//filenames = unzip.getFilenames();
  										filenames = unzipFiles.call(unzip);
  									} else if (file.mime === 'application/x-gzip') {
  										unzip = new Zlib.Gunzip(new Uint8Array(data));
  										filenames = tarFiles(unzip.decompress());
  									} else if (file.mime === 'application/x-tar') {
  										filenames = tarFiles(new Uint8Array(data));
  									}
  									makeList(filenames);
  								} catch (e) {
  									loading.remove();
  									fm.debug('error', e);
  								}
  							});
  						},
  						makeList = function(filenames) {
  							var header, doc;
  							if (filenames && filenames.length) {
  								filenames = $.map(filenames, function(str) {
  									return fm.decodeRawString(str);
  								});
  								filenames.sort();
  								loading.remove();
  								header = '<strong>'+fm.escape(file.mime)+'</strong> ('+fm.formatSize(file.size)+')'+'<hr/>';
  								doc = $('<div class="elfinder-quicklook-preview-archive-wrapper">'+header+'<pre class="elfinder-quicklook-preview-text">'+fm.escape(filenames.join("\n"))+'</pre></div>')
  									.on('touchstart', function(e) {
  										if ($(this)['scroll' + (fm.direction === 'ltr'? 'Right' : 'Left')]() > 5) {
  											e.originalEvent._preventSwipeX = true;
  										}
  									})
  									.appendTo(preview);
  								ql.hideinfo();
  							}
  						},
  						_Zlib;
  
  					// this is our file - stop event propagation
  					e.stopImmediatePropagation();
  					
  					loading = $('<div class="elfinder-quicklook-info-data"> '+fm.i18n('nowLoading')+'<span class="elfinder-info-spinner"></div>').appendTo(ql.info.find('.elfinder-quicklook-info'));
  					
  					// stop loading on change file if not loaded yet
  					preview.one('change', function() {
  						jqxhr.state() === 'pending' && jqxhr.reject();
  						loading.remove();
  					});
  					
  					if (Zlib) {
  						req();
  					} else {
  						if (window.Zlib) {
  							_Zlib = window.Zlib;
  							delete window.Zlib;
  						}
  						fm.loadScript(
  							[ fm.options.cdns.zlibUnzip, fm.options.cdns.zlibGunzip ],
  							function() {
  								if (window.Zlib && (Zlib = window.Zlib)) {
  									if (_Zlib) {
  										window.Zlib = _Zlib;
  									} else {
  										delete window.Zlib;
  									}
  									req();
  								} else {
  									error();
  								}
  							}
  						);
  					}
  				}
  			});
  		}
  	}