hankunkun 10 mesiacov pred
rodič
commit
15cc3d77df

+ 16 - 0
pom.xml

@@ -15,6 +15,7 @@
     <description>models_single</description>
     <properties>
         <java.version>1.8</java.version>
+        <log4j.version>1.2.17</log4j.version>
     </properties>
     <dependencies>
         <dependency>
@@ -137,6 +138,21 @@
             <artifactId>guava</artifactId>
             <version>33.2.0-jre</version>
         </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>${log4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.logging.log4j</groupId>
+            <artifactId>log4j-1.2-api</artifactId>
+            <version>2.8.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-test</artifactId>
+            <version>5.3.1</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 22 - 3
src/main/java/ieven/server/webapp/api/FileController.java

@@ -11,6 +11,8 @@ import ieven.server.webapp.infrastructure.wrapper.Mapped;
 import ieven.server.webapp.util.EncodeDetector;
 import ieven.server.webapp.util.FileUtils;
 import io.swagger.annotations.Api;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.bson.types.ObjectId;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -18,15 +20,16 @@ import org.springframework.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.data.mongodb.gridfs.GridFsOperations;
+import org.springframework.util.MultiValueMap;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
 
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 import java.io.*;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.logging.Logger;
 
 @RestController
@@ -93,6 +96,22 @@ public class FileController {
                 new ByteArrayInputStream(baos.toByteArray()), encoding, filename, contentType, modelId);
     }
 
+    /**
+     * 多文件上传,并存储到临时文件
+     *
+     * @param request request
+     */
+    @ResponseBody
+    @PostMapping(value = "/uploadFiles")
+    public Mapped uploadFiles(MultipartHttpServletRequest request, @RequestParam String modelId) {
+        if (StringUtils.isBlank(modelId)) {
+            return Mapped.ERROR("模块id不能为空");
+        }
+        MultiValueMap<String, MultipartFile> map = request.getMultiFileMap();
+        List<MultipartFile> multipartFiles = map.get("file");
+        return fileService.uploadFilesAndSave(multipartFiles,modelId);
+    }
+
     @PostMapping({"/uploadedList"})
     public Mapped listUploaded(@RequestBody FileListInput fileListInput) {
         return this.fileService.listUploaded(fileListInput);

+ 88 - 3
src/main/java/ieven/server/webapp/domain/file/FileService.java

@@ -6,8 +6,11 @@
 package ieven.server.webapp.domain.file;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.IdUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
 import com.mongodb.client.gridfs.model.GridFSFile;
 import com.mongodb.client.result.DeleteResult;
 import ieven.server.webapp.domain.IdInput;
@@ -16,17 +19,22 @@ import ieven.server.webapp.domain.data.Fields;
 import ieven.server.webapp.domain.model.Model;
 import ieven.server.webapp.infrastructure.wrapper.Mapped;
 import ieven.server.webapp.service.MongoExcelService;
+import ieven.server.webapp.util.EncodeDetector;
+import ieven.server.webapp.util.FileUtils;
 import ieven.server.webapp.util.excel.ExcelXlsReader;
 import ieven.server.webapp.util.excel.ExcelXlsxReader;
 import ieven.server.webapp.util.excel.PublicStatic;
 import info.monitorenter.cpdetector.io.*;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.csv.CSVFormat;
 import org.apache.commons.csv.CSVParser;
 import org.apache.commons.csv.CSVRecord;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.bson.types.ObjectId;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.domain.Sort.Order;
@@ -41,12 +49,12 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.AsyncResult;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
@@ -55,6 +63,9 @@ import java.util.stream.Collectors;
 @EnableAsync
 @Slf4j
 public class FileService {
+    @Value("${spring.data.fileExportPath}")
+    private String fileUploadPath;
+
     String[] order1 = {"反诈数据-订单明细", "治安数据-订单明细","经侦数据-订单明细","网黑数据-订单明细", "反诈治安-交易明细", "反诈治安-账户透视", "反诈治安-对手透视"};
     String[] order2 = {
             "五联单-注册信息",
@@ -444,4 +455,78 @@ public class FileService {
         Model model = this.mongoTemplate.findOne(query, Model.class, "model");
         return new AsyncResult(model != null ? model.getModelName() : "");
     }
+
+    public Mapped uploadFilesAndSave(List<MultipartFile> multipartFiles, String modelId) {
+        List<String> failNameList = new ArrayList<>();
+        for (int i = 1; i <= multipartFiles.size(); i++) {
+            MultipartFile multipartFile = multipartFiles.get(i);
+            String originName = multipartFile.getOriginalFilename();
+            String suffix = originName.substring(originName.lastIndexOf(".") + 1);
+            String prefix = originName.substring(0, originName.lastIndexOf("."));
+            String savedName = prefix + "(" + i + ")." + suffix;
+            String filepath = fileUploadPath + File.separator + modelId + File.separator + savedName;
+            FileUtils.uploadFile(multipartFile, filepath);
+            MultipartFile multipartFile1 = FileUtils.getMultipartFile(new File(filepath));
+            try {
+                Mapped mapped = uploadSingle(multipartFile1, modelId);
+                if(!"200".equals(mapped.get("code"))){
+                    failNameList.add(String.valueOf(mapped.get("message")));
+                }
+                //删除文件
+                FileUtils.deleteFile(filepath);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        Mapped mapped = Mapped.OK();
+        mapped.put("failNameList", failNameList);
+        return mapped;
+    }
+
+    public Mapped uploadSingle(MultipartFile file, String modelId)
+            throws Exception {
+        String filename = file.getOriginalFilename();
+        String extName = FileUtil.extName(filename);
+        String contentType = file.getContentType();
+        ByteArrayOutputStream baos = FileUtils.cloneInputStream(file.getInputStream());
+        if (extName.equalsIgnoreCase("xls") || extName.equalsIgnoreCase("xlsx")) {
+            ExcelReader reader = ExcelUtil.getReader(new ByteArrayInputStream(baos.toByteArray()));
+            List<Sheet> sheets = reader.getSheets();
+            List<String> headers = new ArrayList<>();
+            for (Sheet sheet : sheets) {
+                reader.setSheet(sheet);
+                List<Object> objects = reader.readRow(0);
+                if (objects.size() > 1) { // 至少大于1
+                    StringBuilder stringBuilder = new StringBuilder();
+                    for (Object object : objects) {
+                        stringBuilder.append(object);
+                    }
+                    headers.add(stringBuilder.toString());
+                }
+            }
+            if (headers.size() > 1) {
+                // 判断sheet第一行内容是否一致
+                StringBuilder errorHeaders = new StringBuilder();
+                String baseHeader = headers.get(0);
+                for (int i = 0; i < headers.size(); i++) {
+                    //
+                    if (i == 0) {
+                        continue;
+                    }
+                    if (!headers.get(i).equals(baseHeader)) {
+                        errorHeaders.append("sheet").append(i).append("标题列与第一个sheet不一致!");
+                    }
+                }
+                if (errorHeaders.length() > 0) {
+                    return Mapped.ERROR(errorHeaders.toString());
+                }
+            }
+            reader.close();
+        }
+        String encoding = EncodeDetector.getEncoding(baos.toByteArray());
+        baos.close();
+        return this.fileService.storeUploaded(
+                new ByteArrayInputStream(baos.toByteArray()), encoding, filename, contentType, modelId);
+    }
+
 }

+ 275 - 1
src/main/java/ieven/server/webapp/util/FileUtils.java

@@ -2,13 +2,28 @@ package ieven.server.webapp.util;
 
 import com.ibm.icu.text.CharsetDetector;
 import com.ibm.icu.text.CharsetMatch;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.compress.archivers.sevenz.SevenZFile;
+import org.apache.http.entity.ContentType;
+import org.apache.log4j.Logger;
+import org.springframework.mock.web.MockMultipartFile;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class FileUtils {
+    private static final Logger logger = Logger.getLogger(FileUtils.class);
+
+    public FileUtils() {
+    }
 
     public static ByteArrayOutputStream cloneInputStream(InputStream input) {
         try {
@@ -29,7 +44,7 @@ public class FileUtils {
     /**
      * 读文件,根据文件名,返回文件内容字符串;
      * 读文件之前会探测编码格式,按准确的编码格式进行读取;若编码格式探测失败,则默认按照"UTF-8"进行读取
-     * */
+     */
     public static String getFileCharsetByICU4J(FileInputStream inputStream) {
         String encoding = "UTF-8";
         try {
@@ -57,4 +72,263 @@ public class FileUtils {
         }
         return encoding;
     }
+
+    /**
+     * md5检验上传文件是否与历史文件重复
+     *
+     * @param file
+     * @param filePath
+     * @return
+     */
+    public static Map<Boolean, String> distinctWithMd5(MultipartFile file, String filePath) {
+        boolean result = false;
+        String fileName = file.getOriginalFilename();
+        String md5 = new String();
+        try {
+            md5 = DigestUtils.md5Hex(file.getInputStream());
+
+            File uploadFilePath = new File(filePath);
+            File[] tempList = uploadFilePath.listFiles();
+            for (int i = 0; i < tempList.length; i++) {
+                if (tempList[i].isFile()) {
+                    result = md5.equals(DigestUtils.md5Hex(new FileInputStream(tempList[i])));
+                    if (result == true)
+                        break;
+                }
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        Map<Boolean, String> res = new HashMap<>();
+        res.put(result, fileName);
+        return res;
+    }
+
+    /**
+     * 检验当前上传文件列表中的文件是否与历史冲突
+     *
+     * @param files
+     * @param fileUploadPath
+     * @return 将重复文件名返回,Boolean 标识是否含有重复文件
+     */
+    public static Map<Boolean, List<String>> filesRepetition(List<MultipartFile> files, String fileUploadPath) {
+        Map<Boolean, List<String>> result = new HashMap<>();
+        boolean repetitionExist = false;
+        List<String> repetitionFiles = new ArrayList<>();
+        files.forEach(x -> {
+            Map<Boolean, String> fileRepetition = distinctWithMd5(x, fileUploadPath);
+            if (fileRepetition.containsKey(true)) {
+                repetitionFiles.add(fileRepetition.get(true));
+            }
+        });
+        if (!repetitionFiles.isEmpty()) {
+            repetitionExist = true;
+        }
+        result.put(repetitionExist, repetitionFiles);
+        return result;
+    }
+
+    /**
+     * 将文件按照指定路径上传
+     *
+     * @param file
+     * @param savePath
+     */
+    public static boolean uploadFile(MultipartFile file, String savePath) {
+        //上传
+        File path = new File(savePath);
+        boolean status = true;
+        if (!path.getParentFile().exists()) {
+            try {
+                logger.info("父目录不存在,创建父目录: " + path.getParent());
+                if (path.getParentFile().mkdirs()) {
+                    logger.info("上传文件 : " + savePath);
+                    file.transferTo(new File(savePath));
+                } else {
+                    logger.info("创建文件失败:" + path.getParent() + "无法创建!");
+                    status = false;
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+                status = false;
+            }
+            return status;
+        } else {
+            try {
+                logger.info("上传文件 : " + savePath);
+                file.transferTo(new File(savePath));
+                return status;
+            } catch (IOException e) {
+                logger.error("文件上传错误", e);
+                e.printStackTrace();
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @param fileName 要删除的文件名
+     * @return 删除成功返回true,否则返回false
+     */
+    public static boolean deleteFile(String fileName) {
+        File file = new File(fileName);
+        if (!file.exists()) {
+            logger.info("删除文件失败:" + fileName + "不存在!");
+            return false;
+        } else {
+            if (file.isFile()) {
+                return file.delete();
+            } else {
+                logger.info("删除文件失败:" + fileName + "不是文件!");
+                return false;
+            }
+        }
+    }
+
+    /**
+     * 读文件,根据文件名,返回文件内容字符串;
+     * 读文件之前会探测编码格式,按准确的编码格式进行读取;若编码格式探测失败,则默认按照"UTF-8"进行读取
+     */
+    public static String getFileCharsetByICU4J(File file) {
+        String encoding = null;
+        try {
+            Path path = Paths.get(file.getPath());
+            byte[] data = Files.readAllBytes(path);
+            BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
+            int p = (bin.read() << 8) + bin.read();
+            bin.close();
+            switch (p) {
+                case 0xefbb:
+                    encoding = "UTF-8";
+                    break;
+                case 0xfffe:
+                    encoding = "Unicode";
+                    break;
+                case 0xfeff:
+                    encoding = "UTF-16BE";
+                    break;
+                case 45801:
+                    encoding = "GB18030";
+                    break;
+                default:
+                    CharsetDetector detector = new CharsetDetector();
+                    detector.setText(data);
+                    CharsetMatch match = detector.detect();
+                    if (match == null) {
+                        encoding = "GBK";
+                    } else {
+                        encoding = match.getName();
+                    }
+            }
+
+        } catch (IOException var6) {
+            var6.printStackTrace();
+            encoding = "UTF-8";
+        }
+        return encoding;
+    }
+
+
+
+
+    public static void unPackRar(File rarFile, String destDir) throws Exception {
+
+    }
+
+
+    private static void unPack7z(File file, String destDir) {
+        try {
+            SevenZFile sevenZFile = new SevenZFile(file);
+            SevenZArchiveEntry entry = sevenZFile.getNextEntry();
+            while (entry != null) {
+                File f = new File(destDir + File.separator + entry.getName());
+                if (entry.isDirectory()) {
+                    if (!file.exists()) {
+                        f.mkdirs();
+                    }
+                    entry = sevenZFile.getNextEntry();
+                    continue;
+                }
+                if (!f.getParentFile().exists()) {
+                    f.getParentFile().mkdirs();
+                }
+                FileOutputStream out = new FileOutputStream(file);
+                byte[] content = new byte[(int) entry.getSize()];
+                sevenZFile.read(content, 0, content.length);
+                out.write(content);
+                out.close();
+                entry = sevenZFile.getNextEntry();
+            }
+            sevenZFile.close();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    private static void search(File file, List<File> result) {
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            if (files != null) {
+                for (File subFile : files) {
+                    search(subFile, result);
+                }
+            }
+        } else {
+            String fileName = file.getName();
+            //System.out.println(fileName);
+            if (fileName.endsWith(".xls") || fileName.endsWith(".xlsx") || fileName.endsWith(".csv")) {
+                result.add(file);
+            }
+        }
+    }
+
+
+    public static List<MultipartFile> transferFileToMulti(List<File> files) {
+        List<MultipartFile> list = new ArrayList<>();
+        for (File file : files) {
+            list.add(getMultipartFile(file));
+        }
+        return list;
+    }
+
+    public static MultipartFile getMultipartFile(File file) {
+        FileInputStream fileInputStream = null;
+        MultipartFile multipartFile = null;
+        try {
+            fileInputStream = new FileInputStream(file);
+            multipartFile = new MockMultipartFile(file.getName(), file.getName(),
+                    ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return multipartFile;
+    }
+
+
+    public static void deleteAllFiles(File file) {
+        //判断文件不为null或文件目录存在
+        if (file == null || !file.exists()) {
+            logger.info("文件删除失败,请检查文件路径是否正确");
+            return;
+        }
+        //取得这个目录下的所有子文件对象
+        File[] files = file.listFiles();
+        //遍历该目录下的文件对象
+        for (File f : files) {
+            //打印文件名
+            String name = file.getName();
+            System.out.println(name);
+            //判断子目录是否存在子目录,如果是文件则删除
+            if (f.isDirectory()) {
+                deleteAllFiles(f);
+            } else {
+                f.delete();
+            }
+        }
+        //删除空文件夹  for循环已经把上一层节点的目录清空。
+        file.delete();
+    }
 }

+ 3 - 3
src/main/resources/static/index.html

@@ -1,8 +1,8 @@
-<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"><meta http-equiv=X-UA-Compatible content="IE=edge"><title>追迹者-三方支付数据分析</title><link href=/static/css/app.1f25baa9f2b560f3622142c34afb7309.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.e7065ba1f42a8ca19b31.js></script><script type=text/javascript src=/static/js/vendor.4a30d08b867d4749cfcc.js></script><script type=text/javascript src=/static/js/app.6b79adfa44a0e0d044b9.js></script></body></html>
+<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"><meta http-equiv=X-UA-Compatible content="IE=edge"><title>追迹者-三方支付数据分析</title><link href=/static/css/app.1f25baa9f2b560f3622142c34afb7309.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.ac1346828110953772ce.js></script><script type=text/javascript src=/static/js/vendor.4a30d08b867d4749cfcc.js></script><script type=text/javascript src=/static/js/app.6b79adfa44a0e0d044b9.js></script></body></html>
 <!-- 
  PROJECT_NAME: 三方支付数据分析;
- BUILD_TIME:Mon, 23 Sep 2024 22:49:45 GMT; 
+ BUILD_TIME:Tue, 24 Sep 2024 01:56:26 GMT; 
  GIT_BRANCH:master; 
- GIT_COMMIT:45028b29690f8e6b1ffe2ac85b5cb8555d1b7aa0; 
+ GIT_COMMIT:3ea7a359ef78b24b69c9a2d1e2b986965209cfa5; 
  TICK:3.2.0; 
  -->

+ 1 - 0
src/main/resources/static/static/invoice/professor-yellow.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704888743858" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27187" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M760.384 246.592zM565.312 245.632z" fill="#FFFFFF" p-id="27188"></path><path d="M512 14.4C287.2 14.4 97.6 163.2 35.2 368c-13.6 45.6-21.6 94.4-21.6 144 0 275.2 223.2 497.6 497.6 497.6 192 0 357.6-108 440.8-267.2 36-68.8 56.8-147.2 56.8-230.4 0.8-275.2-221.6-497.6-496.8-497.6zM944 656c-60 180.8-230.4 311.2-432 311.2-251.2 0-455.2-204-455.2-455.2 0-72.8 16.8-141.6 47.2-202.4C178.4 160 333.6 56.8 512 56.8c251.2 0 455.2 204 455.2 455.2 0 50.4-8.8 98.4-23.2 144z" fill="#FFD700" p-id="27189" data-spm-anchor-id="a313x.search_index.0.i49.52633a81F1X3uN" class=""></path><path d="M511.168 785.856c-34.176 0-68.352 0.384-102.656 0-21.632-0.384-43.392-1.28-65.024-2.752a173.184 173.184 0 0 1-57.28-12.224 48 48 0 0 1-24.768-20.736 40.832 40.832 0 0 1-4.608-19.392c-1.344-36.736 5.568-71.744 23.616-104a194.688 194.688 0 0 1 102.656-88.832c23.104-8.96 47.232-12.864 71.936-12.864 38.016-0.064 76.032-0.192 113.92 0 50.368 0.256 94.976 16.384 132.8 49.792 33.728 29.76 54.656 67.136 62.592 111.68 2.88 15.872 3.392 31.872 2.496 48-0.832 14.272-8.768 24.256-20.672 31.488-12.16 7.36-25.664 10.88-39.488 13.376-32.96 6.016-66.304 6.272-99.584 6.528-31.936 0.192-63.936-0.064-95.936-0.064 0 0.128 0 0 0 0zM662.08 358.4c0 64.512-43.008 123.328-107.904 144.064a155.904 155.904 0 0 1-196.608-100.032 152 152 0 0 1 51.2-165.632c23.808-18.56 50.752-29.824 80.768-32.96a155.84 155.84 0 0 1 167.616 114.688c3.264 12.416 4.8 25.152 4.928 39.872z" fill="#EEC900" p-id="27190" data-spm-anchor-id="a313x.search_index.0.i52.52633a81F1X3uN" class=""></path></svg>

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
src/main/resources/static/static/js/1.021b907ea6838e16002a.js


+ 1 - 0
src/main/resources/static/static/js/manifest.ac1346828110953772ce.js

@@ -0,0 +1 @@
+!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var f,i,u,d=0,s=[];d<t.length;d++)i=t[d],o[i]&&s.push(o[i][0]),o[i]=0;for(f in c)Object.prototype.hasOwnProperty.call(c,f)&&(e[f]=c[f]);for(r&&r(t,c,a);s.length;)s.shift()();if(a)for(d=0;d<a.length;d++)u=n(n.s=a[d]);return u};var t={},o={11:0};n.e=function(e){function r(){f.onerror=f.onload=null,clearTimeout(i);var n=o[e];0!==n&&(n&&n[1](new Error("Loading chunk "+e+" failed.")),o[e]=void 0)}var t=o[e];if(0===t)return new Promise(function(e){e()});if(t)return t[2];var c=new Promise(function(n,r){t=o[e]=[n,r]});t[2]=c;var a=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.timeout=12e4,n.nc&&f.setAttribute("nonce",n.nc),f.src=n.p+"static/js/"+({0:"vendor-async"}[e]||e)+"."+{0:"f97ed98272f8cf46d635",1:"021b907ea6838e16002a",2:"43384261e5d6b8c85bb7",3:"8124a69fbfe430b4050f",4:"4cb2bf4ec86307f8aa7d",5:"3defbbaae0fa3bddba52",6:"eedbbe55278fd36cf8c6",7:"83ecdc9548c3706f90ec",8:"1cfc86658a36840181e1"}[e]+".js";var i=setTimeout(r,12e4);return f.onerror=f.onload=r,a.appendChild(f),c},n.m=e,n.c=t,n.d=function(e,r,t){n.o(e,r)||Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(r,"a",r),r},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="/",n.oe=function(e){throw console.error(e),e}}([]);

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov