From b64996712852da89063583f0253326fab9084531 Mon Sep 17 00:00:00 2001 From: Gary <3489015381@qq.com> Date: Mon, 30 Dec 2024 17:42:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85=E7=BB=9F=E4=B8=80=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/dataSources.xml | 18 ++++ README.md | 1 + .../com/gary/exercise/config/FileConfig.java | 20 ++++ .../gary/exercise/config/WebSocketConfig.java | 10 +- .../java/com/gary/exercise/dto/ActionDto.java | 3 +- .../java/com/gary/exercise/dto/GameEvent.java | 19 ++++ .../java/com/gary/exercise/dto/Human.java | 20 ++++ .../java/com/gary/exercise/dto/LeftTime.java | 13 +++ .../java/com/gary/exercise/dto/ScoreDto.java | 12 +++ .../exercise/service/ExerciseService.java | 24 ++--- .../service/impl/ExerciseServiceImpl.java | 95 ++++++++++-------- .../socket/ExerciseWebSocketHandler.java | 66 +++++++++++- src/main/resources/application.yaml | 15 +++ src/main/resources/exercise.xlsx | Bin 9752 -> 10380 bytes .../exercise/ExerciseApplicationTests.java | 21 ++-- target/classes/application.yaml | 15 +++ .../exercise/config/WebSocketConfig.class | Bin 1480 -> 1654 bytes .../com/gary/exercise/dto/ActionDto.class | Bin 2828 -> 2828 bytes .../exercise/service/ExerciseService.class | Bin 577 -> 458 bytes .../service/impl/ExerciseServiceImpl$1.class | Bin 943 -> 943 bytes .../service/impl/ExerciseServiceImpl.class | Bin 5075 -> 4792 bytes .../socket/ExerciseWebSocketHandler.class | Bin 5509 -> 7303 bytes target/classes/exercise.xlsx | Bin 9752 -> 10380 bytes .../exercise/ExerciseApplicationTests.class | Bin 1944 -> 858 bytes 24 files changed, 280 insertions(+), 72 deletions(-) create mode 100644 .idea/dataSources.xml create mode 100644 README.md create mode 100644 src/main/java/com/gary/exercise/config/FileConfig.java create mode 100644 src/main/java/com/gary/exercise/dto/GameEvent.java create mode 100644 src/main/java/com/gary/exercise/dto/Human.java create mode 100644 src/main/java/com/gary/exercise/dto/LeftTime.java create mode 100644 src/main/java/com/gary/exercise/dto/ScoreDto.java diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..3579917 --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,18 @@ + + + + + mysql.8 + true + true + com.mysql.cj.jdbc.Driver + jdbc:mysql://47.122.61.54:3306/?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC + + + + + + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c323144 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# 解析excel 然后设置定时任务发送给前端消息内容 diff --git a/src/main/java/com/gary/exercise/config/FileConfig.java b/src/main/java/com/gary/exercise/config/FileConfig.java new file mode 100644 index 0000000..71406e4 --- /dev/null +++ b/src/main/java/com/gary/exercise/config/FileConfig.java @@ -0,0 +1,20 @@ +package com.gary.exercise.config; + +import cn.hutool.core.io.resource.ClassPathResource; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +/** + *定义文件的路径和地址 + */ +@Data +@Component +@ConfigurationProperties(prefix ="excel" ) +public class FileConfig { + private final String fileName="exercise.xlsx"; + private final String sheetNumber="Sheet1"; + private final String filePath=new ClassPathResource(fileName).getFile().getAbsolutePath(); + +} diff --git a/src/main/java/com/gary/exercise/config/WebSocketConfig.java b/src/main/java/com/gary/exercise/config/WebSocketConfig.java index 5c5daa1..6e30466 100644 --- a/src/main/java/com/gary/exercise/config/WebSocketConfig.java +++ b/src/main/java/com/gary/exercise/config/WebSocketConfig.java @@ -1,4 +1,5 @@ package com.gary.exercise.config; +import com.gary.exercise.service.ExerciseService; import com.gary.exercise.socket.ExerciseWebSocketHandler; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; @@ -11,10 +12,17 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { + private final ExerciseService exerciseService; + + public WebSocketConfig(ExerciseService exerciseService) { + this.exerciseService = exerciseService; + } + + @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // 注册 WebSocket 的处理器 - registry.addHandler(new ExerciseWebSocketHandler(), "/exercise") // 定义路径 /exercise + registry.addHandler(new ExerciseWebSocketHandler(exerciseService), "/exercise") // 定义路径 /exercise .setAllowedOrigins("*"); // 设置允许的跨域请求 } } diff --git a/src/main/java/com/gary/exercise/dto/ActionDto.java b/src/main/java/com/gary/exercise/dto/ActionDto.java index ba47590..71a52c9 100644 --- a/src/main/java/com/gary/exercise/dto/ActionDto.java +++ b/src/main/java/com/gary/exercise/dto/ActionDto.java @@ -1,5 +1,6 @@ package com.gary.exercise.dto; +import cn.hutool.json.JSONUtil; import lombok.Data; /** @@ -8,8 +9,6 @@ import lombok.Data; @Data public class ActionDto { private String human; - private String action; - private String description; } diff --git a/src/main/java/com/gary/exercise/dto/GameEvent.java b/src/main/java/com/gary/exercise/dto/GameEvent.java new file mode 100644 index 0000000..cccd5f5 --- /dev/null +++ b/src/main/java/com/gary/exercise/dto/GameEvent.java @@ -0,0 +1,19 @@ +package com.gary.exercise.dto; + +import lombok.Data; +/** + *用来描述比赛事件 统一返回格式 + */ +@Data +public class GameEvent { + + private String classMessage;//节数信息 + LeftTime time;//剩余时间 + ActionDto lakerActionDto;//湖人队动作 + + ActionDto wolvesActionDto;//森林狼队动作 + + + + +} diff --git a/src/main/java/com/gary/exercise/dto/Human.java b/src/main/java/com/gary/exercise/dto/Human.java new file mode 100644 index 0000000..c6f7017 --- /dev/null +++ b/src/main/java/com/gary/exercise/dto/Human.java @@ -0,0 +1,20 @@ +package com.gary.exercise.dto; + +import lombok.Data; + +/** + *个人得分统计 + */ +@Data +public class Human { + private String name; //姓名 + private int points; // 得分 + private int rebounds; // 篮板 + private int assists; // 助攻 + private int blocks; // 盖帽 + private int steals; // 抢断 + private int fouls; // 犯规 + private int twoPoints; // 2分球数 + private int threePoints; // 3分球数 + private int freeThrows; // 罚球数 +} diff --git a/src/main/java/com/gary/exercise/dto/LeftTime.java b/src/main/java/com/gary/exercise/dto/LeftTime.java new file mode 100644 index 0000000..3f5cb2a --- /dev/null +++ b/src/main/java/com/gary/exercise/dto/LeftTime.java @@ -0,0 +1,13 @@ +package com.gary.exercise.dto; + +import lombok.Data; +/** + *用来描述比赛剩余时间 + */ +@Data +public class LeftTime { + + int minute; + + int second; +} diff --git a/src/main/java/com/gary/exercise/dto/ScoreDto.java b/src/main/java/com/gary/exercise/dto/ScoreDto.java new file mode 100644 index 0000000..844b6a2 --- /dev/null +++ b/src/main/java/com/gary/exercise/dto/ScoreDto.java @@ -0,0 +1,12 @@ +package com.gary.exercise.dto; + +import lombok.Data; + +@Data +public class ScoreDto { + + private int laker_score;//湖人对比分 + private int wolf_score;//森林狼队比分 + + +} diff --git a/src/main/java/com/gary/exercise/service/ExerciseService.java b/src/main/java/com/gary/exercise/service/ExerciseService.java index ef11512..503c36e 100644 --- a/src/main/java/com/gary/exercise/service/ExerciseService.java +++ b/src/main/java/com/gary/exercise/service/ExerciseService.java @@ -1,28 +1,26 @@ package com.gary.exercise.service; +import java.io.IOException; import java.util.List; import java.util.Map; -/** - * @author Gary - * @date 2024/12/11 下午4:13 - * @description: 读取和处理文件流 - */ public interface ExerciseService { /** - * 读取 Excel 文件中的某一行数据,并存储在 List 中返回 - * - * @param filepath Excel 文件路径 - * @param line 要读取的行号(从 1 开始) - * @return List 包含这一行的所有数据 + *读取文件中某一行的数据行数从0开始 */ - List readExcelByLine(String filepath, Integer line); + List readRow( int rowIndex) throws IOException; + /** - *获取excel中的详细信息 + *读取文件中的某一行并以标准化格式输出 */ - Map getDetailInformation(String filepath, Integer line); + Map processRow(int rowIndex) throws IOException; + + + + + } diff --git a/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java b/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java index 7f97096..f7188b1 100644 --- a/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java +++ b/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java @@ -1,56 +1,28 @@ package com.gary.exercise.service.impl; +import com.gary.exercise.config.FileConfig; import com.gary.exercise.service.ExerciseService; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.stereotype.Service; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.*; - +@Service public class ExerciseServiceImpl implements ExerciseService { - @Override - public List readExcelByLine(String filepath, Integer line) { - List result = new ArrayList<>(); - try{ - FileInputStream fis = new FileInputStream(filepath); - Workbook workbook = WorkbookFactory.create(fis); - Sheet sheet = workbook.getSheetAt(0); - Row dataRow = sheet.getRow(line - 1); //获取第i行的数据 - if (dataRow == null) { - throw new IllegalArgumentException("指定的行不存在或文件为空"); - } - for (int i = 0; i < dataRow.getLastCellNum(); i++) { - Cell cell = dataRow.getCell(i); - String cellValue = getCellValue(cell); - result.add(cellValue); - } - } catch (IOException e) { - throw new RuntimeException("读取 Excel 文件失败: " + e.getMessage(), e); - } - return result; - } - @Override - public Map getDetailInformation(String filepath, Integer line) { - - Map result =new HashMap<>(); - List readResult= readExcelByLine(filepath, line);//获取读取到的结果 - if(readResult.isEmpty()) { - throw new RuntimeException("读取到的结果为空"); - }else if(readResult.size()==1){//说明是第一第二节开始的标志 - result.put("now_class",readResult.get(0)); - }else if(Objects.equals(readResult.get(0), "时间")) { - return null; - }else{ - result.put("time",readResult.get(0));//获取当前时间 - result.put("laker_action",readResult.get(1));//获取当前湖人队的动作 - result.put("score",readResult.get(2));//获取当前比分 - result.put("wolf_action",readResult.get(3));//获取当前森林狼队的动作 - } - return result; + + private final FileConfig fileConfig; + + public ExerciseServiceImpl(FileConfig fileConfig) { + this.fileConfig = fileConfig; } + /** * 获取单元格的值,并转换为字符串 */ @@ -62,7 +34,7 @@ public class ExerciseServiceImpl implements ExerciseService { case STRING -> cell.getStringCellValue(); case NUMERIC -> { if (DateUtil.isCellDateFormatted(cell)) { - yield cell.getDateCellValue().toString(); + yield new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue()); } yield String.valueOf(cell.getNumericCellValue()); } @@ -72,7 +44,48 @@ public class ExerciseServiceImpl implements ExerciseService { default -> "UNKNOWN"; }; } + /** + * 读取 Excel 文件中一行的数据 + * @param rowIndex 行号(从 0 开始) + * @return 返回一行数据的列表 + * @throws IOException 如果文件读取失败 + */ + @Override + public List readRow( int rowIndex) throws IOException { + List rowData = new ArrayList<>(); + String filePath = fileConfig.getFilePath(); + String sheetName = fileConfig.getSheetNumber(); + try (FileInputStream fileInputStream = new FileInputStream(new File(filePath)); + Workbook workbook = new XSSFWorkbook(fileInputStream)) { + Sheet sheet = workbook.getSheet(sheetName); + if (sheet == null) { + throw new IllegalArgumentException("Sheet " + sheetName + " does not exist."); + } + Row row = sheet.getRow(rowIndex); + if (row == null) { + throw new IllegalArgumentException("Row " + rowIndex + " does not exist."); + } + for (Cell cell : row) { + rowData.add(getCellValue(cell)); + } + } + return rowData; + } + + + @Override + public Map processRow(int rowIndex) throws IOException{ + List rowData = readRow(rowIndex); + + + + + + return Map.of(); + } + + } diff --git a/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java b/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java index 5c0c716..973e93c 100644 --- a/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java +++ b/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java @@ -1,34 +1,90 @@ package com.gary.exercise.socket; +import com.gary.exercise.service.ExerciseService; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.socket.*; import java.io.IOException; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; + + + + + public class ExerciseWebSocketHandler implements WebSocketHandler { - // 用于存储所有的 WebSocket 会话 + + private static final Logger log = LoggerFactory.getLogger(ExerciseWebSocketHandler.class); + private final ExerciseService exerciseService; + //存储webSocket的消息对话ID private static final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + + + + + public ExerciseWebSocketHandler(ExerciseService exerciseService) { + this.exerciseService = exerciseService; + } + + + + + + + @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 当连接建立时触发 String sessionId = session.getId(); sessions.put(sessionId, session); System.out.println("WebSocket连接已建立: " + sessionId); - // 发送欢迎消息 session.sendMessage(new TextMessage("欢迎连接到 WebSocket 服务,您的会话 ID 是: " + sessionId)); } + + + + + @Override public void handleMessage(@NotNull WebSocketSession session, @NotNull WebSocketMessage message) throws Exception { - // 处理接收到的消息 if (message instanceof TextMessage) { + // 接收客户端的消息 String clientMessage = ((TextMessage) message).getPayload(); System.out.println("收到消息: " + clientMessage); - // 回复客户端 - session.sendMessage(new TextMessage("服务器收到消息: " + clientMessage)); + // 启动一个线程来每秒发送一行数据 + new Thread(() -> { + try { + int rowIndex = 0; // 从第 0 行开始 + while (true) { + List rowData = exerciseService.readRow(rowIndex); // 读取 Excel 数据 + String rowString = String.join(", ", rowData); // 格式化为字符串 + session.sendMessage(new TextMessage(rowString)); // 发送给客户端 + + rowIndex++; // 移动到下一行 + Thread.sleep(1000); // 每秒发送一次 + + // 停止条件:到达 Excel 文件的末尾 + if (rowData.isEmpty()) { + session.sendMessage(new TextMessage("已到达文件末尾")); + break; + } + } + } catch (Exception e) { + log.error("发生错误: {}", e.getMessage()); + try { + session.sendMessage(new TextMessage("发生错误: " + e.getMessage())); + } catch (IOException ioException) { + log.error("发生错误: {}", e.getMessage()); + } + } + }).start(); } else { System.out.println("不支持的消息类型: " + message.getClass().getName()); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index e69de29..96e2aa5 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +server: + port: 9090 + + +# 数据库 +spring: + datasource: + url: jdbc:mysql://47.122.61.54:3306/nba_visualization?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC + username: root + password: GHLgjw168168+ + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + max-lifetime: 27000000 # 7.5 小时(毫秒) + + diff --git a/src/main/resources/exercise.xlsx b/src/main/resources/exercise.xlsx index f204e665a2a6f0c91cc8445b74a5ea4ae75f5266..1ad14d3758d5cf140a72f22438de8a59f214755d 100644 GIT binary patch delta 3625 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 diff --git a/src/test/java/com/gary/exercise/ExerciseApplicationTests.java b/src/test/java/com/gary/exercise/ExerciseApplicationTests.java index 34719ad..516034e 100644 --- a/src/test/java/com/gary/exercise/ExerciseApplicationTests.java +++ b/src/test/java/com/gary/exercise/ExerciseApplicationTests.java @@ -1,27 +1,28 @@ package com.gary.exercise; +import cn.hutool.core.io.resource.ClassPathResource; import com.gary.exercise.service.ExerciseService; import com.gary.exercise.service.impl.ExerciseServiceImpl; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import java.io.IOException; import java.util.List; import java.util.Map; @SpringBootTest class ExerciseApplicationTests { - @Test - void contextLoads() { - } - public static void main(String[] args) { - ExerciseService service = new ExerciseServiceImpl(); - String filepath = "D:\\data\\coding files\\java\\exercise\\src\\main\\resources\\exercise.xlsx"; // 替换为实际路径 - int line = 3; // 读取第2行数据 - Mapresult=service.getDetailInformation(filepath,line); - /* List result = service.readExcelByLine(filepath, line);*/ - System.out.println("读取结果:"+result); + private final ExerciseService exerciseService; + + private final int hang =1; + ExerciseApplicationTests(ExerciseService exerciseService) { + this.exerciseService = exerciseService; } + public static void main(String[] args) throws IOException { + + + } } diff --git a/target/classes/application.yaml b/target/classes/application.yaml index e69de29..96e2aa5 100644 --- a/target/classes/application.yaml +++ b/target/classes/application.yaml @@ -0,0 +1,15 @@ +server: + port: 9090 + + +# 数据库 +spring: + datasource: + url: jdbc:mysql://47.122.61.54:3306/nba_visualization?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC + username: root + password: GHLgjw168168+ + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + max-lifetime: 27000000 # 7.5 小时(毫秒) + + diff --git a/target/classes/com/gary/exercise/config/WebSocketConfig.class b/target/classes/com/gary/exercise/config/WebSocketConfig.class index ad45413781fc21486720edb16dabd2d731e4b06b..890a3841ce07d7fc4fec88d935e1fee5845a8af2 100644 GIT binary patch delta 574 zcmb7A$xZ@66s#V=VHspmQN$e=7?5^1aXGmpCYoqSG#n>5B1XUr1eXinK;|brm>3fc zQR8wXCVqxL;K8Hu4WdzR9{Rnm?y6VaRdu{c_NVuodjRv8EZe!$1}khL>=GQ1^b;Yn zz~EAkR4tj#t8rB;rjsf|WHp(~@RXt*^RGLe|GeZ&zsa*A8q0H2B`4exEbuVILjO>Q zH$^ltxc8Kz!uOSIipL9DI-9bhg~9gi?m#QrMEE7NBfzkd(^5QtU=VjSC8HkZ^hY*b zem(VeGBDYJZuE%gmC%Qve#V~70}PA$Ih)a6gsjKCrWST{+v|!UEvQ;v-!N76sQIB} zg#d8CTNnY*_$Y?!<4Zees43*gEu0DY5@H1|^Bueileam34W9{h)Iq3Az}8=XKY|od j7=a)D^0&W?7&uwh{bS@WV5C+@F$SmcLILA+Fadl3|3Yk2 delta 379 zcmYLEJxjw-6g@XDY1$;#wz2iw){jfLrw-CZOeK_xWT+x8;%^A=7dQ#x zA_zrA-9%jd5B>y4@g^2r&bjB^d(XM=+j=*RkDtdE02}Zk!xK8v(f#V04z5f>?#Ms$ zy<Cv2xNK*)H(dC)!VoCGEYk<*d4P=HOS%LBD8ujsm1B#>ib7$Z7HEsSBD zu*=;Yxv6OKM!BHLXxmNcC=<5$eO(43lwaaaehOROs;`$5P(YaC(_+?;Vyv+8n2A|) zdZ4?cJ7pE6`U%toBO^ v_Wtd&5WJR0nLk>Eoy3&>toku*ig_$>+#*kE#3DZ3Nzla-v%z|qc?I|dX74nP diff --git a/target/classes/com/gary/exercise/dto/ActionDto.class b/target/classes/com/gary/exercise/dto/ActionDto.class index 8f640c7f23f440ffa7e84b559971b3f01ee9ff53..20c301e9d332ed8f0498a8ad51235d093f97fc58 100644 GIT binary patch delta 76 zcmeAX>k->f!pg`wIe<-Z@-$X;Ms6_cK5GFZFOcO4l$pgA2PA)j$q4qRK(-yn6(A|h Sxt5W0^FdA)Mj+=Hmm2^qU=-#6 delta 76 zcmeAX>k->f!pg`oIe<-Z@-$X;MlLYxK5GFZACTnBT0ia$%uyP>);o3Z9 delta 280 zcmX@be2|6f)W2Q(7#J9A83ZSCxr^`@r6#7hRwSq9I92*&=A|++m}^W{V3hUq%qvMv zPc5?6^vOyrOVlqd$;{FB$t*6hW@HfXO)bgDPYFmYO3Y0yNi8a7WZ+24%ti*gf7GV}8o8O*>c zWne0iE%!|<0NNdcYSd%_##~1x26mu_IGGqYKok&j0WlK;Hwz;J4+Afdg;ko5fsuh9 HtWW>|C7eV= diff --git a/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl$1.class b/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl$1.class index 865d1116fab9872c8b7b858fdcd043188a28002a..c90b791d118d7f596ff4dbe6df1686b3e1bc9592 100644 GIT binary patch delta 13 UcmZ3_zMg$UBr~JpjU}#P6Hg&2F+GbU&G$x9`2*{r&xZ z@8!z>ETfC?`=2FTV36H&AARbE&8g8nuP0PeAyEmp~ zv{auS%UDLtabj7r7_hqabgWrVrw@og*Aq83tp#Sxr!C27LXdwD#+JRvFvWc)F_rg@|0brVl`p{ z5vq}NZNu!9%5-SyEDgGe+7trqFH`cZSgW8$MJ?)XAbFSO>W5r|@)jA6WGp9IEPFt6 zUA>!8t+}DKjkSjrtP{A|Q^eJW+;~!AMlY}mVFS@J%+LC^w)NfJVbo)z1S+GrxTe&C z+720}H>lW*Erc>Hm%NJXj^ypmQunxAq}BDT#(3uJ(PM?F!yZL0(im`*s>Z=KY%6CmD39IGk4_*{6HHJEq$T-XgHn zlWbUC`X|gxR>D`;1{53>P>UDCxCa}=Xxe>o$AwD*8DD3d8Md+p<{#s~!7 zE>(Vqgf9t7^r*yxcu2uJRlExi3#^z;1y63saCKXAEn8s8l)O*m<{K;V2u><^kBaxo z7@MRTW!C8tan8IevK5MZEE}Rl8&J*@e3)GetntZdLcE}K@sd-I@ zirNl_vYEYJV1BD%>MYWGrLkYyhWwqIEOYw|X3pjr*yokG-m#~VwZBbw z`>gK$nyn4!#2`79rM$Dks#%j?R(g`pO}bjDpAN|>Q||cHWc94Xe&rxa7-lB!ta}+Z z$_WkTiXltHtlRUojWqM+k*=sp3PgP%m)3D9fx0BjZhc5VBqV06LH1&e9`cC_fZ<-r zS@sPXl9HkzP~mx@ogQVHPmLLmQ#n_~rt#fg%4rAn3Qty0N5PeRn$U#AzR49zOd7qW z=4Ne5Tw4nA>+#OmR*LCFAJdYlWD?{8+e#*9V09hElUCMF>9WN#S*PWLJali6o?}oB zWKGu?&^rvrAgY^8({eT0F$hJ!I5`=4RP2!ml`x1q#Hnt%bY(p0pW&%#WxMXUZMw`B z5-#9@#C2R-%lPn|f1nS1V8%&#BE zVu4XqZ8*yXek?w`#Zf6B#%DdBLwqzo$GLl@zzFu#U%;9tuxtYLU6J);h;w0+WOLgH z>N#!@xPToaSi$iwIo>;hMI7HHiNle(BPfrwO9SS3rfu?Ev7Dx@fI>HI!zwgU`d+Nz z>2WRFV=c0%!vnkqJdAa0@+*tXKRIdsNu0-X)P9tl=kW%-F;rDq87ga1c64$IeMSKcd(=(ysj=99>t^M_(%YqBiCMu2FLM9>Aot;%8ylYR-&O%JQ-Ck zMaxHVW&}~H<&RXkGfHcoj0P{QJ4cJR;0(_42=O%CG0JxxzK1J({}eCcCBDnNaJ2L0 z4s0b_xA882J1^4>+}TL#?bykGN9@K9UJrKSD1(&ZW#&HYBE)v%DdP7G_E16t`R*a- z2K<#ll!5LcHXp-WFF;|^-b)8vV6cypejFDmYYQI51ipnJWsTz7c;18H)yd#q#U*-% zy#_DiyW}6BZok6!@dJV=iWl%hj>_;O%2FqHUFI$chWnvjqsk!#A)(-L;=%hnqQFpi zXvV9!MZtrw$_fAYTn%;18BOa_9V1tI(m Jf5$%&{Xb?2AGZJi literal 5075 zcmbVQd0Z6d8Gb%km}MCiS5em*&s9OhO^i_sYRaLJieSVeXc`@t0Y-)$GBYb`V`Cdr zO`}cQq+YdYVv}NQlW1x|q>a68)BCXZT~X7!{kMmGzS(721<{t@Z+Bl zxNDe^GTYX6R2z;PfFk+i3XJu34J)$DF!icfTimU4ZCz^(Ab?>~%y5DHg6e)j+%{rO zrG@JP$iqklK^3DgTA;|Xn<8497H!reZI%&noJic!?N+NnHzVsUyJd@IwJg)3u4V6_ zno$aIb%Di6-qavXdTC+x?XWA&#TblLFiu4X;|0REb4Vc2q`P&^y6%<{uo(qaLksgL zO9PmII}}V*F$t3eM)m_z6?63_-4^g0F?XG2#%UG7ugb+#Oj8h6FmrVOQP4Y`$4q$*WVATTve5!2M0G_%ZZinr=9cj@-1-sT!s%#T^*czOTc-dB!ZIlAZS z^ZPHIJ<$8|;of5>F7G>d`QYA5J)M`%p1bnWxd3KjST2e&M?plzow!S2(olMP$_}U2 z)tcj0=%!f{Z}qINlU(jrF%S0$C?t@Z0@H70mn0+B3$ReZTUC^xRA6q@YK=5$_Kt|Y zUALo#qemE6+l;6lFfmEm3f>&x$6zLnNNO=HOIzDqRu!h*20z{*Fz)KBJ-tsI?A>>Y z0e_|E>C4X^>x=M88R3huS%oGO+2GxUL2#N@FfsU@B-;5rZW#tY33NLWV4{0t?gaPO=*)U=W#pJj^3CZ49G~jV!lM;C%|7RIwii1SStvw&X#opDYmx76nYMTb+@VtWHni0}4K< z;zKfkhU_{08Y-6EV8k?2s`-qH56k2ZQh`LwNII`l1#k$56&z7<6d$<-^GY_*wQTFG zGKM2L$c1H=-Kx2+&ayQ9c52=RsnADNJd2MpmZ^|rl2V5{_SGCOuH+^Gcpk?Ud|br~ z(u%aAD7V=MU8^q>p1>zmbl?P4Bx^PY-8Q0W+?lYI0W{;JicjKGOyzB|f7Uk2jH^tK z{^Zmlm3>9Ut1|5+$8yUubuE_SD0!Whyk3(WHr#~685N)LG$#jnRALr4H9xwj!P=S? zHMQ$&6m$y|-aLM9XgbW93QjsKak8$_&@H;XMpj26SZzf$de=7Odvej|HXF>!dDSTFm1>Ki5ZLNH)yWr4HZ*{q?h9lwI;gxDSgvAtkkuU^K6^uHWMw=Yc-?N zjPL6!EReSD#7!!gm)Q2gTsC*|7<0YnnEXlag>Rr;l*T%V>k^(HR_AKb7FMz3vAmVK z+iW$g(rm3&cXgX^=hPWZG0lzJG-XA4iB7UfW89~6GN@CE-bDClnajGX8D>?i(JKn9 z-~t?k`uo`J384WrW<;9JiIsrt=BtzN-E;l+AW99CD=~WT|I+8S*$3*ZxEA`?aX zPQ1m}(2Xg4RYJ-I4C}$n`e0!fiq2=w_viaVN;hT;9LMyKlJD=vToUHY3gvWSeo3G> z6zImH46NVd7ai9wb|6&Z>p^9G$k&Nw=kRtQwp0KSXw(G`9?j_>0Kg!_kFm5xZPT;$4+xUv{o*QmZ4L_|i#$as}o2_%T`JWKb$75BLc`8Tcus{0u)&y7(dLn8o#z zJ-DAPuB(|;u8=SLhP6}FHsSaA7{=%6 z#B2sVKa-vT-nX5_%pZ*Cvdmt>v;*QQ@%Nw^3BPVZ;sP9 zzaUO|oFsoqFZnz#jq&^@_kNYyyU0E1uRQqvjj)0i`f19@e=;%#b-}O6g73>ItLOr$4f8|Kvxb7^0UD{F7Mu~66rIJv zBN)N=WAgNK9Vp`Si?S}f)PYHSepx=B>cA*Ie_Eai1b25JE7&Pf&GfQqF5?hX&WA;e zHVe&@Xj-hY12CqM1I#Lpk_C%y$q@fd%R=f|J%S7H|WFX5A( ABLDyZ diff --git a/target/classes/com/gary/exercise/socket/ExerciseWebSocketHandler.class b/target/classes/com/gary/exercise/socket/ExerciseWebSocketHandler.class index 3ad2e894877c20d36241628947d318cf916057ee..a2c4991e4decab2780df9f15a99cd6e2e5843b86 100644 GIT binary patch literal 7303 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 JZo75c^AD`Dm)`&Y diff --git a/target/classes/exercise.xlsx b/target/classes/exercise.xlsx index f204e665a2a6f0c91cc8445b74a5ea4ae75f5266..1ad14d3758d5cf140a72f22438de8a59f214755d 100644 GIT binary patch delta 3625 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 diff --git a/target/test-classes/com/gary/exercise/ExerciseApplicationTests.class b/target/test-classes/com/gary/exercise/ExerciseApplicationTests.class index 2a09fafbc48d611d3dea88ecf9c75c7baa97fac9..8019b435aa1b49884c005d7a6ca1a00dac91ec88 100644 GIT binary patch delta 419 zcmYLFyG{Z@6g@M$fV%<<3y2CLDkjP%u9Z~A!dOrkOiZY3COFC(1%=gYXDlo%%{2ao z1u?Pk1N;O(hInV=Ba?g2eV%hOFV0ue{+zyl0NBO)v+ZXr%)m;)PGc5nb;7r6eK9y^ zU~S#Wrr{vR;K)dhdcjy8tH{_XXZDAKaVQ31S6tpogV-3u)`og8JigggPy8&OJCtF6 zczPs8;!1{cG*&HRuVEiVJ$W4lw4Oqpp>QGYgdYt3cIU67x~8wDys93});;QU1t$Rx zSD!+Wt1ksZ{->(D2^46eNKuDSSDfY>Sks&!)$}IFyvD;N@-9sBMe;5zl#s<7J&?s~ zC}W;7BG7U-q_aRtg1&&j!Xhd#Vj+)mrtP0P85b%soxV^HRIx-@BQq&m{$;CDfnz21 Lt5_q{%MIWg;~6Prc|gi%S@`Fk&Nz%M6zan~-SjT1ka9=cqv?Pv1al5js4OjzLSF z(xxm;O?}q3vk8F{fP*rz$$m@c5qP(-^ zX1i_@UWS=gCeLsBvdMw^rAc*UDynv1e0;9LV`pC}?Py}#NjA+XH#P2)JlTYt8Am$g zL5v_88Ng;1AK;;dqUnVX8Rjl{lKzQ07EVl8+#Z|U)haw=_`1D{6UEr+L+)4UWST1} zb=(Nr8#&>4{+o`3nr zx8JNVD&(T?i?HDFC=!u{ZHAj&dG>;D;bVsD|E)^J6X!|<&eN@6o)o=wFMxWQMh^X% zk=%X)_5%(2ut;CC4A@v|ewzw-70Wa;CIh5pjE$yQ>oUx>8M4IiHBvNgU#I^d?%<8Y z$#;aPpJemrus(f)!P01UYhZ10Y366xzhE?lmGqBzVJiI;*MXn#vH_WDhMp#Wz$h|w z>D!0DnN7$lSmPU`TgU6Wq2b1a((f|Me