From dc2ad15ae1efab4d884beb1d08604bab828c997b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Th=C3=A0nh=20=C4=90=E1=BA=A1t?= <91755733+lds217@users.noreply.github.com> Date: Tue, 22 Jul 2025 20:17:49 +0700 Subject: [PATCH] =?UTF-8?q?commit=20=C4=91i=20t=E1=BA=AFm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/component/CheckUpPage/CheckUpPage.java | 65 +++++++++++++++--- .../PrintDialog/UltrasoundResult.java | 7 +- .../print_forms/ultrasoundresult.jrxml | 23 ++++--- src/main/java/BsK/common/entity/Patient.java | 8 ++- .../server/network/handler/ServerHandler.java | 19 +++-- src/main/resources/database/BSK.db | Bin 1196032 -> 1196032 bytes 6 files changed, 97 insertions(+), 25 deletions(-) diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java index 4150b1c..d8f96bf 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java @@ -164,7 +164,7 @@ public class CheckUpPage extends JPanel { private JTextField checkupIdField, customerLastNameField, customerFirstNameField,customerAddressField, customerPhoneField, customerIdField, customerCccdDdcnField; private JTextArea suggestionField, diagnosisField, conclusionField; // Changed symptomsField to suggestionField private JTextPane notesField; - private JComboBox doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, districtComboBox, wardComboBox, checkupTypeComboBox, templateComboBox; + private JComboBox doctorComboBox, statusComboBox, genderComboBox, provinceComboBox, districtComboBox, wardComboBox, checkupTypeComboBox, templateComboBox, orientationComboBox; // Added orientationComboBox private JSpinner customerWeightSpinner, customerHeightSpinner, patientHeartRateSpinner, bloodPressureSystolicSpinner, bloodPressureDiastolicSpinner; private JDatePickerImpl datePicker, dobPicker, recheckupDatePicker; private String[][] medicinePrescription = new String[0][0]; // Initialize to empty @@ -931,7 +931,23 @@ public class CheckUpPage extends JPanel { // Add "Thêm mẫu" button next to template combobox + // Add orientation dropdown gbcTemplate.gridx = 2; gbcTemplate.weightx = 0.0; + JLabel orientationLabel = new JLabel("Hướng in:"); + orientationLabel.setFont(labelFont); + templatePanel.add(orientationLabel, gbcTemplate); + + gbcTemplate.gridx = 3; + orientationComboBox = new JComboBox<>(new String[]{"ngang", "dọc"}); + orientationComboBox.setFont(fieldFont); + orientationComboBox.setPreferredSize(new Dimension(80, 25)); + orientationComboBox.addActionListener(e -> { + printType = (String) orientationComboBox.getSelectedItem(); + }); + templatePanel.add(orientationComboBox, gbcTemplate); + + // Add template button + gbcTemplate.gridx = 4; gbcTemplate.weightx = 0.0; JButton addTemplateButton = new JButton("Thêm mẫu"); addTemplateButton.setFont(fieldFont); addTemplateButton.setBackground(new Color(63, 81, 181)); @@ -1544,6 +1560,24 @@ public class CheckUpPage extends JPanel { return button; } + /** + * Helper method to get the currently selected patient from the queue + * @return The currently selected Patient object, or null if none selected + */ + private Patient getCurrentSelectedPatient() { + if (selectedCheckupId == null) { + return null; + } + + // Find the patient in the queue by checkupId + for (Patient patient : patientQueue) { + if (patient != null && selectedCheckupId.equals(patient.getCheckupId())) { + return patient; + } + } + return null; + } + private void handleActionPanelClick(String name) { switch (name) { case "service": @@ -1611,6 +1645,10 @@ public class CheckUpPage extends JPanel { } // Step 2: Attempt to create the report object BEFORE saving anything. + // Get current patient's Google Drive URL for QR code + Patient currentPatient = getCurrentSelectedPatient(); + String currentPatientDriveUrl = (currentPatient != null) ? currentPatient.getDriveUrl() : ""; + UltrasoundResult ultrasoundResultPrint = new UltrasoundResult( checkupIdField.getText(), customerLastNameField.getText() + " " + customerFirstNameField.getText(), @@ -1624,12 +1662,13 @@ public class CheckUpPage extends JPanel { suggestionField.getText(), recheckupDatePicker.getJFormattedTextField().getText(), selectedImagesForPrint, - printType, + (String) orientationComboBox.getSelectedItem(), // Use selected orientation templateTitle, customerHeightSpinner.getValue().toString(), customerWeightSpinner.getValue().toString(), patientHeartRateSpinner.getValue().toString(), - bloodPressureSystolicSpinner.getValue() + "/" + bloodPressureDiastolicSpinner.getValue() + bloodPressureSystolicSpinner.getValue() + "/" + bloodPressureDiastolicSpinner.getValue(), + currentPatientDriveUrl // Google Drive URL for QR code ); JasperPrint jasperPrintToPrint; @@ -1652,12 +1691,12 @@ public class CheckUpPage extends JPanel { handleSave(); afterSaveActions(statusToSavePrint, "Đã lưu. Đang gửi lệnh in..."); - // Step 4: Finally, print using the pre-made object. + // Step 4: Finally, show print dialog with the pre-made object. try { - JasperPrintManager.printReport(jasperPrintToPrint, false); + JasperPrintManager.printReport(jasperPrintToPrint, true); // true = show print dialog } catch (JRException e) { - log.error("Error printing report directly", e); - JOptionPane.showMessageDialog(this, "Không thể in trực tiếp: " + e.getMessage(), "Lỗi In", JOptionPane.ERROR_MESSAGE); + log.error("Error showing print dialog", e); + JOptionPane.showMessageDialog(this, "Không thể hiển thị hộp thoại in: " + e.getMessage(), "Lỗi In", JOptionPane.ERROR_MESSAGE); } break; case "loupe": // This case now handles "Lưu & Xem" @@ -1676,6 +1715,10 @@ public class CheckUpPage extends JPanel { } // Step 2: Attempt to create the report object BEFORE saving anything. + // Get current patient's Google Drive URL for QR code + Patient viewPatient = getCurrentSelectedPatient(); + String viewPatientDriveUrl = (viewPatient != null) ? viewPatient.getDriveUrl() : ""; + UltrasoundResult ultrasoundResultView = new UltrasoundResult( checkupIdField.getText(), customerLastNameField.getText() + " " + customerFirstNameField.getText(), @@ -1689,12 +1732,13 @@ public class CheckUpPage extends JPanel { suggestionField.getText(), recheckupDatePicker.getJFormattedTextField().getText(), selectedImagesForPrint, - printType, + (String) orientationComboBox.getSelectedItem(), // Use selected orientation templateTitle, customerHeightSpinner.getValue().toString(), customerWeightSpinner.getValue().toString(), patientHeartRateSpinner.getValue().toString(), - bloodPressureSystolicSpinner.getValue() + "/" + bloodPressureDiastolicSpinner.getValue() + bloodPressureSystolicSpinner.getValue() + "/" + bloodPressureDiastolicSpinner.getValue(), + viewPatientDriveUrl // Google Drive URL for QR code ); JasperPrint jasperPrintToView; @@ -4243,6 +4287,8 @@ public class CheckUpPage extends JPanel { String selectedTemplateName = (String) templateComboBox.getSelectedItem(); if (selectedTemplateName == null || allTemplates == null || selectedTemplateName.equals("Không sử dụng mẫu")) { + // Reset orientation to landscape when no template is selected + orientationComboBox.setSelectedItem("ngang"); return; } @@ -4266,6 +4312,7 @@ public class CheckUpPage extends JPanel { // Set template print setting photoNum = Integer.parseInt(template.getPhotoNum()); printType = template.getPrintType(); + orientationComboBox.setSelectedItem(template.getPrintType()); // Update orientation dropdown templateName = template.getTemplateName(); templateTitle = template.getTemplateTitle(); templateGender = template.getTemplateGender(); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java index c0b6bbb..5664185 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/UltrasoundResult.java @@ -77,6 +77,7 @@ public class UltrasoundResult { private final List selectedImages; private final String printType; // "ngang" or "dọc" private final String templateTitle; + private final String driveUrl; // Google Drive URL for QR code // Vitals data private final String customerHeight; @@ -91,7 +92,7 @@ public class UltrasoundResult { String rtfContent, String conclusion, String suggestion, String recheckupDate, List selectedImages, String printType, String templateTitle, String customerHeight, - String customerWeight, String heartRate, String bloodPressure) { + String customerWeight, String heartRate, String bloodPressure, String driveUrl) { // Defensive null checks to prevent JasperReports from crashing on null parameters this.checkupId = checkupId != null ? checkupId : ""; @@ -112,6 +113,7 @@ public class UltrasoundResult { this.customerWeight = customerWeight != null ? customerWeight : ""; this.heartRate = heartRate != null ? heartRate : ""; this.bloodPressure = bloodPressure != null ? bloodPressure : ""; + this.driveUrl = driveUrl != null ? driveUrl : ""; // Google Drive URL } public void showDirectJasperViewer() { @@ -186,6 +188,9 @@ public class UltrasoundResult { } } + // Google Drive URL for QR code generation + parameters.put("driveURL", this.driveUrl); + // Load and compile the report JasperDesign jasperDesign = JRXmlLoader.load(inputStream); JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml index 3cf54a2..7b6556e 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/print_forms/ultrasoundresult.jrxml @@ -44,6 +44,7 @@ + @@ -55,13 +56,13 @@ <element kind="image" uuid="fd80ab38-4cae-409b-84b9-356220d2b1e5" x="0" y="-5" width="70" height="64"> <expression><![CDATA[$P{logoImage}]]></expression> </element> - <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="0" width="267" height="20" fontName="Times New Roman" fontSize="14.0" bold="true"> + <element kind="textField" uuid="eb56d4c8-2a0d-45fa-89a2-ad6528f9a99b" x="70" y="0" width="233" height="20" fontName="Times New Roman" fontSize="14.0" bold="true"> <expression><![CDATA[$P{clinicName}]]></expression> </element> <element kind="staticText" uuid="2677daaf-d0fb-40ad-afaa-513efa16055c" x="70" y="20" width="150" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> <text><![CDATA[Địa chỉ: ]]></text> </element> - <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="106" y="20" width="231" height="15" fontName="Times New Roman" fontSize="10.0"> + <element kind="textField" uuid="796d9ffd-6d2e-4ae3-bdfb-b08183d7d9c0" x="106" y="20" width="193" height="15" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{clinicAddress}]]></expression> </element> <element kind="staticText" uuid="1a1405ee-b3e4-4e98-ac08-6818bc29e902" x="70" y="36" width="150" height="15" fontName="Times New Roman" fontSize="10.0" bold="true" hTextAlign="Left"> @@ -134,17 +135,22 @@ <text><![CDATA[Huyết áp:]]></text> </element> <element kind="textField" uuid="3e1069a6-daea-45c2-b21f-935b49baba45" x="50" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupHeight} +" cm"]]></expression> + <expression><![CDATA[$P{checkupWeight} +" cm"]]></expression> </element> <element kind="textField" uuid="fb080012-3196-4535-bcd2-e87274c66fa5" x="150" y="150" width="50" height="16" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupWeight} + " kg"]]></expression> </element> <element kind="textField" uuid="e4185ffe-8712-41e3-a9ff-2be6569dff15" x="243" y="150" width="47" height="16" fontName="Times New Roman" fontSize="10.0"> - <expression><![CDATA[$P{checkupHeartBeat} + " bpm"]]></expression> + <expression><![CDATA[$P{checkupHeartBeat} + " l/p"]]></expression> </element> <element kind="textField" uuid="6b0b21be-2ca3-4594-bbe9-34868e13eb1e" x="335" y="150" width="63" height="16" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupBloodPressure} +" mmHg"]]></expression> </element> + <element kind="component" uuid="e8842007-3343-4399-a101-76a302d0755d" x="354" y="8" width="41" height="38"> + <component kind="barcode4j:QRCode"> + <codeExpression><![CDATA[$P{driveURL}]]></codeExpression> + </component> + </element> </element> <element kind="frame" uuid="a72ffc70-007e-43af-a566-b34e6e07b312" x="400" y="0" width="400" height="540"> <element kind="staticText" uuid="246a04b0-2565-4987-b7f3-dd369703035c" x="0" y="340" width="100" height="30" forecolor="#FF0905" fontName="Times New Roman" fontSize="15.0" bold="true"> @@ -168,14 +174,11 @@ <element kind="textField" uuid="e90ad772-4425-482d-9e75-f2bc66b9084d" x="0" y="358" width="400" height="70" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupConclusion}]]></expression> </element> - <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-63" y="13" width="60" height="40"> + <element kind="component" uuid="cb28d811-1328-45dc-9461-cfbb88b7eeae" x="-97" y="9" width="50" height="39"> <component kind="barcode4j:Code128"> <codeExpression><![CDATA[$P{barcodeNumber}]]></codeExpression> </component> </element> - <element kind="staticText" uuid="6a7d5f66-d7cc-481f-9fff-8ece0789b3b4" x="-63" y="2" width="61" height="17" fontName="Times New Roman" fontSize="10.0" bold="false" hTextAlign="Center"> - <text><![CDATA[Mã khám bệnh]]></text> - </element> <element kind="textField" uuid="d63165c2-19e2-43ad-8a3f-004e00bffdfe" x="0" y="450" width="230" height="55" fontName="Times New Roman" fontSize="10.0"> <expression><![CDATA[$P{checkupSuggestion}]]></expression> </element> @@ -266,6 +269,10 @@ <expression><![CDATA[$P{image1}]]></expression> </element> </element> + <element kind="staticText" uuid="8f35aa72-22a4-45f0-a35e-8e35e832404e" x="-55" y="46" width="55" height="14" fontName="Times New Roman" fontSize="8.0" bold="false" hTextAlign="Center"> + <printWhenExpression><![CDATA[$P{driveURL} != null && !$P{driveURL}.trim().isEmpty()]]></printWhenExpression> + <text><![CDATA[Xem KQ online]]></text> + </element> </element> </band> </detail> diff --git a/src/main/java/BsK/common/entity/Patient.java b/src/main/java/BsK/common/entity/Patient.java index 32c915f..18ef7c3 100644 --- a/src/main/java/BsK/common/entity/Patient.java +++ b/src/main/java/BsK/common/entity/Patient.java @@ -29,7 +29,7 @@ public class Patient { private String cccdDdcn; private String heartBeat; private String bloodPressure; - + private String driveUrl; public Patient(String[][] array) { this.checkupId = array[0][0]; @@ -54,12 +54,13 @@ public class Patient { this.cccdDdcn = array[0][19]; this.heartBeat = array[0][20]; this.bloodPressure = array[0][21]; + this.driveUrl = array[0][22]; } // New constructor for a single patient data row public Patient(String[] data) { - if (data.length < 22) { - throw new IllegalArgumentException("Patient data array must contain at least 22 elements to include a conclusion."); + if (data.length < 23) { + throw new IllegalArgumentException("Patient data array must contain at least 23 elements to include a conclusion."); } this.checkupId = data[0]; this.checkupDate = data[1]; @@ -83,5 +84,6 @@ public class Patient { this.cccdDdcn = data[19]; this.heartBeat = data[20]; this.bloodPressure = data[21]; + this.driveUrl = data[22]; } } diff --git a/src/main/java/BsK/server/network/handler/ServerHandler.java b/src/main/java/BsK/server/network/handler/ServerHandler.java index 2771b03..b85704b 100644 --- a/src/main/java/BsK/server/network/handler/ServerHandler.java +++ b/src/main/java/BsK/server/network/handler/ServerHandler.java @@ -111,7 +111,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram ResultSet rs = statement.executeQuery( "select a.checkup_id, a.checkup_date, c.customer_last_name, c.customer_first_name,\n" + "d.doctor_first_name, d.doctor_last_name, a.suggestion, a.diagnosis, a.notes, a.status, a.customer_id, \n" + - "c.customer_number, c.customer_address, a.customer_weight, a.customer_height, c.customer_gender, c.customer_dob, a.checkup_type, a.conclusion, a.reCheckupDate, c.cccd_ddcn, a.heart_beat, a.blood_pressure\n" + + "c.customer_number, c.customer_address, a.customer_weight, a.customer_height, c.customer_gender, c.customer_dob,\n" + + "a.checkup_type, a.conclusion, a.reCheckupDate, c.cccd_ddcn, a.heart_beat, a.blood_pressure, c.drive_url\n" + "from checkup as a\n" + "join customer as c on a.customer_id = c.customer_id\n" + "join Doctor D on a.doctor_id = D.doctor_id\n" + @@ -152,11 +153,16 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram String cccdDdcn = rs.getString("cccd_ddcn"); String heartBeat = rs.getString("heart_beat"); String bloodPressure = rs.getString("blood_pressure"); + String driveUrl = rs.getString("drive_url"); + if (driveUrl == null) { + driveUrl = ""; + } String result = String.join("|", checkupId, checkupDate, customerLastName, customerFirstName, doctorLastName + " " + doctorFirstName, suggestion, diagnosis, notes, status, customerId, customerNumber, customerAddress, customerWeight, customerHeight, - customerGender, customerDob, checkupType, conclusion, reCheckupDate, cccdDdcn, heartBeat, bloodPressure + customerGender, customerDob, checkupType, conclusion, reCheckupDate, cccdDdcn, heartBeat, bloodPressure, + driveUrl ); resultList.add(result); @@ -181,7 +187,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram ResultSet rs = statement.executeQuery( "select a.checkup_id, a.checkup_date, c.customer_last_name, c.customer_first_name,\n" + "d.doctor_first_name, d.doctor_last_name, a.suggestion, a.diagnosis, a.notes, a.status, a.customer_id, \n" + - "c.customer_number, c.customer_address, a.customer_weight, a.customer_height, c.customer_gender, c.customer_dob, a.checkup_type, a.conclusion, a.reCheckupDate, c.cccd_ddcn, a.heart_beat, a.blood_pressure\n" + + "c.customer_number, c.customer_address, a.customer_weight, a.customer_height, c.customer_gender, c.customer_dob, a.checkup_type, a.conclusion, a.reCheckupDate, c.cccd_ddcn, a.heart_beat, a.blood_pressure, c.drive_url\n" + "from checkup as a\n" + "join customer as c on a.customer_id = c.customer_id\n" + "join Doctor D on a.doctor_id = D.doctor_id\n" + @@ -226,11 +232,16 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram String cccdDdcn = rs.getString("cccd_ddcn"); String heartBeat = rs.getString("heart_beat"); String bloodPressure = rs.getString("blood_pressure"); + String driveUrl = rs.getString("drive_url"); + if (driveUrl == null) { + driveUrl = ""; + } String result = String.join("|", checkupId, checkupDate, customerLastName, customerFirstName, doctorLastName + " " + doctorFirstName, suggestion, diagnosis, notes, status, customerId, customerNumber, customerAddress, customerWeight, customerHeight, - customerGender, customerDob, checkupType, conclusion, reCheckupDate, cccdDdcn, heartBeat, bloodPressure + customerGender, customerDob, checkupType, conclusion, reCheckupDate, cccdDdcn, heartBeat, bloodPressure, + driveUrl ); resultList.add(result); diff --git a/src/main/resources/database/BSK.db b/src/main/resources/database/BSK.db index 66eff4a3858dc1fc9f84ed8851f1c3c45a86aa33..4f08c2df8415b3102f8475cc95874e885a8518db 100644 GIT binary patch delta 1697 zcmZWoYitx%6ux(6w>vXCGk5QfL%UsOccyi%rEGV*(*`97U0Ns&ffh=@N97R=5VL7& z5lAH9ZkJa8o5CP>wNxeg1Ia32B`ZM!q=_+*2nlFRcv&$9DNQBS#Mt<_yKQNqlYH~z zeD{3kobTKlkJrcJ^_^Z=abRi<tT?s$DDv`MKyd5@(sjpP`BSc1ba4;S3h_U|DctVC z;TDIIFc}x{s&;IE62sI22~Dzs{#VG}e*CPZ?Kj-zwj8e*rB%RGK$dUqSU%2|<hg*V z*nt6708`5G=ig}<<8|!(4zy0tmvB}-zoaCwG||XY>0Ih2V0wdD=|1m8>rUZdftUt! zDYw*)fZvl9F9xOxXtLHZO-Xp{u8HAnqSi5&?CZxRv}fHd9|lbze@wY7K=T&uk1C0! zoNHn@o408H*0DUpJqNmgN1<MnP%r#BFW&R7e>BSs0Dv-LR;eGDT6Wk(89VA<E~L`X zvJHJ__vtl@`_7(#%#j=K$F1AG*|wHVvDlcB;eN(3)(I6VF3WZ@TQjW9T5#-){)PS( zg3+Ecp@n*(AU6Z_BWjb=Xdx;_C*<pLvpg&(<tn<xeA%j6*#Q04sZ|OaiA=Y;R<6nS zISoiZ$?K7%NH|gz49^HgB4s_wDjXFgQ~X!d#Y^H#G=0!%Y3Uc_s1pLn*GLQlz0<c_ zp|saZrWZ)nqhSZtDzl=W1$zETyVjO2kwa3GjHE&7D%vBRk`793;*g}EZ{-i<?MRWY z$wQKfOsS0)I46>!sW7U{<7i8OXT9V7Wa>0n4&OcpgdC&#swbb}?Qqvejq?`Q)-SHp z=1`u0TtjAd>=~s|3``jjf``hFbOMn9y^XcLn#rQJ38KEH+Q|oUsiU&K=wx27jhFS! zpUjgwKMXMF7-{jtnKpWHbdvVN7YhY+8lbPyX*7)bQ7^iSuAv*~G8#gcd+_Q`L_QC} zBDT!tBiBMOz)t7<yN5%Nf}vn3Y!r5iJPHQ|N5NAF6iy0}LZXl<5QQr<9Kv}g{ahh% z!s8%s7CbJeoI}ED$1R}<UF3Gyy4h;xfrY~xGJAf)MX(^L$f_Mc$j(r~PP^ez?HtFc z0FcrFtdj$O;;rPu0PZ2@O}CxA^&3W{V;H;3VJf1%xyuZhmF+K2ok9h8psJvKqv4UV z0!l(_fT@aA9~KC?mq2wsmYQ4Fv<c0dV&Ues>ncdY-#9;y%6JwYBfI-?EYtl9-p1O5 zZtyzs-NWk&lHS5>XFLdKU?(y>0Xt+M?JN_%hZjN8{t)|#{wtQ8spn?SkG}>EH=311 zzmK=sBn2+d9KDa*7`h6$Gm}4n2bn?>aJ}*+#}4*s;fl!e=YeUzYg;CT;g$nYrJy~^ zjrg!d#Yu1RxDWS#z_qZFMDO4)$<|v~AQyhdx{-=3kh`<vC#Q)tkB985)IZwgBmb_1 z-H|8!W8R37#6uh~Qo(_ac+R|_EjJ@OhgJ=ZR#m9`CvIYublt!TS@K|{@Kd?M&!;@g zeDO#qk`#q(U7ig-zBhQNbaN%3525LslP&A@&An&ne{J8{cc18Ge3wOZ3E_PpH;j)T zF`=G{^5er~mVA#_z>zx;yNNNmYP#J5d^AR8<L`JDlL`KTTiML@zwlM&6L<ChxNy2u delta 1193 zcmZXTUu+ar6voe;ncba#_ujo7rtALi?zX`ew!3uNw8auEl+>oNv=V|wEj0#13?df6 z2U0Cv)IQi!8O>;P6B{w{VXc&njs|K1yckWCq*XLvW1<hFVA`Y_LmJe(WgAJD<oEJ@ z=X~efo4LcoUBkm&6JeBmGqN2erw1l!7ywjt9_T2Ikn?0W5%GsOtxsy-sq;may{Ovr zp(W#Zui}TW;eiAk0V|w79tArVy1*2fLSRkaP=mq#D$;I`ztPHG^sPA$gO%FAo$j%H zwBJj?T&>>&7T0FR`ux2f3h`hmIt7*q*p7^E^Y4==giVi;sBHqv;NtV+d;I<4s>l+x zaj>FX+<dZ^Ju8$&Sf8+>r4{ml$JtRtA!vA5Vm(*mCH38t`-`Z`rD$vM%S?AwNFz-^ zf1-n=K)Xqfrs$_+j;xR;NE1JHfY?p_J5j)%-fN<2`@R0B0ue2N_=m$mj2p5IP3dfN zdQ(eX(b&t{RsAt+>Hp|e`Zv6JQM03kEu=+5fRyc65Ky@KWjj*{+quF+cxzeq@vJ(# z{gayF?SlX5+C?%$#z-H@Py_EG6ffe-bQDkHQ`n*w9@LkyK|iKn<3T=PMt7DYsNHCm z`AVRO;kA9T&2DED)uUHFg5auSqPMJzH-SpRiP4UoJv%C?>_G}|DI27$lON%}yLDXF z1DMyBM)3Oj_a{IX;8JfXh|2#@s6E;U+S-JG#yfVETS|_)=FkJ6m9t{;dp2)SJm|F# zdUy16boF$`TJG_ioz6I_5dfTnakN>AZIKgBA&wpmX><zcdHNZhqAT<Uy+nVb%XF4r zrQa6Wzyx)sGAJq5NfBo@gKETTIq>>Q25|(A$dNc6j+f)($Q*^Eax{+4!5qS&9KXAg zVcs)w<t#sR9=vVXAn$0)>VWSTHAyeXAt|rz7H--syWbuCl_imT>KfaI+_x{YGYI9} z{O@c?lyYXsaAMclGtSa=cFQ^U7t@`gYm7Sb0t-oM9u7I5w^p=PZi=k)@V|&ZQifAO z46-a6{0^SG!J<xbfgO{$^MyOPzy<{=ClJF8{J|E5&|yGl)q`-DT=BGd4@nz+dHjGd zCC_Q6`CgBp5%<L3tW7YFsr)S}ikJp?6{mO<fNVMk{$xRSah7!>_uMUZM64WXlzAOO z;!7sWu~g8!Q`f!3I-L3|>}Pl5Z8j%V=GN(@I3zxKcbxluwqgi{tc=x|3o3VVy3EqN Za*o^g0~<lkzbnk+zHpV@k4{%S_#aTSB&GlW