From cf756ea7eb9d7355f1f7bc0b98436b2e5555e822 Mon Sep 17 00:00:00 2001 From: kl <632104866@QQ.com> Date: Tue, 12 Dec 2017 19:42:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 55 +- pom.xml | 172 ++ .../yudianbank/FilePreviewApplication.java | 23 + .../com/yudianbank/config/RedissonConfig.java | 242 +++ .../extend/ControlDocumentFormatRegistry.java | 211 ++ .../yudianbank/filters/ChinesePathFilter.java | 28 + .../filters/FilterConfiguration.java | 23 + .../com/yudianbank/param/ReturnResponse.java | 57 + .../com/yudianbank/utils/ConverterUtils.java | 68 + .../com/yudianbank/utils/DeleteFileUtil.java | 74 + .../com/yudianbank/utils/DownloadUtils.java | 151 ++ .../java/com/yudianbank/utils/FileUtils.java | 192 ++ .../com/yudianbank/utils/OfficeToPdf.java | 129 ++ .../com/yudianbank/utils/PoiExcelToHtml.java | 194 ++ .../com/yudianbank/utils/ShedulerClean.java | 19 + .../java/com/yudianbank/utils/WordToHtml.java | 61 + .../java/com/yudianbank/utils/ZipReader.java | 392 ++++ .../web/controller/FileController.java | 113 + .../controller/OnlinePreviewController.java | 170 ++ src/main/resources/META-INF/app.properties | 1 + src/main/resources/application.properties | 30 + src/main/resources/logback.xml | 18 + src/main/resources/static/config.js | 8 + .../resources/static/css/img/diy/1_close.png | Bin 0 -> 601 bytes .../resources/static/css/img/diy/1_open.png | Bin 0 -> 580 bytes src/main/resources/static/css/img/diy/2.png | Bin 0 -> 570 bytes src/main/resources/static/css/img/diy/3.png | Bin 0 -> 762 bytes src/main/resources/static/css/img/diy/4.png | Bin 0 -> 399 bytes src/main/resources/static/css/img/diy/5.png | Bin 0 -> 710 bytes src/main/resources/static/css/img/diy/6.png | Bin 0 -> 432 bytes src/main/resources/static/css/img/diy/7.png | Bin 0 -> 534 bytes src/main/resources/static/css/img/diy/8.png | Bin 0 -> 529 bytes src/main/resources/static/css/img/diy/9.png | Bin 0 -> 467 bytes .../resources/static/css/img/line_conn.gif | Bin 0 -> 45 bytes src/main/resources/static/css/img/loading.gif | Bin 0 -> 381 bytes .../static/css/img/zTreeStandard.gif | Bin 0 -> 5564 bytes .../static/css/img/zTreeStandard.png | Bin 0 -> 11173 bytes src/main/resources/static/css/loading.css | 121 ++ src/main/resources/static/css/viewer.min.css | 9 + src/main/resources/static/css/zTreeStyle.css | 97 + src/main/resources/static/images/sorry.jpg | Bin 0 -> 23866 bytes src/main/resources/static/index.html | 172 ++ src/main/resources/static/js/excel.header.js | 19 + .../resources/static/js/jquery-3.0.0.min.js | 4 + .../resources/static/js/jquery.ztree.core.js | 1935 +++++++++++++++++ src/main/resources/static/js/viewer.min.js | 10 + src/main/resources/web/compress.ftl | 95 + src/main/resources/web/doc.ftl | 9 + src/main/resources/web/docxConvert.ftl | 11 + src/main/resources/web/fileNotSupported.ftl | 41 + src/main/resources/web/pdf.ftl | 26 + src/main/resources/web/picture.ftl | 33 + src/main/resources/web/txt.ftl | 18 + .../FilePreviewApplicationTests.java | 16 + 54 files changed, 5029 insertions(+), 18 deletions(-) create mode 100644 pom.xml create mode 100644 src/main/java/com/yudianbank/FilePreviewApplication.java create mode 100644 src/main/java/com/yudianbank/config/RedissonConfig.java create mode 100644 src/main/java/com/yudianbank/extend/ControlDocumentFormatRegistry.java create mode 100644 src/main/java/com/yudianbank/filters/ChinesePathFilter.java create mode 100644 src/main/java/com/yudianbank/filters/FilterConfiguration.java create mode 100644 src/main/java/com/yudianbank/param/ReturnResponse.java create mode 100644 src/main/java/com/yudianbank/utils/ConverterUtils.java create mode 100644 src/main/java/com/yudianbank/utils/DeleteFileUtil.java create mode 100644 src/main/java/com/yudianbank/utils/DownloadUtils.java create mode 100644 src/main/java/com/yudianbank/utils/FileUtils.java create mode 100644 src/main/java/com/yudianbank/utils/OfficeToPdf.java create mode 100644 src/main/java/com/yudianbank/utils/PoiExcelToHtml.java create mode 100644 src/main/java/com/yudianbank/utils/ShedulerClean.java create mode 100644 src/main/java/com/yudianbank/utils/WordToHtml.java create mode 100644 src/main/java/com/yudianbank/utils/ZipReader.java create mode 100644 src/main/java/com/yudianbank/web/controller/FileController.java create mode 100644 src/main/java/com/yudianbank/web/controller/OnlinePreviewController.java create mode 100644 src/main/resources/META-INF/app.properties create mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/resources/static/config.js create mode 100644 src/main/resources/static/css/img/diy/1_close.png create mode 100644 src/main/resources/static/css/img/diy/1_open.png create mode 100644 src/main/resources/static/css/img/diy/2.png create mode 100644 src/main/resources/static/css/img/diy/3.png create mode 100644 src/main/resources/static/css/img/diy/4.png create mode 100644 src/main/resources/static/css/img/diy/5.png create mode 100644 src/main/resources/static/css/img/diy/6.png create mode 100644 src/main/resources/static/css/img/diy/7.png create mode 100644 src/main/resources/static/css/img/diy/8.png create mode 100644 src/main/resources/static/css/img/diy/9.png create mode 100644 src/main/resources/static/css/img/line_conn.gif create mode 100644 src/main/resources/static/css/img/loading.gif create mode 100644 src/main/resources/static/css/img/zTreeStandard.gif create mode 100644 src/main/resources/static/css/img/zTreeStandard.png create mode 100644 src/main/resources/static/css/loading.css create mode 100644 src/main/resources/static/css/viewer.min.css create mode 100644 src/main/resources/static/css/zTreeStyle.css create mode 100644 src/main/resources/static/images/sorry.jpg create mode 100644 src/main/resources/static/index.html create mode 100644 src/main/resources/static/js/excel.header.js create mode 100644 src/main/resources/static/js/jquery-3.0.0.min.js create mode 100644 src/main/resources/static/js/jquery.ztree.core.js create mode 100644 src/main/resources/static/js/viewer.min.js create mode 100644 src/main/resources/web/compress.ftl create mode 100644 src/main/resources/web/doc.ftl create mode 100644 src/main/resources/web/docxConvert.ftl create mode 100644 src/main/resources/web/fileNotSupported.ftl create mode 100644 src/main/resources/web/pdf.ftl create mode 100644 src/main/resources/web/picture.ftl create mode 100644 src/main/resources/web/txt.ftl create mode 100644 src/test/java/com/yudianbank/FilePreviewApplicationTests.java diff --git a/.gitignore b/.gitignore index 6143e53f9..1dcd5ec12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,41 @@ -# Compiled class file -*.class +target/ +!.mvn/wrapper/maven-wrapper.jar -# Log file -*.log +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans -# BlueJ files -*.ctxt +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +### NetBeans ### +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ +/*.iml -# Package Files # -*.jar -*.war -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +**/target/ +.classpath +.project +**/.settings +**/bin/ +**/build/ +**/.externalToolBuilders/ +*.iml +**/.idea/ +**/disconf +**/rpc.properties +/producer/tmp +/.temfile +.temfile +convertedFile/ \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..9e84fb407 --- /dev/null +++ b/pom.xml @@ -0,0 +1,172 @@ + + + 4.0.0 + + com.yudianbank + filepreview + 0.0.1-SNAPSHOT + jar + + file-online-preview + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.5.8.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + 1.0-SNAPSHOT + ${basedir}/target/classes/logs + file-preview + + + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.springframework.boot + spring-boot-starter-web + + + + com.ctrip.framework.apollo + apollo-client + 0.8.0 + + + net.logstash.logback + logstash-logback-encoder + 4.11 + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.redisson + redisson + 3.2.0 + + + org.apache.poi + poi + 3.12 + + + org.apache.poi + poi-scratchpad + 3.12 + + + fr.opensagres.xdocreport + org.apache.poi.xwpf.converter.core + 1.0.5 + + + poi + org.apache.poi + + + + + fr.opensagres.xdocreport + org.apache.poi.xwpf.converter.xhtml + 1.0.5 + + + fr.opensagres.xdocreport + fr.opensagres.xdocreport.document + 1.0.5 + + + commons-io + commons-io + 2.4 + + + + org.apache.commons + commons-compress + 1.9 + + + + com.github.junrar + junrar + 0.7 + + + net.sourceforge.jchardet + jchardet + 1.0 + + + antlr + antlr + 2.7.7 + + + commons-httpclient + commons-httpclient + 3.1 + test + + + commons-logging + commons-logging + + + + + org.artofsolving.jodconverter + jodconverter-core + 3.0-SNAPSHOT + + + commons-io + commons-io + + + + + commons-cli + commons-cli + 1.2 + + + com.thoughtworks.xstream + xstream + 1.3.1 + + + + + + ${basedir}/src/main/resources + + **/* + + true + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + diff --git a/src/main/java/com/yudianbank/FilePreviewApplication.java b/src/main/java/com/yudianbank/FilePreviewApplication.java new file mode 100644 index 000000000..7fb84035e --- /dev/null +++ b/src/main/java/com/yudianbank/FilePreviewApplication.java @@ -0,0 +1,23 @@ +package com.yudianbank; + +import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.PropertySource; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.util.Enumeration; +import java.util.Properties; + +@SpringBootApplication +@EnableScheduling +@ComponentScan(value = "com.yudianbank.*") +//@EnableApolloConfig +public class FilePreviewApplication { + public static void main(String[] args) { + Properties properties = System.getProperties(); + System.out.println(properties.get("user.dir")); + SpringApplication.run(FilePreviewApplication.class, args); + } +} diff --git a/src/main/java/com/yudianbank/config/RedissonConfig.java b/src/main/java/com/yudianbank/config/RedissonConfig.java new file mode 100644 index 000000000..071b74632 --- /dev/null +++ b/src/main/java/com/yudianbank/config/RedissonConfig.java @@ -0,0 +1,242 @@ +package com.yudianbank.config; + +import io.netty.channel.nio.NioEventLoopGroup; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.client.codec.Codec; +import org.redisson.config.Config; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.ClassUtils; + +/** + * Created by kl on 2017/09/26. + * redisson 客户端配置 + */ +@ConfigurationProperties(prefix = "spring.redisson") +@Configuration +public class RedissonConfig { + + private String address; + private int connectionMinimumIdleSize = 10; + private int idleConnectionTimeout=10000; + private int pingTimeout=1000; + private int connectTimeout=10000; + private int timeout=3000; + private int retryAttempts=3; + private int retryInterval=1500; + private int reconnectionTimeout=3000; + private int failedAttempts=3; + private String password = null; + private int subscriptionsPerConnection=5; + private String clientName=null; + private int subscriptionConnectionMinimumIdleSize = 1; + private int subscriptionConnectionPoolSize = 50; + private int connectionPoolSize = 64; + private int database = 0; + private boolean dnsMonitoring = false; + private int dnsMonitoringInterval = 5000; + + private int thread; //当前处理核数量 * 2 + + private String codec="org.redisson.codec.JsonJacksonCodec"; + + @Bean(destroyMethod = "shutdown") + RedissonClient redisson() throws Exception { + Config config = new Config(); + config.useSingleServer().setAddress(address) + .setConnectionMinimumIdleSize(connectionMinimumIdleSize) + .setConnectionPoolSize(connectionPoolSize) + .setDatabase(database) + .setDnsMonitoring(dnsMonitoring) + .setDnsMonitoringInterval(dnsMonitoringInterval) + .setSubscriptionConnectionMinimumIdleSize(subscriptionConnectionMinimumIdleSize) + .setSubscriptionConnectionPoolSize(subscriptionConnectionPoolSize) + .setSubscriptionsPerConnection(subscriptionsPerConnection) + .setClientName(clientName) + .setFailedAttempts(failedAttempts) + .setRetryAttempts(retryAttempts) + .setRetryInterval(retryInterval) + .setReconnectionTimeout(reconnectionTimeout) + .setTimeout(timeout) + .setConnectTimeout(connectTimeout) + .setIdleConnectionTimeout(idleConnectionTimeout) + .setPingTimeout(pingTimeout) + .setPassword(password); + Codec codec=(Codec) ClassUtils.forName(getCodec(), ClassUtils.getDefaultClassLoader()).newInstance(); + config.setCodec(codec); + config.setThreads(thread); + config.setEventLoopGroup(new NioEventLoopGroup()); + config.setUseLinuxNativeEpoll(false); + return Redisson.create(config); + } + + public int getThread() { + return thread; + } + + public void setThread(int thread) { + this.thread = thread; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getIdleConnectionTimeout() { + return idleConnectionTimeout; + } + + public void setIdleConnectionTimeout(int idleConnectionTimeout) { + this.idleConnectionTimeout = idleConnectionTimeout; + } + + public int getPingTimeout() { + return pingTimeout; + } + + public void setPingTimeout(int pingTimeout) { + this.pingTimeout = pingTimeout; + } + + public int getConnectTimeout() { + return connectTimeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getRetryAttempts() { + return retryAttempts; + } + + public void setRetryAttempts(int retryAttempts) { + this.retryAttempts = retryAttempts; + } + + public int getRetryInterval() { + return retryInterval; + } + + public void setRetryInterval(int retryInterval) { + this.retryInterval = retryInterval; + } + + public int getReconnectionTimeout() { + return reconnectionTimeout; + } + + public void setReconnectionTimeout(int reconnectionTimeout) { + this.reconnectionTimeout = reconnectionTimeout; + } + + public int getFailedAttempts() { + return failedAttempts; + } + + public void setFailedAttempts(int failedAttempts) { + this.failedAttempts = failedAttempts; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getSubscriptionsPerConnection() { + return subscriptionsPerConnection; + } + + public void setSubscriptionsPerConnection(int subscriptionsPerConnection) { + this.subscriptionsPerConnection = subscriptionsPerConnection; + } + + public String getClientName() { + return clientName; + } + + public void setClientName(String clientName) { + this.clientName = clientName; + } + + public int getSubscriptionConnectionMinimumIdleSize() { + return subscriptionConnectionMinimumIdleSize; + } + + public void setSubscriptionConnectionMinimumIdleSize(int subscriptionConnectionMinimumIdleSize) { + this.subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize; + } + + public int getSubscriptionConnectionPoolSize() { + return subscriptionConnectionPoolSize; + } + + public void setSubscriptionConnectionPoolSize(int subscriptionConnectionPoolSize) { + this.subscriptionConnectionPoolSize = subscriptionConnectionPoolSize; + } + + public int getConnectionMinimumIdleSize() { + return connectionMinimumIdleSize; + } + + public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) { + this.connectionMinimumIdleSize = connectionMinimumIdleSize; + } + + public int getConnectionPoolSize() { + return connectionPoolSize; + } + + public void setConnectionPoolSize(int connectionPoolSize) { + this.connectionPoolSize = connectionPoolSize; + } + + public int getDatabase() { + return database; + } + + public void setDatabase(int database) { + this.database = database; + } + + public boolean isDnsMonitoring() { + return dnsMonitoring; + } + + public void setDnsMonitoring(boolean dnsMonitoring) { + this.dnsMonitoring = dnsMonitoring; + } + + public int getDnsMonitoringInterval() { + return dnsMonitoringInterval; + } + + public void setDnsMonitoringInterval(int dnsMonitoringInterval) { + this.dnsMonitoringInterval = dnsMonitoringInterval; + } + + public String getCodec() { + return codec; + } + + public void setCodec(String codec) { + this.codec = codec; + } +} diff --git a/src/main/java/com/yudianbank/extend/ControlDocumentFormatRegistry.java b/src/main/java/com/yudianbank/extend/ControlDocumentFormatRegistry.java new file mode 100644 index 000000000..99632680d --- /dev/null +++ b/src/main/java/com/yudianbank/extend/ControlDocumentFormatRegistry.java @@ -0,0 +1,211 @@ +package com.yudianbank.extend; + +import com.google.common.collect.Maps; +import com.sun.star.beans.PropertyValue; +import org.artofsolving.jodconverter.document.DocumentFamily; +import org.artofsolving.jodconverter.document.DocumentFormat; +import org.artofsolving.jodconverter.document.SimpleDocumentFormatRegistry; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 重写了DefaultDocumentFormatRegistry类,因为要添加自定义行为,比如字符编码。。。 + * @author yudian-it + * @date 2017/12/5 + */ +public class ControlDocumentFormatRegistry extends SimpleDocumentFormatRegistry { + + public ControlDocumentFormatRegistry() { + DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf"); + pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export")); + pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export")); + pdf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_pdf_Export")); + pdf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_pdf_Export")); + addFormat(pdf); + + DocumentFormat swf = new DocumentFormat("Macromedia Flash", "swf", "application/x-shockwave-flash"); + swf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_flash_Export")); + swf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_flash_Export")); + addFormat(swf); + + // disabled because it's not always available + //DocumentFormat xhtml = new DocumentFormat("XHTML", "xhtml", "application/xhtml+xml"); + //xhtml.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "XHTML Writer File")); + //xhtml.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "XHTML Calc File")); + //xhtml.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "XHTML Impress File")); + //addFormat(xhtml); + + DocumentFormat html = new DocumentFormat("HTML", "html", "text/html"); + // HTML is treated as Text when supplied as input, but as an output it is also + // available for exporting Spreadsheet and Presentation formats + html.setInputFamily(DocumentFamily.TEXT); + html.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "HTML (StarWriter)")); + Map htmlLoadAndStoreProperties = new LinkedHashMap(); + htmlLoadAndStoreProperties.put("FilterName", "HTML (StarCalc)"); + htmlLoadAndStoreProperties.put("FilterOptions", "utf8"); + html.setStoreProperties(DocumentFamily.SPREADSHEET, htmlLoadAndStoreProperties); + html.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_html_Export")); + addFormat(html); + + DocumentFormat odt = new DocumentFormat("OpenDocument Text", "odt", "application/vnd.oasis.opendocument.text"); + odt.setInputFamily(DocumentFamily.TEXT); + odt.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer8")); + addFormat(odt); + + DocumentFormat sxw = new DocumentFormat("OpenOffice.org 1.0 Text Document", "sxw", "application/vnd.sun.xml.writer"); + sxw.setInputFamily(DocumentFamily.TEXT); + sxw.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "StarOffice XML (Writer)")); + addFormat(sxw); + + DocumentFormat doc = new DocumentFormat("Microsoft Word", "doc", "application/msword"); + doc.setInputFamily(DocumentFamily.TEXT); + doc.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MS Word 97")); + addFormat(doc); + + DocumentFormat docx = new DocumentFormat("Microsoft Word 2007 XML", "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); + docx.setInputFamily(DocumentFamily.TEXT); + addFormat(docx); + + DocumentFormat rtf = new DocumentFormat("Rich Text Format", "rtf", "text/rtf"); + rtf.setInputFamily(DocumentFamily.TEXT); + rtf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "Rich Text Format")); + addFormat(rtf); + + DocumentFormat wpd = new DocumentFormat("WordPerfect", "wpd", "application/wordperfect"); + wpd.setInputFamily(DocumentFamily.TEXT); + addFormat(wpd); + + DocumentFormat txt = new DocumentFormat("Plain Text", "txt", "text/plain"); + txt.setInputFamily(DocumentFamily.TEXT); + Map txtLoadAndStoreProperties = new LinkedHashMap(); + txtLoadAndStoreProperties.put("FilterName", "Text (encoded)"); + txtLoadAndStoreProperties.put("FilterOptions", "utf8"); + txt.setLoadProperties(txtLoadAndStoreProperties); + txt.setStoreProperties(DocumentFamily.TEXT, txtLoadAndStoreProperties); + addFormat(txt); + + DocumentFormat wikitext = new DocumentFormat("MediaWiki wikitext", "wiki", "text/x-wiki"); + wikitext.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MediaWiki")); + //addFormat(wikitext); + + DocumentFormat ods = new DocumentFormat("OpenDocument Spreadsheet", "ods", "application/vnd.oasis.opendocument.spreadsheet"); + ods.setInputFamily(DocumentFamily.SPREADSHEET); + ods.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc8")); + addFormat(ods); + + DocumentFormat sxc = new DocumentFormat("OpenOffice.org 1.0 Spreadsheet", "sxc", "application/vnd.sun.xml.calc"); + sxc.setInputFamily(DocumentFamily.SPREADSHEET); + sxc.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "StarOffice XML (Calc)")); + addFormat(sxc); + + DocumentFormat xls = new DocumentFormat("Microsoft Excel", "xls", "application/vnd.ms-excel"); + xls.setInputFamily(DocumentFamily.SPREADSHEET); + xls.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "MS Excel 97")); + addFormat(xls); + + DocumentFormat xlsx = new DocumentFormat("Microsoft Excel 2007 XML", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + xlsx.setInputFamily(DocumentFamily.SPREADSHEET); + addFormat(xlsx); + + DocumentFormat csv = new DocumentFormat("Comma Separated Values", "csv", "text/csv"); + csv.setInputFamily(DocumentFamily.SPREADSHEET); + Map csvLoadAndStoreProperties = new LinkedHashMap(); + csvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)"); + csvLoadAndStoreProperties.put("FilterOptions", "44,34,0"); // Field Separator: ','; Text Delimiter: '"' + csv.setLoadProperties(csvLoadAndStoreProperties); + csv.setStoreProperties(DocumentFamily.SPREADSHEET, csvLoadAndStoreProperties); + addFormat(csv); + + DocumentFormat tsv = new DocumentFormat("Tab Separated Values", "tsv", "text/tab-separated-values"); + tsv.setInputFamily(DocumentFamily.SPREADSHEET); + Map tsvLoadAndStoreProperties = new LinkedHashMap(); + tsvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)"); + tsvLoadAndStoreProperties.put("FilterOptions", "9,34,0"); // Field Separator: '\t'; Text Delimiter: '"' + tsv.setLoadProperties(tsvLoadAndStoreProperties); + tsv.setStoreProperties(DocumentFamily.SPREADSHEET, tsvLoadAndStoreProperties); + addFormat(tsv); + + DocumentFormat odp = new DocumentFormat("OpenDocument Presentation", "odp", "application/vnd.oasis.opendocument.presentation"); + odp.setInputFamily(DocumentFamily.PRESENTATION); + odp.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress8")); + addFormat(odp); + + DocumentFormat sxi = new DocumentFormat("OpenOffice.org 1.0 Presentation", "sxi", "application/vnd.sun.xml.impress"); + sxi.setInputFamily(DocumentFamily.PRESENTATION); + sxi.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "StarOffice XML (Impress)")); + addFormat(sxi); + + DocumentFormat ppt = new DocumentFormat("Microsoft PowerPoint", "ppt", "application/vnd.ms-powerpoint"); + ppt.setInputFamily(DocumentFamily.PRESENTATION); + ppt.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "MS PowerPoint 97")); + addFormat(ppt); + + DocumentFormat pptx = new DocumentFormat("Microsoft PowerPoint 2007 XML", "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"); + pptx.setInputFamily(DocumentFamily.PRESENTATION); + addFormat(pptx); + + DocumentFormat odg = new DocumentFormat("OpenDocument Drawing", "odg", "application/vnd.oasis.opendocument.graphics"); + odg.setInputFamily(DocumentFamily.DRAWING); + odg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw8")); + addFormat(odg); + + DocumentFormat svg = new DocumentFormat("Scalable Vector Graphics", "svg", "image/svg+xml"); + svg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_svg_Export")); + addFormat(svg); + } + + /** + * 创建默认的导出属性 + * @return + */ + private PropertyValue[] getCommonPropertyValue() { + PropertyValue[] aFilterData = new PropertyValue[11]; + // 不显示文档标题 + aFilterData[0] = new PropertyValue(); + aFilterData[0].Name = "DisplayPDFDocumentTitle"; + aFilterData[0].Value= true; + // 导出文件编码方式 + aFilterData[1] = new PropertyValue(); + aFilterData[1].Name = "Encoding"; + aFilterData[1].Value= "UTF-8"; + // 隐藏工具条 + aFilterData[2] = new PropertyValue(); + aFilterData[2].Name = "HideViewerToolbar"; + aFilterData[2].Value= false; + // 隐藏窗口控制条 + aFilterData[3] = new PropertyValue(); + aFilterData[3].Name = "HideViewerWindowControls"; + aFilterData[3].Value= true; + // 全屏展示 + aFilterData[4] = new PropertyValue(); + aFilterData[4].Name = "OpenInFullScreenMode"; + aFilterData[4].Value= false; + // 第一页左边展示 + aFilterData[5] = new PropertyValue(); + aFilterData[5].Name = "MathToMathType"; + aFilterData[5].Value= true; + // 文档标题内容 + aFilterData[6] = new PropertyValue(); + aFilterData[6].Name = "Watermark"; + aFilterData[6].Value= "KEKING.CN"; + // 导出文件编码方式 + aFilterData[7] = new PropertyValue(); + aFilterData[7].Name = "CharacterSet"; + aFilterData[7].Value= "UTF-8"; + // 导出文件编码方式 + aFilterData[8] = new PropertyValue(); + aFilterData[8].Name = "Encoding"; + aFilterData[8].Value= "UTF-8"; + // 导出文件编码方式 + aFilterData[9] = new PropertyValue(); + aFilterData[9].Name = "CharSet"; + aFilterData[9].Value= "UTF-8"; + // 导出文件编码方式 + aFilterData[10] = new PropertyValue(); + aFilterData[10].Name = "charset"; + aFilterData[10].Value= "UTF-8"; + return aFilterData; + } +} diff --git a/src/main/java/com/yudianbank/filters/ChinesePathFilter.java b/src/main/java/com/yudianbank/filters/ChinesePathFilter.java new file mode 100644 index 000000000..ea0b18da8 --- /dev/null +++ b/src/main/java/com/yudianbank/filters/ChinesePathFilter.java @@ -0,0 +1,28 @@ +package com.yudianbank.filters; + +import javax.servlet.*; +import java.io.IOException; + +/** + * + * @author yudian-it + * @date 2017/11/30 + */ +public class ChinesePathFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + request.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding("UTF-8"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + + } +} diff --git a/src/main/java/com/yudianbank/filters/FilterConfiguration.java b/src/main/java/com/yudianbank/filters/FilterConfiguration.java new file mode 100644 index 000000000..246a4611d --- /dev/null +++ b/src/main/java/com/yudianbank/filters/FilterConfiguration.java @@ -0,0 +1,23 @@ +package com.yudianbank.filters; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +/** + * + * @author yudian-it + * @date 2017/11/30 + */ +@Configuration +public class FilterConfiguration { + + @Bean + public FilterRegistrationBean getChinesePathFilter(){ + ChinesePathFilter filter = new ChinesePathFilter(); + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + registrationBean.setFilter(filter); + return registrationBean; + } +} diff --git a/src/main/java/com/yudianbank/param/ReturnResponse.java b/src/main/java/com/yudianbank/param/ReturnResponse.java new file mode 100644 index 000000000..d1438662b --- /dev/null +++ b/src/main/java/com/yudianbank/param/ReturnResponse.java @@ -0,0 +1,57 @@ +package com.yudianbank.param; + +import java.io.Serializable; + +/** + * 接口返回值结构 + * @author yudian-it + * @date 2017/11/17 + */ +public class ReturnResponse implements Serializable{ + private static final long serialVersionUID = 313975329998789878L; + /** + * 返回状态 + * 0. 成功 + * 1. 失败 + */ + private int code; + + /** + * 返回状态描述 + * XXX成功 + * XXX失败 + */ + private String msg; + + private T content; + + public ReturnResponse(int code, String msg, T content) { + this.code = code; + this.msg = msg; + this.content = content; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getContent() { + return content; + } + + public void setContent(T content) { + this.content = content; + } +} diff --git a/src/main/java/com/yudianbank/utils/ConverterUtils.java b/src/main/java/com/yudianbank/utils/ConverterUtils.java new file mode 100644 index 000000000..53a306cc2 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/ConverterUtils.java @@ -0,0 +1,68 @@ +package com.yudianbank.utils; + +import com.sun.star.document.UpdateDocMode; +import com.yudianbank.extend.ControlDocumentFormatRegistry; +import org.artofsolving.jodconverter.OfficeDocumentConverter; +import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration; +import org.artofsolving.jodconverter.office.OfficeManager; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +/** + * 创建文件转换器 + * + * @author yudian-it + * @date 2017/11/13 + */ +@Component +public class ConverterUtils { + + @Value("${office.home}") + String officeHome; +// OpenOfficeConnection connection; + OfficeManager officeManager; + + @PostConstruct + public void initOfficeManager() { + //// connection = new SocketOpenOfficeConnection(host,8100); +//// connection.connect(); + DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration(); + configuration.setOfficeHome(officeHome); + configuration.setPortNumber(8100); + officeManager = configuration.buildOfficeManager(); + officeManager.start(); + // 设置任务执行超时为5分钟 + // configuration.setTaskExecutionTimeout(1000 * 60 * 5L);// + // 设置任务队列超时为24小时 + // configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);// + } + + public OfficeDocumentConverter getDocumentConverter() { + OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new ControlDocumentFormatRegistry()); + converter.setDefaultLoadProperties(getLoadProperties()); + return converter; + } + + private Map getLoadProperties() { + Map loadProperties = new HashMap<>(10); + loadProperties.put("Hidden", true); + loadProperties.put("ReadOnly", true); + loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE); + loadProperties.put("CharacterSet", Charset.forName("UTF-8").name()); + return loadProperties; + } + + @PreDestroy + public void destroyOfficeManager(){ + if (null != officeManager && officeManager.isRunning()) { + officeManager.stop(); + } + } + +} diff --git a/src/main/java/com/yudianbank/utils/DeleteFileUtil.java b/src/main/java/com/yudianbank/utils/DeleteFileUtil.java new file mode 100644 index 000000000..896ef78d7 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/DeleteFileUtil.java @@ -0,0 +1,74 @@ +package com.yudianbank.utils; + +import java.io.File; + +public class DeleteFileUtil { + /** + * 删除单个文件 + * + * @param fileName + * 要删除的文件的文件名 + * @return 单个文件删除成功返回true,否则返回false + */ + public static boolean deleteFile(String fileName) { + File file = new File(fileName); + // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除 + if (file.exists() && file.isFile()) { + if (file.delete()) { + System.out.println("删除单个文件" + fileName + "成功!"); + return true; + } else { + System.out.println("删除单个文件" + fileName + "失败!"); + return false; + } + } else { + System.out.println("删除单个文件失败:" + fileName + "不存在!"); + return false; + } + } + + + /** + * 删除目录及目录下的文件 + * + * @param dir + * 要删除的目录的文件路径 + * @return 目录删除成功返回true,否则返回false + */ + public static boolean deleteDirectory(String dir) { + // 如果dir不以文件分隔符结尾,自动添加文件分隔符 + if (!dir.endsWith(File.separator)) { + dir = dir + File.separator; + } + File dirFile = new File(dir); + // 如果dir对应的文件不存在,或者不是一个目录,则退出 + if ((!dirFile.exists()) || (!dirFile.isDirectory())) { + System.out.println("删除目录失败:" + dir + "不存在!"); + return false; + } + boolean flag = true; + // 删除文件夹中的所有文件包括子目录 + File[] files = dirFile.listFiles(); + for (int i = 0; i < files.length; i++) { + // 删除子文件 + if (files[i].isFile()) { + flag = DeleteFileUtil.deleteFile(files[i].getAbsolutePath()); + if (!flag) + break; + } + // 删除子目录 + else if (files[i].isDirectory()) { + flag = DeleteFileUtil.deleteDirectory(files[i] + .getAbsolutePath()); + if (!flag) + break; + } + } + if (!flag) { + System.out.println("删除目录失败!"); + return false; + } + return true; + } + +} diff --git a/src/main/java/com/yudianbank/utils/DownloadUtils.java b/src/main/java/com/yudianbank/utils/DownloadUtils.java new file mode 100644 index 000000000..5980feec2 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/DownloadUtils.java @@ -0,0 +1,151 @@ +package com.yudianbank.utils; + +import com.yudianbank.param.ReturnResponse; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import java.io.*; +import java.net.*; +import java.util.UUID; + +/** + * @author yudian-it + */ +@Component +public class DownloadUtils { + + @Value("${file.dir}") + String fileDir; + + /** + * 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解 + * 再次测试的时候,通过前台对比url发现,原来参数中有+号特殊字符存在,但是到后之后却变成了空格,突然恍然大悟 + * 应该是转义出了问题,url转义中会把+号当成空格来计算,所以才会出现这种情况,遂想要通过整体替换空格为加号,因为url + * 中的参数部分是不会出现空格的,但是文件名中就不好确定了,所以只对url参数部分做替换 + * @param urlAddress + * @param type + * @param needEncode + * 在处理本地文件(测试预览界面的,非ufile)的时候要对中文进行转码, + * 因为tomcat对[英文字母(a-z,A-Z)、数字(0-9)、- _ . ~ 4个特殊字符以及所有保留字符] + * 以外的字符会处理不正常,导致失败 + * @return + */ + public ReturnResponse downLoad(String urlAddress, String type, String fileName, String needEncode){ +// type = dealWithMS2013(type); + ReturnResponse response = new ReturnResponse<>(0, "下载成功!!!", ""); + URL url = null; + try { + if (null != needEncode) { + urlAddress = encodeUrlParam(urlAddress); + // 因为tomcat不能处理'+'号,所以讲'+'号替换成'%20%' + urlAddress = urlAddress.replaceAll("\\+", "%20"); + }else{ + urlAddress = replacePlusMark(urlAddress); + } + url = new URL(urlAddress); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + UUID uuid = UUID.randomUUID(); + if (null == fileName) { + fileName = uuid+ "."+type; + } + String realPath = fileDir + fileName; + File dirFile = new File(fileDir); + if (!dirFile.exists()) { + dirFile.mkdirs(); + } + try { + URLConnection connection = url.openConnection(); + InputStream in = connection.getInputStream(); + + FileOutputStream os = new FileOutputStream(realPath); + byte[] buffer = new byte[4 * 1024]; + int read; + while ((read = in.read(buffer)) > 0) { + os.write(buffer, 0, read); + } + os.close(); + in.close(); + response.setContent(realPath); + return response; + } catch (IOException e) { + e.printStackTrace(); + response.setCode(1); + response.setContent(null); + if (e instanceof FileNotFoundException) { + response.setMsg("文件不存在!!!"); + }else { + response.setMsg(e.getMessage()); + } + return response; + } + } + + /** + * 转换url参数部分的空格为加号(因为在url编解码的过程中出现+转为空格的情况) + * @param urlAddress + * @return + */ + private String replacePlusMark(String urlAddress) { + String nonParamStr = urlAddress.substring(0,urlAddress.indexOf("?") + 1); + String paramStr = urlAddress.substring(nonParamStr.length()); + return nonParamStr + paramStr.replace(" ", "+"); + } + + /** + * 对最有一个路径进行转码 + * @param urlAddress + * http://192.168.2.111:8013/demo/Handle中文.zip + * @return + */ + private String encodeUrlParam(String urlAddress) { + String newUrl = ""; + try { + String path = ""; + String param = ""; + if (urlAddress.contains("?")) { + path = urlAddress.substring(0, urlAddress.indexOf("?")); + param = urlAddress.substring(urlAddress.indexOf("?") + 1); + }else { + path = urlAddress; + } + String lastPath = path.substring(path.lastIndexOf("/") + 1); + String leftPath = path.substring(0, path.lastIndexOf("/") + 1); + String encodeLastPath = URLEncoder.encode(lastPath, "UTF-8"); + newUrl += leftPath + encodeLastPath; + if (urlAddress.contains("?")) { + newUrl += param; + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + return newUrl; + } + + + + /** + * 因为jodConvert2.1不支持ms2013版本的office转换,这里偷懒,尝试看改一下文件类型,让jodConvert2.1去 + * 处理ms2013,看结果如何,如果问题很大的话只能采取其他方式,如果没有问题,暂时使用该版本来转换 + * @param type + * @return + */ + private String dealWithMS2013(String type) { + String newType = null; + switch (type){ + case "docx": + newType = "doc"; + break; + case "xlsx": + newType = "doc"; + break; + case "pptx": + newType = "ppt"; + break; + default: + newType = type; + break; + } + return newType; + } +} diff --git a/src/main/java/com/yudianbank/utils/FileUtils.java b/src/main/java/com/yudianbank/utils/FileUtils.java new file mode 100644 index 000000000..0b59fc8c2 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/FileUtils.java @@ -0,0 +1,192 @@ +package com.yudianbank.utils; + +import com.google.common.collect.Lists; +import org.redisson.api.RMapCache; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map; + +/** + * + * @author yudian-it + * @date 2017/11/13 + */ +@Component +public class FileUtils { + + final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file"; + + @Autowired + RedissonClient redissonClient; + @Value("${file.dir}") + String fileDir; + + @Value("${converted.file.charset}") + String charset; + + /** + * 已转换过的文件集合(redis缓存) + * @return + */ + public Map listConvertedFiles() { + RMapCache convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); + return convertedList; + } + + /** + * 已转换过的文件,根据文件名获取 + * @return + */ + public String getConvertedFile(String key) { + RMapCache convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); + return convertedList.get(key); + } + + /** + * 从url中剥离出文件名 + * @param url + * 格式如:http://keking.ufile.ucloud.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k= + * @return + */ + public String getFileNameFromURL(String url) { + // 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题 + // 所以先从?处将url截断,然后运用url.lastIndexOf("/")获取文件名 + String noQueryUrl = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?"): url.length()); + String fileName = noQueryUrl.substring(noQueryUrl.lastIndexOf("/") + 1); + return fileName; + } + + /** + * 获取文件后缀 + * @param fileName + * @return + */ + public String getSuffixFromFileName(String fileName) { + String suffix = fileName.substring(fileName.lastIndexOf(".")); + return suffix; + } + + /** + * 从路径中获取 + * @param path + * 类似这种:C:\Users\yudian-it\Downloads + * @return + */ + public String getFileNameFromPath(String path) { + return path.substring(path.lastIndexOf(File.separator) + 1); + } + + public List listPictureTypes(){ + List list = Lists.newArrayList(); + list.add("jpg"); + list.add("jpeg"); + list.add("png"); + list.add("gif"); + list.add("bmp"); + return list; + } + + public List listArchiveTypes(){ + List list = Lists.newArrayList(); + list.add("rar"); + list.add("zip"); + list.add("jar"); + list.add("7-zip"); + list.add("tar"); + list.add("gzip"); + list.add("7z"); + return list; + } + + public List listOfficeTypes() { + List list = Lists.newArrayList(); + list.add("docx"); + list.add("doc"); + list.add("xls"); + list.add("xlsx"); + list.add("ppt"); + list.add("pptx"); + return list; + } + + /** + * 获取相对路径 + * @param absolutePath + * @return + */ + public String getRelativePath(String absolutePath) { + return absolutePath.substring(fileDir.length()); + } + + public void addConvertedFile(String fileName, String value){ + RMapCache convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); + convertedList.fastPut(fileName, value); + } + + /** + * 判断文件编码格式 + * @param path + * @return + */ + public String getFileEncodeUTFGBK(String path){ + String enc = Charset.forName("GBK").name(); + File file = new File(path); + InputStream in= null; + try { + in = new FileInputStream(file); + byte[] b = new byte[3]; + in.read(b); + in.close(); + if (b[0] == -17 && b[1] == -69 && b[2] == -65) { + enc = Charset.forName("UTF-8").name(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + System.out.println("文件编码格式为:" + enc); + return enc; + } + + /** + * 对转换后的文件进行操作(改变编码方式) + * @param outFilePath + */ + public void doActionConvertedFile(String outFilePath) { + StringBuffer sb = new StringBuffer(); + try (InputStream inputStream = new FileInputStream(outFilePath); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){ + String line; + while(null != (line = reader.readLine())){ + if (line.contains("charset=gb2312")) { + line = line.replace("charset=gb2312", "charset=utf-8"); + } + sb.append(line); + } + // 添加sheet控制头 + sb.append(""); + sb.append(""); + sb.append(""); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + // 重新写入文件 + try(FileOutputStream fos = new FileOutputStream(outFilePath); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos))){ + writer.write(sb.toString()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/yudianbank/utils/OfficeToPdf.java b/src/main/java/com/yudianbank/utils/OfficeToPdf.java new file mode 100644 index 000000000..7f8334463 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/OfficeToPdf.java @@ -0,0 +1,129 @@ +package com.yudianbank.utils; +import org.artofsolving.jodconverter.OfficeDocumentConverter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.File; +@Component +public class OfficeToPdf { + /** + * 获取OpenOffice.org 3的安装目录 + * + * @return OpenOffice.org 3的安装目录 + */ + @Value("${openOfficePath}") + private String openOfficePath; + @Autowired + ConverterUtils converterUtils; + /** + * 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件
+ * + * @param inputFilePath + * 源文件路径,如:"e:/test.docx" + * @param outputFilePath + * 目标文件路径,如:"e:/test_docx.pdf" + * @return + */ + public boolean openOfficeToPDF(String inputFilePath, String outputFilePath) { + return office2pdf(inputFilePath, outputFilePath); + } + + + + /** + * 连接OpenOffice.org 并且启动OpenOffice.org + * + * @return + */ + /*public OfficeManager getOfficeManager() { + DefaultOfficeManagerConfiguration config = new DefaultOfficeManagerConfiguration(); + // 获取OpenOffice.org 3的安装目录 + String officeHome = openOfficePath; + config.setOfficeHome(officeHome); + // 启动OpenOffice的服务 + OfficeManager officeManager = config.buildOfficeManager(); + officeManager.start(); + return officeManager; + }*/ + + /** + * 转换文件 + * + * @param inputFile + * @param outputFilePath_end + * @param inputFilePath + * @param outputFilePath + * @param converter + */ + public static void converterFile(File inputFile, String outputFilePath_end, + String inputFilePath, String outputFilePath, + OfficeDocumentConverter converter) { + File outputFile = new File(outputFilePath_end); + // 假如目标路径不存在,则新建该路径 + if (!outputFile.getParentFile().exists()) { + outputFile.getParentFile().mkdirs(); + } + converter.convert(inputFile, outputFile); + } + + /** + * 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件 + * + * @param inputFilePath + * 源文件路径,如:"e:/test.docx" + * @param outputFilePath + * 目标文件路径,如:"e:/test_docx.pdf" + * @return + */ + public boolean office2pdf(String inputFilePath, String outputFilePath) { + boolean flag = false; + OfficeDocumentConverter converter = converterUtils.getDocumentConverter(); + if (null != inputFilePath) { + File inputFile = new File(inputFilePath); + // 判断目标文件路径是否为空 + if (null == outputFilePath) { + // 转换后的文件路径 + String outputFilePath_end = getOutputFilePath(inputFilePath); + if (inputFile.exists()) {// 找不到源文件, 则返回 + converterFile(inputFile, outputFilePath_end, inputFilePath, + outputFilePath, converter); + flag = true; + } + } else { + if (inputFile.exists()) {// 找不到源文件, 则返回 + converterFile(inputFile, outputFilePath, inputFilePath, + outputFilePath, converter); + flag = true; + } + } +// officeManager.stop(); + } else { + flag = false; + } + return flag; + } + + /** + * 获取输出文件 + * + * @param inputFilePath + * @return + */ + public static String getOutputFilePath(String inputFilePath) { + String outputFilePath = inputFilePath.replaceAll("." + + getPostfix(inputFilePath), ".pdf"); + return outputFilePath; + } + + /** + * 获取inputFilePath的后缀名,如:"e:/test.pptx"的后缀名为:"pptx" + * + * @param inputFilePath + * @return + */ + public static String getPostfix(String inputFilePath) { + return inputFilePath.substring(inputFilePath.lastIndexOf(".") + 1); + } + +} diff --git a/src/main/java/com/yudianbank/utils/PoiExcelToHtml.java b/src/main/java/com/yudianbank/utils/PoiExcelToHtml.java new file mode 100644 index 000000000..e08883bf3 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/PoiExcelToHtml.java @@ -0,0 +1,194 @@ +package com.yudianbank.utils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.poi.hssf.converter.ExcelToHtmlConverter; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hwpf.converter.PicturesManager; +import org.apache.poi.hwpf.converter.WordToHtmlConverter; +import org.apache.poi.hwpf.usermodel.Picture; +import org.apache.poi.hwpf.usermodel.PictureType; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.w3c.dom.Document; + + +public class PoiExcelToHtml { +// String path = getClass().getClassLoader().getResource(".").getPath()+File.separator+"static"+File.separator; + public static void excelConvert(URL url) { + try { + String path = ""; + +// http://keking.ufile.ucloud.com.cn/20171101152525_左晓晖2017年9.xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=1n8ASiYMcfiF30YHxwpzwfqmlM0= +// URL url = new URL("http://keking.ufile.ucloud.com.cn/20171101150322_运费贷信审资料(给予客户收集版).xlsx?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=RRVFIICITMNFed1LQgB10WdKHiE="); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + //设置超时间为3秒 + conn.setConnectTimeout(3*1000); + //防止屏蔽程序抓取而返回403错误 + conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + //得到输入流 + InputStream inputStream = conn.getInputStream(); + HSSFWorkbook excelBook = new HSSFWorkbook(inputStream); + ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + excelToHtmlConverter.processWorkbook(excelBook); + List pics = excelBook.getAllPictures(); + if (pics != null) { + for (int i = 0; i < pics.size(); i++) { + Picture pic = (Picture) pics.get(i); + try { + pic.writeImageContent(new FileOutputStream(path + pic.suggestFullFileName())); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + } + Document htmlDocument = excelToHtmlConverter.getDocument(); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + DOMSource domSource = new DOMSource(htmlDocument); + StreamResult streamResult = new StreamResult(outStream); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer serializer = tf.newTransformer(); + serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); + serializer.setOutputProperty(OutputKeys.INDENT, "yes"); + serializer.setOutputProperty(OutputKeys.METHOD, "html"); + serializer.transform(domSource, streamResult); + outStream.close(); + + String content = new String(outStream.toByteArray()); + + } catch (IOException e) { + e.printStackTrace(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } catch (TransformerException e) { + e.printStackTrace(); + } + } + + /** + * excel07转html + * filename:要读取的文件所在文件夹 + * filepath:文件名 + * htmlname:生成html名称 + * path:html存放路径 + * */ + public static void excelToHtml () throws Exception{ + String htmlname="exportExcel"+"07Test"+".html"; + + + URL url = new URL("http://keking.ufile.ucloud.com.cn/20171101150322_运费贷信审资料(给予客户收集版).xlsx?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=RRVFIICITMNFed1LQgB10WdKHiE="); + HttpURLConnection conn = (HttpURLConnection)url.openConnection(); + //设置超时间为3秒 + conn.setConnectTimeout(3*1000); + //防止屏蔽程序抓取而返回403错误 + conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); + //得到输入流 + InputStream is = conn.getInputStream(); + + Workbook workbook = null; +// InputStream is = new FileInputStream(filename+"/"+filepath); + try { + String html=""; + workbook = new XSSFWorkbook(is); + for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) { + Sheet sheet = workbook.getSheetAt(numSheet); + if (sheet == null) { + continue; + } + html+="=======================" + sheet.getSheetName() + "=========================

"; + + int firstRowIndex = sheet.getFirstRowNum(); + int lastRowIndex = sheet.getLastRowNum(); + html+=""; + Row firstRow = sheet.getRow(firstRowIndex); + for (int i = firstRow.getFirstCellNum(); i <= firstRow.getLastCellNum(); i++) { + Cell cell = firstRow.getCell(i); + String cellValue = getCellValue(cell, true); + html+=""; + } + + + //行 + for (int rowIndex = firstRowIndex + 1; rowIndex <= lastRowIndex; rowIndex++) { + Row currentRow = sheet.getRow(rowIndex); + html+=""; + if(currentRow!=null){ + + int firstColumnIndex = currentRow.getFirstCellNum(); + int lastColumnIndex = currentRow.getLastCellNum(); + //列 + for (int columnIndex = firstColumnIndex; columnIndex <= lastColumnIndex; columnIndex++) { + Cell currentCell = currentRow.getCell(columnIndex); + String currentCellValue = getCellValue(currentCell, true); + html+=""; + } + }else{ + html+=" "; + } + html+=""; + } + html+="
" + cellValue + "
"+currentCellValue + "
"; + + + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + DOMSource domSource = new DOMSource (); + StreamResult streamResult = new StreamResult (outStream); + + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer serializer = tf.newTransformer(); + serializer.setOutputProperty (OutputKeys.ENCODING, "utf-8"); + serializer.setOutputProperty (OutputKeys.INDENT, "yes"); + serializer.setOutputProperty (OutputKeys.METHOD, "html"); + serializer.transform (domSource, streamResult); + outStream.close(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * 读取单元格 + * + */ + private static String getCellValue(Cell cell, boolean treatAsStr) { + if (cell == null) { + return ""; + } + + if (treatAsStr) { + cell.setCellType(Cell.CELL_TYPE_STRING); + } + + if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) { + return String.valueOf(cell.getBooleanCellValue()); + } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { + return String.valueOf(cell.getNumericCellValue()); + } else { + return String.valueOf(cell.getStringCellValue()); + } + } +} diff --git a/src/main/java/com/yudianbank/utils/ShedulerClean.java b/src/main/java/com/yudianbank/utils/ShedulerClean.java new file mode 100644 index 000000000..761a464df --- /dev/null +++ b/src/main/java/com/yudianbank/utils/ShedulerClean.java @@ -0,0 +1,19 @@ +package com.yudianbank.utils; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.io.File; + +@Component +public class ShedulerClean { + @Value("${file.dir}") + String fileDir; + + @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次 + public void clean(){ + System.out.println("执行一次清空文件夹"); + DeleteFileUtil.deleteDirectory(fileDir); + } +} diff --git a/src/main/java/com/yudianbank/utils/WordToHtml.java b/src/main/java/com/yudianbank/utils/WordToHtml.java new file mode 100644 index 000000000..9184e28d1 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/WordToHtml.java @@ -0,0 +1,61 @@ +package com.yudianbank.utils; + +import java.io.*; +import java.util.*; +import java.util.function.Function; +import java.util.function.ToDoubleFunction; +import java.util.function.ToIntFunction; +import java.util.function.ToLongFunction; + +import com.github.junrar.Archive; +import com.github.junrar.exception.RarException; +import com.github.junrar.rarfile.FileHeader; +import org.apache.commons.compress.archivers.ArchiveException; +import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.poi.xwpf.converter.core.FileImageExtractor; +import org.apache.poi.xwpf.converter.core.FileURIResolver; +import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter; +import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions; +import org.apache.poi.xwpf.usermodel.XWPFDocument; + +public class WordToHtml { + /** 这是2007版本 转html 已测试成功的代码 07和03版要用两种代码转 但因为后面说要用 + * 38 * 2007版本word转换成html + * 39 * @throws IOException + * 40 + */ + + public static String Word2007ToHtml(InputStream inputStream) throws IOException { + // 1) 加载word文档生成 XWPFDocument对象 + XWPFDocument document = new XWPFDocument(inputStream); + + // 2) 解析 XHTML配置 (这里设置IURIResolver来设置图片存放的目录) +// File imageFolderFile = new File("/Users/zuoxiaohui/IdeaProjects/yudian-preview-boot/yudian-preview-boot/src/main/resources/picture/"); + File imageFolderFile = new File("/Users/zuoxiaohui/IdeaProjects/yudian-preview-boot/yudian-preview-boot/src/main/resources/static/"); + XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(imageFolderFile)); + options.setExtractor(new FileImageExtractor(imageFolderFile)); + options.setIgnoreStylesIfUnused(false); + options.setFragment(true); + + File file = new File("/Users/zuoxiaohui/Test/" + "test.html"); + // 3) 将 XWPFDocument转换成XHTML + OutputStream out = new FileOutputStream(file); + XHTMLConverter.getInstance().convert(document, out, options); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + XHTMLConverter.getInstance().convert(document, baos, options); + String content = baos.toString(); + System.out.println(content); + baos.close(); + return content; + + + } + + public static void main(String[] args) throws IOException, ArchiveException, RarException { + File file = new File("C:\\Users\\yudian-it\\Downloads\\Downloads.zip"); + System.out.println("Objects.equals(new Integer(1000), new Integer(1000)) :" + Objects.equals(new Integer(1000), new Integer(1000))); + System.out.println(Integer.valueOf("-129") == Integer.valueOf("-129")); + } + +} diff --git a/src/main/java/com/yudianbank/utils/ZipReader.java b/src/main/java/com/yudianbank/utils/ZipReader.java new file mode 100644 index 000000000..2f774eac3 --- /dev/null +++ b/src/main/java/com/yudianbank/utils/ZipReader.java @@ -0,0 +1,392 @@ +package com.yudianbank.utils; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.junrar.Archive; +import com.github.junrar.exception.RarException; +import com.github.junrar.rarfile.FileHeader; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.*; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * + * @author yudian-it + * @date 2017/11/27 + */ +@Component +public class ZipReader { + + @Autowired + FileUtils fileUtils; + @Value("${file.dir}") + String fileDir; + + ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + + /** + * 读取压缩文件 + * 文件压缩到统一目录fileDir下,并且命名使用压缩文件名+文件名因为文件名 + * 可能会重复(在系统中对于同一种类型的材料压缩文件内的文件是一样的,如果文件名 + * 重复,那么这里会被覆盖[同一个压缩文件中的不同目录中的相同文件名暂时不考虑]) + * 注: + *

+ * 文件名命名中的参数的说明: + * 1.archiveName,为避免解压的文件中有重名的文件会彼此覆盖,所以加上了archiveName,因为在ufile中archiveName + * 是不会重复的。 + * 2.level,这里层级结构的列表我是通过一个map来构造的,map的key是文件的名字,值是对应的文件,这样每次向map中 + * 加入节点的时候都会获取父节点是否存在,存在则会获取父节点的value并将当前节点加入到父节点的childList中(这里利用 + * 的是java语言的引用的特性)。 + *

+ * @param filePath + */ + public String readZipFile(String filePath) { + String archiveSeparator = "/"; + Map appender = Maps.newHashMap(); + String archiveFileName = fileUtils.getFileNameFromPath(filePath); + try { + ZipFile zipFile = new ZipFile(filePath, fileUtils.getFileEncodeUTFGBK(filePath)); + Enumeration entries = zipFile.getEntries(); + // 排序 + entries = sortZipEntries(entries); + List> entriesToBeExtracted = Lists.newArrayList(); + while (entries.hasMoreElements()){ + ZipArchiveEntry entry = entries.nextElement(); + String fullName = entry.getName(); + int level = fullName.split(archiveSeparator).length; + // 展示名 + String originName = getLastFileName(fullName, archiveSeparator); + String childName = level + "_" + originName; + boolean directory = entry.isDirectory(); + if (!directory) { + childName = archiveFileName + "_" + originName; + entriesToBeExtracted.add(Collections.singletonMap(childName, entry)); + } + String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName); + parentName = (level-1) + "_" + parentName; + FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory); + addNodes(appender, parentName, node); + appender.put(childName, node); + } + // 开启新的线程处理文件解压 + executors.submit(new ZipExtractorWorker(entriesToBeExtracted, zipFile, filePath)); + return new ObjectMapper().writeValueAsString(appender.get("")); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 排序zipEntries(对原来列表倒序) + * @param entries + */ + private Enumeration sortZipEntries(Enumeration entries) { + List sortedEntries = Lists.newArrayList(); + while(entries.hasMoreElements()){ + sortedEntries.add(entries.nextElement()); + } + Collections.sort(sortedEntries, Comparator.comparingInt(o -> o.getName().length())); + return Collections.enumeration(sortedEntries); + } + + public String unRar(String filePath){ + Map appender = Maps.newHashMap(); + try { + Archive archive = new Archive(new File(filePath)); + List headers = archive.getFileHeaders(); + headers = sortedHeaders(headers); + String archiveFileName = fileUtils.getFileNameFromPath(filePath); + List> headersToBeExtracted = Lists.newArrayList(); + for (FileHeader header : headers) { + String fullName; + if (header.isUnicode()) { + fullName = header.getFileNameW(); + }else { + fullName = header.getFileNameString(); + } + // 展示名 + String originName = getLastFileName(fullName, "\\"); + String childName = originName; + boolean directory = header.isDirectory(); + if (!directory) { + childName = archiveFileName + "_" + originName; + headersToBeExtracted.add(Collections.singletonMap(childName, header)); + } + String parentName = getLast2FileName(fullName, "\\", archiveFileName); + FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory); + addNodes(appender, parentName, node); + appender.put(childName, node); + } + executors.submit(new RarExtractorWorker(headersToBeExtracted, archive, filePath)); + return new ObjectMapper().writeValueAsString(appender.get("")); + } catch (RarException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private void addNodes(Map appender, String parentName, FileNode node) { + if (appender.containsKey(parentName)) { + appender.get(parentName).getChildList().add(node); + }else { // 根节点 + FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true); + nodeRoot.getChildList().add(node); + appender.put("", nodeRoot); + appender.put(parentName, nodeRoot); + } + } + + private List sortedHeaders(List headers) { + List sortedHeaders = new ArrayList<>(); + Map mapHeaders = new TreeMap<>(); + headers.forEach(header -> mapHeaders.put(header.getFileNameW().length(), header)); + for (Map.Entry entry : mapHeaders.entrySet()){ + for (FileHeader header : headers) { + if (entry.getKey().intValue() == header.getFileNameW().length()) { + sortedHeaders.add(header); + } + } + } + return sortedHeaders; + } + + /** + * 获取倒数第二个文件(夹)名 + * @param fullName + * @param seperator + * 压缩文件解压后,不同的压缩格式分隔符不一样zip是/,而rar是\ + * @param rootName + * 根目录名:如果倒数第二个路径为空,那么赋值为rootName + * @return + */ + private static String getLast2FileName(String fullName, String seperator, String rootName) { + if (fullName.endsWith(seperator)) { + fullName = fullName.substring(0, fullName.length()-1); + } + // 1.获取剩余部分 + int endIndex = fullName.lastIndexOf(seperator); + String leftPath = fullName.substring(0, endIndex == -1 ? 0 : endIndex); + if (null != leftPath && leftPath.length() > 1) { + // 2.获取倒数第二个 + return getLastFileName(leftPath, seperator); + }else { + return rootName; + } + } + + /** + * 获取最后一个文件(夹)的名字 + * @param fullName + * @param seperator + * 压缩文件解压后,不同的压缩格式分隔符不一样zip是/,而rar是\ + * @return + */ + private static String getLastFileName(String fullName, String seperator) { + if (fullName.endsWith(seperator)) { + fullName = fullName.substring(0, fullName.length()-1); + } + String newName = fullName; + if (null != fullName && fullName.contains(seperator)) { + newName = fullName.substring(fullName.lastIndexOf(seperator) + 1); + } + return newName; + } + + /** + * 文件节点(区分文件上下级) + */ + public class FileNode{ + + private String originName; + private String fileName; + private String parentFileName; + private boolean directory; + + private List childList; + + public FileNode(String originName, String fileName, String parentFileName, List childList, boolean directory) { + this.originName = originName; + this.fileName = fileName; + this.parentFileName = parentFileName; + this.childList = childList; + this.directory = directory; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getParentFileName() { + return parentFileName; + } + + public void setParentFileName(String parentFileName) { + this.parentFileName = parentFileName; + } + + public List getChildList() { + return childList; + } + + public void setChildList(List childList) { + this.childList = childList; + } + + @Override + public String toString() { + try { + return new ObjectMapper().writeValueAsString(this); + } catch (JsonProcessingException e) { + e.printStackTrace(); + return ""; + } + } + + public String getOriginName() { + return originName; + } + + public void setOriginName(String originName) { + this.originName = originName; + } + + public boolean isDirectory() { + return directory; + } + + public void setDirectory(boolean directory) { + this.directory = directory; + } + } + + /** + * Zip文件抽取线程 + */ + class ZipExtractorWorker implements Runnable { + + private List> entriesToBeExtracted; + private ZipFile zipFile; + private String filePath; + + public ZipExtractorWorker(List> entriesToBeExtracted, ZipFile zipFile, String filePath) { + this.entriesToBeExtracted = entriesToBeExtracted; + this.zipFile = zipFile; + this.filePath = filePath; + } + + @Override + public void run() { + System.out.println("解析压缩文件开始《《《《《《《《《《《《《《《《《《《《《《《"); + for (Map entryMap : entriesToBeExtracted) { + String childName = entryMap.keySet().iterator().next(); + ZipArchiveEntry entry = entryMap.values().iterator().next(); + try { + extractZipFile(childName, zipFile.getInputStream(entry)); + } catch (IOException e) { + e.printStackTrace(); + } + } + try { + zipFile.close(); + } catch (IOException e) { + e.printStackTrace(); + } + if (new File(filePath).exists()) { + new File(filePath).delete(); + } + System.out.println("解析压缩文件结束《《《《《《《《《《《《《《《《《《《《《《《"); + } + + + /** + * 读取压缩文件并写入到fileDir文件夹下 + * @param childName + * @param zipFile + */ + private void extractZipFile(String childName, InputStream zipFile) { + String outPath = fileDir + childName; + try (OutputStream ot = new FileOutputStream(outPath)){ + byte[] inByte = new byte[1024]; + int len; + while ((-1 != (len = zipFile.read(inByte)))){ + ot.write(inByte, 0, len); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + /** + * Rar文件抽取 + */ + class RarExtractorWorker implements Runnable { + private List> headersToBeExtracted; + private Archive archive; + /** + * 用以删除源文件 + */ + private String filePath; + + public RarExtractorWorker(List> headersToBeExtracted, Archive archive, String filePath) { + this.headersToBeExtracted = headersToBeExtracted; + this.archive = archive; + this.filePath = filePath; + } + + @Override + public void run() { + System.out.println("解析压缩文件开始《《《《《《《《《《《《《《《《《《《《《《《"); + for (Map entryMap : headersToBeExtracted) { + String childName = entryMap.keySet().iterator().next(); + extractRarFile(childName, entryMap.values().iterator().next(), archive); + } + try { + archive.close(); + } catch (IOException e) { + e.printStackTrace(); + } + if (new File(filePath).exists()) { + new File(filePath).delete(); + } + System.out.println("解析压缩文件结束《《《《《《《《《《《《《《《《《《《《《《《"); + } + + /** + * 抽取rar文件到指定目录下 + * @param childName + * @param header + * @param archive + */ + private void extractRarFile(String childName, FileHeader header, Archive archive) { + String outPath = fileDir + childName; + try(OutputStream ot = new FileOutputStream(outPath)) { + archive.extractFile(header, ot); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (RarException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/yudianbank/web/controller/FileController.java b/src/main/java/com/yudianbank/web/controller/FileController.java new file mode 100644 index 000000000..331032bcc --- /dev/null +++ b/src/main/java/com/yudianbank/web/controller/FileController.java @@ -0,0 +1,113 @@ +package com.yudianbank.web.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.yudianbank.param.ReturnResponse; +import com.yudianbank.utils.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import java.io.*; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * + * @author yudian-it + * @date 2017/12/1 + */ +@RestController +public class FileController { + @Value("${file.dir}") + String fileDir; + @Autowired + FileUtils fileUtils; + String demoDir = "demo"; + String demoPath = demoDir + File.separator; + + @RequestMapping(value = "fileUpload", method = RequestMethod.POST) + public String fileUpload(@RequestParam("file") MultipartFile file, + HttpServletRequest request) throws JsonProcessingException { + String fileName = file.getOriginalFilename(); + // 判断该文件类型是否有上传过,如果上传过则提示不允许再次上传 + if (existsTypeFile(fileName)) { + return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "每一种类型只可以上传一个文件,请先删除原有文件再次上传", null)); + } + File outFile = new File(fileDir + demoPath); + if (!outFile.exists()) { + outFile.mkdirs(); + } + try(InputStream in = file.getInputStream(); + OutputStream ot = new FileOutputStream(fileDir + demoPath + fileName)){ + byte[] buffer = new byte[1024]; + int len; + while ((-1 != (len = in.read(buffer)))) { + ot.write(buffer, 0, len); + } + return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null)); + } catch (IOException e) { + e.printStackTrace(); + return new ObjectMapper().writeValueAsString(new ReturnResponse(1, "FAILURE", null)); + } + } + + @RequestMapping(value = "deleteFile", method = RequestMethod.GET) + public String deleteFile(String fileName) throws JsonProcessingException { + if (fileName.contains("/")) { + fileName = fileName.substring(fileName.lastIndexOf("/") + 1); + } + File file = new File(fileDir + demoPath + fileName); + if (file.exists()) { + file.delete(); + } + return new ObjectMapper().writeValueAsString(new ReturnResponse(0, "SUCCESS", null)); + } + + @RequestMapping(value = "listFiles", method = RequestMethod.GET) + public String getFiles() throws JsonProcessingException { + List> list = Lists.newArrayList(); + File file = new File(fileDir + demoPath); + if (file.exists()) { + Arrays.stream(file.listFiles()).forEach(file1 -> list.add(ImmutableMap.of("fileName", demoDir + "/" + file1.getName()))); + } + return new ObjectMapper().writeValueAsString(list); + } + + private String getFileName(String name) { + String suffix = name.substring(name.lastIndexOf(".")); + String nameNoSuffix = name.substring(0, name.lastIndexOf(".")); + String uuid = UUID.randomUUID().toString(); + return uuid + "-" + nameNoSuffix + suffix; + } + + /** + * 是否存在该类型的文件 + * @return + * @param fileName + */ + private boolean existsTypeFile(String fileName) { + boolean result = false; + String suffix = fileUtils.getSuffixFromFileName(fileName); + File file = new File(fileDir + demoPath); + if (file.exists()) { + for(File file1 : file.listFiles()){ + String existsFileSuffix = fileUtils.getSuffixFromFileName(file1.getName()); + if (suffix.equals(existsFileSuffix)) { + result = true; + break; + } + } + } + return result; + } +} diff --git a/src/main/java/com/yudianbank/web/controller/OnlinePreviewController.java b/src/main/java/com/yudianbank/web/controller/OnlinePreviewController.java new file mode 100644 index 000000000..eece64f08 --- /dev/null +++ b/src/main/java/com/yudianbank/web/controller/OnlinePreviewController.java @@ -0,0 +1,170 @@ +package com.yudianbank.web.controller; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.yudianbank.param.ReturnResponse; +import com.yudianbank.utils.DownloadUtils; +import com.yudianbank.utils.FileUtils; +import com.yudianbank.utils.OfficeToPdf; +import com.yudianbank.utils.ZipReader; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; + +/** + * @author yudian-it + */ +@Controller +public class OnlinePreviewController { + @Autowired + private OfficeToPdf officeToPdf; + @Autowired + FileUtils fileUtils; + @Autowired + DownloadUtils downloadUtils; + @Autowired + ZipReader zipReader; + + @Value("${file.dir}") + String fileDir; + + /** + * xls:http://keking.ufile.ucloud.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I+D1NOFtAJSPT16E6imv6JWuq0k= + * img:http://keking.ufile.ucloud.com.cn/ufile-a703a5a2-788f-488c-a9bf-f36878d5e308.JPG?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=W9TKj5Kp9oxg85fn5/0zgwF2PL4= + * doc:http://keking.ufile.ucloud.com.cn/20171113173342_凯京新员工试用期评估与转正确认表.doc?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=v1fC5ijYs8WnPzbSYa/bb0Z2Jf4= + * docx:http://keking.ufile.ucloud.com.cn/20171103180053_财产线索类需求20170920(1).docx?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=p7/L1W3iwktzRtkY5Ef2vK7kn3o= + * @param url + * @param model + * @return + */ + @RequestMapping(value = "onlinePreview",method = RequestMethod.GET) + public String onlinePreview(String url, String needEncode, Model model) throws UnsupportedEncodingException { + // 路径转码 + url = URLDecoder.decode(url, "utf-8"); + String type = typeFromUrl(url); + String suffix = suffixFromUrl(url); + model.addAttribute("fileType", suffix); + if (type.equalsIgnoreCase("picture")) { + model.addAttribute("imgurl", url); + return "picture"; + } else if (type.equalsIgnoreCase("txt") + || type.equalsIgnoreCase("html") + || type.equalsIgnoreCase("xml") + || type.equalsIgnoreCase("java") + || type.equalsIgnoreCase("properties") + || type.equalsIgnoreCase("mp3")){ + model.addAttribute("ordinaryUrl",url); + return "txt"; + } else if(type.equalsIgnoreCase("pdf")){ + model.addAttribute("pdfUrl",url); + return "pdf"; + } else if(type.equalsIgnoreCase("compress")){ + // 抽取文件并返回文件列表 + String fileName = fileUtils.getFileNameFromURL(url); + String fileTree = null; + // 判断文件名是否存在(redis缓存读取) + if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) { + ReturnResponse response = downloadUtils.downLoad(url, suffix, fileName, needEncode); + if (0 != response.getCode()) { + model.addAttribute("msg", response.getMsg()); + return "fileNotSupported"; + } + String filePath = response.getContent(); + if ("zip".equalsIgnoreCase(suffix) + || "jar".equalsIgnoreCase(suffix) + || "gzip".equalsIgnoreCase(suffix)) { + fileTree = zipReader.readZipFile(filePath); + } else if ("rar".equalsIgnoreCase(suffix)) { + fileTree = zipReader.unRar(filePath); + } + fileUtils.addConvertedFile(fileName, fileTree); + }else { + fileTree = fileUtils.getConvertedFile(fileName); + } + System.out.println("返回文件tree》》》》》》》》》》》》》》》》》》》"); + if (null != fileTree) { + model.addAttribute("fileTree",fileTree); + return "compress"; + }else { + model.addAttribute("msg", "压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式"); + return "fileNotSupported"; + } + } else if ("office".equalsIgnoreCase(type)) { + String fileName = fileUtils.getFileNameFromURL(url); + String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + + ((suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx")) ? + "html" : "pdf"); + // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 + if (!fileUtils.listConvertedFiles().containsKey(pdfName)) { + String filePath = fileDir + fileName; + if (!new File(filePath).exists()) { + ReturnResponse response = downloadUtils.downLoad(url, suffix, null, needEncode); + if (0 != response.getCode()) { + model.addAttribute("msg", response.getMsg()); + return "fileNotSupported"; + } + filePath = response.getContent(); + } + String outFilePath = fileDir + pdfName; + if (StringUtils.hasText(outFilePath)) { + officeToPdf.openOfficeToPDF(filePath, outFilePath); + File f = new File(filePath); + if (f.exists()) { + f.delete(); + } + if (suffix.equalsIgnoreCase("xls") + || suffix.equalsIgnoreCase("xlsx")) { + // 对转换后的文件进行操作(改变编码方式) + fileUtils.doActionConvertedFile(outFilePath); + } + // 加入缓存 + fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath)); + } + } + model.addAttribute("pdfUrl", pdfName); + return "pdf"; + }else { + model.addAttribute("msg", "系统还不支持该格式文件的在线预览," + "如有需要请按下方显示的邮箱地址联系系统维护人员"); + return "fileNotSupported"; + } + } + + private String suffixFromUrl(String url) { + String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?"): url.length()); + String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); + String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); + return fileType; + } + + /** + * 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型) + * @param url + * @return + */ + private String typeFromUrl(String url) { + String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?"): url.length()); + String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1); + String fileType = fileName.substring(fileName.lastIndexOf(".") + 1); + if (fileUtils.listPictureTypes().contains(fileType.toLowerCase())) { + fileType = "picture"; + } + if (fileUtils.listArchiveTypes().contains(fileType.toLowerCase())) { + fileType = "compress"; + } + if (fileUtils.listOfficeTypes().contains(fileType.toLowerCase())) { + fileType = "office"; + } + return fileType; + } + + +} diff --git a/src/main/resources/META-INF/app.properties b/src/main/resources/META-INF/app.properties new file mode 100644 index 000000000..ca9d3a6d2 --- /dev/null +++ b/src/main/resources/META-INF/app.properties @@ -0,0 +1 @@ +app.id=file-preview diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 000000000..830769bd9 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,30 @@ +server.port = 8012 +spring.http.encoding.charset = utf8 + +## Freemarker 配置 +## 文件配置路径 +spring.freemarker.template-loader-path = classpath:/web/ +spring.freemarker.cache = false +spring.freemarker.charset = UTF-8 +spring.freemarker.check-template-location = true +spring.freemarker.content-type = text/html +spring.freemarker.expose-request-attributes = true +spring.freemarker.expose-session-attributes = true +spring.freemarker.request-context-attribute = request +spring.freemarker.suffix = .ftl + +#=============================================#spring Redisson配置#===================================# +spring.redisson.address = 192.168.1.204:6379 +#Redisson配置end + +##资源映射路径(因为jar方式运行的原因) +file.dir = C:\\Users\\yudian\\Desktop\\dev\\ +spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${file.dir} + +## openoffice相关配置 +openOfficePath = /Applications/OpenOffice.app/Contents +office.home = C:\\Program Files (x86)\\OpenOffice 4 +server.tomcat.uri-encoding = UTF-8 +converted.file.charset = GBK +#======================================#文件上传限制#======================================# +spring.http.multipart.max-file-size=100MB \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 000000000..cb40b4099 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + + + 10800 + 192.168.1.109 + true + {"app_name":"@appName@"} + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/config.js b/src/main/resources/static/config.js new file mode 100644 index 000000000..51ac0bd76 --- /dev/null +++ b/src/main/resources/static/config.js @@ -0,0 +1,8 @@ +env_base_config = { + server_base_url:'http://127.0.0.1:8012/', +} +env_config = { + server_base_url:env_base_config.server_base_url, + server_preview_url:env_base_config.server_base_url + 'onlinePreview?url=', + server_delete_url:env_base_config.server_base_url + 'deleteFile?fileName=', +} \ No newline at end of file diff --git a/src/main/resources/static/css/img/diy/1_close.png b/src/main/resources/static/css/img/diy/1_close.png new file mode 100644 index 0000000000000000000000000000000000000000..68ccb3c3b90170df7cddab1fe6e8e455c3854573 GIT binary patch literal 601 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/css/img/diy/5.png b/src/main/resources/static/css/img/diy/5.png new file mode 100644 index 0000000000000000000000000000000000000000..0c5eccd562c303cf5197629ef5f2666b6180bd48 GIT binary patch literal 710 zcmV;%0y+JOP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ;Oi4sRRCwB?l21sJaTv!xzis}To8;O?C>{dC{zy=SO6rn?>JoVfJ9PB0!cw|< z5rY2EH4^INrK0lE$(TB`L1J|?w{{RVwVX+{e0A>6yZ3#69o{*#LV~{V{P^I25M99V?Z$DfCOu%f*iEi)VM!&PQ0~X={*pIhRm&^JADx2Ei zO9FtZ)17!zihou!LclW{fUsJ6-KRQWX%RLy%#rdc&iw~WzZ8c|*7UlD+tm4dPcnr0SiDoFEg5E2Y&dPN717pvrG@d&~qN)SLk2YQ}eWhnzS2NsMXU@e;q z$#1J?MTrek>$@}ysIbH4Pn4|s4!{BsRg~ey@o{jwK^l-v|2=daTrL(~1&Auja1qcm zA0Pb~i;esUhr#VZ*EO_EW=H6T4sH+MBVlG^vFAPW@zEjxNMD$XUVj}71~yd{>Do)) z&``4()NF>lp&_eXY~*rG1t$YtbJ2bvy&WKdWa#Vaz0czlsCFm9?LkALArT%gs@=iz zM3Aw>%3UB?=s|4%%0TI@ntc}!?y2fKbE&)8wwW?tw9>)Yi;(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-Hc3Q5RCwBylf6#EFcgKqR*|SEf;KdQN{mQMNM#6bz*E3p!3*#TJOP9q=I%T} z)g_1#i3ub?3{8Itwu2ecv`#4@J&R@g=<~Vv$_3Z+FM(5**Hx$4IK%aP-43;Gb+vXq zUuVhneBJ75-43T-EP$6WJoRVj!|QthI?cwfXCHeI>Dj&rpcKd`Uv3%2{zO&+5OQ|7 z=;cI0rUAu-Dnz~nLZs7L08+*mb;p_3zesh*i2-sBFdS=wK}gNEso8dBf?)8;uvD5$ zpcK!qZv_3`za>=GH`uH0qya)Hf_^WvdFF_P+D(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-oJmAMRCwCNld)>sP!xtg$;P&DX##d?FjXy#1Btu@<1TrIE}b(6+V0u<0C|G+ z1!6E{h#^zPfVNUH1)Si?mq44L)RLtur52}yfrAIB@yT&wtK6#}E;o1CwW> zs0MEifRF!B`^DaweqwrPizJsaJ+ws@N@V7V{5<_TW}e7G$pgN~T?_h(db5KXZbM-X z@i~OveZ=Qbn4^Z<)SDg9SGgG&F_ybUT3JJlcA@4#C4%DjEY}>=XqU9IhUIR75$6O7 z8YIQ(_la3W9qobDhNK8q8+Eit%qmX550Ym5hYkYx{R_;P^`1+ZR#BsUc>NAF+9yn_ ztoK|n4k(!k^_NgGljU2p)j*9W zaI13;R$T12?;o{2_N$D)6u7>L2Aq7}dD;>lbA1yHY`_4jK;tey79sFML_*`gU*n$v Y0CUjIYVM#Hl>h($07*qoM6N<$g3L4G@&Et; literal 0 HcmV?d00001 diff --git a/src/main/resources/static/css/img/diy/8.png b/src/main/resources/static/css/img/diy/8.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f3a86e7091de4acdd38745f74b30f0f3d40f9e GIT binary patch literal 529 zcmV+s0`C2ZP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-mq|oHRCwB?ld(!1Q51&1(I{htpn+Xo2nhiLK7gQ=rAta1-4c z23I~Dy#=Bx=-sES#qFU9A~NtT@3!SYME0%7fru>cwq@9yhz#EV;MBm^6uNgtR8Xr= z2i9fl6|Mue0M{9PgJ@>&J^Va_d-JF#FCqZvz~tbj{^y9_PT}y_|FTqGfU(|32N(ld zdoN`zWX3zdQtSRe)z51`wtYaRAywY{0S-(qSQqqB^m^?LF~6wMV5jvm0?L4k3s8yo zD*>6YSQl38yF2Ej`-O+&`dWo7gEaA8Rp?@@!`g|8C0WWJ_m{hqX~o6>&}D$W3~-$S zV;!z@c}1laaT=qvy0*ci2asppOD)WX6h)7P*^pMr>b(YuB-DG2YA$FmJ^na9HNDvf zXGS+Sp6w9M)GC&%xasQa+^&Tc%i_FwxOx6O0H%St(lzkAoEgbPL(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZ-SxH1eRCwCFlD%phK@^3*HCYugNa+j-+qg=ez>lIrt6Er<-ysj+R54r6Ea(-| zq;X*c?zeMmf*6eCC_6h695=JJ71{U?e45KW_s-#5&LjXuQTzlBfs@f_G?s+5w&eg$ zhQs057_-6Uc|IlzNRo=85P&3%F=}Cq5wOKcVuv^4*#fPL|MB6ehpW|!JkK}!G)eCUA?`kDYU+wRQl|@AsL{=k$6#thE3*=Sl#oqXX&kO!|GS z@au=FqXS6-*ah~DF{o$>nU{_K+;olW3X86D1zL_O(0T4pKdrt_r^NSay z@PGjCE6_9z-g}y+dE_5_`V3#b@v&aP`RUeDmSwEhYqBic7MNZ8lJBEIOU$l)`Ssp{ zbFQ3BCIf)!bb1$GL=xlLi**V7k+e*bq}|z?$BHD9nE9)5GXRrS-uaN7-+2H4002ov JPDHLkV1iKO%vb;b literal 0 HcmV?d00001 diff --git a/src/main/resources/static/css/img/line_conn.gif b/src/main/resources/static/css/img/line_conn.gif new file mode 100644 index 0000000000000000000000000000000000000000..d561d36a915776730eb3069cee4c949f027667ed GIT binary patch literal 45 xcmZ?wbhEHbT_)p@)n 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 Ap8x;= literal 0 HcmV?d00001 diff --git a/src/main/resources/static/css/img/zTreeStandard.png b/src/main/resources/static/css/img/zTreeStandard.png new file mode 100644 index 0000000000000000000000000000000000000000..ffda01ef1cccc398ee4e2327f4093ba1130a4961 GIT binary patch literal 11173 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 X3wf1`XyoU;TL_tNiW1dgpn(4aGkUu% literal 0 HcmV?d00001 diff --git a/src/main/resources/static/css/loading.css b/src/main/resources/static/css/loading.css new file mode 100644 index 000000000..771a6d8eb --- /dev/null +++ b/src/main/resources/static/css/loading.css @@ -0,0 +1,121 @@ +.loading_container{ + margin:0; + padding:0; + position: absolute; + left:0; + top:0; + width:100%; + display: none; + opacity: 0.5; + background-color: black; +} +.spinner { + margin: 245px auto; + width: 60px; + height: 60px; + position: relative; +} + +.container1 > div, .container2 > div, .container3 > div { + width: 16px; + height: 16px; + background-color: #67CF22; + + border-radius: 100%; + position: absolute; + -webkit-animation: bouncedelay 1.2s infinite ease-in-out; + animation: bouncedelay 1.2s infinite ease-in-out; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; +} + +.spinner .spinner-container { + position: absolute; + width: 100%; + height: 100%; +} + +.container2 { + -webkit-transform: rotateZ(45deg); + transform: rotateZ(45deg); +} + +.container3 { + -webkit-transform: rotateZ(90deg); + transform: rotateZ(90deg); +} + +.circle1 { top: 0; left: 0; } +.circle2 { top: 0; right: 0; } +.circle3 { right: 0; bottom: 0; } +.circle4 { left: 0; bottom: 0; } + +.container2 .circle1 { + -webkit-animation-delay: -1.1s; + animation-delay: -1.1s; +} + +.container3 .circle1 { + -webkit-animation-delay: -1.0s; + animation-delay: -1.0s; +} + +.container1 .circle2 { + -webkit-animation-delay: -0.9s; + animation-delay: -0.9s; +} + +.container2 .circle2 { + -webkit-animation-delay: -0.8s; + animation-delay: -0.8s; +} + +.container3 .circle2 { + -webkit-animation-delay: -0.7s; + animation-delay: -0.7s; +} + +.container1 .circle3 { + -webkit-animation-delay: -0.6s; + animation-delay: -0.6s; +} + +.container2 .circle3 { + -webkit-animation-delay: -0.5s; + animation-delay: -0.5s; +} + +.container3 .circle3 { + -webkit-animation-delay: -0.4s; + animation-delay: -0.4s; +} + +.container1 .circle4 { + -webkit-animation-delay: -0.3s; + animation-delay: -0.3s; +} + +.container2 .circle4 { + -webkit-animation-delay: -0.2s; + animation-delay: -0.2s; +} + +.container3 .circle4 { + -webkit-animation-delay: -0.1s; + animation-delay: -0.1s; +} + +@-webkit-keyframes bouncedelay { + 0%, 80%, 100% { -webkit-transform: scale(0.0) } + 40% { -webkit-transform: scale(1.0) } +} + +@keyframes bouncedelay { + 0%, 80%, 100% { + transform: scale(0.0); + -webkit-transform: scale(0.0); + } 40% { + transform: scale(1.0); + -webkit-transform: scale(1.0); + } +} \ No newline at end of file diff --git a/src/main/resources/static/css/viewer.min.css b/src/main/resources/static/css/viewer.min.css new file mode 100644 index 000000000..10f7a6398 --- /dev/null +++ b/src/main/resources/static/css/viewer.min.css @@ -0,0 +1,9 @@ +/*! + * Viewer.js v0.3.1 + * https://github.com/fengyuanchen/viewerjs + * + * Copyright (c) 2015-2016 Fengyuan Chen + * Released under the MIT license + * + * Date: 2016-02-02T11:35:36.273Z + */.viewer-container,.viewer-navbar{background-color:#000;overflow:hidden}.viewer-canvas,.viewer-container,.viewer-footer,.viewer-player{right:0;bottom:0;left:0}.viewer-button,.viewer-canvas,.viewer-container,.viewer-footer,.viewer-list,.viewer-navbar,.viewer-open,.viewer-title,.viewer-toolbar,.viewer-toolbar>li{overflow:hidden}.viewer-close:before,.viewer-flip-horizontal:before,.viewer-flip-vertical:before,.viewer-fullscreen-exit:before,.viewer-fullscreen:before,.viewer-next:before,.viewer-one-to-one:before,.viewer-play:before,.viewer-prev:before,.viewer-reset:before,.viewer-rotate-left:before,.viewer-rotate-right:before,.viewer-zoom-in:before,.viewer-zoom-out:before{font-size:0;line-height:0;display:block;width:20px;height:20px;color:transparent;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC);background-repeat:no-repeat}.viewer-zoom-in:before{content:'Zoom In';background-position:0 0}.viewer-zoom-out:before{content:'Zoom Out';background-position:-20px 0}.viewer-one-to-one:before{content:'One to One';background-position:-40px 0}.viewer-reset:before{content:'Reset';background-position:-60px 0}.viewer-prev:before{content:'Previous';background-position:-80px 0}.viewer-play:before{content:'Play';background-position:-100px 0}.viewer-next:before{content:'Next';background-position:-120px 0}.viewer-rotate-left:before{content:'Rotate Left';background-position:-140px 0}.viewer-rotate-right:before{content:'Rotate Right';background-position:-160px 0}.viewer-flip-horizontal:before{content:'Flip Horizontal';background-position:-180px 0}.viewer-flip-vertical:before{content:'Flip Vertical';background-position:-200px 0}.viewer-fullscreen:before{content:'Enter Full Screen';background-position:-220px 0}.viewer-fullscreen-exit:before{content:'Exit Full Screen';background-position:-240px 0}.viewer-close:before{content:'Close';background-position:-260px 0}.viewer-container{font-size:0;line-height:0;position:absolute;top:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:rgba(0,0,0,.5);direction:ltr!important;-ms-touch-action:none;touch-action:none;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}.viewer-container ::-moz-selection,.viewer-container::-moz-selection{background-color:transparent}.viewer-container ::selection,.viewer-container::selection{background-color:transparent}.viewer-container img{display:block;width:100%;min-width:0!important;max-width:none!important;height:auto;min-height:0!important;max-height:none!important}.viewer-player,.viewer-tooltip{display:none;position:absolute}.viewer-canvas{position:absolute;top:0}.viewer-canvas>img{width:auto;max-width:90%!important;height:auto;margin:15px auto}.viewer-footer{position:absolute;text-align:center}.viewer-navbar{background-color:rgba(0,0,0,.5)}.viewer-list{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:50px;margin:0;padding:1px 0}.viewer-list>li{font-size:0;line-height:0;float:left;overflow:hidden;width:30px;height:50px;cursor:pointer;opacity:.5;color:transparent;filter:alpha(opacity=50)}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-active{opacity:1;filter:alpha(opacity=100)}.viewer-player{top:0;cursor:none;background-color:#000}.viewer-player>img{position:absolute;top:0;left:0}.viewer-toolbar{width:280px;margin:0 auto 5px;padding:3px 0}.viewer-toolbar>li{float:left;width:24px;height:24px;cursor:pointer;border-radius:50%;background-color:#000;background-color:rgba(0,0,0,.5)}.viewer-toolbar>li:hover{background-color:#000;background-color:rgba(0,0,0,.8)}.viewer-toolbar>li:before{margin:2px}.viewer-toolbar>li+li{margin-left:1px}.viewer-toolbar>.viewer-play{width:30px;height:30px;margin-top:-3px;margin-bottom:-3px}.viewer-toolbar>.viewer-play:before{margin:5px}.viewer-tooltip{font-size:12px;line-height:20px;top:50%;left:50%;width:50px;height:20px;margin-top:-10px;margin-left:-25px;text-align:center;color:#fff;border-radius:10px;background-color:#000;background-color:rgba(0,0,0,.8)}.viewer-title{font-size:12px;line-height:1;display:inline-block;max-width:90%;margin:0 5% 5px;white-space:nowrap;text-overflow:ellipsis;opacity:.8;color:#ccc;filter:alpha(opacity=80)}.viewer-title:hover{opacity:1;filter:alpha(opacity=100)}.viewer-button{position:absolute;top:-40px;right:-40px;width:80px;height:80px;cursor:pointer;border-radius:50%;background-color:#000;background-color:rgba(0,0,0,.5)}.viewer-button:before{position:absolute;bottom:15px;left:15px}.viewer-fixed{position:fixed}.viewer-show{display:block}.viewer-hide{display:none}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.viewer-fade{opacity:0;filter:alpha(opacity=0)}.viewer-in{opacity:1;filter:alpha(opacity=100)}.viewer-transition{-webkit-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}} \ No newline at end of file diff --git a/src/main/resources/static/css/zTreeStyle.css b/src/main/resources/static/css/zTreeStyle.css new file mode 100644 index 000000000..4a1705b14 --- /dev/null +++ b/src/main/resources/static/css/zTreeStyle.css @@ -0,0 +1,97 @@ +/*------------------------------------- +zTree Style + +version: 3.5.19 +author: Hunter.z +email: hunter.z@263.net +website: http://code.google.com/p/jquerytree/ + +-------------------------------------*/ + +.ztree * {padding:0; margin:0; font-size:12px; font-family: Verdana, Arial, Helvetica, AppleGothic, sans-serif} +.ztree {margin:0; padding:5px; color:#333} +.ztree li{padding:0; margin:0; list-style:none; line-height:14px; text-align:left; white-space:nowrap; outline:0} +.ztree li ul{ margin:0; padding:0 0 0 18px} +.ztree li ul.line{ background:url(./img/line_conn.gif) 0 0 repeat-y;} + +.ztree li a {padding:1px 3px 0 0; margin:0; cursor:pointer; height:17px; color:#333; background-color: transparent; + text-decoration:none; vertical-align:top; display: inline-block} +.ztree li a:hover {text-decoration:underline} +.ztree li a.curSelectedNode {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.curSelectedNode_Edit {padding-top:0px; background-color:#FFE6B0; color:black; height:16px; border:1px #FFB951 solid; opacity:0.8;} +.ztree li a.tmpTargetNode_inner {padding-top:0px; background-color:#316AC5; color:white; height:16px; border:1px #316AC5 solid; + opacity:0.8; filter:alpha(opacity=80)} +.ztree li a.tmpTargetNode_prev {} +.ztree li a.tmpTargetNode_next {} +.ztree li a input.rename {height:14px; width:80px; padding:0; margin:0; + font-size:12px; border:1px #7EC4CC solid; *border:0px} +.ztree li span {line-height:16px; margin-right:2px} +.ztree li span.button {line-height:0; margin:0; width:16px; height:16px; display: inline-block; vertical-align:middle; + border:0 none; cursor: pointer;outline:none; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +.ztree li span.button.chk {width:13px; height:13px; margin:0 3px 0 0; cursor: auto} +.ztree li span.button.chk.checkbox_false_full {background-position:0 0} +.ztree li span.button.chk.checkbox_false_full_focus {background-position:0 -14px} +.ztree li span.button.chk.checkbox_false_part {background-position:0 -28px} +.ztree li span.button.chk.checkbox_false_part_focus {background-position:0 -42px} +.ztree li span.button.chk.checkbox_false_disable {background-position:0 -56px} +.ztree li span.button.chk.checkbox_true_full {background-position:-14px 0} +.ztree li span.button.chk.checkbox_true_full_focus {background-position:-14px -14px} +.ztree li span.button.chk.checkbox_true_part {background-position:-14px -28px} +.ztree li span.button.chk.checkbox_true_part_focus {background-position:-14px -42px} +.ztree li span.button.chk.checkbox_true_disable {background-position:-14px -56px} +.ztree li span.button.chk.radio_false_full {background-position:-28px 0} +.ztree li span.button.chk.radio_false_full_focus {background-position:-28px -14px} +.ztree li span.button.chk.radio_false_part {background-position:-28px -28px} +.ztree li span.button.chk.radio_false_part_focus {background-position:-28px -42px} +.ztree li span.button.chk.radio_false_disable {background-position:-28px -56px} +.ztree li span.button.chk.radio_true_full {background-position:-42px 0} +.ztree li span.button.chk.radio_true_full_focus {background-position:-42px -14px} +.ztree li span.button.chk.radio_true_part {background-position:-42px -28px} +.ztree li span.button.chk.radio_true_part_focus {background-position:-42px -42px} +.ztree li span.button.chk.radio_true_disable {background-position:-42px -56px} + +.ztree li span.button.switch {width:18px; height:18px} +.ztree li span.button.root_open{background-position:-92px -54px} +.ztree li span.button.root_close{background-position:-74px -54px} +.ztree li span.button.roots_open{background-position:-92px 0} +.ztree li span.button.roots_close{background-position:-74px 0} +.ztree li span.button.center_open{background-position:-92px -18px} +.ztree li span.button.center_close{background-position:-74px -18px} +.ztree li span.button.bottom_open{background-position:-92px -36px} +.ztree li span.button.bottom_close{background-position:-74px -36px} +.ztree li span.button.noline_open{background-position:-92px -72px} +.ztree li span.button.noline_close{background-position:-74px -72px} +.ztree li span.button.root_docu{ background:none;} +.ztree li span.button.roots_docu{background-position:-56px 0} +.ztree li span.button.center_docu{background-position:-56px -18px} +.ztree li span.button.bottom_docu{background-position:-56px -36px} +.ztree li span.button.noline_docu{ background:none;} + +.ztree li span.button.ico_open{margin-right:2px; background-position:-110px -16px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_close{margin-right:2px; background-position:-110px 0; vertical-align:top; *vertical-align:middle} +.ztree li span.button.ico_docu{margin-right:2px; background-position:-110px -32px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.edit {margin-right:2px; background-position:-110px -48px; vertical-align:top; *vertical-align:middle} +.ztree li span.button.remove {margin-right:2px; background-position:-110px -64px; vertical-align:top; *vertical-align:middle} + +.ztree li span.button.ico_loading{margin-right:2px; background:url(./img/loading.gif) no-repeat scroll 0 0 transparent; vertical-align:top; *vertical-align:middle} + +ul.tmpTargetzTree {background-color:#FFE6B0; opacity:0.8; filter:alpha(opacity=80)} + +span.tmpzTreeMove_arrow {width:16px; height:16px; display: inline-block; padding:0; margin:2px 0 0 1px; border:0 none; position:absolute; + background-color:transparent; background-repeat:no-repeat; background-attachment: scroll; + background-position:-110px -80px; background-image:url("./img/zTreeStandard.png"); *background-image:url("./img/zTreeStandard.gif")} + +ul.ztree.zTreeDragUL {margin:0; padding:0; position:absolute; width:auto; height:auto;overflow:hidden; background-color:#cfcfcf; border:1px #00B83F dotted; opacity:0.8; filter:alpha(opacity=80)} +.zTreeMask {z-index:10000; background-color:#cfcfcf; opacity:0.0; filter:alpha(opacity=0); position:absolute} + +/* level style*/ +/*.ztree li span.button.level0 { + display:none; +} +.ztree li ul.level0 { + padding:0; + background:none; +}*/ \ No newline at end of file diff --git a/src/main/resources/static/images/sorry.jpg b/src/main/resources/static/images/sorry.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03c9dd37eae9e44816dcfe8ea4282fc5b4d53fb5 GIT binary patch literal 23866 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 000000000..f235f26a9 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,172 @@ + + + + + 图片预览图 + + + + + + + + +

文件预览项目接入和测试界面

+
+
+ +
+
+
+ 如果你的项目需要接入文件预览项目,达到对docx、excel、ppt、jpg等文件的预览效果,那么通过在你的项目中加入下面的代码就可以 + 成功实现: +
+                        $scope.openWin = function (fileUrl) {
+                            var url = configuration.previewUrl + encodeURIComponent(fileUrl);
+                            var winHeight = window.document.documentElement.clientHeight-10;
+                            $window.open(url, "_blank", "height=" + winHeight
+                                + ",top=80,left=80,toolbar=no, menubar=no, scrollbars=yes, resizable=yes");
+                        };
+                    
+ 说明: +

1.这里的fileUrl即是需要预览的服务器文件,一般是ufile文件

+

2.只所以使用encodeURIComponent转码是因为ufile文件中可能会存在&等特殊字符,那么如果不转码会被浏览器处理成多参数 + 这样后台获取的就不是需要预览的文件的全路径了。

+

3.configuration.previewUrl是需要接入项目中配置文件预览项目的地址的配置 + 现在开发和测试地址都是: + http://106.75.31.215:8012/onlinePreview?url=服务器(ufile)文件路径

+
+
+
+
+ +
+ +
+
+

因为是测试所以一种文件只允许上传一个

+
+
+ + +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/js/excel.header.js b/src/main/resources/static/js/excel.header.js new file mode 100644 index 000000000..8852d1f8e --- /dev/null +++ b/src/main/resources/static/js/excel.header.js @@ -0,0 +1,19 @@ +/**创建一个div并固定在底部,将center中的所有a标签放在改div中**/ +$("body").append($("
").css({"width":"100%","height":"30px","position":"fixed","top":"0","left":"0" + ,"background-color":"rgba(53, 53, 53, 1)","line-height":"30px","font-size":"13px"}).attr("id","excel-header-nav")); +$("center").css("display", "none"); +var centerChildrenA = $("center").children("a"); +if (centerChildrenA.length === 0) { + $("#excel-header-nav").hide(); +} +$(centerChildrenA).each(function (a, b) { + // 获取a标签对应的target的name值,并设置name对应标签的样式以避免锚点标签标题被覆盖 + var href = $(b).attr("href"); + var name = href.substr(1); + console.log(href + ":" + name); + $("[name=" + name + "]").css({"display":"block","padding-top":"14.01px"}); + $(b).css({"padding":"5px","border-right":"1px solid white","color":"#f9f9f9"}); + $("#excel-header-nav").append(b); +}); +/**给所有的table添加class=table table-striped样式**/ +$("table").addClass("table table-striped"); \ No newline at end of file diff --git a/src/main/resources/static/js/jquery-3.0.0.min.js b/src/main/resources/static/js/jquery-3.0.0.min.js new file mode 100644 index 000000000..62d410d95 --- /dev/null +++ b/src/main/resources/static/js/jquery-3.0.0.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.0.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"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){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.0.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.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()},push:h,sort:c.sort,splice:c.splice},r.extend=r.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||r.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&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return a&&"[object Object]"===k.call(a)?(b=e(a))?(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n):!0:!1},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?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.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,e,f=0,h=[];if(w(a))for(d=a.length;d>f;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;return"string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a)?(d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e):void 0},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"===c||r.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;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="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),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(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),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-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=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)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\x00"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){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 ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(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 qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(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"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.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},B=b?function(a,b){if(a===b)return l=!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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.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=ga.selectors={cacheLength:50,createPseudo:ia,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(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===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]||ga.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]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(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(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.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.replace(O," ")+" ").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(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(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),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?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===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!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:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[0>c?c+b:c]}),even:pa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(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 va(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function wa(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 xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(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(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,e>i&&ya(a.slice(i,e)),f>e&&ya(a=a.slice(e)),f>e&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(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}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;d>b;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;d>b;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;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&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(f>b)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(1>=b&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){ +return j.call(r(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},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.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=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.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 V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthf;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;g>f;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;d>c;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;o>n;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),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),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==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,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;cc;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.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++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;m>l;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;i>l;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;e>d;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;e>d;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.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 Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(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 r.clone(this,a,b)})},html:function(a){return S(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&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;f>=g;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.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 Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(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+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),0>=d||null==d){if(d=Ma(a,b,f),(0>d||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!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=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.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=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){return c?!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)}):void 0},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){return b?(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;e>g;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=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):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.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 gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),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:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.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.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);g>f;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.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)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;e>d;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.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=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.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||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.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})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c); +}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.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){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,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)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){return r.isArray(b)?a.checked=r.inArray(r(a).val(),b)>-1:void 0}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?r.event.trigger(a,b,c,!0):void 0}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.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 Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.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 Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(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 Nb(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}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",0>b&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(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 r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;return o.cors||Pb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + + + + \ No newline at end of file diff --git a/src/main/resources/web/doc.ftl b/src/main/resources/web/doc.ftl new file mode 100644 index 000000000..4d4d3cfd6 --- /dev/null +++ b/src/main/resources/web/doc.ftl @@ -0,0 +1,9 @@ + + + + + +${doc} + + + \ No newline at end of file diff --git a/src/main/resources/web/docxConvert.ftl b/src/main/resources/web/docxConvert.ftl new file mode 100644 index 000000000..3b2ad7de8 --- /dev/null +++ b/src/main/resources/web/docxConvert.ftl @@ -0,0 +1,11 @@ + + + + + + +${docxConvert} + + + + \ No newline at end of file diff --git a/src/main/resources/web/fileNotSupported.ftl b/src/main/resources/web/fileNotSupported.ftl new file mode 100644 index 000000000..a11323b64 --- /dev/null +++ b/src/main/resources/web/fileNotSupported.ftl @@ -0,0 +1,41 @@ + + + + + + + +
+ + + 该文件类型(${fileType})系统暂时不支持在线预览,说明: +

${msg}

+ 如有需要请联系@HappyPig +
+
+ + + \ No newline at end of file diff --git a/src/main/resources/web/pdf.ftl b/src/main/resources/web/pdf.ftl new file mode 100644 index 000000000..148dcafba --- /dev/null +++ b/src/main/resources/web/pdf.ftl @@ -0,0 +1,26 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/web/picture.ftl b/src/main/resources/web/picture.ftl new file mode 100644 index 000000000..bc5f9d555 --- /dev/null +++ b/src/main/resources/web/picture.ftl @@ -0,0 +1,33 @@ + + + + + 图片预览图 + + + + +

如果图片质量很好,首次加载图片时间可能会有点长,请耐心等待

+ +
    +
  • + +
+ + + + + + diff --git a/src/main/resources/web/txt.ftl b/src/main/resources/web/txt.ftl new file mode 100644 index 000000000..60555044c --- /dev/null +++ b/src/main/resources/web/txt.ftl @@ -0,0 +1,18 @@ + + + + + 普通文件预览 + + + + + + + + + + + diff --git a/src/test/java/com/yudianbank/FilePreviewApplicationTests.java b/src/test/java/com/yudianbank/FilePreviewApplicationTests.java new file mode 100644 index 000000000..d92b62453 --- /dev/null +++ b/src/test/java/com/yudianbank/FilePreviewApplicationTests.java @@ -0,0 +1,16 @@ +package com.yudianbank; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class FilePreviewApplicationTests { + + @Test + public void contextLoads() { + } + +}