├── package.bat ├── screenshot ├── log.png └── light.png ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── src ├── main │ ├── resources │ │ ├── static │ │ │ ├── assets │ │ │ │ ├── img │ │ │ │ │ ├── android.png │ │ │ │ │ ├── favicon.ico │ │ │ │ │ ├── favicon.png │ │ │ │ │ ├── faviconH.png │ │ │ │ │ └── qq-group.png │ │ │ │ └── css │ │ │ │ │ └── index.css │ │ │ └── plugins │ │ │ │ ├── layer │ │ │ │ ├── theme │ │ │ │ │ └── default │ │ │ │ │ │ ├── icon.png │ │ │ │ │ │ ├── icon-ext.png │ │ │ │ │ │ ├── loading-0.gif │ │ │ │ │ │ ├── loading-1.gif │ │ │ │ │ │ ├── loading-2.gif │ │ │ │ │ │ └── layer.css │ │ │ │ ├── mobile │ │ │ │ │ ├── layer.js │ │ │ │ │ └── need │ │ │ │ │ │ └── layer.css │ │ │ │ └── layer.js │ │ │ │ ├── bootstrap-fileinput │ │ │ │ ├── img │ │ │ │ │ ├── loading.gif │ │ │ │ │ └── loading-sm.gif │ │ │ │ ├── themes │ │ │ │ │ ├── explorer │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ ├── theme.js │ │ │ │ │ │ ├── theme.min.css │ │ │ │ │ │ └── theme.css │ │ │ │ │ ├── fa │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ ├── fas │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ ├── bs5 │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ ├── gly │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ └── theme.js │ │ │ │ │ ├── explorer-fa │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ ├── theme.min.css │ │ │ │ │ │ ├── theme.js │ │ │ │ │ │ └── theme.css │ │ │ │ │ └── explorer-fas │ │ │ │ │ │ ├── theme.min.js │ │ │ │ │ │ ├── theme.min.css │ │ │ │ │ │ ├── theme.js │ │ │ │ │ │ └── theme.css │ │ │ │ ├── css │ │ │ │ │ ├── fileinput-rtl.min.css │ │ │ │ │ └── fileinput.min.css │ │ │ │ └── js │ │ │ │ │ └── locales │ │ │ │ │ └── zh.js │ │ │ │ ├── bootstrap-icons │ │ │ │ └── fonts │ │ │ │ │ ├── bootstrap-icons.woff │ │ │ │ │ └── bootstrap-icons.woff2 │ │ │ │ └── clipboard │ │ │ │ └── clipboard.min.js │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ └── resource-config.json │ │ ├── application.properties │ │ └── templates │ │ │ └── index.html │ └── java │ │ └── com │ │ └── mueeee │ │ └── unpackerpanel │ │ ├── common │ │ ├── Constant.java │ │ ├── CorsConfig.java │ │ ├── MD5Util.java │ │ └── ApiResult.java │ │ ├── AppRunner.java │ │ ├── Application.java │ │ ├── MainController.java │ │ └── Unpacker.java └── test │ └── java │ └── com │ └── mueeee │ └── unpackerpanel │ └── ApplicationTests.java ├── native-image-agent.bat ├── .gitignore ├── README.md ├── pom.xml ├── mvnw.cmd ├── mvnw └── LICENSE /package.bat: -------------------------------------------------------------------------------- 1 | mvn clean package -DskipTests -------------------------------------------------------------------------------- /screenshot/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/screenshot/log.png -------------------------------------------------------------------------------- /screenshot/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/screenshot/light.png -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/static/assets/img/android.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/assets/img/android.png -------------------------------------------------------------------------------- /src/main/resources/static/assets/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/assets/img/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/assets/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/assets/img/favicon.png -------------------------------------------------------------------------------- /src/main/resources/static/assets/img/faviconH.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/assets/img/faviconH.png -------------------------------------------------------------------------------- /src/main/resources/static/assets/img/qq-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/assets/img/qq-group.png -------------------------------------------------------------------------------- /native-image-agent.bat: -------------------------------------------------------------------------------- 1 | java -DspringAot=true -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image -jar ./target/unpacker-panel-1.0.jar -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/layer/theme/default/icon.png -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/layer/theme/default/icon-ext.png -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/layer/theme/default/loading-0.gif -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/layer/theme/default/loading-1.gif -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/layer/theme/default/loading-2.gif -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/bootstrap-fileinput/img/loading.gif -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/img/loading-sm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/bootstrap-fileinput/img/loading-sm.gif -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-icons/fonts/bootstrap-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/bootstrap-icons/fonts/bootstrap-icons.woff -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-icons/fonts/bootstrap-icons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/westinyang/unpacker-panel/HEAD/src/main/resources/static/plugins/bootstrap-icons/fonts/bootstrap-icons.woff2 -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/native-image/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":{ 3 | "includes":[ 4 | { 5 | "pattern":"\\Qr_styles.ini\\E" 6 | }, 7 | { 8 | "pattern":"\\Qr_values.ini\\E" 9 | } 10 | ]}, 11 | "bundles":[ 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/mueeee/unpackerpanel/ApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/common/Constant.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel.common; 2 | 3 | /** 4 | * 常量 5 | */ 6 | public class Constant { 7 | public static final int OPERATE_SUCCESS = 0; 8 | public static final int OPERATE_ERROR = 1; 9 | 10 | public static final String OPERATE_SUCCESS_STR = "操作成功!"; 11 | public static final String OPERATE_ERROR_STR = "操作失败!"; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | 35 | uploads/ 36 | -------------------------------------------------------------------------------- /src/main/resources/static/assets/css/index.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | min-height: 100%; 3 | } 4 | 5 | body { 6 | --bs-bg-opacity: 1; 7 | } 8 | .bg-dark:not(header) { 9 | --bs-bg-opacity: 1; 10 | } 11 | .bg-light, .bg-white { 12 | --bs-bg-opacity: 1; 13 | } 14 | .dropdown-menu.bg-white { 15 | --bs-bg-opacity: 1; 16 | } 17 | 18 | .transparent-0-9 { 19 | /*opacity: 0.9 !important;*/ 20 | } 21 | 22 | .container { 23 | /*max-width: 960px;*/ 24 | } 25 | 26 | .file-preview { 27 | border: none !important; 28 | padding: 0 !important; 29 | } 30 | 31 | .file-drop-zone { 32 | margin: 0 !important; 33 | } 34 | 35 | .kv-upload-progress { 36 | display: none !important; 37 | } 38 | 39 | .form-control { 40 | border: 1px solid rgba(0,0,0,.125) !important; 41 | } 42 | 43 | .file-drop-zone { 44 | border: 1px dashed rgba(0,0,0,.225) !important; 45 | } 46 | 47 | /* Layer */ 48 | 49 | .layui-layer .layui-layer-btn * { 50 | font-size: 14px !important; 51 | } -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Server 2 | server.port=8888 3 | 4 | # Spring 5 | spring.servlet.multipart.max-file-size=512MB 6 | spring.servlet.multipart.max-request-size=512MB 7 | spring.mvc.async.request-timeout=1200000 8 | spring.thymeleaf.cache=false 9 | 10 | # Log 11 | # 2021-12-22 13:22:27.078 INFO 20608 --- [ main] com.mueeee.unpackerpanel.AppRunner : Server is running on 127.0.0.1:6666 12 | # %clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} 13 | logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:yyyy-MM-dd HH:mm:ss}}){faint} %clr(${LOG_LEVEL_PATTERN:%5p}) %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx} 14 | logging.level.root=info 15 | logging.level.org.springframework=off 16 | logging.level.org.apache=off 17 | logging.level.com.mueeee.unpackerpanel.Application=off 18 | logging.level.com.mueeee=info 19 | 20 | # Android device no 21 | app.device= -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/common/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel.common; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.cors.CorsConfiguration; 6 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 7 | import org.springframework.web.filter.CorsFilter; 8 | 9 | /** 10 | * Cross-domain configuration 11 | */ 12 | @Configuration 13 | public class CorsConfig { 14 | 15 | /*private CorsConfiguration buildConfig() { 16 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 17 | corsConfiguration.addAllowedOrigin("*"); 18 | corsConfiguration.addAllowedHeader("*"); 19 | corsConfiguration.addAllowedMethod("*"); 20 | return corsConfiguration; 21 | } 22 | 23 | @Bean 24 | public CorsFilter corsFilter() { 25 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 26 | source.registerCorsConfiguration("/**", this.buildConfig()); 27 | return new CorsFilter(source); 28 | }*/ 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/AppRunner.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.boot.ApplicationArguments; 7 | import org.springframework.boot.ApplicationRunner; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.PostConstruct; 11 | 12 | /** 13 | * Execute after the application started 14 | */ 15 | @Component 16 | public class AppRunner implements ApplicationRunner { 17 | 18 | private static final Logger log = LoggerFactory.getLogger(AppRunner.class); 19 | 20 | @Value("${server.port}") 21 | private int serverPort; 22 | 23 | @Value("${app.device}") 24 | private String appDevice; 25 | 26 | public static String APP_DEVICE = null; 27 | 28 | @PostConstruct 29 | public void init() { 30 | APP_DEVICE = appDevice; 31 | } 32 | 33 | @Override 34 | public void run(ApplicationArguments args) throws Exception { 35 | // 打印日志 36 | log.info("Server is running on 127.0.0.1:" + serverPort); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme configuration for bootstrap-fileinput. Load this theme file after loading `fileinput.js`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):e("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(e){"use strict";e.fn.fileinputThemes.explorer={layoutTemplates:{footer:'
{caption}
{size}{progress}
{indicator} {actions}
',actions:'{drag}\n
\n \n
'},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame"}}); -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/common/MD5Util.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel.common; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.security.MessageDigest; 7 | 8 | import org.apache.commons.codec.binary.Hex; 9 | import org.apache.commons.codec.digest.DigestUtils; 10 | 11 | /** 12 | * MD5 Util 13 | */ 14 | public class MD5Util { 15 | 16 | /** 17 | * 获取一个文件的md5值(可处理大文件) 18 | * @return md5 value 19 | */ 20 | public static String md5(File file) { 21 | FileInputStream fileInputStream = null; 22 | try { 23 | MessageDigest MD5 = MessageDigest.getInstance("MD5"); 24 | fileInputStream = new FileInputStream(file); 25 | byte[] buffer = new byte[8192]; 26 | int length; 27 | while ((length = fileInputStream.read(buffer)) != -1) { 28 | MD5.update(buffer, 0, length); 29 | } 30 | return new String(Hex.encodeHex(MD5.digest())); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | return null; 34 | } finally { 35 | try { 36 | if (fileInputStream != null) { 37 | fileInputStream.close(); 38 | } 39 | } catch (IOException e) { 40 | e.printStackTrace(); 41 | } 42 | } 43 | } 44 | 45 | /** 46 | * 求一个字符串的md5值 47 | * @param target 字符串 48 | * @return md5 value 49 | */ 50 | public static String md5(String target) { 51 | return DigestUtils.md5Hex(target); 52 | } 53 | } -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/Application.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel; 2 | 3 | import org.springframework.boot.Banner; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @SpringBootApplication 11 | public class Application { 12 | 13 | // unpacker-panel 14 | // unpacker-panel.exe --server.port=8888 15 | public static void main(String[] args) { 16 | SpringApplication springApplication = new SpringApplication(Application.class); 17 | springApplication.setBannerMode(Banner.Mode.OFF); // 关闭Banner打印 18 | // springApplication.setAddCommandLineProperties(false); // 禁用命令行参数设置 19 | springApplication.run(filterArgs(args)); 20 | } 21 | 22 | /** 23 | * 过滤命令行参数,实现参数白名单效果 24 | * @param args 原始参数列表 25 | * @return 26 | */ 27 | public static String[] filterArgs(String[] args) { 28 | if (args.length == 0) { 29 | return args; 30 | } 31 | List finalArgs = new ArrayList<>(); 32 | for (String arg : args) { 33 | // 服务端口号 34 | if (arg.startsWith("--server.port=")) { 35 | try { 36 | Integer.parseInt(arg.split("=")[1]); 37 | finalArgs.add(arg); 38 | } catch (Exception ignored) { 39 | } 40 | } 41 | } 42 | if (finalArgs.isEmpty()) { 43 | return new String[0]; 44 | } 45 | return finalArgs.toArray(new String[0]); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unpacker Panel 2 | 3 | ## 项目介绍 4 | 5 | > 技术咨询请来这里:[关于作者](https://kaihongpai.feishu.cn/wiki/CqWLwJRadibxztkrIWZcogWxnXd) 6 | 7 | 基于Youpk脱壳机的一键脱壳Web面板 8 | 9 | - 目前仅支持单个设备控制,不支持多设备并发和任务队列(如果并发会导致程序异常) 10 | - [关于脱壳失败和项目其他用途的探讨](https://github.com/westinyang/unpacker-panel/discussions/6) 11 | 12 | ## 使用说明 13 | 14 | > 该工具仅仅用来学习交流, 请勿用于非法用途, 否则后果自付! 15 | 16 | 1. ADB环境 17 | - windows `自己配置好adb环境变量` 18 | - linux `sudo apt install android-tools-adb` 19 | 2. 电脑连接刷好Youpk的Pixel 1代,或者编译Youpk适配的其他安卓设备 20 | 3. 运行程序,不指定端口默认就是:8888 21 | - windows 直接打开或者指定端口运行 22 | ```batch 23 | unpacker-panel.exe 24 | unpacker-panel.exe --server.port=8888 25 | ``` 26 | - linux 27 | ```shell 28 | chmod 777 unpacker-panel 29 | ./unpacker-panel 30 | ./unpacker-panel --server.port=8888 31 | ``` 32 | 4. 浏览器访问 `http://ip:port` 33 | 34 | ## 开发技术 35 | 36 | > - GraalVM让Java再次变得强大,使用native-image把程序编译为目标平台的可执行文件,脱离jvm直接运行,启动速度快,内存负载低。 37 | > - 关于GraalVM技术实践,请参考我的另一个开源项目:[java-graalvm-start](https://github.com/westinyang/java-graalvm-start) 38 | 39 | - 后端 40 | - GraalVM CE 22.1.0 (native-image) (based on Java 17) 41 | - SpringBoot 2.7 42 | - apk-parser 43 | - hutool 44 | - 前端 45 | - jquery 3.5 46 | - bootstrap 5 47 | - bootstrap-fileinput 48 | - bootstrap-icons 49 | - clipboard 50 | - layer 51 | 52 | ## 项目截图 53 | 54 | 网页面板 55 | 56 | ![light.png](./screenshot/light.png) 57 | 58 | 后台日志 59 | 60 | ![log.png](./screenshot/log.png) 61 | 62 | ## 仓库地址 63 | 64 | https://github.com/westinyang/unpacker-panel 65 | 66 | ## 写在最后 67 | 68 | > 膜拜 Youlor 大佬提供的技术和思路,开发这个项目也是在学习技术和实践应用,底层由 Youpk 强力驱动! 69 | 70 | - [Youpk: 又一款基于ART的主动调用的脱壳机](https://bbs.pediy.com/thread-259854.htm) 71 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/fa/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome icon theme configuration for bootstrap-fileinput. Requires font awesome assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(a){"use strict";a.fn.fileinputThemes.fa={fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},layoutTemplates:{fileIcon:' '},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:'',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/fas/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(a){"use strict";a.fn.fileinputThemes.fas={fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},layoutTemplates:{fileIcon:' '},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:'',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/bs5/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Bootstrap 5.x icon theme configuration for bootstrap-fileinput. Requires bootstrap 5.x icons CSS to be loaded. 6 | * This is used as the default theme within the bootstrap-fileinput plugin. 7 | * 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 10 | * 11 | * Licensed under the BSD-3-Clause 12 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 13 | */!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):i("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(i){"use strict";i.fn.fileinputBsVersion="5.x.x",i.fn.fileinputThemes.bs5={fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},layoutTemplates:{fileIcon:''},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:' ',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme configuration for bootstrap-fileinput. Load this theme file after loading `fileinput.js`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function (factory) { 14 | 'use strict'; 15 | if (typeof define === 'function' && define.amd) { 16 | define(['jquery'],factory); 17 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 18 | factory(require('jquery')); 19 | } else { 20 | factory(window.jQuery); 21 | } 22 | }(function ($) { 23 | "use strict"; 24 | $.fn.fileinputThemes.explorer = { 25 | layoutTemplates: { 26 | footer: '
' + 27 | '
{caption}
' + '{size}{progress}' + 28 | '
' + 29 | '
{indicator} {actions}
', 30 | actions: '{drag}\n' + 31 | '
\n' + 32 | ' \n' + 35 | '
', 36 | }, 37 | previewSettings: { 38 | html: {width: "100px", height: "60px"}, 39 | text: {width: "100px", height: "60px"}, 40 | video: {width: "auto", height: "60px"}, 41 | audio: {width: "auto", height: "60px"}, 42 | flash: {width: "100%", height: "60px"}, 43 | object: {width: "100%", height: "60px"}, 44 | pdf: {width: "100px", height: "60px"}, 45 | other: {width: "100%", height: "60px"} 46 | }, 47 | frameClass: 'explorer-frame' 48 | }; 49 | })); 50 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/gly/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Glyphicon (default) theme configuration for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):i("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(i){"use strict";i.fn.fileinputThemes.gly={fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},layoutTemplates:{fileIcon:''},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:' ',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/css/fileinput-rtl.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee RTL (Right To Left) default styling for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */.kv-rtl .close,.kv-rtl .krajee-default .file-actions,.kv-rtl .krajee-default .file-other-error{float:left}.kv-rtl .krajee-default .file-drag-handle,.kv-rtl .krajee-default .file-upload-indicator,.kv-rtl .krajee-default.file-preview-frame{float:right}.kv-rtl .file-error-message pre,.kv-rtl .file-error-message ul,.kv-rtl .file-zoom-dialog{text-align:right}.kv-rtl .file-zoom-dialog .kv-desc-hide{float:left}.kv-rtl{direction:rtl}.kv-rtl .floating-buttons{left:10px;right:auto}.kv-rtl .floating-buttons .btn-kv{margin-left:0;margin-right:3px}.kv-rtl .file-caption-icon{left:auto;padding:.5rem;right:4px}.kv-rtl .file-drop-zone{margin:12px 12px 12px 15px}.kv-rtl .btn-kv-prev{right:0;left:auto}.kv-rtl .btn-kv-next{left:0;right:auto}.kv-rtl .float-right,.kv-rtl .pull-right{float:left!important}.kv-rtl .float-left,.kv-rtl .pull-left{float:right!important}.kv-rtl .kv-zoom-title{direction:ltr}.kv-rtl .krajee-default.file-preview-frame{box-shadow:-1px 1px 5px 0 #a2958a}.kv-rtl .krajee-default.file-preview-frame:not(.file-preview-error):hover{box-shadow:-3px 3px 5px 0 #333}.kv-rtl .kv-zoom-actions .btn-kv{margin-left:0;margin-right:3px}.kv-rtl .file-caption.icon-visible .file-caption-name{padding-left:0;padding-right:30px}.kv-rtl .input-group>.input-group-btn:last-child>.btn:last-child{border-radius:4px 0 0 4px!important}.kv-rtl .input-group>.input-group-btn:first-child>.btn:first-child{border-radius:0 4px 4px 0!important}.kv-rtl .input-group>.btn:last-child,.kv-rtl .input-group>.form-control:last-child,.kv-rtl .input-group>.input-group-append:last-child>.btn:last-child{border-radius:.25rem 0 0 .25rem!important}.kv-rtl .input-group>.form-control:first-child,.kv-rtl .input-group>.input-group-prepend:first-child>.btn:first-child,.kv-rtl .input-group>.input-group>.btn:first-child{border-radius:0 .25rem .25rem 0!important}.kv-rtl .input-group>.file-caption-icon:first-child~.form-control:last-child{border-radius:.25rem!important}.kv-rtl .btn-file input[type=file]{left:auto;right:0;text-align:left;background:100% 0 none} -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/fa/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome icon theme configuration for bootstrap-fileinput. Requires font awesome assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function (factory) { 14 | 'use strict'; 15 | if (typeof define === 'function' && define.amd) { 16 | define(['jquery'],factory); 17 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 18 | factory(require('jquery')); 19 | } else { 20 | factory(window.jQuery); 21 | } 22 | }(function ($) { 23 | "use strict"; 24 | 25 | $.fn.fileinputThemes.fa = { 26 | fileActionSettings: { 27 | removeIcon: '', 28 | uploadIcon: '', 29 | uploadRetryIcon: '', 30 | downloadIcon: '', 31 | zoomIcon: '', 32 | dragIcon: '', 33 | indicatorNew: '', 34 | indicatorSuccess: '', 35 | indicatorError: '', 36 | indicatorLoading: '', 37 | indicatorPaused: '' 38 | }, 39 | layoutTemplates: { 40 | fileIcon: ' ' 41 | }, 42 | previewZoomButtonIcons: { 43 | prev: '', 44 | next: '', 45 | toggleheader: '', 46 | fullscreen: '', 47 | borderless: '', 48 | close: '' 49 | }, 50 | previewFileIcon: '', 51 | browseIcon: '', 52 | removeIcon: '', 53 | cancelIcon: '', 54 | pauseIcon: '', 55 | uploadIcon: '', 56 | msgValidationErrorIcon: ' ' 57 | }; 58 | })); 59 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer-fa/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput. 6 | * Load this theme file after loading `fileinput.js`. Ensure that 7 | * font awesome assets and CSS are loaded on the page as well. 8 | * 9 | * Author: Kartik Visweswaran 10 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 11 | * 12 | * Licensed under the BSD-3-Clause 13 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 14 | */!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(a){"use strict";a.fn.fileinputThemes["explorer-fa"]={layoutTemplates:{footer:'
{caption}
{size}{progress}
{indicator} {actions}
',actions:'{drag}\n
\n \n
',fileIcon:' '},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame",fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:'',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/fas/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function (factory) { 14 | 'use strict'; 15 | if (typeof define === 'function' && define.amd) { 16 | define(['jquery'],factory); 17 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 18 | factory(require('jquery')); 19 | } else { 20 | factory(window.jQuery); 21 | } 22 | }(function ($) { 23 | "use strict"; 24 | 25 | $.fn.fileinputThemes.fas = { 26 | fileActionSettings: { 27 | removeIcon: '', 28 | uploadIcon: '', 29 | uploadRetryIcon: '', 30 | downloadIcon: '', 31 | zoomIcon: '', 32 | dragIcon: '', 33 | indicatorNew: '', 34 | indicatorSuccess: '', 35 | indicatorError: '', 36 | indicatorLoading: '', 37 | indicatorPaused: '' 38 | }, 39 | layoutTemplates: { 40 | fileIcon: ' ' 41 | }, 42 | previewZoomButtonIcons: { 43 | prev: '', 44 | next: '', 45 | toggleheader: '', 46 | fullscreen: '', 47 | borderless: '', 48 | close: '' 49 | }, 50 | previewFileIcon: '', 51 | browseIcon: '', 52 | removeIcon: '', 53 | cancelIcon: '', 54 | pauseIcon: '', 55 | uploadIcon: '', 56 | msgValidationErrorIcon: ' ' 57 | }; 58 | })); 59 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer-fas/theme.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput. 6 | * Load this theme file after loading `fileinput.js`. Ensure that 7 | * font awesome assets and CSS are loaded on the page as well. 8 | * 9 | * Author: Kartik Visweswaran 10 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 11 | * 12 | * Licensed under the BSD-3-Clause 13 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 14 | */!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof module&&"object"==typeof module.exports?require("jquery"):window.jQuery)}(function(a){"use strict";a.fn.fileinputThemes["explorer-fas"]={layoutTemplates:{footer:'
{caption}
{size}{progress}
{indicator} {actions}
',actions:'{drag}\n
\n \n
',fileIcon:' '},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame",fileActionSettings:{removeIcon:'',uploadIcon:'',uploadRetryIcon:'',downloadIcon:'',zoomIcon:'',dragIcon:'',indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:''},previewZoomButtonIcons:{prev:'',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewFileIcon:'',browseIcon:'',removeIcon:'',cancelIcon:'',pauseIcon:'',uploadIcon:'',msgValidationErrorIcon:' '}}); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/bs5/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Bootstrap 5.x icon theme configuration for bootstrap-fileinput. Requires bootstrap 5.x icons CSS to be loaded. 6 | * This is used as the default theme within the bootstrap-fileinput plugin. 7 | * 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 10 | * 11 | * Licensed under the BSD-3-Clause 12 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 13 | */ 14 | (function (factory) { 15 | 'use strict'; 16 | if (typeof define === 'function' && define.amd) { 17 | define(['jquery'],factory); 18 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 19 | factory(require('jquery')); 20 | } else { 21 | factory(window.jQuery); 22 | } 23 | }(function ($) { 24 | 'use strict'; 25 | $.fn.fileinputBsVersion = '5.x.x'; 26 | $.fn.fileinputThemes.bs5 = { 27 | fileActionSettings: { 28 | removeIcon: '', 29 | uploadIcon: '', 30 | uploadRetryIcon: '', 31 | downloadIcon: '', 32 | zoomIcon: '', 33 | dragIcon: '', 34 | indicatorNew: '', 35 | indicatorSuccess: '', 36 | indicatorError: '', 37 | indicatorLoading: '', 38 | indicatorPaused: '', 39 | }, 40 | layoutTemplates: { 41 | fileIcon: '' 42 | }, 43 | previewZoomButtonIcons: { 44 | prev: '', 45 | next: '', 46 | toggleheader: '', 47 | fullscreen: '', 48 | borderless: '', 49 | close: '' 50 | }, 51 | previewFileIcon: '', 52 | browseIcon: ' ', 53 | removeIcon: '', 54 | cancelIcon: '', 55 | pauseIcon: '', 56 | uploadIcon: '', 57 | msgValidationErrorIcon: ' ' 58 | }; 59 | })); 60 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/gly/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Glyphicon (default) theme configuration for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | (function (factory) { 14 | 'use strict'; 15 | if (typeof define === 'function' && define.amd) { 16 | define(['jquery'], factory); 17 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 18 | factory(require('jquery')); 19 | } else { 20 | factory(window.jQuery); 21 | } 22 | }(function ($) { 23 | "use strict"; 24 | 25 | $.fn.fileinputThemes.gly = { 26 | fileActionSettings: { 27 | removeIcon: '', 28 | uploadIcon: '', 29 | uploadRetryIcon: '', 30 | downloadIcon: '', 31 | zoomIcon: '', 32 | dragIcon: '', 33 | indicatorNew: '', 34 | indicatorSuccess: '', 35 | indicatorError: '', 36 | indicatorLoading: '', 37 | indicatorPaused: '' 38 | }, 39 | layoutTemplates: { 40 | fileIcon: '' 41 | }, 42 | previewZoomButtonIcons: { 43 | prev: '', 44 | next: '', 45 | toggleheader: '', 46 | fullscreen: '', 47 | borderless: '', 48 | close: '' 49 | }, 50 | previewFileIcon: '', 51 | browseIcon: ' ', 52 | removeIcon: '', 53 | cancelIcon: '', 54 | pauseIcon: '', 55 | uploadIcon: '', 56 | msgValidationErrorIcon: ' ' 57 | }; 58 | })); 59 | -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/common/ApiResult.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel.common; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | import com.fasterxml.jackson.annotation.JsonInclude; 5 | 6 | /** 7 | * 异步请求返回结果封装 8 | */ 9 | public class ApiResult { 10 | 11 | private int code; 12 | private String message; 13 | @JsonInclude(JsonInclude.Include.NON_EMPTY) 14 | private Object data; 15 | 16 | public static ApiResult success() { 17 | return new ApiResult(Constant.OPERATE_SUCCESS, Constant.OPERATE_SUCCESS_STR, null); 18 | } 19 | 20 | public static ApiResult success(String message) { 21 | return new ApiResult(Constant.OPERATE_SUCCESS, message, null); 22 | } 23 | 24 | public static ApiResult success(Object data) { 25 | return new ApiResult(Constant.OPERATE_SUCCESS, Constant.OPERATE_SUCCESS_STR, data); 26 | } 27 | 28 | public static ApiResult success(String message, Object data) { 29 | return new ApiResult(Constant.OPERATE_SUCCESS, message, data); 30 | } 31 | public static ApiResult success(int code, String message, Object data) { 32 | return new ApiResult(code, message, data); 33 | } 34 | 35 | // ... 36 | 37 | public static ApiResult failure() { 38 | return new ApiResult(Constant.OPERATE_ERROR, Constant.OPERATE_ERROR_STR, null); 39 | } 40 | 41 | public static ApiResult failure(String message) { 42 | return new ApiResult(Constant.OPERATE_ERROR, message, null); 43 | } 44 | 45 | public static ApiResult failure(Object data) { 46 | return new ApiResult(Constant.OPERATE_ERROR, Constant.OPERATE_ERROR_STR, data); 47 | } 48 | 49 | public static ApiResult failure(String message, Object data) { 50 | return new ApiResult(Constant.OPERATE_ERROR, message, data); 51 | } 52 | 53 | // ... 54 | 55 | public static ApiResult failure(int code, String message) { 56 | return new ApiResult(code, message, null); 57 | } 58 | 59 | public static ApiResult failure(int code, String message, Object data) { 60 | return new ApiResult(code, message, data); 61 | } 62 | 63 | public ApiResult() { 64 | } 65 | 66 | private ApiResult(int code, String message, Object data) { 67 | this.code = code; 68 | this.message = message; 69 | this.data = data; 70 | } 71 | 72 | @JsonIgnore 73 | public boolean isSuccess() { 74 | return this.code == Constant.OPERATE_SUCCESS; 75 | } 76 | 77 | public int getCode() { 78 | return code; 79 | } 80 | 81 | public void setCode(int code) { 82 | this.code = code; 83 | } 84 | 85 | public String getMessage() { 86 | return message; 87 | } 88 | 89 | public void setMessage(String message) { 90 | this.message = message; 91 | } 92 | 93 | public Object getData() { 94 | return data; 95 | } 96 | 97 | public void setData(Object data) { 98 | this.data = data; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer/theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme style for bootstrap-fileinput. Load this theme file after loading `fileinput.css`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */.theme-explorer .file-preview-frame{border:1px solid #ddd;margin:2px 0;width:100%;display:flex;justify-content:space-between;align-items:center}.explorer-frame .file-preview-other,.theme-explorer .explorer-frame .kv-file-content,.theme-explorer .file-actions,.theme-explorer .file-drag-handle,.theme-explorer .file-upload-indicator{text-align:center}.theme-explorer .file-drag-handle,.theme-explorer .file-upload-indicator{position:absolute;display:inline-block;bottom:8px;right:4px;width:16px;height:16px;font-size:16px}.theme-explorer .explorer-caption,.theme-explorer .file-thumb-progress .progress{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.theme-explorer .file-thumb-progress .progress{margin-top:5px}.theme-explorer .explorer-caption,.theme-explorer .file-footer-buttons{padding:5px}.theme-explorer .file-footer-buttons{text-align:right}.theme-explorer .explorer-caption{color:#777;padding-top:5px}.theme-explorer .kvsortable-ghost{opacity:.6;background:#e1edf7;border:2px solid #a1abff}.theme-explorer .file-preview .table{margin:0}.theme-explorer .file-error-message ul{padding:5px 0 0 20px}.explorer-frame .file-preview-text{display:inline-block;color:#428bca;border:1px solid #ddd;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;outline:0;padding:8px;resize:none}.explorer-frame .file-preview-html{display:inline-block;border:1px solid #ddd;padding:8px;overflow:auto}.explorer-frame .file-other-icon{font-size:2.6em}.explorer-frame:not(.kv-zoom-body):hover{background-color:#f5f5f5}.theme-explorer .file-preview-frame samp{font-size:.9rem}.theme-explorer .explorer-frame .kv-file-content{width:160px;height:80px;padding:5px;text-align:left}.theme-explorer .file-details-cell{width:60%;font-size:.95rem;text-align:left;margin-right:auto}.theme-explorer .file-actions-cell{position:relative;height:80px;width:200px}.file-zoom-dialog .explorer-frame .file-other-icon{font-size:22em;font-size:50vmin}@media only screen and (max-width:1249px){.theme-explorer .file-preview-frame .file-details-cell{width:40%}}@media only screen and (max-width:1023px){.theme-explorer .file-preview-frame .file-details-cell{width:30%}}@media only screen and (max-width:767px){.theme-explorer .file-preview-frame .file-details-cell{width:200px}}@media only screen and (max-width:575px){.theme-explorer .file-preview-frame{flex-direction:column}.theme-explorer .file-preview-frame .kv-file-content{text-align:center}.theme-explorer .file-details-cell{text-align:center;margin-right:0}.theme-explorer .file-actions-cell,.theme-explorer .file-details-cell,.theme-explorer .file-preview-frame .kv-file-content{width:100%}.theme-explorer .file-actions-cell{height:auto}.theme-explorer .file-footer-buttons{text-align:left}} -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/mobile/layer.js: -------------------------------------------------------------------------------- 1 | /*! layer mobile-v2.0.0 Web 通用弹出层组件 MIT License */ 2 | ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

'+(e?n.title[0]:n.title)+"

":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
'+e+"
"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

'+(n.content||"")+"

"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
':"")+'
"+l+'
'+n.content+"
"+c+"
",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;o' + 29 | '
{caption}
' + '{size}{progress}' + 30 | '' + 31 | '
{indicator} {actions}
', 32 | actions: '{drag}\n' + 33 | '
\n' + 34 | ' \n' + 37 | '
', 38 | fileIcon: ' ' 39 | }, 40 | previewSettings: { 41 | html: {width: '100px', height: '60px'}, 42 | text: {width: '100px', height: '60px'}, 43 | video: {width: 'auto', height: '60px'}, 44 | audio: {width: 'auto', height: '60px'}, 45 | flash: {width: '100%', height: '60px'}, 46 | object: {width: '100%', height: '60px'}, 47 | pdf: {width: '100px', height: '60px'}, 48 | other: {width: '100%', height: '60px'} 49 | }, 50 | frameClass: 'explorer-frame', 51 | fileActionSettings: { 52 | removeIcon: '', 53 | uploadIcon: '', 54 | uploadRetryIcon: '', 55 | downloadIcon: '', 56 | zoomIcon: '', 57 | dragIcon: '', 58 | indicatorNew: '', 59 | indicatorSuccess: '', 60 | indicatorError: '', 61 | indicatorLoading: '', 62 | indicatorPaused: '' 63 | }, 64 | previewZoomButtonIcons: { 65 | prev: '', 66 | next: '', 67 | toggleheader: '', 68 | fullscreen: '', 69 | borderless: '', 70 | close: '' 71 | }, 72 | previewFileIcon: '', 73 | browseIcon: '', 74 | removeIcon: '', 75 | cancelIcon: '', 76 | pauseIcon: '', 77 | uploadIcon: '', 78 | msgValidationErrorIcon: ' ' 79 | }; 80 | })); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer-fas/theme.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput. 6 | * Load this theme file after loading `fileinput.js`. Ensure that 7 | * font awesome assets and CSS are loaded on the page as well. 8 | * 9 | * Author: Kartik Visweswaran 10 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 11 | * 12 | * Licensed under the BSD-3-Clause 13 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 14 | */ 15 | (function (factory) { 16 | 'use strict'; 17 | if (typeof define === 'function' && define.amd) { 18 | define(['jquery'],factory); 19 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 20 | factory(require('jquery')); 21 | } else { 22 | factory(window.jQuery); 23 | } 24 | }(function ($) { 25 | 'use strict'; 26 | $.fn.fileinputThemes['explorer-fas'] = { 27 | layoutTemplates: { 28 | footer: '
' + 29 | '
{caption}
' + '{size}{progress}' + 30 | '
' + 31 | '
{indicator} {actions}
', 32 | actions: '{drag}\n' + 33 | '
\n' + 34 | ' \n' + 37 | '
', 38 | fileIcon: ' ' 39 | }, 40 | previewSettings: { 41 | html: {width: '100px', height: '60px'}, 42 | text: {width: '100px', height: '60px'}, 43 | video: {width: 'auto', height: '60px'}, 44 | audio: {width: 'auto', height: '60px'}, 45 | flash: {width: '100%', height: '60px'}, 46 | object: {width: '100%', height: '60px'}, 47 | pdf: {width: '100px', height: '60px'}, 48 | other: {width: '100%', height: '60px'} 49 | }, 50 | frameClass: 'explorer-frame', 51 | fileActionSettings: { 52 | removeIcon: '', 53 | uploadIcon: '', 54 | uploadRetryIcon: '', 55 | downloadIcon: '', 56 | zoomIcon: '', 57 | dragIcon: '', 58 | indicatorNew: '', 59 | indicatorSuccess: '', 60 | indicatorError: '', 61 | indicatorLoading: '', 62 | indicatorPaused: '' 63 | }, 64 | previewZoomButtonIcons: { 65 | prev: '', 66 | next: '', 67 | toggleheader: '', 68 | fullscreen: '', 69 | borderless: '', 70 | close: '' 71 | }, 72 | previewFileIcon: '', 73 | browseIcon: '', 74 | removeIcon: '', 75 | cancelIcon: '', 76 | pauseIcon: '', 77 | uploadIcon: '', 78 | msgValidationErrorIcon: ' ' 79 | }; 80 | })); -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer/theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer theme style for bootstrap-fileinput. Load this theme file after loading `fileinput.css`. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */ 13 | .theme-explorer .file-preview-frame { 14 | border: 1px solid #ddd; 15 | margin: 2px 0; 16 | width: 100%; 17 | display: flex; 18 | justify-content: space-between; 19 | align-items: center; 20 | } 21 | .theme-explorer .file-actions, 22 | .theme-explorer .file-upload-indicator, .theme-explorer .file-drag-handle, .theme-explorer .explorer-frame .kv-file-content, .theme-explorer .file-actions, .explorer-frame .file-preview-other { 23 | text-align: center; 24 | } 25 | .theme-explorer .file-upload-indicator, .theme-explorer .file-drag-handle { 26 | position: absolute; 27 | display: inline-block; 28 | bottom: 8px; 29 | right: 4px; 30 | width: 16px; 31 | height: 16px; 32 | font-size: 16px; 33 | } 34 | .theme-explorer .file-thumb-progress .progress, .theme-explorer .explorer-caption { 35 | display: block; 36 | white-space: nowrap; 37 | text-overflow: ellipsis; 38 | overflow: hidden; 39 | } 40 | .theme-explorer .file-thumb-progress .progress { 41 | margin-top: 5px; 42 | } 43 | .theme-explorer .explorer-caption, 44 | .theme-explorer .file-footer-buttons { 45 | padding: 5px; 46 | } 47 | .theme-explorer .file-footer-buttons { 48 | text-align: right; 49 | } 50 | .theme-explorer .explorer-caption { 51 | color: #777; 52 | padding-top: 5px; 53 | } 54 | .theme-explorer .kvsortable-ghost { 55 | opacity: 0.6; 56 | background: #e1edf7; 57 | border: 2px solid #a1abff; 58 | } 59 | .theme-explorer .file-preview .table { 60 | margin: 0; 61 | } 62 | .theme-explorer .file-error-message ul { 63 | padding: 5px 0 0 20px; 64 | } 65 | .explorer-frame .file-preview-text { 66 | display: inline-block; 67 | color: #428bca; 68 | border: 1px solid #ddd; 69 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 70 | outline: none; 71 | padding: 8px; 72 | resize: none; 73 | } 74 | .explorer-frame .file-preview-html { 75 | display: inline-block; 76 | border: 1px solid #ddd; 77 | padding: 8px; 78 | overflow: auto; 79 | } 80 | .explorer-frame .file-other-icon { 81 | font-size: 2.6em; 82 | } 83 | .explorer-frame:not(.kv-zoom-body):hover { 84 | background-color: #f5f5f5; 85 | } 86 | .theme-explorer .file-preview-frame samp { 87 | font-size: 0.9rem; 88 | } 89 | .theme-explorer .explorer-frame .kv-file-content { 90 | width: 160px; 91 | height: 80px; 92 | padding: 5px; 93 | text-align: left; 94 | } 95 | .theme-explorer .file-details-cell { 96 | width: 60%; 97 | font-size: 0.95rem; 98 | text-align: left; 99 | margin-right: auto; 100 | } 101 | .theme-explorer .file-actions-cell { 102 | position: relative; 103 | height: 80px; 104 | width: 200px; 105 | } 106 | /*noinspection CssOverwrittenProperties*/ 107 | .file-zoom-dialog .explorer-frame .file-other-icon { 108 | font-size: 22em; 109 | font-size: 50vmin; 110 | } 111 | @media only screen and (max-width: 1249px) { 112 | .theme-explorer .file-preview-frame .file-details-cell { 113 | width: 40%; 114 | } 115 | } 116 | @media only screen and (max-width: 1023px) { 117 | .theme-explorer .file-preview-frame .file-details-cell { 118 | width: 30%; 119 | } 120 | } 121 | @media only screen and (max-width: 767px) { 122 | .theme-explorer .file-preview-frame .file-details-cell { 123 | width: 200px; 124 | } 125 | } 126 | @media only screen and (max-width: 575px) { 127 | .theme-explorer .file-preview-frame { 128 | flex-direction: column; 129 | } 130 | 131 | .theme-explorer .file-preview-frame .kv-file-content { 132 | width: auto; 133 | text-align: center; 134 | } 135 | 136 | .theme-explorer .file-details-cell { 137 | width: 100px; 138 | text-align: center; 139 | margin-right: 0; 140 | } 141 | 142 | .theme-explorer .file-preview-frame .kv-file-content, 143 | .theme-explorer .file-details-cell, 144 | .theme-explorer .file-actions-cell { 145 | width: 100%; 146 | } 147 | 148 | .theme-explorer .file-actions-cell { 149 | height: auto; 150 | } 151 | 152 | .theme-explorer .file-footer-buttons { 153 | text-align: left; 154 | } 155 | } -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer-fa/theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading 6 | * font awesome 4.x CSS and `fileinput.css`. 7 | * 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 10 | * 11 | * Licensed under the BSD-3-Clause 12 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 13 | */ 14 | .theme-explorer-fa .file-preview-frame { 15 | border: 1px solid #ddd; 16 | margin: 2px 0; 17 | width: 100%; 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | } 22 | .theme-explorer-fa .file-actions, 23 | .theme-explorer-fa .file-upload-indicator, .theme-explorer-fa .file-drag-handle, .theme-explorer-fa .explorer-frame .kv-file-content, .theme-explorer-fa .file-actions, .explorer-frame .file-preview-other { 24 | text-align: center; 25 | } 26 | .theme-explorer-fa .file-upload-indicator, .theme-explorer-fa .file-drag-handle { 27 | position: absolute; 28 | display: inline-block; 29 | bottom: 8px; 30 | right: 4px; 31 | width: 16px; 32 | height: 16px; 33 | font-size: 16px; 34 | } 35 | .theme-explorer-fa .file-thumb-progress .progress, .theme-explorer-fa .explorer-caption { 36 | display: block; 37 | white-space: nowrap; 38 | text-overflow: ellipsis; 39 | overflow: hidden; 40 | } 41 | .theme-explorer-fa .file-thumb-progress .progress { 42 | margin-top: 5px; 43 | } 44 | .theme-explorer-fa .explorer-caption, 45 | .theme-explorer-fa .file-footer-buttons { 46 | padding: 5px; 47 | } 48 | .theme-explorer-fa .file-footer-buttons { 49 | text-align: right; 50 | } 51 | .theme-explorer-fa .explorer-caption { 52 | color: #777; 53 | padding-top: 5px; 54 | } 55 | .theme-explorer-fa .kvsortable-ghost { 56 | opacity: 0.6; 57 | background: #e1edf7; 58 | border: 2px solid #a1abff; 59 | } 60 | .theme-explorer-fa .file-preview .table { 61 | margin: 0; 62 | } 63 | .theme-explorer-fa .file-error-message ul { 64 | padding: 5px 0 0 20px; 65 | } 66 | .explorer-frame .file-preview-text { 67 | display: inline-block; 68 | color: #428bca; 69 | border: 1px solid #ddd; 70 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 71 | outline: none; 72 | padding: 8px; 73 | resize: none; 74 | } 75 | .explorer-frame .file-preview-html { 76 | display: inline-block; 77 | border: 1px solid #ddd; 78 | padding: 8px; 79 | overflow: auto; 80 | } 81 | .explorer-frame .file-other-icon { 82 | font-size: 2.6em; 83 | } 84 | .explorer-frame:not(.kv-zoom-body):hover { 85 | background-color: #f5f5f5; 86 | } 87 | .theme-explorer-fa .file-preview-frame samp { 88 | font-size: 0.9rem; 89 | } 90 | .theme-explorer-fa .explorer-frame .kv-file-content { 91 | width: 160px; 92 | height: 80px; 93 | padding: 5px; 94 | text-align: left; 95 | } 96 | .theme-explorer-fa .file-details-cell { 97 | width: 60%; 98 | font-size: 0.95rem; 99 | text-align: left; 100 | margin-right: auto; 101 | } 102 | .theme-explorer-fa .file-actions-cell { 103 | position: relative; 104 | height: 80px; 105 | width: 200px; 106 | } 107 | /*noinspection CssOverwrittenProperties*/ 108 | .file-zoom-dialog .explorer-frame .file-other-icon { 109 | font-size: 22em; 110 | font-size: 50vmin; 111 | } 112 | @media only screen and (max-width: 1249px) { 113 | .theme-explorer-fa .file-preview-frame .file-details-cell { 114 | width: 40%; 115 | } 116 | } 117 | @media only screen and (max-width: 1023px) { 118 | .theme-explorer-fa .file-preview-frame .file-details-cell { 119 | width: 30%; 120 | } 121 | } 122 | @media only screen and (max-width: 767px) { 123 | .theme-explorer-fa .file-preview-frame .file-details-cell { 124 | width: 200px; 125 | } 126 | } 127 | @media only screen and (max-width: 575px) { 128 | .theme-explorer-fa .file-preview-frame { 129 | flex-direction: column; 130 | } 131 | 132 | .theme-explorer-fa .file-preview-frame .kv-file-content { 133 | width: auto; 134 | text-align: center; 135 | } 136 | 137 | .theme-explorer-fa .file-details-cell { 138 | width: 100px; 139 | text-align: center; 140 | margin-right: 0; 141 | } 142 | 143 | .theme-explorer-fa .file-preview-frame .kv-file-content, 144 | .theme-explorer-fa .file-details-cell, 145 | .theme-explorer-fa .file-actions-cell { 146 | width: 100%; 147 | } 148 | 149 | .theme-explorer-fa .file-actions-cell { 150 | height: auto; 151 | } 152 | 153 | .theme-explorer-fa .file-footer-buttons { 154 | text-align: left; 155 | } 156 | } -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/themes/explorer-fas/theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading 6 | * font awesome 5.x CSS and `fileinput.css`. 7 | * 8 | * Author: Kartik Visweswaran 9 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 10 | * 11 | * Licensed under the BSD-3-Clause 12 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 13 | */ 14 | .theme-explorer-fas .file-preview-frame { 15 | border: 1px solid #ddd; 16 | margin: 2px 0; 17 | width: 100%; 18 | display: flex; 19 | justify-content: space-between; 20 | align-items: center; 21 | } 22 | .theme-explorer-fas .file-actions, 23 | .theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle, .theme-explorer-fas .explorer-frame .kv-file-content, .theme-explorer-fas .file-actions, .explorer-frame .file-preview-other { 24 | text-align: center; 25 | } 26 | .theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle { 27 | position: absolute; 28 | display: inline-block; 29 | bottom: 8px; 30 | right: 4px; 31 | width: 16px; 32 | height: 16px; 33 | font-size: 16px; 34 | } 35 | .theme-explorer-fas .file-thumb-progress .progress, .theme-explorer-fas .explorer-caption { 36 | display: block; 37 | white-space: nowrap; 38 | text-overflow: ellipsis; 39 | overflow: hidden; 40 | } 41 | .theme-explorer-fas .file-thumb-progress .progress { 42 | margin-top: 5px; 43 | } 44 | .theme-explorer-fas .explorer-caption, 45 | .theme-explorer-fas .file-footer-buttons { 46 | padding: 5px; 47 | } 48 | .theme-explorer-fas .file-footer-buttons { 49 | text-align: right; 50 | } 51 | .theme-explorer-fas .explorer-caption { 52 | color: #777; 53 | padding-top: 5px; 54 | } 55 | .theme-explorer-fas .kvsortable-ghost { 56 | opacity: 0.6; 57 | background: #e1edf7; 58 | border: 2px solid #a1abff; 59 | } 60 | .theme-explorer-fas .file-preview .table { 61 | margin: 0; 62 | } 63 | .theme-explorer-fas .file-error-message ul { 64 | padding: 5px 0 0 20px; 65 | } 66 | .explorer-frame .file-preview-text { 67 | display: inline-block; 68 | color: #428bca; 69 | border: 1px solid #ddd; 70 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 71 | outline: none; 72 | padding: 8px; 73 | resize: none; 74 | } 75 | .explorer-frame .file-preview-html { 76 | display: inline-block; 77 | border: 1px solid #ddd; 78 | padding: 8px; 79 | overflow: auto; 80 | } 81 | .explorer-frame .file-other-icon { 82 | font-size: 2.6em; 83 | } 84 | .explorer-frame:not(.kv-zoom-body):hover { 85 | background-color: #f5f5f5; 86 | } 87 | .theme-explorer-fas .file-preview-frame samp { 88 | font-size: 0.9rem; 89 | } 90 | .theme-explorer-fas .explorer-frame .kv-file-content { 91 | width: 160px; 92 | height: 80px; 93 | padding: 5px; 94 | text-align: left; 95 | } 96 | .theme-explorer-fas .file-details-cell { 97 | width: 60%; 98 | font-size: 0.95rem; 99 | text-align: left; 100 | margin-right: auto; 101 | } 102 | .theme-explorer-fas .file-actions-cell { 103 | position: relative; 104 | height: 80px; 105 | width: 200px; 106 | } 107 | /*noinspection CssOverwrittenProperties*/ 108 | .file-zoom-dialog .explorer-frame .file-other-icon { 109 | font-size: 22em; 110 | font-size: 50vmin; 111 | } 112 | @media only screen and (max-width: 1249px) { 113 | .theme-explorer-fas .file-preview-frame .file-details-cell { 114 | width: 40%; 115 | } 116 | } 117 | @media only screen and (max-width: 1023px) { 118 | .theme-explorer-fas .file-preview-frame .file-details-cell { 119 | width: 30%; 120 | } 121 | } 122 | @media only screen and (max-width: 767px) { 123 | .theme-explorer-fas .file-preview-frame .file-details-cell { 124 | width: 200px; 125 | } 126 | } 127 | @media only screen and (max-width: 575px) { 128 | .theme-explorer-fas .file-preview-frame { 129 | flex-direction: column; 130 | } 131 | 132 | .theme-explorer-fas .file-preview-frame .kv-file-content { 133 | width: auto; 134 | text-align: center; 135 | } 136 | 137 | .theme-explorer-fas .file-details-cell { 138 | width: 100px; 139 | text-align: center; 140 | margin-right: 0; 141 | } 142 | 143 | .theme-explorer-fas .file-preview-frame .kv-file-content, 144 | .theme-explorer-fas .file-details-cell, 145 | .theme-explorer-fas .file-actions-cell { 146 | width: 100%; 147 | } 148 | 149 | .theme-explorer-fas .file-actions-cell { 150 | height: auto; 151 | } 152 | 153 | .theme-explorer-fas .file-footer-buttons { 154 | text-align: left; 155 | } 156 | } -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/mobile/need/layer.css: -------------------------------------------------------------------------------- 1 | .layui-m-layer{position:relative;z-index:19891014}.layui-m-layer *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.layui-m-layermain,.layui-m-layershade{position:fixed;left:0;top:0;width:100%;height:100%}.layui-m-layershade{background-color:rgba(0,0,0,.7);pointer-events:auto}.layui-m-layermain{display:table;font-family:Helvetica,arial,sans-serif;pointer-events:none}.layui-m-layermain .layui-m-layersection{display:table-cell;vertical-align:middle;text-align:center}.layui-m-layerchild{position:relative;display:inline-block;text-align:left;background-color:#fff;font-size:14px;border-radius:5px;box-shadow:0 0 8px rgba(0,0,0,.1);pointer-events:auto;-webkit-overflow-scrolling:touch;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layui-m-anim-scale{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.layui-m-anim-scale{animation-name:layui-m-anim-scale;-webkit-animation-name:layui-m-anim-scale}@-webkit-keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layui-m-anim-up{0%{opacity:0;-webkit-transform:translateY(800px);transform:translateY(800px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}.layui-m-anim-up{-webkit-animation-name:layui-m-anim-up;animation-name:layui-m-anim-up}.layui-m-layer0 .layui-m-layerchild{width:90%;max-width:640px}.layui-m-layer1 .layui-m-layerchild{border:none;border-radius:0}.layui-m-layer2 .layui-m-layerchild{width:auto;max-width:260px;min-width:40px;border:none;background:0 0;box-shadow:none;color:#fff}.layui-m-layerchild h3{padding:0 10px;height:60px;line-height:60px;font-size:16px;font-weight:400;border-radius:5px 5px 0 0;text-align:center}.layui-m-layerbtn span,.layui-m-layerchild h3{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.layui-m-layercont{padding:50px 30px;line-height:22px;text-align:center}.layui-m-layer1 .layui-m-layercont{padding:0;text-align:left}.layui-m-layer2 .layui-m-layercont{text-align:center;padding:0;line-height:0}.layui-m-layer2 .layui-m-layercont i{width:25px;height:25px;margin-left:8px;display:inline-block;background-color:#fff;border-radius:100%;-webkit-animation:layui-m-anim-loading 1.4s infinite ease-in-out;animation:layui-m-anim-loading 1.4s infinite ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both}.layui-m-layerbtn,.layui-m-layerbtn span{position:relative;text-align:center;border-radius:0 0 5px 5px}.layui-m-layer2 .layui-m-layercont p{margin-top:20px}@-webkit-keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}@keyframes layui-m-anim-loading{0%,100%,80%{transform:scale(0);-webkit-transform:scale(0)}40%{transform:scale(1);-webkit-transform:scale(1)}}.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0;-webkit-animation-delay:-.32s;animation-delay:-.32s}.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay:-.16s;animation-delay:-.16s}.layui-m-layer2 .layui-m-layercont>div{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/js/locales/zh.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * FileInput Chinese Translations 3 | * 4 | * This file must be loaded after 'fileinput.js'. Patterns in braces '{}', or 5 | * any HTML markup tags in the messages must not be converted or translated. 6 | * 7 | * @see http://github.com/kartik-v/bootstrap-fileinput 8 | * @author kangqf 9 | * 10 | * NOTE: this file must be saved in UTF-8 encoding. 11 | */ 12 | (function (factory) { 13 | 'use strict'; 14 | if (typeof define === 'function' && define.amd) { 15 | define(['jquery'], factory); 16 | } else if (typeof module === 'object' && typeof module.exports === 'object') { 17 | factory(require('jquery')); 18 | } else { 19 | factory(window.jQuery); 20 | } 21 | }(function ($) { 22 | "use strict"; 23 | 24 | $.fn.fileinputLocales['zh'] = { 25 | sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], 26 | bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'], 27 | fileSingle: '文件', 28 | filePlural: '个文件', 29 | browseLabel: '选择 …', 30 | removeLabel: '移除', 31 | removeTitle: '清除选中文件', 32 | cancelLabel: '取消', 33 | cancelTitle: '取消进行中的上传', 34 | pauseLabel: '暂停', 35 | pauseTitle: '暂停上传', 36 | uploadLabel: '上传', 37 | uploadTitle: '上传选中文件', 38 | msgNo: '没有', 39 | msgNoFilesSelected: '未选择文件', 40 | msgPaused: '已暂停', 41 | msgCancelled: '取消', 42 | msgPlaceholder: '选择 {files} ...', 43 | msgZoomModalHeading: '详细预览', 44 | msgFileRequired: '必须选择一个文件上传.', 45 | msgSizeTooSmall: '文件 "{name}" ({size} KB) 必须大于限定大小 {minSize} KB.', 46 | msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB.', 47 | msgFilesTooLess: '你必须选择最少 {n} {files} 来上传. ', 48 | msgFilesTooMany: '选择的上传文件个数 ({n}) 超出最大文件的限制个数 {m}.', 49 | msgTotalFilesTooMany: '你最多可以上传 {m} 个文件 (当前有{n} 个文件).', 50 | msgFileNotFound: '文件 "{name}" 未找到!', 51 | msgFileSecured: '安全限制,为了防止读取文件 "{name}".', 52 | msgFileNotReadable: '文件 "{name}" 不可读.', 53 | msgFilePreviewAborted: '取消 "{name}" 的预览.', 54 | msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', 55 | msgInvalidFileName: '文件名 "{name}" 包含非法字符.', 56 | msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', 57 | msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', 58 | msgFileTypes: { 59 | 'image': 'image', 60 | 'html': 'HTML', 61 | 'text': 'text', 62 | 'video': 'video', 63 | 'audio': 'audio', 64 | 'flash': 'flash', 65 | 'pdf': 'PDF', 66 | 'object': 'object' 67 | }, 68 | msgUploadAborted: '该文件上传被中止', 69 | msgUploadThreshold: '处理中 …', 70 | msgUploadBegin: '正在初始化 …', 71 | msgUploadEnd: '完成', 72 | msgUploadResume: '继续上传 …', 73 | msgUploadEmpty: '无效的文件上传.', 74 | msgUploadError: '上传出错', 75 | msgDeleteError: '删除出错', 76 | msgProgressError: '上传出错', 77 | msgValidationError: '验证错误', 78 | msgLoading: '加载第 {index} 文件 共 {files} …', 79 | msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', 80 | msgSelected: '{n} {files} 选中', 81 | msgProcessing: '处理中 ...', 82 | msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', 83 | msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.', 84 | msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', 85 | msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.', 86 | msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', 87 | msgImageResizeError: '无法获取的图像尺寸调整。', 88 | msgImageResizeException: '调整图像大小时发生错误。
{errors}
', 89 | msgAjaxError: '{operation} 发生错误. 请重试!', 90 | msgAjaxProgressError: '{operation} 失败', 91 | msgDuplicateFile: '文件 "{name}",大小 "{size} KB" 已经被选中.忽略相同的文件.', 92 | msgResumableUploadRetriesExceeded: '文件 {file} 上传失败超过 {max} 次重试 ! 错误详情:
{error}
', 93 | msgPendingTime: '{time} 剩余', 94 | msgCalculatingTime: '计算剩余时间', 95 | ajaxOperations: { 96 | deleteThumb: '删除文件', 97 | uploadThumb: '上传文件', 98 | uploadBatch: '批量上传', 99 | uploadExtra: '表单数据上传' 100 | }, 101 | dropZoneTitle: '拖拽文件到这里 …
支持多文件同时上传', 102 | dropZoneClickTitle: '
(或点击{files}按钮选择文件)', 103 | fileActionSettings: { 104 | removeTitle: '删除文件', 105 | uploadTitle: '上传文件', 106 | downloadTitle: '下载文件', 107 | uploadRetryTitle: '重试', 108 | zoomTitle: '查看详情', 109 | dragTitle: '移动 / 重置', 110 | indicatorNewTitle: '没有上传', 111 | indicatorSuccessTitle: '上传', 112 | indicatorErrorTitle: '上传错误', 113 | indicatorPausedTitle: '上传已暂停', 114 | indicatorLoadingTitle: '上传 …' 115 | }, 116 | previewZoomButtonTitles: { 117 | prev: '预览上一个文件', 118 | next: '预览下一个文件', 119 | toggleheader: '缩放', 120 | fullscreen: '全屏', 121 | borderless: '无边界模式', 122 | close: '关闭当前预览' 123 | } 124 | }; 125 | })); 126 | -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/MainController.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel; 2 | 3 | import cn.hutool.core.io.FileUtil; 4 | import cn.hutool.core.util.*; 5 | import cn.hutool.extra.servlet.ServletUtil; 6 | import com.mueeee.unpackerpanel.common.ApiResult; 7 | import com.mueeee.unpackerpanel.common.MD5Util; 8 | import net.dongliu.apk.parser.ApkFile; 9 | import net.dongliu.apk.parser.bean.ApkMeta; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.util.StringUtils; 14 | import org.springframework.web.bind.annotation.GetMapping; 15 | import org.springframework.web.bind.annotation.PathVariable; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.bind.annotation.ResponseBody; 18 | import org.springframework.web.multipart.MultipartFile; 19 | 20 | import javax.servlet.http.Cookie; 21 | import javax.servlet.http.HttpServletRequest; 22 | import javax.servlet.http.HttpServletResponse; 23 | import java.io.File; 24 | import java.nio.charset.Charset; 25 | import java.nio.file.Paths; 26 | import java.text.MessageFormat; 27 | import java.util.Base64; 28 | import java.util.HashMap; 29 | 30 | /** 31 | * Main Controller 32 | */ 33 | @Controller 34 | public class MainController { 35 | 36 | private static final Logger log = LoggerFactory.getLogger(MainController.class); 37 | 38 | // 根目录 39 | public static final String ROOT_DIR = new File("").getAbsolutePath(); 40 | // 文件上传目录 41 | public static final String UPLOAD_DIR = ROOT_DIR + File.separator + "uploads"; 42 | 43 | @GetMapping("/") 44 | public String index(HttpServletRequest request) { 45 | Cookie theme = ServletUtil.getCookie(request, "theme"); 46 | if (theme != null && StrUtil.isNotEmpty(theme.getValue())) { 47 | request.setAttribute("theme", theme.getValue()); 48 | } 49 | 50 | // QQGroup num 51 | // System.out.println(Base64.getEncoder().encodeToString("190033401".getBytes(Charset.defaultCharset()))); 52 | var QQGroupNum = new String(Base64.getDecoder().decode("MTkwMDMzNDAx"), Charset.defaultCharset()); 53 | request.setAttribute("QQGroupNum", QQGroupNum); 54 | 55 | // QQGroup QRCode 56 | // System.out.println(Base64.getEncoder().encodeToString("/assets/img/qq-group.png".getBytes(Charset.defaultCharset()))); 57 | var QQGroupQRCode = new String(Base64.getDecoder().decode("L2Fzc2V0cy9pbWcvcXEtZ3JvdXAucG5n"), Charset.defaultCharset()); 58 | request.setAttribute("QQGroupQRCode", QQGroupQRCode); 59 | 60 | return "index"; 61 | } 62 | 63 | @ResponseBody 64 | @PostMapping("/upload") 65 | public Object upload(MultipartFile file) { 66 | try { 67 | // 如果不存在则创建 68 | FileUtil.mkdir(UPLOAD_DIR); 69 | // 临时路径 70 | String tmpFilePath = UPLOAD_DIR + File.separator + "app.apk"; 71 | // 保存文件 72 | File tmpFile = FileUtil.writeFromStream(file.getInputStream(), tmpFilePath); 73 | // 计算文件md5 74 | String tmpFileMd5 = MD5Util.md5(tmpFile); 75 | // 以文件md5值创建新文件夹 76 | String uploadFileDir = UPLOAD_DIR + File.separator + tmpFileMd5; 77 | FileUtil.mkdir(uploadFileDir); 78 | // tmp.apk 移动到 fileMd5Dir 79 | FileUtil.move(Paths.get(tmpFilePath), Paths.get(uploadFileDir), true); 80 | // 上传文件路径(最终) 81 | String uploadFilePath = uploadFileDir + File.separator + "app.apk"; 82 | 83 | // 解析App 84 | log.info("===================================================================================================="); 85 | log.info("解析App..."); 86 | ApkFile apkFile = null; 87 | ApkMeta apkMeta = null; 88 | try { 89 | apkFile = new ApkFile(new File(uploadFilePath)); 90 | apkMeta = apkFile.getApkMeta(); 91 | } catch (Exception e) { 92 | log.error("App信息解析失败,{}", e.getMessage()); 93 | } finally { 94 | if (apkFile != null) { 95 | apkFile.close(); 96 | } 97 | } 98 | if (apkFile == null || apkMeta == null || !StringUtils.hasLength(apkMeta.getPackageName())) { 99 | try { 100 | FileUtil.del(uploadFileDir); 101 | } catch (Exception ignored) { 102 | } 103 | return ApiResult.failure("App信息解析失败"); 104 | } 105 | log.info("解析成功,名字: {}, 包名: {}", apkMeta.getLabel(), apkMeta.getPackageName()); 106 | 107 | // 脱壳任务 108 | var unpackBeginTime = System.currentTimeMillis(); 109 | ApiResult taskResult = Unpacker.unpack(uploadFilePath, apkMeta); 110 | var unpackUseTime = (System.currentTimeMillis() - unpackBeginTime) / 1000; 111 | // 任务失败,删除文件目录,返回响应 112 | if (!taskResult.isSuccess()) { 113 | try { 114 | FileUtil.del(uploadFileDir); 115 | } catch (Exception ignored) { 116 | } 117 | return taskResult; 118 | } 119 | 120 | // 压缩unpacker目录 121 | String unpackerDir = uploadFileDir + File.separator + "unpacker"; 122 | if (!FileUtil.exist(unpackerDir)) { 123 | return ApiResult.failure("设备未连接或其他异常..."); 124 | } 125 | ZipUtil.zip(unpackerDir); 126 | // 删除unpacker目录 127 | FileUtil.del(unpackerDir); 128 | // ... 129 | var name = MessageFormat.format("{0}-{1}.zip", apkMeta.getPackageName(), tmpFileMd5); 130 | var link = "/download/" + tmpFileMd5; 131 | return ApiResult.success(new HashMap(){{ 132 | put("time", unpackUseTime); // 耗时 133 | put("name", name); // 下载文件名 134 | put("link", link); // 下载链接 135 | }}); 136 | } catch (Exception e) { 137 | e.printStackTrace(); 138 | return ApiResult.failure(e.getMessage()); 139 | } 140 | } 141 | 142 | @GetMapping("/download/{id}") 143 | public void download(HttpServletResponse response, @PathVariable String id) { 144 | if (StrUtil.isEmpty(id)) { 145 | return; 146 | } 147 | 148 | var zipPath = UPLOAD_DIR + File.separator + id + File.separator + "unpacker.zip"; 149 | if (!FileUtil.exist(zipPath)) { 150 | return; 151 | } 152 | 153 | try { 154 | var contentType = ObjectUtil.defaultIfNull(FileUtil.getMimeType(zipPath), "application/octet-stream"); 155 | var fileName = MessageFormat.format("{0}.zip", id); 156 | ServletUtil.write(response, FileUtil.getInputStream(zipPath), contentType, fileName); 157 | } catch (Exception ignored) { 158 | } 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.0 9 | 10 | 11 | com.mueeee 12 | unpacker-panel 13 | 1.0 14 | unpacker-panel 15 | Unpacker Panel project for Spring Boot 16 | 17 | 18 | UTF-8 19 | 17 20 | ${java.version} 21 | ${java.version} 22 | 22.1.0 23 | 0.9.11 24 | 0.12.0 25 | com.mueeee.unpackerpanel.Application 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | org.apache.tomcat.embed 35 | tomcat-embed-core 36 | 37 | 38 | org.apache.tomcat.embed 39 | tomcat-embed-websocket 40 | 41 | 42 | 43 | 44 | 45 | org.apache.tomcat.experimental 46 | tomcat-embed-programmatic 47 | 9.0.56 48 | 49 | 50 | org.springframework.experimental 51 | spring-native 52 | ${spring.native.plugin.version} 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-thymeleaf 58 | 59 | 60 | org.springframework 61 | spring-context-indexer 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-starter-test 66 | test 67 | 68 | 69 | 70 | net.dongliu 71 | apk-parser 72 | 2.6.10 73 | 74 | 75 | cn.hutool 76 | hutool-json 77 | 5.7.17 78 | 79 | 80 | cn.hutool 81 | hutool-extra 82 | 5.7.17 83 | 84 | 85 | commons-codec 86 | commons-codec 87 | 1.15 88 | 89 | 90 | 91 | 92 | 93 | 94 | org.graalvm.buildtools 95 | native-maven-plugin 96 | ${native.maven.plugin.version} 97 | 98 | false 99 | false 100 | ${project.artifactId} 101 | ${start-class} 102 | 103 | --no-fallback 104 | 105 | 106 | true 107 | 108 | 109 | 110 | build 111 | 112 | package 113 | 114 | 115 | 116 | 117 | org.springframework.experimental 118 | spring-aot-maven-plugin 119 | ${spring.native.plugin.version} 120 | 121 | 126 | native 127 | 128 | 129 | 130 | generate 131 | 132 | generate 133 | 134 | 135 | 136 | 137 | 138 | org.springframework.boot 139 | spring-boot-maven-plugin 140 | 141 | 142 | 143 | gcr.io/paketo-buildpacks/java-native-image:${graalvm.version} 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | spring-release 154 | Spring release 155 | https://repo.spring.io/release 156 | 157 | 158 | 159 | 160 | 161 | spring-release 162 | Spring release 163 | https://repo.spring.io/release 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 124 | 125 | FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 162 | if ERRORLEVEL 1 goto error 163 | goto end 164 | 165 | :error 166 | set ERROR_CODE=1 167 | 168 | :end 169 | @endlocal & set ERROR_CODE=%ERROR_CODE% 170 | 171 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 172 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 173 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 174 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 175 | :skipRcPost 176 | 177 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 178 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 179 | 180 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 181 | 182 | exit /B %ERROR_CODE% 183 | -------------------------------------------------------------------------------- /src/main/java/com/mueeee/unpackerpanel/Unpacker.java: -------------------------------------------------------------------------------- 1 | package com.mueeee.unpackerpanel; 2 | 3 | import cn.hutool.core.thread.ThreadUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.mueeee.unpackerpanel.common.ApiResult; 6 | import net.dongliu.apk.parser.bean.ApkMeta; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.io.BufferedReader; 11 | import java.io.File; 12 | import java.io.IOException; 13 | import java.io.InputStreamReader; 14 | import java.text.MessageFormat; 15 | import java.util.Arrays; 16 | import java.util.concurrent.Future; 17 | import java.util.concurrent.atomic.AtomicBoolean; 18 | import java.util.regex.Pattern; 19 | 20 | public class Unpacker { 21 | 22 | private static final Logger log = LoggerFactory.getLogger(Unpacker.class); 23 | 24 | public static Process exec(String command, boolean isShell) throws IOException { 25 | StringBuilder sb = new StringBuilder("adb "); 26 | // 是否指定设备编号 27 | if (StrUtil.isNotEmpty(AppRunner.APP_DEVICE)) { 28 | sb.append(MessageFormat.format("-s {0} ", AppRunner.APP_DEVICE)); 29 | } 30 | // 是否shell,加双引号 31 | if (isShell) { 32 | command = MessageFormat.format("shell \"{0}\"", command); 33 | } 34 | sb.append(command); 35 | // 完整命令 36 | String fullCommand = sb.toString(); 37 | // 判断操作系统 38 | String commander = ""; 39 | String arg1 = ""; 40 | String osName = System.getProperty("os.name"); 41 | if (Pattern.matches("Windows.*", osName)) { 42 | commander = "cmd.exe"; 43 | arg1 = "/c"; 44 | } else if (Pattern.matches("Linux.*", osName)) { 45 | commander = "/bin/sh"; 46 | arg1 = "-c"; 47 | // Linux上$符需要做特殊转义,把 $ 符号 替换为 \$ 48 | fullCommand = fullCommand.replaceAll("\\$", "\\\\\\$"); 49 | } else if (Pattern.matches("Mac.*", osName)) { 50 | // Mac暂未测试,先按照Linux的设置来 51 | commander = "/bin/sh"; 52 | arg1 = "-c"; 53 | // Linux上$符需要做特殊转义,把 $ 符号 替换为 \$ 54 | fullCommand = fullCommand.replaceAll("\\$", "\\\\\\$"); 55 | } 56 | // 最终命令 57 | String[] finalCommand = new String[] {commander,arg1, fullCommand}; 58 | log.debug("{}", Arrays.toString(finalCommand)); 59 | return Runtime.getRuntime().exec(finalCommand); 60 | } 61 | 62 | public static ApiResult unpack(String APK_PATH, ApkMeta apkMeta) { 63 | var APK_PACKAGE = apkMeta.getPackageName(); 64 | 65 | var startTimeMillis = System.currentTimeMillis(); 66 | log.info("===================================================================================================="); 67 | log.info("任务开始"); 68 | try { 69 | // 卸載App 70 | // log.info("卸載App"); 71 | exec(MessageFormat.format("pm uninstall {0} > /dev/null 2>&1", APK_PACKAGE), true).waitFor(); 72 | // 安裝App 73 | log.info("安裝App"); 74 | exec(MessageFormat.format("install {0}", APK_PATH), false).waitFor(); 75 | // 赋予权限 76 | // log.info("赋予权限"); 77 | exec(MessageFormat.format("LIST=$(dumpsys package {0} | tr '' '' ''\\n'' | grep ''^android.permission.'' | grep -v '':$''); PERMS=$(pm list permissions -d -g); for i in $LIST; do if echo $PERMS | grep -q $i; then echo grant $i; pm grant {1} $i; fi; done;", APK_PACKAGE, APK_PACKAGE), true).waitFor(); 78 | // 配置包名 79 | // log.info("配置包名,{}", APK_PACKAGE); 80 | exec(MessageFormat.format("echo {0} > /data/local/tmp/unpacker.config", APK_PACKAGE), true).waitFor(); 81 | // 清理日志 82 | // log.info("清理日志"); 83 | exec("logcat -c", true).waitFor(); 84 | // 打开App 85 | log.info("打开App"); 86 | exec(MessageFormat.format("am start -S $(dumpsys package {0} | grep -A 1 android.intent.action.MAIN | tr '' '' ''\\n'' | grep ''/'')", APK_PACKAGE), true).waitFor(); 87 | 88 | // 监听日志... 89 | log.info("监听日志..."); 90 | var beginTime = System.currentTimeMillis(); 91 | final AtomicBoolean isBegin = new AtomicBoolean(false); 92 | final AtomicBoolean isEnd = new AtomicBoolean(false); 93 | // 启动监听日志的线程 94 | Future futureTask = ThreadUtil.execAsync(() -> { 95 | var process = exec("logcat -s unpacker", true); 96 | var bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); 97 | var line = ""; 98 | while ((line = bufferedReader.readLine()) != null) { 99 | // log.debug("- " + line); 100 | // [unpack:415]unpack begin! || [unpack:424]unpack end! 101 | if (line.contains("]unpack begin!")) { 102 | isBegin.set(true); 103 | log.info("- 监听到脱壳开始日志,{}", line); 104 | } else if (line.contains("]unpack end!")) { 105 | isEnd.set(true); 106 | log.info("- 监听到脱壳结束日志,{}", line); 107 | break; 108 | } 109 | } 110 | bufferedReader.close(); 111 | return 1; 112 | }); 113 | // 等待 begin,超时时间20秒 114 | while (true) { 115 | //noinspection BusyWait 116 | Thread.sleep(1000); 117 | if (!isBegin.get()) { 118 | if ((System.currentTimeMillis() - beginTime) > 20 * 1000) { 119 | futureTask.cancel(true); 120 | break; 121 | } 122 | } else { 123 | break; 124 | } 125 | } 126 | // 如果等待到 begin,开始等待 end,重置开始时间,超时时间60秒,否则跳过 127 | if (isBegin.get()) { 128 | beginTime = System.currentTimeMillis(); 129 | while (true) { 130 | //noinspection BusyWait 131 | Thread.sleep(1000); 132 | if (!isEnd.get()) { 133 | if ((System.currentTimeMillis() - beginTime) > 60 * 1000) { 134 | futureTask.cancel(true); 135 | break; 136 | } 137 | } else { 138 | break; 139 | } 140 | } 141 | } 142 | // 日志监听结果最终判定 143 | log.info("监听结束,isBegin: {},isEnd: {}", isBegin.get(), isEnd.get()); 144 | if (!isBegin.get()) { 145 | ApiResult tmp = ApiResult.failure("脱壳失败,等待“unpack begin”日志超时(> 20s)"); 146 | log.error(tmp.getMessage()); 147 | interruptClean(APK_PACKAGE, startTimeMillis); 148 | return tmp; 149 | } 150 | if (!isEnd.get()) { 151 | ApiResult tmp = ApiResult.failure("脱壳失败,等待“unpack end”日志超时(> 60s)"); 152 | log.error(tmp.getMessage()); 153 | interruptClean(APK_PACKAGE, startTimeMillis); 154 | return tmp; 155 | } 156 | 157 | // 拉取dex 158 | var pullToPath = new File(APK_PATH).getParent() + File.separator + "unpacker"; 159 | log.info("拉取dex"); 160 | exec(MessageFormat.format("pull /data/data/{0}/unpacker {1}", APK_PACKAGE, pullToPath), false).waitFor(); 161 | // 卸载App 162 | log.info("卸載App"); 163 | exec(MessageFormat.format("pm uninstall {0} > /dev/null 2>&1", APK_PACKAGE), true).waitFor(); 164 | // 清理dex 165 | // log.info("清理dex"); 166 | exec(MessageFormat.format("rm -rf /data/data/{0}/unpacker", APK_PACKAGE), true); 167 | // 打印耗时 168 | var timeConsuming = (System.currentTimeMillis() - startTimeMillis) / 1000; 169 | log.info("任务结束,耗时:{}s", timeConsuming); 170 | 171 | return ApiResult.success(); 172 | } catch (Exception e) { 173 | // e.printStackTrace(); 174 | log.error("任务异常,{}", e.getMessage()); 175 | try { 176 | interruptClean(APK_PACKAGE, startTimeMillis); 177 | } catch (Exception ignored) { 178 | } 179 | return ApiResult.failure("任务异常:" + e.getMessage()); 180 | } 181 | } 182 | 183 | private static void interruptClean(String APK_PACKAGE, long startTimeMillis) throws IOException, InterruptedException { 184 | // 卸载App 185 | log.info("卸載App"); 186 | exec(MessageFormat.format("pm uninstall {0} > /dev/null 2>&1", APK_PACKAGE), true).waitFor(); 187 | // 打印耗时 188 | var timeConsuming = (System.currentTimeMillis() - startTimeMillis) / 1000; 189 | log.info("任务结束,耗时:{}s", timeConsuming); 190 | } 191 | 192 | } 193 | -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Unpacker Panel 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 | 29 |  Unpacker Panel 30 | 31 |
32 |
33 |
34 | 43 |
44 |
45 |
46 | 47 | 48 |
49 |

在线一键脱壳

50 |

Online one-click shelling

51 |
52 | 53 | 54 |
55 |
56 |
57 |
58 |
59 | 60 | 61 |
62 | 66 |
67 |
68 |
69 |
70 |
脱壳信息
71 |
72 |

等待上传APK ...

73 |
74 |
75 |
76 |
77 | 78 | 83 | 84 | 85 |
86 | 87 | 88 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/bootstrap-fileinput/css/fileinput.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * bootstrap-fileinput v5.2.7 3 | * http://plugins.krajee.com/file-input 4 | * 5 | * Krajee default styling for bootstrap-fileinput. 6 | * 7 | * Author: Kartik Visweswaran 8 | * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com 9 | * 10 | * Licensed under the BSD-3-Clause 11 | * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md 12 | */.btn-file input[type=file],.file-caption-icon,.file-no-browse,.file-preview .fileinput-remove,.file-zoom-dialog .btn-navigate,.file-zoom-dialog .floating-buttons,.krajee-default .file-thumb-progress{position:absolute}.file-loading input[type=file],input[type=file].file-loading{width:0;height:0}.file-no-browse{left:50%;bottom:20%;width:1px;height:1px;font-size:0;opacity:0;border:none;background:0 0;outline:0;box-shadow:none}.file-caption-icon,.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-ajax-new .no-browse .input-group-btn,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file,.file-input-new .no-browse .input-group-btn,.file-zoom-dialog .modal-header:after,.file-zoom-dialog .modal-header:before,.hide-content .kv-file-content,.is-locked .fileinput-remove-button,.is-locked .fileinput-upload-button,.kv-hidden{display:none}.file-caption-icon .kv-caption-icon{line-height:inherit}.btn-file,.file-caption,.file-input,.file-loading:before,.file-preview,.file-zoom-dialog .modal-dialog,.krajee-default .file-thumbnail-footer,.krajee-default.file-preview-frame{position:relative}.file-error-message pre,.file-error-message ul,.krajee-default .file-actions,.krajee-default .file-other-error{text-align:left}.file-error-message pre,.file-error-message ul{margin:0}.krajee-default .file-drag-handle,.krajee-default .file-upload-indicator{float:left;margin-top:10px;width:16px;height:16px}.file-thumb-progress .progress,.file-thumb-progress .progress-bar{font-family:Verdana,Helvetica,sans-serif;font-size:.7rem}.krajee-default .file-thumb-progress .progress,.kv-upload-progress .progress{background-color:#ccc}.krajee-default .file-caption-info,.krajee-default .file-size-info{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;height:15px;margin:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-image,.file-zoom-content>.file-object.type-video{max-width:100%;max-height:100%;width:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-video{height:100%}.file-zoom-content>.file-object.type-default,.file-zoom-content>.file-object.type-html,.file-zoom-content>.file-object.type-pdf,.file-zoom-content>.file-object.type-text{width:100%}.file-loading:before{content:" Loading...";display:inline-block;padding-left:20px;line-height:16px;font-size:13px;font-variant:small-caps;color:#999;background:url(../img/loading.gif) top left no-repeat}.file-object{margin:0 0 -5px;padding:0}.btn-file{overflow:hidden}.btn-file input[type=file]{top:0;left:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:none;cursor:inherit;display:block}.btn-file ::-ms-browse{font-size:10000px;width:100%;height:100%}.file-caption.icon-visible .file-caption-icon{display:inline-block}.file-caption.icon-visible .file-caption-name{padding-left:25px}.file-caption.icon-visible>.input-group-lg .file-caption-name{padding-left:30px}.file-caption.icon-visible>.input-group-sm .file-caption-name{padding-left:22px}.file-caption-name:not(.file-caption-disabled){background-color:transparent}.file-caption-name.file-processing{font-style:italic;border-color:#bbb;opacity:.5}.file-caption-icon{padding:7px 5px;left:4px}.input-group-lg .file-caption-icon{font-size:1.25rem}.input-group-sm .file-caption-icon{font-size:.875rem;padding:.25rem}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#eee;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:8px;width:100%;margin-bottom:5px}.file-preview .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.file-preview .fileinput-remove{top:1px;right:1px;line-height:10px}.file-preview .clickable{cursor:pointer}.file-preview-image{font:40px Impact,Charcoal,sans-serif;color:green;width:auto;height:auto;max-width:100%;max-height:100%}.krajee-default.file-preview-frame{margin:8px;border:1px solid rgba(0,0,0,.2);box-shadow:0 0 10px 0 rgba(0,0,0,.2);padding:6px;float:left;text-align:center}.krajee-default.file-preview-frame .kv-file-content{width:213px;height:160px}.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:400px}.krajee-default.file-preview-frame[data-template=audio] .kv-file-content{width:240px;height:55px}.krajee-default.file-preview-frame .file-thumbnail-footer{height:70px}.krajee-default.file-preview-frame:not(.file-preview-error):hover{border:1px solid rgba(0,0,0,.3);box-shadow:0 0 10px 0 rgba(0,0,0,.4)}.krajee-default .file-preview-text{color:#428bca;border:1px solid #ddd;outline:0;resize:none}.krajee-default .file-preview-html{border:1px solid #ddd}.krajee-default .file-other-icon{font-size:6em;line-height:1}.krajee-default .file-footer-buttons{float:right}.krajee-default .file-footer-caption{display:block;text-align:center;padding-top:4px;font-size:11px;color:#777;margin-bottom:30px}.file-upload-stats{font-size:10px;text-align:center;width:100%}.kv-upload-progress .file-upload-stats{font-size:12px;margin:-10px 0 5px}.krajee-default .file-preview-error{opacity:.65;box-shadow:none}.krajee-default .file-thumb-progress{top:37px;left:0;right:0}.krajee-default.kvsortable-ghost{background:#e1edf7;border:2px solid #a1abff}.krajee-default .file-preview-other:hover{opacity:.8}.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.kv-upload-progress .progress{height:20px;margin:10px 0;overflow:hidden}.kv-upload-progress .progress-bar{height:20px;font-family:Verdana,Helvetica,sans-serif}.file-zoom-dialog .file-other-icon{font-size:22em;font-size:50vmin}.file-zoom-dialog .modal-dialog{width:auto}.file-zoom-dialog .modal-header{display:flex;align-items:center;justify-content:space-between}.file-zoom-dialog .btn-navigate{margin:0 .1rem;padding:0;font-size:1.2rem;width:2.4rem;height:2.4rem;top:50%;border-radius:50%;text-align:center}.btn-navigate *{width:auto}.file-zoom-dialog .floating-buttons{top:5px;right:10px}.file-zoom-dialog .btn-kv-prev{left:0}.file-zoom-dialog .btn-kv-next{right:0}.file-zoom-dialog .kv-zoom-header{padding:.5rem}.file-zoom-dialog .kv-zoom-body{padding:.25rem}.file-zoom-dialog .kv-zoom-description{position:absolute;opacity:.8;font-size:.8rem;background-color:#1a1a1a;padding:1rem;text-align:center;border-radius:.5rem;color:#fff;left:15%;right:15%;bottom:15%}.file-zoom-dialog .kv-desc-hide{float:right;color:#fff;padding:0 .1rem;background:0 0;border:none}.file-zoom-dialog .kv-desc-hide:hover{opacity:.7}.file-zoom-dialog .kv-desc-hide:focus{opacity:.9}.file-input-ajax-new .no-browse .form-control,.file-input-new .no-browse .form-control{border-top-right-radius:4px;border-bottom-right-radius:4px}.file-caption{width:100%;position:relative}.file-thumb-loading{background:url(../img/loading.gif) center center no-repeat content-box!important}.file-drop-zone{border:1px dashed #aaa;min-height:260px;border-radius:4px;text-align:center;vertical-align:middle;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone.clickable:hover{border:2px dashed #999}.file-drop-zone.clickable:focus{border:2px solid #5acde2}.file-drop-zone .file-preview-thumbnails{cursor:default}.file-drop-zone-title{color:#aaa;font-size:1.6em;text-align:center;padding:85px 10px;cursor:default}.file-highlighted{border:2px dashed #999!important;background-color:#eee}.file-uploading{background:url(../img/loading-sm.gif) center bottom 10px no-repeat;opacity:.65}.file-zoom-fullscreen .modal-dialog{min-width:100%;margin:0}.file-zoom-fullscreen .modal-content{border-radius:0;box-shadow:none;min-height:100vh}.file-zoom-fullscreen .kv-zoom-body{overflow-y:auto}.floating-buttons{z-index:3000}.floating-buttons .btn-kv{margin-left:3px;z-index:3000}.kv-zoom-actions{min-width:140px}.kv-zoom-actions .btn-kv{margin-left:3px}.file-zoom-content{text-align:center;white-space:nowrap;min-height:300px}.file-zoom-content:hover{background:0 0}.file-zoom-content .file-preview-image,.file-zoom-content .file-preview-video{max-height:100%}.file-zoom-content>.file-object.type-image{height:auto;min-height:inherit}.file-zoom-content>.file-object.type-audio{width:auto;height:30px}@media (min-width:576px){.file-zoom-dialog .modal-dialog{max-width:500px}}@media (min-width:992px){.file-zoom-dialog .modal-lg{max-width:800px}}@media (max-width:767px){.file-preview-thumbnails{display:flex;justify-content:center;align-items:center;flex-direction:column}.file-zoom-dialog .modal-header{flex-direction:column}}@media (max-width:350px){.krajee-default.file-preview-frame:not([data-template=audio]) .kv-file-content{width:160px}}@media (max-width:420px){.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:100%}}.file-loading[dir=rtl]:before{background:url(../img/loading.gif) top right no-repeat;padding-left:0;padding-right:20px}.clickable .file-drop-zone-title{cursor:pointer}.file-sortable .file-drag-handle:hover{opacity:.7}.file-sortable .file-drag-handle{cursor:grab;opacity:1}.file-grabbing,.file-grabbing *{cursor:not-allowed!important}.file-grabbing .file-preview-thumbnails *{cursor:grabbing!important}.file-preview-frame.sortable-chosen{background-color:#d9edf7;border-color:#17a2b8;box-shadow:none!important}.file-preview .kv-zoom-cache{display:none}.file-preview-object,.file-preview-other-frame,.kv-zoom-body{display:flex;align-items:center;justify-content:center} -------------------------------------------------------------------------------- /src/main/resources/static/plugins/clipboard/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.6 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return o={},r.m=n=[function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}return e}},function(t,e){function n(){}n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | fi 118 | 119 | if [ -z "$JAVA_HOME" ]; then 120 | javaExecutable="`which javac`" 121 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 122 | # readlink(1) is not available as standard on Solaris 10. 123 | readLink=`which readlink` 124 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 125 | if $darwin ; then 126 | javaHome="`dirname \"$javaExecutable\"`" 127 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 128 | else 129 | javaExecutable="`readlink -f \"$javaExecutable\"`" 130 | fi 131 | javaHome="`dirname \"$javaExecutable\"`" 132 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 133 | JAVA_HOME="$javaHome" 134 | export JAVA_HOME 135 | fi 136 | fi 137 | fi 138 | 139 | if [ -z "$JAVACMD" ] ; then 140 | if [ -n "$JAVA_HOME" ] ; then 141 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 142 | # IBM's JDK on AIX uses strange locations for the executables 143 | JAVACMD="$JAVA_HOME/jre/sh/java" 144 | else 145 | JAVACMD="$JAVA_HOME/bin/java" 146 | fi 147 | else 148 | JAVACMD="`which java`" 149 | fi 150 | fi 151 | 152 | if [ ! -x "$JAVACMD" ] ; then 153 | echo "Error: JAVA_HOME is not defined correctly." >&2 154 | echo " We cannot execute $JAVACMD" >&2 155 | exit 1 156 | fi 157 | 158 | if [ -z "$JAVA_HOME" ] ; then 159 | echo "Warning: JAVA_HOME environment variable is not set." 160 | fi 161 | 162 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 163 | 164 | # traverses directory structure from process work directory to filesystem root 165 | # first directory with .mvn subdirectory is considered project base directory 166 | find_maven_basedir() { 167 | 168 | if [ -z "$1" ] 169 | then 170 | echo "Path not specified to find_maven_basedir" 171 | return 1 172 | fi 173 | 174 | basedir="$1" 175 | wdir="$1" 176 | while [ "$wdir" != '/' ] ; do 177 | if [ -d "$wdir"/.mvn ] ; then 178 | basedir=$wdir 179 | break 180 | fi 181 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 182 | if [ -d "${wdir}" ]; then 183 | wdir=`cd "$wdir/.."; pwd` 184 | fi 185 | # end of workaround 186 | done 187 | echo "${basedir}" 188 | } 189 | 190 | # concatenates all lines of a file 191 | concat_lines() { 192 | if [ -f "$1" ]; then 193 | echo "$(tr -s '\n' ' ' < "$1")" 194 | fi 195 | } 196 | 197 | BASE_DIR=`find_maven_basedir "$(pwd)"` 198 | if [ -z "$BASE_DIR" ]; then 199 | exit 1; 200 | fi 201 | 202 | ########################################################################################## 203 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 204 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 205 | ########################################################################################## 206 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 207 | if [ "$MVNW_VERBOSE" = true ]; then 208 | echo "Found .mvn/wrapper/maven-wrapper.jar" 209 | fi 210 | else 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 213 | fi 214 | if [ -n "$MVNW_REPOURL" ]; then 215 | jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 216 | else 217 | jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" 218 | fi 219 | while IFS="=" read key value; do 220 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 221 | esac 222 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 223 | if [ "$MVNW_VERBOSE" = true ]; then 224 | echo "Downloading from: $jarUrl" 225 | fi 226 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 227 | if $cygwin; then 228 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 229 | fi 230 | 231 | if command -v wget > /dev/null; then 232 | if [ "$MVNW_VERBOSE" = true ]; then 233 | echo "Found wget ... using wget" 234 | fi 235 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 236 | wget "$jarUrl" -O "$wrapperJarPath" 237 | else 238 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" 239 | fi 240 | elif command -v curl > /dev/null; then 241 | if [ "$MVNW_VERBOSE" = true ]; then 242 | echo "Found curl ... using curl" 243 | fi 244 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 245 | curl -o "$wrapperJarPath" "$jarUrl" -f 246 | else 247 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 248 | fi 249 | 250 | else 251 | if [ "$MVNW_VERBOSE" = true ]; then 252 | echo "Falling back to using Java to download" 253 | fi 254 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 255 | # For Cygwin, switch paths to Windows format before running javac 256 | if $cygwin; then 257 | javaClass=`cygpath --path --windows "$javaClass"` 258 | fi 259 | if [ -e "$javaClass" ]; then 260 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 261 | if [ "$MVNW_VERBOSE" = true ]; then 262 | echo " - Compiling MavenWrapperDownloader.java ..." 263 | fi 264 | # Compiling the Java class 265 | ("$JAVA_HOME/bin/javac" "$javaClass") 266 | fi 267 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 268 | # Running the downloader 269 | if [ "$MVNW_VERBOSE" = true ]; then 270 | echo " - Running MavenWrapperDownloader.java ..." 271 | fi 272 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 273 | fi 274 | fi 275 | fi 276 | fi 277 | ########################################################################################## 278 | # End of extension 279 | ########################################################################################## 280 | 281 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 282 | if [ "$MVNW_VERBOSE" = true ]; then 283 | echo $MAVEN_PROJECTBASEDIR 284 | fi 285 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 286 | 287 | # For Cygwin, switch paths to Windows format before running java 288 | if $cygwin; then 289 | [ -n "$M2_HOME" ] && 290 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 291 | [ -n "$JAVA_HOME" ] && 292 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 293 | [ -n "$CLASSPATH" ] && 294 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 295 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 296 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 297 | fi 298 | 299 | # Provide a "standardized" way to retrieve the CLI args that will 300 | # work with both Windows and non-Windows executions. 301 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 302 | export MAVEN_CMD_LINE_ARGS 303 | 304 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 305 | 306 | exec "$JAVACMD" \ 307 | $MAVEN_OPTS \ 308 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 309 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 310 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 311 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/theme/default/layer.css: -------------------------------------------------------------------------------- 1 | .layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:50px;line-height:50px;border-bottom:1px solid #F0F0F0;font-size:14px;color:#333;overflow:hidden;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:17px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:300px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:260px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:300px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:51px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{background:0 0;box-shadow:none}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgnext,.layui-layer-imgprev{position:fixed;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:30px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:30px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:fixed;left:0;right:0;bottom:0;width:100%;height:40px;line-height:40px;background-color:#000\9;filter:Alpha(opacity=60);background-color:rgba(2,0,0,.35);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} -------------------------------------------------------------------------------- /src/main/resources/static/plugins/layer/layer.js: -------------------------------------------------------------------------------- 1 | /*! layer-v3.5.1 Web 通用弹出层组件 MIT License */ 2 | ;!function(e,t){"use strict";var i,n,a=e.layui&&layui.define,o={getPath:function(){var t=document.currentScript?document.currentScript.src:function(){for(var e,t=document.scripts,i=t.length-1,n=i;n>0;n--)if("interactive"===t[n].readyState){e=t[n].src;break}return e||t[i].src}(),i=e.LAYUI_GLOBAL||{};return i.layer_dir||t.substring(0,t.lastIndexOf("/")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:["确定","取消"],type:["dialog","page","iframe","loading","tips"],getStyle:function(t,i){var n=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return n[n.getPropertyValue?"getPropertyValue":"getAttribute"](i)},link:function(t,i,n){if(r.path){var a=document.getElementsByTagName("head")[0],s=document.createElement("link");"string"==typeof i&&(n=i);var l=(n||t).replace(/\.|\//g,""),f="layuicss-"+l,c="creating",u=0;s.rel="stylesheet",s.href=r.path+t,s.id=f,document.getElementById(f)||a.appendChild(s),"function"==typeof i&&!function d(t){var n=100,a=document.getElementById(f);return++u>1e4/n?e.console&&console.error(l+".css: Invalid"):void(1989===parseInt(o.getStyle(a,"width"))?(t===c&&a.removeAttribute("lay-status"),a.getAttribute("lay-status")===c?setTimeout(d,n):i()):(a.setAttribute("lay-status",c),setTimeout(function(){d(c)},n)))}()}}},r={v:"3.5.1",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||"ActiveXObject"in e)&&((t.match(/msie\s(\d+)/)||[])[1]||"11")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,"string"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss("modules/layer/"+e.extend):o.link("theme/"+e.extend),this):this},ready:function(e){var t="layer",i="",n=(a?"modules/layer/":"theme/")+"default/layer.css?v="+r.v+i;return a?layui.addcss(n,e,t):o.link(n,e,t),this},alert:function(e,t,n){var a="function"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var s="function"==typeof t;return s&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},s?{}:t))},msg:function(e,n,a){var s="function"==typeof n,f=o.config.skin,c=(f?f+" "+f+"-msg":"")||"layui-layer-msg",u=l.anim.length-1;return s&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},s&&!o.config.skin?{skin:c+" layui-layer-hui",anim:u}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+" "+(n.skin||"layui-layer-hui")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:260},n))}},s=function(e){var t=this,a=function(){t.creat()};t.index=++r.index,t.config.maxWidth=i(n).width()-30,t.config=i.extend({},t.config,o.config,e),document.body?a():setTimeout(function(){a()},30)};s.pt=s.prototype;var l=["layui-layer",".layui-layer-title",".layui-layer-main",".layui-layer-dialog","layui-layer-iframe","layui-layer-content","layui-layer-btn","layui-layer-close"];l.anim=["layer-anim-00","layer-anim-01","layer-anim-02","layer-anim-03","layer-anim-04","layer-anim-05","layer-anim-06"],l.SHADE="layui-layer-shade",l.MOVE="layui-layer-move",s.pt.config={type:0,shade:.3,fixed:!0,move:l[1],title:"信息",offset:"auto",area:"auto",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,isOutAnim:!0,minStack:!0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},s.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,s=r.zIndex+a,f="object"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),u=r.title?'
'+(f?r.title[0]:r.title)+"
":"";return r.zIndex=s,t([r.shade?'
':"",'
'+(e&&2!=r.type?"":u)+'
'+(0==r.type&&r.icon!==-1?'':"")+(1==r.type&&e?"":r.content||"")+'
'+function(){var e=c?'':"";return r.closeBtn&&(e+=''),e}()+""+(r.btn?function(){var e="";"string"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t'+r.btn[t]+"";return'
'+e+"
"}():"")+(r.resize?'':"")+"
"],u,i('
')),n},s.pt.creat=function(){var e=this,t=e.config,a=e.index,s=t.content,f="object"==typeof s,c=i("body");if(!t.id||!i("#"+t.id)[0]){switch("string"==typeof t.area&&(t.area="auto"===t.area?["",""]:[t.area,""]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn="btn"in t?t.btn:o.btn[0],r.closeAll("dialog");break;case 2:var s=t.content=f?t.content:[t.content||"","auto"];t.content='';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i("#"+l.MOVE)[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),e.shadeo=i("#"+l.SHADE+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),e.shadeo.css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():function(){e.offset(),parseInt(o.getStyle(document.getElementById(l.MOVE),"z-index"))||function(){e.layero.css("visibility","hidden"),r.ready(function(){e.offset(),e.layero.css("visibility","visible")})}()}(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;af&&(a=f),ou&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&t.shadeo.on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n,t.index);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n,t.index)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n,t.index)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){t=t||{};var a=i("#"+l[0]+e),s=i("#"+l.SHADE+e),f=a.find(l[1]).outerHeight()||0,c=a.attr("minLeft")||181*o.minIndex+"px",u=a.css("position"),d={width:180,height:f,position:"fixed",overflow:"hidden"};o.record(a),o.minLeft[0]&&(c=o.minLeft[0],o.minLeft.shift()),t.minStack&&(d.left=c,d.top=n.height()-f,a.attr("minLeft")||o.minIndex++,a.attr("minLeft",c)),a.attr("position",u),r.style(e,d,!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),s.hide()},r.restore=function(e){var t=i("#"+l[0]+e),n=i("#"+l.SHADE+e),a=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(a[0]),height:parseFloat(a[1]),top:parseFloat(a[2]),left:parseFloat(a[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e),n.show()},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e,t){var n=i("#"+l[0]+e),a=n.attr("type"),s="layer-anim-close";if(n[0]){var f="layui-layer-wrap",c=function(){if(a===o.type[1]&&"object"===n.attr("conType")){n.children(":not(."+l[5]+")").remove();for(var r=n.find("."+f),s=0;s<2;s++)r.unwrap();r.css("display",r.data("display")).removeClass(f)}else{if(a===o.type[2])try{var c=i("#"+l[4]+e)[0];c.contentWindow.document.write(""),c.contentWindow.close(),n.find("."+l[5])[0].removeChild(c)}catch(u){}n[0].innerHTML="",n.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e],"function"==typeof t&&t()};n.data("isOutAnim")&&n.addClass("layer-anim "+s),i("#layui-layer-moves, #"+l.SHADE+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),n.attr("minLeft")&&(o.minIndex--,o.minLeft.push(n.attr("minLeft"))),r.ie&&r.ie<10||!n.data("isOutAnim")?c():setTimeout(function(){c()},200)}},r.closeAll=function(e,t){"function"==typeof e&&(t=e,e=null);var n=i("."+l[0]);i.each(n,function(a){var o=i(this),s=e?o.attr("type")===e:1;s&&r.close(o.attr("times"),a===n.length-1?t:null),s=null}),0===n.length&&"function"==typeof t&&t()};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'":function(){return''}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["确定","取消"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(t){s=t.find(".layui-layer-input"),s.val(e.value||"").focus(),"function"==typeof f&&f(t)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a=''+t[0].title+"";i"+t[i].title+"";return a}(),content:'
    '+function(){var e=t.length,i=1,a="";if(e>0)for(a='
  • '+(t[0].content||"no content")+"
  • ";i'+(t[i].content||"no content")+"";return a}()+"
",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=!("string"==typeof t.photos||t.photos instanceof i),f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("没有图片")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){h();var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0)}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev(!0)}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext(!0)}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),a&&(t.anim=-1),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(u[d].alt||'+function(){return u.length>1?'
'+(u[d].alt||"")+""+s.imgIndex+" / "+u.length+"
":""}()+"",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("当前图片地址异常
是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){r.ready(),o.run(e.jQuery)}()}(window); --------------------------------------------------------------------------------