diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b242572 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0980fe5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jay Arre P. Talosig + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 737c50a..612f610 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ ### Professor: Jay D. Abaleta          ### No. of Units: 3 Units ### Prerequisite: [CCPRGG1L Fundamentals of Programming](https://github.com/flexycode/CCPRGG1L_FUNDAMENTALS_COM23P) +### GPA : 3.50 [Passed](https://www.youtube.com/watch?v=19fUYjhGy0c) # 📊 Table of Contents @@ -16,7 +17,7 @@ - [FAQ](#faq)       - [Changelog](#changelogs)   -## [Introduction](#introduction) +## [Introduction](#introduction) This repository contains source code for a Java project that focuses on Intermediate concepts, codes and exercises. #### Course Description: @@ -30,32 +31,31 @@ At the end of the course, the studend must be able to: ###### ⚡ Course Outline: ACO -CI-F- 030(01) Course Outline - CCPRGG2L - COM -# 💻 Lesson +# 💻 Lesson  ### CCPRGG1L Table lecture #### Course Outline and Timeframe -| Week No. | Date Coverage | Topic | Reference | -|----------|--------------------------------------------------------------|-------------------------------------------------------------------|-----------------------------------------------------------------------| -| 1 | April 6 | Class Orientation | Course Syllabus | -| | | Ø University Mission & Vision | | | | | Ø College Mission & Vision | | -| | | Ø Course Syllabi | | -| | | Ø Lab Guidelines and Safety Review | | -| 2 | April 6 | Arrays | Chapter 8&9 Java Programming Eight Edition, Farrell, Joyce | -| 3 | April 13-17 | File and String manipulation | Chapter 7&13 Java Programming Eight Edition, Farrell, Joyce | -| 4 | April 20 | Recursion | Chapter 2 Introduction to Programming in Java: | -| | April 27 | | An Interdisciplinary Approach, 2nd Edition, Robert Sedgewick | -| | | | Chapter 13 Java Programming: From Problem Analysis to | -| | | | Program Design, Fifth Edition., Malik, DS | -| 5 | May 4 | Regular Expression | Chapter 30 Java : The Complete Reference Tenth Edition, Schildt, Herbert, 2018 | -| 6 | May 11 | Introduction to Classes | Chapter 3 Java Programming Eight Edition, Farrell, Joyce | -| 7 | May 18 | Composition, objects, and classes | Chapter 3 Introduction to Programming in Java: An Interdisciplinary Approach, 2nd Edition, Robert Sedgewick | -| 8 | May 25 | Instance method Inheritance Polymorphism | Chapter 10 Java Programming: From Problem Analysis to Program Design, Fifth Edition., Malik, DS | -| 9 | June 1 | Introduction to Swing package | Chapter 14 Java Programming Eight Edition, Farrell, Joyce | -| 10 | June 8 | Interfaces and event-driven programming | Chapter 10 Core Java: Volume II Advanced Features Tenth Edition, Hortsmann, Cay S., 2017 | -| 11 | June 15 | Threads | Chapter 11 Java : The Complete Reference Tenth Edition, Schildt, Herbert, 2018 | -| 12 | July 29 | Runnable interface Synchronization | Chapter 11 Core Java: Volume II Advanced Features Tenth Edition, Hortsmann, Cay S., 2017 | -| 13 | July 6 | Course Synthesis & Final Examination | | +| Week No. | Date Coverage | Topic | Reference | +|----------|---------------|------------------------------------------------------|-----------------------------------------------------------------------------------------------------| +| 1 | April 6 | Class Orientation | Course Syllabus | +| | | - Ø University Mission & Vision | | +| | | - Ø College Mission & Vision | |   +| | | - Ø Course Syllabi | |  +| | | - Ø Lab Guidelines and Safety Review | | +| 2 | April 6 | Arrays | Chapter 8&9 Java Programming Eight Edition, Farrell, Joyce | +| 3 | April 13 | File and String manipulation | Chapter 7&13 Java Programming Eight Edition, Farrell, Joyce | +| 4 | April 20 | Recursion | Chapter 2 Introduction to Programming in Java: An Interdisciplinary Approach, 2nd Edition, Robert Sedgewick | +| | April 27 | | Chapter 13 Java Programming: From Problem Analysis to Program Design, Fifth Edition, Malik, DS | +| 5 | May 4 | Regular Expression | Chapter 30 Java: The Complete Reference Tenth Edition, Schildt, Herbert, 2018 | +| 6 | May 11 | Introduction to Classes | Chapter 3 Java Programming Eight Edition, Farrell, Joyce | +| 7 | May 18 | Composition, objects, and classes | Chapter 3 Introduction to Programming in Java: An Interdisciplinary Approach, 2nd Edition, Robert Sedgewick | +| 8 | May 25 | Instance method Inheritance Polymorphism | Chapter 10 Java Programming: From Problem Analysis to Program Design, Fifth Edition, Malik, DS | +| 9 | June 1 | Introduction to Swing package | Chapter 14 Java Programming Eight Edition, Farrell, Joyce | +| 10 | June 8 | Interfaces and event-driven programming | Chapter 10 Core Java: Volume II Advanced Features Tenth Edition, Hortsmann, Cay S., 2017 | +| 11 | June 15 | Threads | Chapter 11 Java: The Complete Reference Tenth Edition, Schildt, Herbert, 2018 | +| 12 | June 22 | Runnable interface Synchronization | Chapter 11 Core Java: Volume II Advanced Features Tenth Edition, Hortsmann, Cay S., 2017 | +| 13 | June 29 | Course Synthesis & Final Examination | | #### SUGGESTED READINGS AND REFERENCES @@ -101,13 +101,12 @@ coming soon 🤖 Compile the Java code using javac and run the compiled program with java. - ```bash -javac ProgScanner.java -java ProgScanner +javac [java file name]  +java [java file name]  ``` -# 🏆 Contributing  +# 🏆 Contributing   ### 🧠 Submitting Changes @@ -125,7 +124,7 @@ java ProgScanner # 🔑 License  -This course project repository is licensed under the MIT License and National University. +This course project repository is licensed under the [MIT License and National University](https://github.com/flexycode/CCPRGG2L_INTERMEDIATE_PROGRAMMING/blob/main/LICENSE) ## National University of Manila License    @@ -149,7 +148,7 @@ This project is provided "as is" without warranty of any kind, express or implie # 🔭Acknowledgements    -### ✨ Professor Jay A. Abaleta  +### ✨ Professor Jay A. Abaleta   Professor Jay Abaleta is a Senior Software Engineer and esteemed faculty member at National University. With a strong background in teaching the core principles and advanced concepts of Java, he is highly regarded in the field. In addition to his role at National University, Prof. Abaleta also serves as a Professor at Adamson University and as a lecturer of IT/CS at Arba Minch University, sharing his expertise with students worldwide. Having studied at St. Paul University Philippines, Prof. Abaleta brings a wealth of knowledge and experience to his teaching. Known for his friendly and approachable nature, Prof. Abaleta fosters a positive learning environment where students thrive. His dedication and passion for teaching have made him a beloved professor among his students. # 💬FAQ     @@ -158,17 +157,112 @@ To be follow ``` # 📫 Changelogs      -## [4.1.1] - 2024-04-6      -### Added -- Uploaded the Course Syllabus -- Added breakdown and documentation +## [4.1.4] - 2024-04-6       +### Added   +- ✨ Uploaded the Course Syllabus +- ✨ Added breakdown and documentation ### Changed - ✨ revised icon +### Fixed  +- ✨ Revised my documentaion + +## [4.1.5] - 2024-04-14        +### Added   +- ✨ Added Exception-Handling Lab-1 Activity +- ✨ Added File-Handling Lab-2 Activity + +### Changed +- ✨ Change documentation +- ✨ Change some variable and refix function in both Lab Activity + +### Fixed +- ✨ Fixed commit error changes + +## [4.1.4] - 2024-04-20          +### Added  +- ✨ Added StringBuilder.java for StringManipulation activity + +### Changed +- ✨ Changed documentatation + ### Fixed -- Revised my documentaion +- ✨ Fixed commit error changes +- ✨ Fixed Systax error +- ✨ Fixed build structure + +## [4.1.4] - 2024-05-04  +- ✨ Discussion regarding recursion  +- ✨ Added Source code for recursion + +### Activity +- 💻 45 Minutes  +- 💻 Long Quiz + +## [4.1.5] - 2024-05-11          +### Added  +- ✨ Discussion material for Regular Expression (RegEx) +- ✨ Added Lab activity 4 for Regular Expression +- ✨ Added source code example for Regular Expression (RegEx) + +### Changed +- ✨ Changed documentatation +### Activity +- 💻 Lab Class +- 💻 Lab Activity 4 + +## [4.1.5] - 2024-05-18          +### Added  +- ✨ Add Object and Classes java file +- ✨ Add Professor Jay example for object and classes java file + +### Changed +- ✨ Move Object and Classes java file into folder week 6 to week 7 folder + +### Activity +- 💻 Class Lecture about Classes and Object +- 💻 Lab Class +- 💻 Lab Activity 5 Object and Classes + +## [5.1.2] - 2024-05-25           +### Added     +- ✨ Added Polymorphism code example + + +## [6.1.1] - 2024-06-01    +### Activity +- 💻 Long Quiz No. 2                  + +## [6.1.10] - 2024-06-08 +### Added +- ✨ Add 2 Sample of JButton      +- ✨ Add Java file for JCheckBox     +- ✨ Add Java file for JComboBox         +- ✨ Add Java file for JFrame     +- ✨ Add Java file for JLabel           +- ✨ Add JList Java file folder for Single & Multiple Selection    +- ✨ Add Java file for JPanel  +- ✨ Add Java file for JRadioButton +- ✨ Add 3 file folder for Layout: ( BorderLayout, FlowLayout and GridLayout )                          +### Activity  +- 💻 Lab Lecture - Introduction to Swing Packages  + +## [6.1.1] - 2024-06-15    +### Added +- ✨ Add Java file for Image as Background        +- ✨ Add Java file for MouseEvents +- ✨ Add Java Application: Snake Game      +### Activity    +- 💻 Lab Lecture - Introduction to Swing Packages + +## [6.1.2] - 2024-06-22        +### Added +- ✨ Add Thread topic and source code          +- ✨ Add Multithreading with 3 sample Java file        + +  #### [Back to Table of Content](#introduction)     diff --git a/XActivityCode/week_3/Exception-Handling/bin/ArrayExceptionHandling/ArrayExceptionHandling.class b/XActivityCode/week_3/Exception-Handling/bin/ArrayExceptionHandling/ArrayExceptionHandling.class new file mode 100644 index 0000000..09ca8da Binary files /dev/null and b/XActivityCode/week_3/Exception-Handling/bin/ArrayExceptionHandling/ArrayExceptionHandling.class differ diff --git a/XActivityCode/week_3/Exception-Handling/src/ArrayExceptionHandling/ArrayExceptionHandling.java b/XActivityCode/week_3/Exception-Handling/src/ArrayExceptionHandling/ArrayExceptionHandling.java new file mode 100644 index 0000000..a29db9d --- /dev/null +++ b/XActivityCode/week_3/Exception-Handling/src/ArrayExceptionHandling/ArrayExceptionHandling.java @@ -0,0 +1,35 @@ +package ArrayExceptionHandling; + +import java.util.Scanner; + +public class ArrayExceptionHandling { + public static void main(String[] args) { + String[] array = {"One", "Two", "Three"}; + Scanner scanner = new Scanner(System.in); + + System.out.println("Array values: " + String.join(", ", array)); + + while (true) { + try { + System.out.print("Enter Array Index: "); + int index = scanner.nextInt(); + + if (index >= 0 && index < array.length) { + System.out.println("Array Element = " + array[index]); + System.out.println("Exception: Caught"); + } else { + throw new ArrayIndexOutOfBoundsException("Index " + index + " out of bounds for length " + array.length); + } + } catch (ArrayIndexOutOfBoundsException e) { + System.out.println(e.getMessage()); + System.out.println("Quitting..."); + break; + } catch (Exception e) { + System.out.println("Exception: Caught"); + scanner.nextLine(); // Clear the input buffer + } + } + + scanner.close(); + } +} \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/File-Handlingnamepass_0.txt b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_0.txt new file mode 100644 index 0000000..39d6886 --- /dev/null +++ b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_0.txt @@ -0,0 +1 @@ +Juan Limbo34 \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/File-Handlingnamepass_1.txt b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_1.txt new file mode 100644 index 0000000..fad2901 --- /dev/null +++ b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_1.txt @@ -0,0 +1 @@ +Alan 12Laure \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/File-Handlingnamepass_2.txt b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_2.txt new file mode 100644 index 0000000..61984fc --- /dev/null +++ b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_2.txt @@ -0,0 +1 @@ +Kenzo Virus26 \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/File-Handlingnamepass_3.txt b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_3.txt new file mode 100644 index 0000000..b226898 --- /dev/null +++ b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_3.txt @@ -0,0 +1 @@ +Gabriel Macato36 \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/File-Handlingnamepass_4.txt b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_4.txt new file mode 100644 index 0000000..f051df6 --- /dev/null +++ b/XActivityCode/week_3/File-Handling/File-Handlingnamepass_4.txt @@ -0,0 +1 @@ +Joshua 78Manalansan \ No newline at end of file diff --git a/XActivityCode/week_3/File-Handling/bin/FileHandling/FileHandling.class b/XActivityCode/week_3/File-Handling/bin/FileHandling/FileHandling.class new file mode 100644 index 0000000..a2d7bb0 Binary files /dev/null and b/XActivityCode/week_3/File-Handling/bin/FileHandling/FileHandling.class differ diff --git a/XActivityCode/week_3/File-Handling/src/FileHandling/FileHandling.java b/XActivityCode/week_3/File-Handling/src/FileHandling/FileHandling.java new file mode 100644 index 0000000..346a23d --- /dev/null +++ b/XActivityCode/week_3/File-Handling/src/FileHandling/FileHandling.java @@ -0,0 +1,66 @@ +package FileHandling; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Scanner; + +public class FileHandling { + public static void main(String[] args) { + // Create a file containing the usernames and passwords + String[] fileContents = {"Juan Limbo34", "Alan 12Laure", "Kenzo Virus26", "Gabriel Macato36", "Joshua 78Manalansan"}; + createFile(fileContents); + + // Read the file and validate the username and password + Scanner scanner = new Scanner(System.in); + System.out.print("Enter username: "); + String username = scanner.nextLine(); + System.out.print("Enter password: "); + String password = scanner.nextLine(); + + boolean validCredentials = validateCredentials(username, password); + if (validCredentials) { + System.out.println("Successfully entered the program!"); + } else { + System.out.println("Invalid username or password."); + } + + scanner.close(); + } + + private static void createFile(String[] fileContents) { + try { + // Set the file path to your Documents folder + String filePath = "C:\\Users\\flexycode\\eclipse-workspace\\File-Handling"; + for (int i = 0; i < fileContents.length; i++) { + FileWriter textOut = new FileWriter(filePath + "namepass_" + i + ".txt"); + textOut.write(fileContents[i]); + textOut.close(); + } + } catch (IOException e) { + System.out.println("An error occurred while creating the file."); + e.printStackTrace(); + } + } + + private static boolean validateCredentials(String username, String password) { + for (int i = 0; i < 5; i++) { + try { + File file = new File("namepass_" + i + ".txt"); + Scanner fileScanner = new Scanner(file); + String line = fileScanner.nextLine(); + String[] credentials = line.split(" "); + if (credentials.length == 2 && credentials[0].equals(username) && credentials[1].equals(password)) { + fileScanner.close(); + return true; + } + fileScanner.close(); + } catch (FileNotFoundException e) { + System.out.println("An error occurred while reading the file."); + e.printStackTrace(); + } + } + return false; + } +} \ No newline at end of file diff --git a/XActivityCode/week_3/Instruction.txt b/XActivityCode/week_3/Instruction.txt new file mode 100644 index 0000000..6d9b8b2 --- /dev/null +++ b/XActivityCode/week_3/Instruction.txt @@ -0,0 +1,19 @@ +# Lab Activity 1 - Exception Handling + +## Instructions +Create a java Program use the exception handling to Compile and run the Test Exceptions +program. The program will ask the user to input the array index to validate the exception handling in Array Exception, The output should look like this: + +array value of: One, Two, Three + +Enter Array Index: 1 +Output: +Array Element = Two +Exception: Caught + +Enter Array Index: 6 +Output: +Index 6 out of bounds for length 3 + +Quitting... + diff --git a/XActivityCode/week_4/Instruction.txt b/XActivityCode/week_4/Instruction.txt new file mode 100644 index 0000000..2ffe195 --- /dev/null +++ b/XActivityCode/week_4/Instruction.txt @@ -0,0 +1,24 @@ +# Lab Activity 3 - String Handling and Manipulation + +## Instructions +Create a program in JAVA using the StringBuilder class that the user has a choice to use the different methods in class in StringBuilder where the program can Append, Insert, Delete, Replace and Reverse the input string by the user. + +Program Requirements: +Append +The user will enter any string +The program will ask the user what string to append. +Insert + - The user will enter any string + - The program will ask the user which index part of the input string is to insert the new inputted string + +Delete + - The user will enter any string + - The program will ask the user which starting index you want to start the delete methods and how many length of string you want to delete + +Replace + - The user will enter any string + - The program will ask the user which starting index you want to start the replace methods and how many length of string you want to replace + +Reverse + - The user will enter any string + - The program will reverse the input string diff --git a/XActivityCode/week_4/bin/StringBuilder/StringManipulator.class b/XActivityCode/week_4/bin/StringBuilder/StringManipulator.class new file mode 100644 index 0000000..b66a198 Binary files /dev/null and b/XActivityCode/week_4/bin/StringBuilder/StringManipulator.class differ diff --git a/XActivityCode/week_4/src/StringBuilder/StringManipulator.java b/XActivityCode/week_4/src/StringBuilder/StringManipulator.java new file mode 100644 index 0000000..51fd749 --- /dev/null +++ b/XActivityCode/week_4/src/StringBuilder/StringManipulator.java @@ -0,0 +1,103 @@ +package StringBuilder; + +import java.util.Scanner; + +public class StringManipulator { + private static StringBuilder sb; + private static Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + System.out.print("Enter a string: "); + String input = scanner.nextLine(); + sb = new StringBuilder(input); + + boolean continueOperations = true; + + while (continueOperations) { + displayMenu(); + int choice = scanner.nextInt(); + scanner.nextLine(); // Consume the newline character + + switch (choice) { + case 1: + appendString(); + break; + case 2: + insertString(); + break; + case 3: + deleteString(); + break; + case 4: + replaceString(); + break; + case 5: + reverseString(); + break; + case 6: + continueOperations = false; + break; + default: + System.out.println("Invalid choice. Please try again."); + } + } + } + + private static void displayMenu() { + // This method display the menu of the operations to the user ^_^ + System.out.println("\nChoose an operation:"); + System.out.println("1. Append"); + System.out.println("2. Insert"); + System.out.println("3. Delete"); + System.out.println("4. Replace"); + System.out.println("5. Reverse"); + System.out.println("6. Exit"); + } + + private static void appendString() { + // This method appends a string to the end to the end of the existing string ^_^ + System.out.print("Enter a string to append: "); + String appendStr = scanner.nextLine(); + sb.append(appendStr); + System.out.println("Result: " + sb); + } + + private static void insertString() { + // This method insert a portion of the existing string ^_^ + System.out.print("Enter a string to insert: "); + String insertStr = scanner.nextLine(); + System.out.print("Enter the index to insert at: "); + int index = scanner.nextInt(); + sb.insert(index, insertStr); + System.out.println("Result: " + sb); + } + + private static void deleteString() { + // This method delete a portion of the existing string ^_^ + System.out.print("Enter the starting index to delete: "); + int startIndex = scanner.nextInt(); + System.out.print("Enter the length to delete: "); + int length = scanner.nextInt(); + sb.delete(startIndex, startIndex + length); + System.out.println("Result: " + sb); + } + + private static void replaceString() { + // This method replace a portion of the existing string ^_^ + System.out.print("Enter the starting index to replace: "); + int replaceStartIndex = scanner.nextInt(); + System.out.print("Enter the length to replace: "); + int replaceLength = scanner.nextInt(); + scanner.nextLine(); + System.out.print("Enter the replacement string: "); + String replaceStr = scanner.nextLine(); + sb.replace(replaceStartIndex, replaceStartIndex + replaceLength, replaceStr); + System.out.println("Result: " + sb); + } + + private static void reverseString() { + // This method reverse a portion of the existing string ^_^ + sb.reverse(); + System.out.println("Result: " + sb); + } +} \ No newline at end of file diff --git a/XActivityCode/week_5_LQ/LongQuiz/Instruction.txt b/XActivityCode/week_5_LQ/LongQuiz/Instruction.txt new file mode 100644 index 0000000..44f11a9 --- /dev/null +++ b/XActivityCode/week_5_LQ/LongQuiz/Instruction.txt @@ -0,0 +1,17 @@ +// Instruction for this Quiz + +Create a java program that count the following inputs and reverse the string based on the given output below. + +// The Output should be like this precisely like this + +Output: + +Enter Any String: NatioNal Un@verSity 23 + +Numbers in String: : 2 + +Special Character in String: 1 + +The Reverse string is : 32 ytiSrev@nU laNoitaN + +Press any key to continue... diff --git a/XActivityCode/week_5_LQ/LongQuiz/bin/StringCountAndReverse/StringCountAndReverse.class b/XActivityCode/week_5_LQ/LongQuiz/bin/StringCountAndReverse/StringCountAndReverse.class new file mode 100644 index 0000000..8609dba Binary files /dev/null and b/XActivityCode/week_5_LQ/LongQuiz/bin/StringCountAndReverse/StringCountAndReverse.class differ diff --git a/XActivityCode/week_5_LQ/LongQuiz/src/StringCountAndReverse/StringCountAndReverse.java b/XActivityCode/week_5_LQ/LongQuiz/src/StringCountAndReverse/StringCountAndReverse.java new file mode 100644 index 0000000..41a41ce --- /dev/null +++ b/XActivityCode/week_5_LQ/LongQuiz/src/StringCountAndReverse/StringCountAndReverse.java @@ -0,0 +1,39 @@ +package StringCountAndReverse; + +import java.util.Scanner; + +public class StringCountAndReverse { + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.print("Enter Any String: "); + String input = scanner.nextLine(); + + int numberCount = 0; + int specialCharCount = 0; + + // Count the numbers and special characters in the input string + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (Character.isDigit(c)) { + numberCount++; // Increment the number count if the character is a digit :) + } else if (!Character.isLetterOrDigit(c)) { + specialCharCount++; // Increment the special character count if the character is not a letter or digit :) + } + } + + StringBuilder reversedString = new StringBuilder(); + + // Reverse the input string + for (int i = input.length() - 1; i >= 0; i--) { + reversedString.append(input.charAt(i)); // Append each character in reverse order to the StringBuilder :) + } + + // Print the counts and the reversed string + System.out.println("Numbers in String: " + numberCount); + System.out.println("Special Character in String: " + specialCharCount); + System.out.println("The Reverse string is: " + reversedString); + + scanner.close(); + } +} \ No newline at end of file diff --git a/XActivityCode/week_6/RegularExpression/Instruction.txt b/XActivityCode/week_6/RegularExpression/Instruction.txt new file mode 100644 index 0000000..c0c3b7b --- /dev/null +++ b/XActivityCode/week_6/RegularExpression/Instruction.txt @@ -0,0 +1,15 @@ +# Lab Activity 4 - Regular Expression + +### Instructions + +* Create a program that validate the user input using regular expression for the format of Email address and Contact Mobile number. +* The program will use the matcher, pattern and Matches. +* Evaluate the input, if the format is correct for email address. +* Print the message "VALID EMAIL ADDRESS" and for Mobile number print the message "VALID CONTACT NUMBER" otherwise "Invalid EMAIL and MOBILE NUMBER". + +#### Output: + +// Sample format: + +Email: magicMan99@Lucky.com +Mobile Number: +63-918-267-2289 diff --git a/XActivityCode/week_6/RegularExpression/bin/Intermediate/RegexValidator.class b/XActivityCode/week_6/RegularExpression/bin/Intermediate/RegexValidator.class new file mode 100644 index 0000000..598721e Binary files /dev/null and b/XActivityCode/week_6/RegularExpression/bin/Intermediate/RegexValidator.class differ diff --git a/XActivityCode/week_6/RegularExpression/src/Intermediate/RegexValidator.java b/XActivityCode/week_6/RegularExpression/src/Intermediate/RegexValidator.java new file mode 100644 index 0000000..44f4e45 --- /dev/null +++ b/XActivityCode/week_6/RegularExpression/src/Intermediate/RegexValidator.java @@ -0,0 +1,40 @@ +package Intermediate; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class RegexValidator { + public static void main(String[] args) { + // Try statement + try + (Scanner scanner = new Scanner(System.in)) { + System.out.print("Enter an email address: "); + String email = scanner.nextLine(); + System.out.print("Enter a mobile number: "); + String mobileNumber = scanner.nextLine(); + + // Regular expression patterns + String emailPattern = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$"; + String mobileNumberPattern = "^\\+\\d{1,3}-\\d{3}-\\d{3}-\\d{4}$"; + + // Validate email address + Pattern emailRegex = Pattern.compile(emailPattern); + Matcher emailMatcher = emailRegex.matcher(email); + if (emailMatcher.matches()) { + System.out.println("VALID EMAIL ADDRESS"); + } else { + System.out.println("Invalid EMAIL"); + } + + // Validate mobile number + Pattern mobileNumberRegex = Pattern.compile(mobileNumberPattern); + Matcher mobileNumberMatcher = mobileNumberRegex.matcher(mobileNumber); + if (mobileNumberMatcher.matches()) { + System.out.println("VALID CONTACT NUMBER"); + } else { + System.out.println("Invalid MOBILE"); + } + } + } +} \ No newline at end of file diff --git a/XSampleCode/GUI/App.java b/XSampleCode/GUI/App.java new file mode 100644 index 0000000..184edb4 --- /dev/null +++ b/XSampleCode/GUI/App.java @@ -0,0 +1,50 @@ +package GUIExample; + +import javax.swing.*; + +public class GUIExample { + public static void main(String[] args) { + JFrame frame = new JFrame("AI Chat"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + String name = JOptionPane.showInputDialog(frame, "Hi! What's your name?"); // Prompt for user's name + + String[] options = {"About love", "About life"}; + int choice = JOptionPane.showOptionDialog(frame, "Hello " + name + "! How can I help you?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); // Prompt for user's choice + + if (choice == 0) { // If user chooses "About love" + String[] loveOptions = {"Yes", "No"}; + int loveChoice = JOptionPane.showOptionDialog(frame, "Do you want a date this coming weekend?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, loveOptions, loveOptions[0]); // Prompt for love-related choice + + if (loveChoice == 0) { // If user chooses to have a date + String[] dateOptions = {"Flower", "Ice Cream"}; + int dateChoice = JOptionPane.showOptionDialog(frame, "Would you give her a Flower or Ice Cream?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dateOptions, dateOptions[0]); // Prompt for date-related choice + + if (dateChoice >= 0) { // If user makes a choice for the date + JOptionPane.showMessageDialog(frame, "You are really a nice guy charot"); // Display message + } + } + // If user chooses "About life" + } else if (choice == 1) { + String[] tiredOptions = {"Yes", "No"}; + int tiredChoice = JOptionPane.showOptionDialog(frame, "Are you ok? Tired?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, tiredOptions, tiredOptions[0]); // Prompt for tired-related choice + + if (tiredChoice == 0) { // If user is tired + JOptionPane.showMessageDialog(frame, "I'm sorry about that"); // Display message + + // Prompt for user response + String response; + // Use the 'response' variable as needed + response = JOptionPane.showInputDialog(frame, "Please type your response:"); + } + // Display message prompt for Advice about life + JOptionPane.showMessageDialog(frame, "I know you're tired"); + JOptionPane.showMessageDialog(frame, "Learn to rest and not to quit"); + JOptionPane.showMessageDialog(frame, "Life is cruel"); + JOptionPane.showMessageDialog(frame, "Trust me, everything will be alright"); + JOptionPane.showMessageDialog(frame, "Always pray to God"); + JOptionPane.showMessageDialog(frame, "He will help you everyday"); + JOptionPane.showMessageDialog(frame, "CHEER UP ^_^"); + } + } +} \ No newline at end of file diff --git a/XSampleCode/GUI/bin/GUIExample/GUIExample.class b/XSampleCode/GUI/bin/GUIExample/GUIExample.class new file mode 100644 index 0000000..87efbb0 Binary files /dev/null and b/XSampleCode/GUI/bin/GUIExample/GUIExample.class differ diff --git a/XSampleCode/GUI/src/GUIExample/GUIExample.class b/XSampleCode/GUI/src/GUIExample/GUIExample.class new file mode 100644 index 0000000..d1deed0 Binary files /dev/null and b/XSampleCode/GUI/src/GUIExample/GUIExample.class differ diff --git a/XSampleCode/GUI/src/GUIExample/GUIExample.java b/XSampleCode/GUI/src/GUIExample/GUIExample.java new file mode 100644 index 0000000..a25b7b8 --- /dev/null +++ b/XSampleCode/GUI/src/GUIExample/GUIExample.java @@ -0,0 +1,50 @@ +package GUIExample; + +import javax.swing.*; + +public class GUIExample { + public static void main(String[] args) { + JFrame frame = new JFrame("AI Chat"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + String name = JOptionPane.showInputDialog(frame, "Hi! What's your name?"); // Prompt for user's name + + String[] options = {"About love", "About life"}; + int choice = JOptionPane.showOptionDialog(frame, "Hello " + name + "! How can I help you?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); // Prompt for user's choice + + if (choice == 0) { // If user chooses "About love" + String[] loveOptions = {"Yes", "No"}; + int loveChoice = JOptionPane.showOptionDialog(frame, "Do you want a date this coming weekend?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, loveOptions, loveOptions[0]); // Prompt for love-related choice + + if (loveChoice == 0) { // If user chooses to have a date + String[] dateOptions = {"Flower", "Ice Cream"}; + int dateChoice = JOptionPane.showOptionDialog(frame, "Would you give her a Flower or Ice Cream?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, dateOptions, dateOptions[0]); // Prompt for date-related choice + + if (dateChoice >= 0) { // If user makes a choice for the date + JOptionPane.showMessageDialog(frame, "You are really a nice guy charot"); // Display message + } + } + // If user chooses "About life" + } else if (choice == 1) { + String[] tiredOptions = {"Yes", "No"}; + int tiredChoice = JOptionPane.showOptionDialog(frame, "Are you ok? Tired?", "AI Chat", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, tiredOptions, tiredOptions[0]); // Prompt for tired-related choice + + if (tiredChoice == 0) { // If user is tired + JOptionPane.showMessageDialog(frame, "I'm sorry about that"); // Display message + + // Prompt for user response + String response; + // Use the 'response' variable as needed + response = JOptionPane.showInputDialog(frame, "Please type your response:"); + } + // Display message prompt for Advice about life + JOptionPane.showMessageDialog(frame, "I know you're tired"); + JOptionPane.showMessageDialog(frame, "Learn to rest and not to quit"); + JOptionPane.showMessageDialog(frame, "Life is cruel"); + JOptionPane.showMessageDialog(frame, "Trust me, everything will be alright"); + JOptionPane.showMessageDialog(frame, "Always pray to God"); + JOptionPane.showMessageDialog(frame, "He will help you everyday"); + JOptionPane.showMessageDialog(frame, "CHEER UP ^_^"); + } + } +} \ No newline at end of file diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/README.md b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/README.md new file mode 100644 index 0000000..f768e33 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/README.md @@ -0,0 +1,8 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/index.html b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/index.html new file mode 100644 index 0000000..0c589ec --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + + +
+ + + diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package-lock.json b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package-lock.json new file mode 100644 index 0000000..af7896d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package-lock.json @@ -0,0 +1,4233 @@ +{ + "name": "lakeside-hotel", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "lakeside-hotel", + "version": "0.0.0", + "dependencies": { + "axios": "^1.5.0", + "bootstrap": "^5.3.2", + "date-fns": "^2.30.0", + "jwt-decode": "^3.1.2", + "moment": "^2.29.4", + "react": "^18.2.0", + "react-bootstrap": "^2.8.0", + "react-date-range": "^1.4.0", + "react-dom": "^18.2.0", + "react-icons": "^4.11.0", + "react-router-dom": "^6.16.0" + }, + "devDependencies": { + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@vitejs/plugin-react": "^4.0.3", + "eslint": "^8.45.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "vite": "^4.4.5" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", + "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", + "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz", + "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", + "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz", + "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz", + "integrity": "sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz", + "integrity": "sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", + "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz", + "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.3", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.3", + "@babel/types": "^7.23.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.3.tgz", + "integrity": "sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz", + "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", + "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-aria/ssr": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.8.0.tgz", + "integrity": "sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A==", + "dependencies": { + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.9.0.tgz", + "integrity": "sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@restart/hooks": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz", + "integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==", + "dependencies": { + "dequal": "^2.0.3" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@restart/ui": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz", + "integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@popperjs/core": "^2.11.6", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", + "@types/warning": "^3.0.0", + "dequal": "^2.0.3", + "dom-helpers": "^5.2.0", + "uncontrollable": "^8.0.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + } + }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "peerDependencies": { + "react": ">=16.14.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", + "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz", + "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz", + "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz", + "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.7", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz", + "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==" + }, + "node_modules/@types/react": { + "version": "18.2.22", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.22.tgz", + "integrity": "sha512-60fLTOLqzarLED2O3UQImc/lsNRgG0jE/a1mPW9KjMemY0LMITWEsbS4VvZ4p6rorEHd5YKxxmMKSDK505GHpA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", + "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "node_modules/@types/warning": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.1.tgz", + "integrity": "sha512-ywJmriP+nvjBKNBEMaNZgj2irZHoxcKeYcyMLbqhYKbDVn8yCIULy2Ol/tvIb37O3IBeZj3RU4tXqQTtGwoAMg==" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.1.0.tgz", + "integrity": "sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.22.20", + "@babel/plugin-transform-react-jsx-self": "^7.22.5", + "@babel/plugin-transform-react-jsx-source": "^7.22.5", + "@types/babel__core": "^7.20.2", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0" + } + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz", + "integrity": "sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", + "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bootstrap": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz", + "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.21.11", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz", + "integrity": "sha512-xn1UXOKUz7DjdGlg9RrUr0GGiWzI97UQJnugHtH0OLDfJB7jMgoIkYvRIEO1l9EeEERVqeqLYOcFBW9ldjypbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001538", + "electron-to-chromium": "^1.4.526", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001539", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001539.tgz", + "integrity": "sha512-hfS5tE8bnNiNvEOEkm8HElUHroYwlqMMENEzELymy77+tJ6m+gA2krtHl5hxJaj71OlpC2cHZbdSMX1/YEqEkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/classnames": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.528", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.528.tgz", + "integrity": "sha512-UdREXMXzLkREF4jA8t89FQjA8WHI6ssP38PMY4/4KhXFQbtImnghh4GkCgrtiZwLKUKVD2iTVXvDVQjfomEQuA==", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", + "dev": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz", + "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.50.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz", + "integrity": "sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz", + "integrity": "sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA==", + "dev": true, + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.22.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.22.0.tgz", + "integrity": "sha512-H1Ddc/PbZHTDVJSnj8kWptIRSD6AM3pK+mKytuIVF4uoBV7rshFlhhvA58ceJ5wp3Er58w6zj7bykMpYXt3ETw==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz", + "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==", + "dev": true, + "dependencies": { + "flatted": "^3.2.7", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/follow-redirects": { + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", + "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", + "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types-extra": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz", + "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==", + "dependencies": { + "react-is": "^16.3.2", + "warning": "^4.0.0" + }, + "peerDependencies": { + "react": ">=0.14.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-bootstrap": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.8.0.tgz", + "integrity": "sha512-e/aNtxl0Z2ozrIaR82jr6Zz7ss9GSoaXpQaxmvtDUsTZIq/XalkduR/ZXP6vbQHz2T4syvjA+4FbtwELxxmpww==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.3", + "@types/react-transition-group": "^4.4.5", + "classnames": "^2.3.2", + "dom-helpers": "^5.2.1", + "invariant": "^2.2.4", + "prop-types": "^15.8.1", + "prop-types-extra": "^1.1.0", + "react-transition-group": "^4.4.5", + "uncontrollable": "^7.2.1", + "warning": "^4.0.3" + }, + "peerDependencies": { + "@types/react": ">=16.14.8", + "react": ">=16.14.0", + "react-dom": ">=16.14.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-date-range": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-date-range/-/react-date-range-1.4.0.tgz", + "integrity": "sha512-+9t0HyClbCqw1IhYbpWecjsiaftCeRN5cdhsi9v06YdimwyMR2yYHWcgVn3URwtN/txhqKpEZB6UX1fHpvK76w==", + "dependencies": { + "classnames": "^2.2.6", + "prop-types": "^15.7.2", + "react-list": "^0.8.13", + "shallow-equal": "^1.2.1" + }, + "peerDependencies": { + "date-fns": "2.0.0-alpha.7 || >=2.0.0", + "react": "^0.14 || ^15.0.0-rc || >=15.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-icons": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz", + "integrity": "sha512-V+4khzYcE5EBk/BvcuYRq6V/osf11ODUM2J8hg2FDSswRrGvqiYUYPRy4OdrWaQOBj4NcpJfmHZLNaD+VH0TyA==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "node_modules/react-list": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.17.tgz", + "integrity": "sha512-pgmzGi0G5uGrdHzMhgO7KR1wx5ZXVvI3SsJUmkblSAKtewIhMwbQiMuQiTE83ozo04BQJbe0r3WIWzSO0dR1xg==", + "dependencies": { + "prop-types": "15" + }, + "peerDependencies": { + "react": "0.14 || 15 - 18" + } + }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.16.0.tgz", + "integrity": "sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA==", + "dependencies": { + "@remix-run/router": "1.9.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.16.0.tgz", + "integrity": "sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg==", + "dependencies": { + "@remix-run/router": "1.9.0", + "react-router": "6.16.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", + "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "3.29.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.3.tgz", + "integrity": "sha512-T7du6Hum8jOkSWetjRgbwpM6Sy0nECYrYRSmZjayFcOddtKJWU4d17AC3HNUk7HRuqy4p+G7aEZclSHytqUmEg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", + "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-equal": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz", + "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uncontrollable": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", + "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "dependencies": { + "@babel/runtime": "^7.6.3", + "@types/react": ">=16.9.11", + "invariant": "^2.2.4", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">=15.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", + "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", + "dev": true, + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package.json b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package.json new file mode 100644 index 0000000..7a0bcd8 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/package.json @@ -0,0 +1,35 @@ +{ + "name": "lakeside-hotel", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "axios": "^1.5.0", + "bootstrap": "^5.3.2", + "date-fns": "^2.30.0", + "jwt-decode": "^3.1.2", + "moment": "^2.29.4", + "react": "^18.2.0", + "react-bootstrap": "^2.8.0", + "react-date-range": "^1.4.0", + "react-dom": "^18.2.0", + "react-icons": "^4.11.0", + "react-router-dom": "^6.16.0" + }, + "devDependencies": { + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@vitejs/plugin-react": "^4.0.3", + "eslint": "^8.45.0", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "vite": "^4.4.5" + } +} diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/public/vite.svg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.css b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.jsx new file mode 100644 index 0000000..b98d20f --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/App.jsx @@ -0,0 +1,63 @@ +import React from "react" +import "../node_modules/bootstrap/dist/css/bootstrap.min.css" +import "/node_modules/bootstrap/dist/js/bootstrap.min.js" +import ExistingRooms from "./components/room/ExistingRooms" +import { BrowserRouter as Router, Routes, Route } from "react-router-dom" +import Home from "./components/home/Home" +import EditRoom from "./components/room/EditRoom" +import AddRoom from "./components/room/AddRoom" +import NavBar from "./components/layout/NavBar" +import Footer from "./components/layout/Footer" +import RoomListing from "./components/room/RoomListing" +import Admin from "./components/admin/Admin" +import Checkout from "./components/booking/Checkout" +import BookingSuccess from "./components/booking/BookingSuccess" +import Bookings from "./components/booking/Bookings" +import FindBooking from "./components/booking/FindBooking" +import Login from "./components/auth/Login" +import Registration from "./components/auth/Registration" +import Profile from "./components/auth/Profile" +import { AuthProvider } from "./components/auth/AuthProvider" +import RequireAuth from "./components/auth/RequireAuth" + +function App() { + return ( + +
+ + + + } /> + } /> + } /> + } /> + + + + + } + /> + } /> + + } /> + } /> + } /> + } /> + + } /> + } /> + + } /> + } /> + + +
+
+ ) +} + +export default App diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/parrall.jpg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/parrall.jpg new file mode 100644 index 0000000..0344591 Binary files /dev/null and b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/parrall.jpg differ diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/room7.jpg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/room7.jpg new file mode 100644 index 0000000..be84a14 Binary files /dev/null and b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/room7.jpg differ diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services-1.jpg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services-1.jpg new file mode 100644 index 0000000..2d0cac2 Binary files /dev/null and b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services-1.jpg differ diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services4.jpg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services4.jpg new file mode 100644 index 0000000..0dd6af6 Binary files /dev/null and b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/images/services4.jpg differ diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/react.svg b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/admin/Admin.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/admin/Admin.jsx new file mode 100644 index 0000000..3b5917c --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/admin/Admin.jsx @@ -0,0 +1,15 @@ +import React from "react" +import { Link } from "react-router-dom" + +const Admin = () => { + return ( +
+

Welcome to Adimin Panel

+
+ Manage Rooms
+ Manage Bookings +
+ ) +} + +export default Admin diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/AuthProvider.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/AuthProvider.jsx new file mode 100644 index 0000000..3a06ad5 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/AuthProvider.jsx @@ -0,0 +1,38 @@ +import React, { createContext, useState, useContext } from "react" +import jwt_decode from "jwt-decode" + +export const AuthContext = createContext({ + user: null, + handleLogin: (token) => {}, + handleLogout: () => {} +}) + +export const AuthProvider = ({ children }) => { + const [user, setUser] = useState(null) + + const handleLogin = (token) => { + const decodedUser = jwt_decode(token) + localStorage.setItem("userId", decodedUser.sub) + localStorage.setItem("userRole", decodedUser.roles) + localStorage.setItem("token", token) + setUser(decodedUser) + } + + const handleLogout = () => { + localStorage.removeItem("userId") + localStorage.removeItem("userRole") + localStorage.removeItem("token") + setUser(null) + } + + return ( + + {children} + + ) +} + +export const useAuth = () => { + return useContext(AuthContext) +} + diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Login.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Login.jsx new file mode 100644 index 0000000..5e17861 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Login.jsx @@ -0,0 +1,87 @@ +import React, { useState } from "react" +import { loginUser } from "../utils/ApiFunctions" +import { Link, useLocation, useNavigate } from "react-router-dom" +import { useAuth } from "./AuthProvider" + +const Login = () => { + const [errorMessage, setErrorMessage] = useState("") + const [login, setLogin] = useState({ + email: "", + password: "" + }) + + const navigate = useNavigate() + const auth = useAuth() + const location = useLocation() + const redirectUrl = location.state?.path || "/" + + const handleInputChange = (e) => { + setLogin({ ...login, [e.target.name]: e.target.value }) + } + + const handleSubmit = async (e) => { + e.preventDefault() + const success = await loginUser(login) + if (success) { + const token = success.token + auth.handleLogin(token) + navigate(redirectUrl, { replace: true }) + } else { + setErrorMessage("Invalid username or password. Please try again.") + } + setTimeout(() => { + setErrorMessage("") + }, 4000) + } + + return ( +
+ {errorMessage &&

{errorMessage}

} +

Login

+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ + + Don't' have an account yet? Register + +
+
+
+ ) +} + +export default Login diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Logout.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Logout.jsx new file mode 100644 index 0000000..fc3029a --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Logout.jsx @@ -0,0 +1,31 @@ +import React, { useContext } from "react" +import { AuthContext } from "./AuthProvider" +import { Link, useNavigate } from "react-router-dom" + +const Logout = () => { + const auth = useContext(AuthContext) + const navigate = useNavigate() + + const handleLogout = () => { + auth.handleLogout() + navigate("/", { state: { message: " You have been logged out!" } }) + } + + return ( + <> +
  • + + Profile + +
  • +
  • +
    +
  • + + + ) +} + +export default Logout diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Profile.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Profile.jsx new file mode 100644 index 0000000..fad327d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Profile.jsx @@ -0,0 +1,207 @@ +import React, { useEffect, useState } from "react" +import { deleteUser, getBookingsByUserId, getUser } from "../utils/ApiFunctions" +import { useNavigate } from "react-router-dom" +import moment from "moment" + +const Profile = () => { + const [user, setUser] = useState({ + id: "", + email: "", + firstName: "", + lastName: "", + roles: [{ id: "", name: "" }] + }) + + const [bookings, setBookings] = useState([ + { + id: "", + room: { id: "", roomType: "" }, + checkInDate: "", + checkOutDate: "", + bookingConfirmationCode: "" + } + ]) + const [message, setMessage] = useState("") + const [errorMessage, setErrorMessage] = useState("") + const navigate = useNavigate() + + const userId = localStorage.getItem("userId") + const token = localStorage.getItem("token") + + useEffect(() => { + const fetchUser = async () => { + try { + const userData = await getUser(userId, token) + setUser(userData) + } catch (error) { + console.error(error) + } + } + + fetchUser() + }, [userId]) + + useEffect(() => { + const fetchBookings = async () => { + try { + const response = await getBookingsByUserId(userId, token) + setBookings(response) + } catch (error) { + console.error("Error fetching bookings:", error.message) + setErrorMessage(error.message) + } + } + + fetchBookings() + }, [userId]) + + const handleDeleteAccount = async () => { + const confirmed = window.confirm( + "Are you sure you want to delete your account? This action cannot be undone." + ) + if (confirmed) { + await deleteUser(userId) + .then((response) => { + setMessage(response.data) + localStorage.removeItem("token") + localStorage.removeItem("userId") + localStorage.removeItem("userRole") + navigate("/") + window.location.reload() + }) + .catch((error) => { + setErrorMessage(error.data) + }) + } + } + + return ( +
    + {errorMessage &&

    {errorMessage}

    } + {message &&

    {message}

    } + {user ? ( +
    +

    User Information

    +
    +
    +
    +
    +
    +
    + Profile +
    +
    + +
    +
    +
    + +
    +

    {user.id}

    +
    +
    +
    + +
    + +
    +

    {user.firstName}

    +
    +
    +
    + +
    + +
    +

    {user.lastName}

    +
    +
    +
    + +
    + +
    +

    {user.email}

    +
    +
    +
    + +
    + +
    +
      + {user.roles.map((role) => ( +
    • + {role.name} +
    • + ))} +
    +
    +
    +
    +
    +
    +
    + +

    Booking History

    + + {bookings.length > 0 ? ( + + + + + + + + + + + + + + {bookings.map((booking, index) => ( + + + + + + + + + + ))} + +
    Booking IDRoom IDRoom TypeCheck In DateCheck Out DateConfirmation CodeStatus
    {booking.id}{booking.room.id}{booking.room.roomType} + {moment(booking.checkInDate).subtract(1, "month").format("MMM Do, YYYY")} + + {moment(booking.checkOutDate) + .subtract(1, "month") + .format("MMM Do, YYYY")} + {booking.bookingConfirmationCode}On-going
    + ) : ( +

    You have not made any bookings yet.

    + )} + +
    +
    + +
    +
    +
    +
    +
    + ) : ( +

    Loading user data...

    + )} +
    + ) +} + +export default Profile diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Registration.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Registration.jsx new file mode 100644 index 0000000..3049692 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/Registration.jsx @@ -0,0 +1,120 @@ +import React, { useState } from "react" +import { registerUser } from "../utils/ApiFunctions" +import { Link } from "react-router-dom" + +const Registration = () => { + const [registration, setRegistration] = useState({ + firstName: "", + lastName: "", + email: "", + password: "" + }) + + const [errorMessage, setErrorMessage] = useState("") + const [successMessage, setSuccessMessage] = useState("") + + const handleInputChange = (e) => { + setRegistration({ ...registration, [e.target.name]: e.target.value }) + } + + const handleRegistration = async (e) => { + e.preventDefault() + try { + const result = await registerUser(registration) + setSuccessMessage(result) + setErrorMessage("") + setRegistration({ firstName: "", lastName: "", email: "", password: "" }) + } catch (error) { + setSuccessMessage("") + setErrorMessage(`Registration error : ${error.message}`) + } + setTimeout(() => { + setErrorMessage("") + setSuccessMessage("") + }, 5000) + } + + return ( +
    + {errorMessage &&

    {errorMessage}

    } + {successMessage &&

    {successMessage}

    } + +

    Register

    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + + + Already have an account? Login + +
    +
    +
    + ) +} + +export default Registration diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/RequireAuth.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/RequireAuth.jsx new file mode 100644 index 0000000..9663079 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/auth/RequireAuth.jsx @@ -0,0 +1,12 @@ +import React from "react" +import { Navigate, useLocation } from "react-router-dom" + +const RequireAuth = ({ children }) => { + const user = localStorage.getItem("userId") + const location = useLocation() + if (!user) { + return + } + return children +} +export default RequireAuth diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingForm.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingForm.jsx new file mode 100644 index 0000000..5ce9c76 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingForm.jsx @@ -0,0 +1,254 @@ +import React, { useEffect } from "react" +import moment from "moment" +import { useState } from "react" +import { Form, FormControl, Button } from "react-bootstrap" +import BookingSummary from "./BookingSummary" +import { bookRoom, getRoomById } from "../utils/ApiFunctions" +import { useNavigate, useParams } from "react-router-dom" +import { useAuth } from "../auth/AuthProvider" + +const BookingForm = () => { + const [validated, setValidated] = useState(false) + const [isSubmitted, setIsSubmitted] = useState(false) + const [errorMessage, setErrorMessage] = useState("") + const [roomPrice, setRoomPrice] = useState(0) + +const currentUser = localStorage.getItem("userId") + + const [booking, setBooking] = useState({ + guestFullName: "", + guestEmail: currentUser, + checkInDate: "", + checkOutDate: "", + numOfAdults: "", + numOfChildren: "" + }) + + const { roomId } = useParams() + const navigate = useNavigate() + + const handleInputChange = (e) => { + const { name, value } = e.target + setBooking({ ...booking, [name]: value }) + setErrorMessage("") + } + + + const getRoomPriceById = async (roomId) => { + try { + const response = await getRoomById(roomId) + setRoomPrice(response.roomPrice) + } catch (error) { + throw new Error(error) + } + } + + useEffect(() => { + getRoomPriceById(roomId) + }, [roomId]) + + const calculatePayment = () => { + const checkInDate = moment(booking.checkInDate) + const checkOutDate = moment(booking.checkOutDate) + const diffInDays = checkOutDate.diff(checkInDate, "days") + const paymentPerDay = roomPrice ? roomPrice : 0 + return diffInDays * paymentPerDay + } + + const isGuestCountValid = () => { + const adultCount = parseInt(booking.numOfAdults) + const childrenCount = parseInt(booking.numOfChildren) + const totalCount = adultCount + childrenCount + return totalCount >= 1 && adultCount >= 1 + } + + const isCheckOutDateValid = () => { + if (!moment(booking.checkOutDate).isSameOrAfter(moment(booking.checkInDate))) { + setErrorMessage("Check-out date must be after check-in date") + return false + } else { + setErrorMessage("") + return true + } + } + + const handleSubmit = (e) => { + e.preventDefault() + const form = e.currentTarget + if (form.checkValidity() === false || !isGuestCountValid() || !isCheckOutDateValid()) { + e.stopPropagation() + } else { + setIsSubmitted(true) + } + setValidated(true) + } + + const handleFormSubmit = async () => { + try { + const confirmationCode = await bookRoom(roomId, booking) + setIsSubmitted(true) + navigate("/booking-success", { state: { message: confirmationCode } }) + } catch (error) { + const errorMessage = error.message + console.log(errorMessage) + navigate("/booking-success", { state: { error: errorMessage } }) + } + } + + return ( + <> +
    +
    +
    +
    +

    Reserve Room

    + +
    + + + Fullname + + + + Please enter your fullname. + + + + + + Email + + + + Please enter a valid email address. + + + +
    + Lodging Period +
    +
    + + Check-in date + + + + Please select a check in date. + +
    + +
    + + Check-out date + + + + Please select a check out date. + +
    + {errorMessage &&

    {errorMessage}

    } +
    +
    + +
    + Number of Guest +
    +
    + + Adults + + + + Please select at least 1 adult. + +
    +
    + + Children + + + + Select 0 if no children + +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    + {isSubmitted && ( + + )} +
    +
    +
    + + ) +} +export default BookingForm diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSuccess.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSuccess.jsx new file mode 100644 index 0000000..08110a4 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSuccess.jsx @@ -0,0 +1,30 @@ +import React from "react" +import { Link, useLocation } from "react-router-dom" +import Header from "../common/Header" + +const BookingSuccess = () => { + const location = useLocation() + const message = location.state?.message + const error = location.state?.error + return ( +
    +
    +
    + {message ? ( +
    +

    Booking Success!

    +

    {message}

    +
    + ) : ( +
    +

    Error Booking Room!

    +

    {error}

    + +
    + )} +
    +
    + ) +} + +export default BookingSuccess diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSummary.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSummary.jsx new file mode 100644 index 0000000..d04e83a --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingSummary.jsx @@ -0,0 +1,96 @@ +import React, { useState, useEffect } from "react" +import moment from "moment" +import Button from "react-bootstrap/Button" +import { useNavigate } from "react-router-dom" + +const BookingSummary = ({ booking, payment, isFormValid, onConfirm }) => { + const checkInDate = moment(booking.checkInDate) + const checkOutDate = moment(booking.checkOutDate) + const numberOfDays = checkOutDate.diff(checkInDate, "days") + const [isBookingConfirmed, setIsBookingConfirmed] = useState(false) + const [isProcessingPayment, setIsProcessingPayment] = useState(false) + const navigate = useNavigate() + + const handleConfirmBooking = () => { + setIsProcessingPayment(true) + setTimeout(() => { + setIsProcessingPayment(false) + setIsBookingConfirmed(true) + onConfirm() + }, 3000) + } + + useEffect(() => { + if (isBookingConfirmed) { + navigate("/booking-success") + } + }, [isBookingConfirmed, navigate]) + + return ( +
    +
    +
    +

    Reservation Summary

    +

    + Name: {booking.guestFullName} +

    +

    + Email: {booking.guestEmail} +

    +

    + Check-in Date: {moment(booking.checkInDate).format("MMM Do YYYY")} +

    +

    + Check-out Date: {moment(booking.checkOutDate).format("MMM Do YYYY")} +

    +

    + Number of Days Booked: {numberOfDays} +

    + +
    +
    Number of Guest
    + + Adult{booking.numOfAdults > 1 ? "s" : ""} : {booking.numOfAdults} + + +

    Children : {booking.numOfChildren}

    +
    +
    + + {payment > 0 ? ( + <> +

    + Total payment: ${payment} +

    + + {isFormValid && !isBookingConfirmed ? ( + + ) : isBookingConfirmed ? ( +
    +
    + Loading... +
    +
    + ) : null} + + ) : ( +

    Check-out date must be after check-in date.

    + )} +
    +
    + ) +} + +export default BookingSummary diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Bookings.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Bookings.jsx new file mode 100644 index 0000000..a240493 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Bookings.jsx @@ -0,0 +1,51 @@ +import React, { useState, useEffect } from "react" +import { cancelBooking, getAllBookings } from "../utils/ApiFunctions" +import Header from "../common/Header" +import BookingsTable from "./BookingsTable" + +const Bookings = () => { + const [bookingInfo, setBookingInfo] = useState([]) + const [isLoading, setIsLoading] = useState(true) + const [error, setError] = useState("") + + useEffect(() => { + setTimeout(() => { + getAllBookings() + .then((data) => { + setBookingInfo(data) + setIsLoading(false) + }) + .catch((error) => { + setError(error.message) + setIsLoading(false) + }) + }, 1000) + }, []) + + const handleBookingCancellation = async (bookingId) => { + try { + await cancelBooking(bookingId) + const data = await getAllBookings() + setBookingInfo(data) + } catch (error) { + setError(error.message) + } + } + + return ( +
    +
    + {error &&
    {error}
    } + {isLoading ? ( +
    Loading existing bookings
    + ) : ( + + )} +
    + ) +} + +export default Bookings diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingsTable.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingsTable.jsx new file mode 100644 index 0000000..68d4940 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/BookingsTable.jsx @@ -0,0 +1,78 @@ +import { parseISO } from "date-fns" +import React, { useState, useEffect } from "react" +import DateSlider from "../common/DateSlider" + +const BookingsTable = ({ bookingInfo, handleBookingCancellation }) => { + const [filteredBookings, setFilteredBookings] = useState(bookingInfo) + + const filterBooknigs = (startDate, endDate) => { + let filtered = bookingInfo + if (startDate && endDate) { + filtered = bookingInfo.filter((booking) => { + const bookingStarDate = parseISO(booking.checkInDate) + const bookingEndDate = parseISO(booking.checkOutDate) + return ( + bookingStarDate >= startDate && bookingEndDate <= endDate && bookingEndDate > startDate + ) + }) + } + setFilteredBookings(filtered) + } + + useEffect(() => { + setFilteredBookings(bookingInfo) + }, [bookingInfo]) + + return ( +
    + + + + + + + + + + + + + + + + + + + + + {filteredBookings.map((booking, index) => ( + + + + + + + + + + + + + + + + ))} + +
    S/NBooking IDRoom IDRoom TypeCheck-In DateCheck-Out DateGuest NameGuest EmailAdultsChildrenTotal GuestConfirmation CodeActions
    {index + 1}{booking.id}{booking.room.id}{booking.room.roomType}{booking.checkInDate}{booking.checkOutDate}{booking.guestName}{booking.guestEmail}{booking.numOfAdults}{booking.numOfChildren}{booking.totalNumOfGuests}{booking.bookingConfirmationCode} + +
    + {filterBooknigs.length === 0 &&

    No booking found for the selected dates

    } +
    + ) +} + +export default BookingsTable diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Checkout.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Checkout.jsx new file mode 100644 index 0000000..7e9d7f1 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/Checkout.jsx @@ -0,0 +1,112 @@ +import React, { useEffect, useState } from "react" +import BookingForm from "../booking/BookingForm" +import { + FaUtensils, + FaWifi, + FaTv, + FaWineGlassAlt, + FaParking, + FaCar, + FaTshirt +} from "react-icons/fa" + +import { useParams } from "react-router-dom" +import { getRoomById } from "../utils/ApiFunctions" +import RoomCarousel from "../common/RoomCarousel" + +const Checkout = () => { + const [error, setError] = useState(null) + const [isLoading, setIsLoading] = useState(true) + const [roomInfo, setRoomInfo] = useState({ + photo: "", + roomType: "", + roomPrice: "" + }) + + const { roomId } = useParams() + + useEffect(() => { + setTimeout(() => { + getRoomById(roomId) + .then((response) => { + setRoomInfo(response) + setIsLoading(false) + }) + .catch((error) => { + setError(error) + setIsLoading(false) + }) + }, 1000) + }, [roomId]) + + return ( +
    +
    +
    +
    + {isLoading ? ( +

    Loading room information...

    + ) : error ? ( +

    {error}

    + ) : ( +
    + Room photo + + + + + + + + + + + + + + + +
    Room Type:{roomInfo.roomType}
    Price per night:${roomInfo.roomPrice}
    Room Service: +
      +
    • + Wifi +
    • +
    • + Netfilx Premium +
    • +
    • + Breakfast +
    • +
    • + Mini bar refreshment +
    • +
    • + Car Service +
    • +
    • + Parking Space +
    • +
    • + Laundry +
    • +
    +
    +
    + )} +
    +
    + +
    +
    +
    +
    + +
    +
    + ) +} +export default Checkout diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/FindBooking.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/FindBooking.jsx new file mode 100644 index 0000000..bf64057 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/booking/FindBooking.jsx @@ -0,0 +1,144 @@ +import React, { useState } from "react" +import moment from "moment" +import { cancelBooking, getBookingByConfirmationCode } from "../utils/ApiFunctions" + +const FindBooking = () => { + const [confirmationCode, setConfirmationCode] = useState("") + const [error, setError] = useState(null) + const [successMessage, setSuccessMessage] = useState("") + const [isLoading, setIsLoading] = useState(false) + const [bookingInfo, setBookingInfo] = useState({ + id: "", + bookingConfirmationCode: "", + room: { id: "", roomType: "" }, + roomNumber: "", + checkInDate: "", + checkOutDate: "", + guestName: "", + guestEmail: "", + numOfAdults: "", + numOfChildren: "", + totalNumOfGuests: "" + }) + + const emptyBookingInfo = { + id: "", + bookingConfirmationCode: "", + room: { id: "", roomType: "" }, + roomNumber: "", + checkInDate: "", + checkOutDate: "", + guestName: "", + guestEmail: "", + numOfAdults: "", + numOfChildren: "", + totalNumOfGuests: "" + } + const [isDeleted, setIsDeleted] = useState(false) + + const handleInputChange = (event) => { + setConfirmationCode(event.target.value) + } + + const handleFormSubmit = async (event) => { + event.preventDefault() + setIsLoading(true) + + try { + const data = await getBookingByConfirmationCode(confirmationCode) + setBookingInfo(data) + setError(null) + } catch (error) { + setBookingInfo(emptyBookingInfo) + if (error.response && error.response.status === 404) { + setError(error.response.data.message) + } else { + setError(error.message) + } + } + + setTimeout(() => setIsLoading(false), 2000) + } + + const handleBookingCancellation = async (bookingId) => { + try { + await cancelBooking(bookingInfo.id) + setIsDeleted(true) + setSuccessMessage("Booking has been cancelled successfully!") + setBookingInfo(emptyBookingInfo) + setConfirmationCode("") + setError(null) + } catch (error) { + setError(error.message) + } + setTimeout(() => { + setSuccessMessage("") + setIsDeleted(false) + }, 2000) + } + + return ( + <> +
    +

    Find My Booking

    +
    +
    + + + +
    +
    + + {isLoading ? ( +
    Finding your booking...
    + ) : error ? ( +
    Error: {error}
    + ) : bookingInfo.bookingConfirmationCode ? ( +
    +

    Booking Information

    +

    Confirmation Code: {bookingInfo.bookingConfirmationCode}

    +

    Room Number: {bookingInfo.room.id}

    +

    Room Type: {bookingInfo.room.roomType}

    +

    + Check-in Date:{" "} + {moment(bookingInfo.checkInDate).subtract(1, "month").format("MMM Do, YYYY")} +

    +

    + Check-out Date:{" "} + {moment(bookingInfo.checkInDate).subtract(1, "month").format("MMM Do, YYYY")} +

    +

    Full Name: {bookingInfo.guestName}

    +

    Email Address: {bookingInfo.guestEmail}

    +

    Adults: {bookingInfo.numOfAdults}

    +

    Children: {bookingInfo.numOfChildren}

    +

    Total Guest: {bookingInfo.totalNumOfGuests}

    + + {!isDeleted && ( + + )} +
    + ) : ( +
    find booking...
    + )} + + {isDeleted &&
    {successMessage}
    } +
    + + ) +} + +export default FindBooking diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/DateSlider.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/DateSlider.jsx new file mode 100644 index 0000000..61cc07b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/DateSlider.jsx @@ -0,0 +1,39 @@ +import React, { useState } from "react" +import "react-date-range/dist/styles.css" +import "react-date-range/dist/theme/default.css" +import { DateRangePicker } from "react-date-range" + +const DateSlider = ({ onDateChange, onFilterChange }) => { + const [dateRange, setDateRange] = useState({ + startDate: undefined, + endDate: undefined, + key: "selection" + }) + + const handleSelect = (ranges) => { + setDateRange(ranges.selection) + onDateChange(ranges.selection.startDate, ranges.selection.endDate) + onFilterChange(ranges.selection.startDate, ranges.selection.endDate) + } + + const handleClearFilter = () => { + setDateRange({ + startDate: undefined, + endDate: undefined, + key: "selection" + }) + onDateChange(null, null) + onFilterChange(null, null) + } + return ( + <> +
    Filter bookings by date
    + + + + ) +} + +export default DateSlider diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Header.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Header.jsx new file mode 100644 index 0000000..cedb0af --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Header.jsx @@ -0,0 +1,14 @@ +import React from "react" + +const Header = ({ title }) => { + return ( +
    +
    +
    +

    {title}

    +
    +
    + ) +} + +export default Header diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/HotelService.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/HotelService.jsx new file mode 100644 index 0000000..729fcc6 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/HotelService.jsx @@ -0,0 +1,98 @@ +import React from "react" +import { Container, Row, Col, Card } from "react-bootstrap" +import Header from "./Header" +import { + FaClock, + FaCocktail, + FaParking, + FaSnowflake, + FaTshirt, + FaUtensils, + FaWifi +} from "react-icons/fa" + +const HotelService = () => { + return ( + <> +
    +
    + + +

    + Services at lakeSide - Hotel + + 24-Hour Front Desk + +

    +
    +
    + + + + + + + WiFi + + Stay connected with high-speed internet access. + + + + + + + + Breakfast + + Start your day with a delicious breakfast buffet. + + + + + + + + Laundry + + Keep your clothes clean and fresh with our laundry service. + + + + + + + + Mini-bar + + Enjoy a refreshing drink or snack from our in-room mini-bar. + + + + + + + + Parking + + Park your car conveniently in our on-site parking lot. + + + + + + + + Air conditioning + + Stay cool and comfortable with our air conditioning system. + + + + +
    +
    + + ) +} + +export default HotelService diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Parallax.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Parallax.jsx new file mode 100644 index 0000000..0a37c26 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/Parallax.jsx @@ -0,0 +1,19 @@ +import React from "react" +import { Container } from "react-bootstrap" + +const Parallax = () => { + return ( +
    + +
    +

    + Experience the Best hospitality at lakeSide Hotel +

    +

    We offer the best services for all your needs.

    +
    +
    +
    + ) +} + +export default Parallax diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomCarousel.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomCarousel.jsx new file mode 100644 index 0000000..d06ff32 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomCarousel.jsx @@ -0,0 +1,75 @@ +import React, { useEffect, useState } from "react" +import { getAllRooms } from "../utils/ApiFunctions" +import { Link } from "react-router-dom" +import { Card, Carousel, Col, Container, Row } from "react-bootstrap" + +const RoomCarousel = () => { + const [rooms, setRooms] = useState([{ id: "", roomType: "", roomPrice: "", photo: "" }]) + const [errorMessage, setErrorMessage] = useState("") + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => { + setIsLoading(true) + getAllRooms() + .then((data) => { + setRooms(data) + setIsLoading(false) + }) + .catch((error) => { + setErrorMessage(error.message) + setIsLoading(false) + }) + }, []) + + if (isLoading) { + return
    Loading rooms....
    + } + if (errorMessage) { + return
    Error : {errorMessage}
    + } + + return ( +
    + + Browse all rooms + + + + + {[...Array(Math.ceil(rooms.length / 4))].map((_, index) => ( + + + {rooms.slice(index * 4, index * 4 + 4).map((room) => ( + + + + + + + {room.roomType} + ${room.roomPrice}/night +
    + + Book Now + +
    +
    +
    + + ))} +
    +
    + ))} +
    +
    +
    + ) +} + +export default RoomCarousel diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomFilter.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomFilter.jsx new file mode 100644 index 0000000..b5c534b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomFilter.jsx @@ -0,0 +1,46 @@ +import React, { useState } from "react" + +const RoomFilter = ({ data, setFilteredData }) => { + const [filter, setFilter] = useState("") + + const handleSelectChange = (e) => { + const selectedType = e.target.value + setFilter(selectedType) + + const filteredRooms = data.filter((room) => + room.roomType.toLowerCase().includes(selectedType.toLowerCase()) + ) + setFilteredData(filteredRooms) + } + + const clearFilter = () => { + setFilter("") + setFilteredData(data) + } + + const roomTypes = ["", ...new Set(data.map((room) => room.roomType))] + + return ( +
    + + FIlter rooms by type + + + +
    + ) +} +export default RoomFilter diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomPaginator.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomPaginator.jsx new file mode 100644 index 0000000..3577f3b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomPaginator.jsx @@ -0,0 +1,22 @@ +import React from "react" + +const RoomPaginator = ({ currentPage, totalPages, onPageChange }) => { + const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1) + return ( + + ) +} + +export default RoomPaginator diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearch.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearch.jsx new file mode 100644 index 0000000..e41f369 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearch.jsx @@ -0,0 +1,122 @@ +import React, { useState } from "react" +import { Form, Button, Row, Col, Container } from "react-bootstrap" +import moment from "moment" +import { getAvailableRooms } from "../utils/ApiFunctions" +import RoomSearchResults from "./RoomSearchResult" +import RoomTypeSelector from "./RoomTypeSelector" + +const RoomSearch = () => { + const [searchQuery, setSearchQuery] = useState({ + checkInDate: "", + checkOutDate: "", + roomType: "" + }) + + const [errorMessage, setErrorMessage] = useState("") + const [availableRooms, setAvailableRooms] = useState([]) + const [isLoading, setIsLoading] = useState(false) + + const handleSearch = (e) => { + e.preventDefault() + const checkInMoment = moment(searchQuery.checkInDate) + const checkOutMoment = moment(searchQuery.checkOutDate) + if (!checkInMoment.isValid() || !checkOutMoment.isValid()) { + setErrorMessage("Please enter valid dates") + return + } + if (!checkOutMoment.isSameOrAfter(checkInMoment)) { + setErrorMessage("Check-out date must be after check-in date") + return + } + setIsLoading(true) + getAvailableRooms(searchQuery.checkInDate, searchQuery.checkOutDate, searchQuery.roomType) + .then((response) => { + setAvailableRooms(response.data) + setTimeout(() => setIsLoading(false), 2000) + }) + .catch((error) => { + console.log(error) + }) + .finally(() => { + setIsLoading(false) + }) + } + + const handleInputChange = (e) => { + const { name, value } = e.target + setSearchQuery({ ...searchQuery, [name]: value }) + const checkInDate = moment(searchQuery.checkInDate) + const checkOutDate = moment(searchQuery.checkOutDate) + if (checkInDate.isValid() && checkOutDate.isValid()) { + setErrorMessage("") + } + } + const handleClearSearch = () => { + setSearchQuery({ + checkInDate: "", + checkOutDate: "", + roomType: "" + }) + setAvailableRooms([]) + } + + return ( + <> + +
    + + + + Check-in Date + + + + + + Check-out Date + + + + + + Room Type +
    + + +
    +
    + +
    +
    + + {isLoading ? ( +

    Finding availble rooms....

    + ) : availableRooms ? ( + + ) : ( +

    No rooms available for the selected dates and room type.

    + )} + {errorMessage &&

    {errorMessage}

    } +
    + + ) +} + +export default RoomSearch diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearchResult.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearchResult.jsx new file mode 100644 index 0000000..1bf4d1d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomSearchResult.jsx @@ -0,0 +1,50 @@ +import React, { useState } from "react" +import RoomCard from "../room/RoomCard" +import { Button, Row } from "react-bootstrap" +import RoomPaginator from "./RoomPaginator" + +const RoomSearchResults = ({ results, onClearSearch }) => { + const [currentPage, setCurrentPage] = useState(1) + const resultsPerPage = 3 + const totalResults = results.length + const totalPages = Math.ceil(totalResults / resultsPerPage) + + const handlePageChange = (pageNumber) => { + setCurrentPage(pageNumber) + } + + const startIndex = (currentPage - 1) * resultsPerPage + const endIndex = startIndex + resultsPerPage + const paginatedResults = results.slice(startIndex, endIndex) + + return ( + <> + {results.length > 0 ? ( + <> +
    Search Results
    + + {paginatedResults.map((room) => ( + + ))} + + + {totalResults > resultsPerPage && ( + + )} + + + + ) : ( +

    + )} + + ) +} + +export default RoomSearchResults diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomTypeSelector.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomTypeSelector.jsx new file mode 100644 index 0000000..3c0ab2b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/common/RoomTypeSelector.jsx @@ -0,0 +1,73 @@ +import React, { useState, useEffect } from "react" +import { getRoomTypes } from "../utils/ApiFunctions" + +const RoomTypeSelector = ({ handleRoomInputChange, newRoom }) => { + const [roomTypes, setRoomTypes] = useState([""]) + const [showNewRoomTypeInput, setShowNewRoomTypeInput] = useState(false) + const [newRoomType, setNewRoomType] = useState("") + + useEffect(() => { + getRoomTypes().then((data) => { + setRoomTypes(data) + }) + }, []) + + const handleNewRoomTypeInputChange = (e) => { + setNewRoomType(e.target.value) + } + + const handleAddNewRoomType = () => { + if (newRoomType !== "") { + setRoomTypes([...roomTypes, newRoomType]) + setNewRoomType("") + setShowNewRoomTypeInput(false) + } + } + + return ( + <> + {roomTypes.length > 0 && ( +
    + + {showNewRoomTypeInput && ( +
    +
    + + +
    +
    + )} +
    + )} + + ) +} + +export default RoomTypeSelector diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/home/Home.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/home/Home.jsx new file mode 100644 index 0000000..cde99b2 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/home/Home.jsx @@ -0,0 +1,34 @@ +import React, { useContext } from "react" +import MainHeader from "../layout/MainHeader" +import HotelService from "../common/HotelService" +import Parallax from "../common/Parallax" +import RoomCarousel from "../common/RoomCarousel" +import RoomSearch from "../common/RoomSearch" +import { useLocation } from "react-router-dom" +import { useAuth } from "../auth/AuthProvider" +const Home = () => { + const location = useLocation() + + const message = location.state && location.state.message + const currentUser = localStorage.getItem("userId") + return ( +
    + {message &&

    {message}

    } + {currentUser && ( +
    You are logged-In as {currentUser}
    + )} + +
    + + + + + + + +
    +
    + ) +} + +export default Home diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/Footer.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/Footer.jsx new file mode 100644 index 0000000..48c9a5b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/Footer.jsx @@ -0,0 +1,19 @@ +import React from "react" +import { Col, Container, Row } from "react-bootstrap" + +const Footer = () => { + let today = new Date() + return ( +
    + + + +

    © {today.getFullYear()} lakeSide Hotel

    + +
    +
    +
    + ) +} + +export default Footer diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/MainHeader.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/MainHeader.jsx new file mode 100644 index 0000000..a4b6657 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/MainHeader.jsx @@ -0,0 +1,17 @@ +import React from "react" + +const MainHeader = () => { + return ( +
    +
    +
    +

    + Welcome to lakeSide Hotel +

    +

    Experience the Best Hospitality in Town

    +
    +
    + ) +} + +export default MainHeader diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/NavBar.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/NavBar.jsx new file mode 100644 index 0000000..8a3a2f6 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/layout/NavBar.jsx @@ -0,0 +1,91 @@ +import React, { useContext, useState } from "react" +import { NavLink, Link } from "react-router-dom" +import Logout from "../auth/Logout" + + +const NavBar = () => { + const [showAccount, setShowAccount] = useState(false) + + const handleAccountClick = () => { + setShowAccount(!showAccount) + } + + const isLoggedIn = localStorage.getItem("token") + const userRole = localStorage.getItem("userRole") + + return ( + + ) +} + +export default NavBar diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/AddRoom.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/AddRoom.jsx new file mode 100644 index 0000000..6c2bf7e --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/AddRoom.jsx @@ -0,0 +1,132 @@ +import React, { useState } from "react" +import { addRoom } from "../utils/ApiFunctions" +import RoomTypeSelector from "../common/RoomTypeSelector" +import { Link } from "react-router-dom" + +const AddRoom = () => { + const [newRoom, setNewRoom] = useState({ + photo: null, + roomType: "", + roomPrice: "" + }) + + const [successMessage, setSuccessMessage] = useState("") + const [errorMessage, setErrorMessage] = useState("") + const [imagePreview, setImagePreview] = useState("") + + const handleRoomInputChange = (e) => { + const name = e.target.name + let value = e.target.value + if (name === "roomPrice") { + if (!isNaN(value)) { + value = parseInt(value) + } else { + value = "" + } + } + setNewRoom({ ...newRoom, [name]: value }) + } + + const handleImageChange = (e) => { + const selectedImage = e.target.files[0] + setNewRoom({ ...newRoom, photo: selectedImage }) + setImagePreview(URL.createObjectURL(selectedImage)) + } + + const handleSubmit = async (e) => { + e.preventDefault() + try { + const success = await addRoom(newRoom.photo, newRoom.roomType, newRoom.roomPrice) + if (success !== undefined) { + setSuccessMessage("A new room was added successfully !") + setNewRoom({ photo: null, roomType: "", roomPrice: "" }) + setImagePreview("") + setErrorMessage("") + } else { + setErrorMessage("Error adding new room") + } + } catch (error) { + setErrorMessage(error.message) + } + setTimeout(() => { + setSuccessMessage("") + setErrorMessage("") + }, 3000) + } + + return ( + <> +
    +
    +
    +

    Add a New Room

    + {successMessage && ( +
    {successMessage}
    + )} + + {errorMessage &&
    {errorMessage}
    } + +
    +
    + +
    + +
    +
    +
    + + +
    + +
    + + + {imagePreview && ( + Preview  room photo + )} +
    +
    + + Existing rooms + + +
    +
    +
    +
    +
    + + ) +} + +export default AddRoom diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/EditRoom.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/EditRoom.jsx new file mode 100644 index 0000000..426e7eb --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/EditRoom.jsx @@ -0,0 +1,140 @@ +import React, { useEffect, useState } from "react" +import { getRoomById, updateRoom } from "../utils/ApiFunctions" +import { Link, useParams } from "react-router-dom" + +const EditRoom = () => { + const [room, setRoom] = useState({ + photo: "", + roomType: "", + roomPrice: "" + }) + + const [imagePreview, setImagePreview] = useState("") + const [successMessage, setSuccessMessage] = useState("") + const [errorMessage, setErrorMessage] = useState("") + const { roomId } = useParams() + + const handleImageChange = (e) => { + const selectedImage = e.target.files[0] + setRoom({ ...room, photo: selectedImage }) + setImagePreview(URL.createObjectURL(selectedImage)) + } + + const handleInputChange = (event) => { + const { name, value } = event.target + setRoom({ ...room, [name]: value }) + } + + useEffect(() => { + const fetchRoom = async () => { + try { + const roomData = await getRoomById(roomId) + setRoom(roomData) + setImagePreview(roomData.photo) + } catch (error) { + console.error(error) + } + } + + fetchRoom() + }, [roomId]) + + const handleSubmit = async (e) => { + e.preventDefault() + + try { + const response = await updateRoom(roomId, room) + if (response.status === 200) { + setSuccessMessage("Room updated successfully!") + const updatedRoomData = await getRoomById(roomId) + setRoom(updatedRoomData) + setImagePreview(updatedRoomData.photo) + setErrorMessage("") + } else { + setErrorMessage("Error updating room") + } + } catch (error) { + console.error(error) + setErrorMessage(error.message) + } + } + + return ( +
    +

    Edit Room

    +
    +
    + {successMessage && ( +
    + {successMessage} +
    + )} + {errorMessage && ( +
    + {errorMessage} +
    + )} +
    +
    + + +
    +
    + + +
    + +
    + + + {imagePreview && ( + Room preview + )} +
    +
    + + back + + +
    +
    +
    +
    +
    + ) +} +export default EditRoom diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/ExistingRooms.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/ExistingRooms.jsx new file mode 100644 index 0000000..fb8790c --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/ExistingRooms.jsx @@ -0,0 +1,152 @@ +import React, { useEffect, useState } from "react" +import { deleteRoom, getAllRooms } from "../utils/ApiFunctions" +import { Col, Row } from "react-bootstrap" +import RoomFilter from "../common/RoomFilter" +import RoomPaginator from "../common/RoomPaginator" +import { FaEdit, FaEye, FaPlus, FaTrashAlt } from "react-icons/fa" +import { Link } from "react-router-dom" + +const ExistingRooms = () => { + const [rooms, setRooms] = useState([{ id: "", roomType: "", roomPrice: "" }]) + const [currentPage, setCurrentPage] = useState(1) + const [roomsPerPage] = useState(8) + const [isLoading, setIsLoading] = useState(false) + const [filteredRooms, setFilteredRooms] = useState([{ id: "", roomType: "", roomPrice: "" }]) + const [selectedRoomType, setSelectedRoomType] = useState("") + const [errorMessage, setErrorMessage] = useState("") + const [successMessage, setSuccessMessage] = useState("") + + useEffect(() => { + fetchRooms() + }, []) + + const fetchRooms = async () => { + setIsLoading(true) + try { + const result = await getAllRooms() + setRooms(result) + setIsLoading(false) + } catch (error) { + setErrorMessage(error.message) + setIsLoading(false) + } + } + + useEffect(() => { + if (selectedRoomType === "") { + setFilteredRooms(rooms) + } else { + const filteredRooms = rooms.filter((room) => room.roomType === selectedRoomType) + setFilteredRooms(filteredRooms) + } + setCurrentPage(1) + }, [rooms, selectedRoomType]) + + const handlePaginationClick = (pageNumber) => { + setCurrentPage(pageNumber) + } + + const handleDelete = async (roomId) => { + try { + const result = await deleteRoom(roomId) + if (result === "") { + setSuccessMessage(`Room No ${roomId} was delete`) + fetchRooms() + } else { + console.error(`Error deleting room : ${result.message}`) + } + } catch (error) { + setErrorMessage(error.message) + } + setTimeout(() => { + setSuccessMessage("") + setErrorMessage("") + }, 3000) + } + + const calculateTotalPages = (filteredRooms, roomsPerPage, rooms) => { + const totalRooms = filteredRooms.length > 0 ? filteredRooms.length : rooms.length + return Math.ceil(totalRooms / roomsPerPage) + } + + const indexOfLastRoom = currentPage * roomsPerPage + const indexOfFirstRoom = indexOfLastRoom - roomsPerPage + const currentRooms = filteredRooms.slice(indexOfFirstRoom, indexOfLastRoom) + + return ( + <> +
    + {successMessage &&

    {successMessage}

    } + + {errorMessage &&

    {errorMessage}

    } +
    + + {isLoading ? ( +

    Loading existing rooms

    + ) : ( + <> +
    +
    +

    Existing Rooms

    +
    + + + + + + + + + Add Room + + + + + + + + + + + + + + + + {currentRooms.map((room) => ( + + + + + + + ))} + +
    IDRoom TypeRoom PriceActions
    {room.id}{room.roomType}{room.roomPrice} + + + + + + + + + +
    + +
    + + )} + + ) +} + +export default ExistingRooms diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/Room.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/Room.jsx new file mode 100644 index 0000000..b110f90 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/Room.jsx @@ -0,0 +1,81 @@ +import React, { useEffect, useState } from "react" +import { getAllRooms } from "../utils/ApiFunctions" +import RoomCard from "./RoomCard" +import { Col, Container, Row } from "react-bootstrap" +import RoomFilter from "../common/RoomFilter" +import RoomPaginator from "../common/RoomPaginator" + +const Room = () => { + const [data, setData] = useState([]) + const [error, setError] = useState(null) + const [isLoading, setIsLoading] = useState(false) + const [currentPage, setCurrentPage] = useState(1) + const [roomsPerPage] = useState(6) + const [filteredData, setFilteredData] = useState([{ id: "" }]) + + useEffect(() => { + setIsLoading(true) + getAllRooms() + .then((data) => { + setData(data) + setFilteredData(data) + setIsLoading(false) + }) + .catch((error) => { + setError(error.message) + setIsLoading(false) + }) + }, []) + if (isLoading) { + return
    Loading rooms.....
    + } + if (error) { + return
    Error : {error}
    + } + + const handlePageChange = (pageNumber) => { + setCurrentPage(pageNumber) + } + + const totalPages = Math.ceil(filteredData.length / roomsPerPage) + + const renderRooms = () => { + const startIndex = (currentPage - 1) * roomsPerPage + const endIndex = startIndex + roomsPerPage + return filteredData + .slice(startIndex, endIndex) + .map((room) => ) + } + + return ( + + + + + + + + + + + + {renderRooms()} + + + + + + + + ) +} + +export default Room diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomCard.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomCard.jsx new file mode 100644 index 0000000..59d8285 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomCard.jsx @@ -0,0 +1,36 @@ +import React, { useContext } from "react" +import { Card, Col } from "react-bootstrap" +import { Link } from "react-router-dom" + +const RoomCard = ({ room }) => { + return ( + + + +
    + + + +
    +
    + {room.roomType} + {room.roomPrice} / night + Some room information goes here for the guest to read through +
    +
    + + Book Now + +
    +
    +
    + + ) +} + +export default RoomCard diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomListing.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomListing.jsx new file mode 100644 index 0000000..23daf12 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/room/RoomListing.jsx @@ -0,0 +1,12 @@ +import React from "react" +import Room from "./Room" + +const RoomListing = () => { + return ( +
    + +
    + ) +} + +export default RoomListing diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/utils/ApiFunctions.js b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/utils/ApiFunctions.js new file mode 100644 index 0000000..8f8642e --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/components/utils/ApiFunctions.js @@ -0,0 +1,219 @@ +import axios from "axios" + +export const api = axios.create({ + baseURL: "http://localhost:9192" +}) + +export const getHeader = () => { + const token = localStorage.getItem("token") + return { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json" + } +} + +/* This function adds a new room room to the database */ +export async function addRoom(photo, roomType, roomPrice) { + const formData = new FormData() + formData.append("photo", photo) + formData.append("roomType", roomType) + formData.append("roomPrice", roomPrice) + + const response = await api.post("/rooms/add/new-room", formData,{ + headers: getHeader() + }) + if (response.status === 201) { + return true + } else { + return false + } +} + +/* This function gets all room types from thee database */ +export async function getRoomTypes() { + try { + const response = await api.get("/rooms/room/types") + return response.data + } catch (error) { + throw new Error("Error fetching room types") + } +} +/* This function gets all rooms from the database */ +export async function getAllRooms() { + try { + const result = await api.get("/rooms/all-rooms") + return result.data + } catch (error) { + throw new Error("Error fetching rooms") + } +} + +/* This function deletes a room by the Id */ +export async function deleteRoom(roomId) { + try { + const result = await api.delete(`/rooms/delete/room/${roomId}`, { + headers: getHeader() + }) + return result.data + } catch (error) { + throw new Error(`Error deleting room ${error.message}`) + } +} +/* This function update a room */ +export async function updateRoom(roomId, roomData) { + const formData = new FormData() + formData.append("roomType", roomData.roomType) + formData.append("roomPrice", roomData.roomPrice) + formData.append("photo", roomData.photo) + const response = await api.put(`/rooms/update/${roomId}`, formData,{ + headers: getHeader() + }) + return response +} + +/* This funcction gets a room by the id */ +export async function getRoomById(roomId) { + try { + const result = await api.get(`/rooms/room/${roomId}`) + return result.data + } catch (error) { + throw new Error(`Error fetching room ${error.message}`) + } +} + +/* This function saves a new booking to the databse */ +export async function bookRoom(roomId, booking) { + try { + const response = await api.post(`/bookings/room/${roomId}/booking`, booking) + return response.data + } catch (error) { + if (error.response && error.response.data) { + throw new Error(error.response.data) + } else { + throw new Error(`Error booking room : ${error.message}`) + } + } +} + +/* This function gets alll bokings from the database */ +export async function getAllBookings() { + try { + const result = await api.get("/bookings/all-bookings", { + headers: getHeader() + }) + return result.data + } catch (error) { + throw new Error(`Error fetching bookings : ${error.message}`) + } +} + +/* This function get booking by the cnfirmation code */ +export async function getBookingByConfirmationCode(confirmationCode) { + try { + const result = await api.get(`/bookings/confirmation/${confirmationCode}`) + return result.data + } catch (error) { + if (error.response && error.response.data) { + throw new Error(error.response.data) + } else { + throw new Error(`Error find booking : ${error.message}`) + } + } +} + +/* This is the function to cancel user booking */ +export async function cancelBooking(bookingId) { + try { + const result = await api.delete(`/bookings/booking/${bookingId}/delete`) + return result.data + } catch (error) { + throw new Error(`Error cancelling booking :${error.message}`) + } +} + +/* This function gets all availavle rooms from the database with a given date and a room type */ +export async function getAvailableRooms(checkInDate, checkOutDate, roomType) { + const result = await api.get( + `rooms/available-rooms?checkInDate=${checkInDate} + &checkOutDate=${checkOutDate}&roomType=${roomType}` + ) + return result +} + +/* This function register a new user */ +export async function registerUser(registration) { + try { + const response = await api.post("/auth/register-user", registration) + return response.data + } catch (error) { + if (error.reeponse && error.response.data) { + throw new Error(error.response.data) + } else { + throw new Error(`User registration error : ${error.message}`) + } + } +} + +/* This function login a registered user */ +export async function loginUser(login) { + try { + const response = await api.post("/auth/login", login) + if (response.status >= 200 && response.status < 300) { + return response.data + } else { + return null + } + } catch (error) { + console.error(error) + return null + } +} + +/* This is function to get the user profile */ +export async function getUserProfile(userId, token) { + try { + const response = await api.get(`users/profile/${userId}`, { + headers: getHeader() + }) + return response.data + } catch (error) { + throw error + } +} + +/* This isthe function to delete a user */ +export async function deleteUser(userId) { + try { + const response = await api.delete(`/users/delete/${userId}`, { + headers: getHeader() + }) + return response.data + } catch (error) { + return error.message + } +} + +/* This is the function to get a single user */ +export async function getUser(userId, token) { + try { + const response = await api.get(`/users/${userId}`, { + headers: getHeader() + }) + return response.data + } catch (error) { + throw error + } +} + +/* This is the function to get user bookings by the user id */ +export async function getBookingsByUserId(userId, token) { + try { + const response = await api.get(`/bookings/user/${userId}/bookings`, { + headers: getHeader() + }) + return response.data + } catch (error) { + console.error("Error fetching bookings:", error.message) + throw new Error("Failed to fetch bookings") + } +} diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/index.css b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/index.css new file mode 100644 index 0000000..f7ba894 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/index.css @@ -0,0 +1,228 @@ +body { + min-height: 100vh; + padding-bottom: 50px; +} +.card { + opacity: 0.9; +} + +/* Navigation bar definitions */ + .navbar{ + padding: 0; + } + .navbar .navbar-nav .nav-link{ + padding: 1em; + } + .navbar .navbar-nav .nav-item{ + position: relative; + } + + .navbar .navbar-nav .nav-item::after{ + position: absolute; + bottom: 0; + left: 0; + right: 0; + content: ''; + background-color:rgb(169, 77, 123) ; + width: 0; + margin: 0 auto; + height: 4px; + transition: all .5s; + } + .navbar .navbar-nav .nav-item:hover::after{ + width: 100%; + } + .navbar-dark .navbar-nav .nav-link { + color: rgb(25, 24, 24); +} + +.navbar-dark .navbar-brand { + color: rgb(25, 24, 24); +} + + @media screen and (min-width: 992px){ + .navbar{ + padding: 0; + } + .navbar .navbar-nav .nav-link{ + padding: 1em 0; + } + .navbar .navbar-nav .nav-item{ + margin: 0 1em; + } + } + + /* Hotel custom color */ + .btn-hotel{ + background-color: rgb(169, 77, 123); + color: #fff; + } + .btn-hotel:hover{ + background-color: rgb(137, 127, 132); + color: #fff; + transition: 0.7s; + outline-color: transparent; + outline-style:solid; + + } + + .hotel-color{ + color: rgb(169, 77, 123); + } + .room-price{ + color:darkgoldenrod; + font-family: 'Courier New', Courier, monospace; + font-size:medium; + } + .vertical-rule{ + border-left: '0.5px solid black'; + height: '100vh' + } + + + +.parallax { + background-image: url("./assets/images/parrall.jpg"); + background-attachment: fixed; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + height: 50vh; +} + +.header { + position: relative; + height: 150px; + background-size: cover; + background-image: url("./assets/images/services4.jpg"); + background-position: center center; +} +.header-title { + color: #fff; + font-size: 4rem; + align-content: center; +} + +.parallax { + margin-top: 50px; + color: white; + text-shadow: 2px 2px black; +} + +.animated { + animation-duration: 1s; +} + +.animated-texts h1 { + animation: fadeInDown 1s ease-in-out; +} + +.animated-texts p, h1, h2 { + animation: fadeInUp 1s ease-in-out; +} + +@keyframes bounceIn { + from, 20%, 40%, 60%, 80%, to { + animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); + transform: translate3d(0,0,0); + } + + 40%, 60% { + animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transform: translate3d(0, -30px, 0); + } + + 70% { + animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); + transform: translate3d(0, -15px, 0); + } + + 90% { + transform: translate3d(0,-4px,0); + } +} + +.bounceIn { + animation-name: bounceIn; +} + +@keyframes fadeInDown { + from { + opacity: 0; + transform: translate3d(0, -50%, 0); + } + + to { + opacity: 1; + transform: none; + } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translate3d(0, 50%, 0); + } + + to { + opacity: 1; + transform: none; + } +} +/* Header overlay */ + .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + } + .overlay-content { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: #fff; + justify-content: flex-start; + } + +/* The header banner */ +.header-banner { + background-image: url("./assets/images/services-1.jpg"); + background-size: cover; + background-position: center; + position: relative; + height: 80vh; + } + +.header-banner { + position: relative; + height: 500px; +} + +@media only screen and (max-width: 768px) { + .header-banner h1 { + font-size: 20px; + } +} + +@media only screen and (max-width: 480px) { + .header-banner h1 { + font-size: 16px; + } +} + + .footer { + position: fixed; + left: 0; + bottom: 0; + width: 100%; + background-color: #f5f5f5; + height: 60px; + text-align: center; +} + + + + diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/main.jsx b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/main.jsx new file mode 100644 index 0000000..54b39dd --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/src/main.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from './App.jsx' +import './index.css' + +ReactDOM.createRoot(document.getElementById('root')).render( + + + , +) diff --git a/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/vite.config.js b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/vite.config.js new file mode 100644 index 0000000..5a33944 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/client/flexycode-hotel-client-main/vite.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], +}) diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw new file mode 100644 index 0000000..66df285 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw.cmd b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/pom.xml b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/pom.xml new file mode 100644 index 0000000..4143db9 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/pom.xml @@ -0,0 +1,114 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.4 + + + com.dailycodework + lakeSide-hotel + 0.0.1-SNAPSHOT + lakeSide-hotel + lakeSide-hotel + + 17 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-validation + + + + com.mysql + mysql-connector-j + runtime + + + org.projectlombok + lombok + true + + + + + com.fasterxml.jackson.core + jackson-databind + 2.15.2 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + + + + + diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/LakeSideHotelApplication.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/LakeSideHotelApplication.java new file mode 100644 index 0000000..2280650 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/LakeSideHotelApplication.java @@ -0,0 +1,13 @@ +package com.dailycodework.lakesidehotel; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class LakeSideHotelApplication { + + public static void main(String[] args) { + SpringApplication.run(LakeSideHotelApplication.class, args); + } + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/AuthController.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/AuthController.java new file mode 100644 index 0000000..37a502c --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/AuthController.java @@ -0,0 +1,67 @@ +package com.dailycodework.lakesidehotel.controller; + +import com.dailycodework.lakesidehotel.exception.UserAlreadyExistsException; +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.request.LoginRequest; +import com.dailycodework.lakesidehotel.response.JwtResponse; +import com.dailycodework.lakesidehotel.security.jwt.JwtUtils; +import com.dailycodework.lakesidehotel.security.user.HotelUserDetails; +import com.dailycodework.lakesidehotel.service.IUserService; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + + +/** + * @author Simpson Alfred + */ +@RestController +@RequestMapping("/auth") +@RequiredArgsConstructor +public class AuthController { + private final IUserService userService; + private final AuthenticationManager authenticationManager; + private final JwtUtils jwtUtils; + + @PostMapping("/register-user") + public ResponseEntity registerUser(@RequestBody User user){ + try{ + userService.registerUser(user); + return ResponseEntity.ok("Registration successful!"); + + }catch (UserAlreadyExistsException e){ + return ResponseEntity.status(HttpStatus.CONFLICT).body(e.getMessage()); + } + } + + @PostMapping("/login") + public ResponseEntity authenticateUser(@Valid @RequestBody LoginRequest request){ + Authentication authentication = + authenticationManager + .authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(), request.getPassword())); + SecurityContextHolder.getContext().setAuthentication(authentication); + String jwt = jwtUtils.generateJwtTokenForUser(authentication); + HotelUserDetails userDetails = (HotelUserDetails) authentication.getPrincipal(); + List roles = userDetails.getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority).toList(); + return ResponseEntity.ok(new JwtResponse( + userDetails.getId(), + userDetails.getEmail(), + jwt, + roles)); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/BookingController.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/BookingController.java new file mode 100644 index 0000000..6313edc --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/BookingController.java @@ -0,0 +1,97 @@ +package com.dailycodework.lakesidehotel.controller; + +import com.dailycodework.lakesidehotel.exception.InvalidBookingRequestException; +import com.dailycodework.lakesidehotel.exception.ResourceNotFoundException; +import com.dailycodework.lakesidehotel.model.BookedRoom; +import com.dailycodework.lakesidehotel.model.Room; +import com.dailycodework.lakesidehotel.response.BookingResponse; +import com.dailycodework.lakesidehotel.response.RoomResponse; +import com.dailycodework.lakesidehotel.service.IBookingService; +import com.dailycodework.lakesidehotel.service.IRoomService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Simpson Alfred + */ + +@RequiredArgsConstructor +@RestController +@RequestMapping("/bookings") +public class BookingController { + private final IBookingService bookingService; + private final IRoomService roomService; + + @GetMapping("/all-bookings") + @PreAuthorize("hasRole('ROLE_ADMIN')") + public ResponseEntity> getAllBookings(){ + List bookings = bookingService.getAllBookings(); + List bookingResponses = new ArrayList<>(); + for (BookedRoom booking : bookings){ + BookingResponse bookingResponse = getBookingResponse(booking); + bookingResponses.add(bookingResponse); + } + return ResponseEntity.ok(bookingResponses); + } + + @PostMapping("/room/{roomId}/booking") + public ResponseEntity saveBooking(@PathVariable Long roomId, + @RequestBody BookedRoom bookingRequest){ + try{ + String confirmationCode = bookingService.saveBooking(roomId, bookingRequest); + return ResponseEntity.ok( + "Room booked successfully, Your booking confirmation code is :"+confirmationCode); + + }catch (InvalidBookingRequestException e){ + return ResponseEntity.badRequest().body(e.getMessage()); + } + } + + @GetMapping("/confirmation/{confirmationCode}") + public ResponseEntity getBookingByConfirmationCode(@PathVariable String confirmationCode){ + try{ + BookedRoom booking = bookingService.findByBookingConfirmationCode(confirmationCode); + BookingResponse bookingResponse = getBookingResponse(booking); + return ResponseEntity.ok(bookingResponse); + }catch (ResourceNotFoundException ex){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); + } + } + + @GetMapping("/user/{email}/bookings") + public ResponseEntity> getBookingsByUserEmail(@PathVariable String email) { + List bookings = bookingService.getBookingsByUserEmail(email); + List bookingResponses = new ArrayList<>(); + for (BookedRoom booking : bookings) { + BookingResponse bookingResponse = getBookingResponse(booking); + bookingResponses.add(bookingResponse); + } + return ResponseEntity.ok(bookingResponses); + } + + @DeleteMapping("/booking/{bookingId}/delete") + public void cancelBooking(@PathVariable Long bookingId){ + bookingService.cancelBooking(bookingId); + } + + private BookingResponse getBookingResponse(BookedRoom booking) { + Room theRoom = roomService.getRoomById(booking.getRoom().getId()).get(); + RoomResponse room = new RoomResponse( + theRoom.getId(), + theRoom.getRoomType(), + theRoom.getRoomPrice()); + return new BookingResponse( + booking.getBookingId(), booking.getCheckInDate(), + booking.getCheckOutDate(),booking.getGuestFullName(), + booking.getGuestEmail(), booking.getNumOfAdults(), + booking.getNumOfChildren(), booking.getTotalNumOfGuest(), + booking.getBookingConfirmationCode(), room); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoleController.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoleController.java new file mode 100644 index 0000000..c8b6c9d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoleController.java @@ -0,0 +1,63 @@ +package com.dailycodework.lakesidehotel.controller; + +import com.dailycodework.lakesidehotel.exception.RoleAlreadyExistException; +import com.dailycodework.lakesidehotel.model.Role; +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.service.IRoleService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static org.springframework.http.HttpStatus.FOUND; + +/** + * @author Simpson Alfred + */ + +@RestController +@RequestMapping("/roles") +@RequiredArgsConstructor +public class RoleController { + private final IRoleService roleService; + + @GetMapping("/all-roles") + public ResponseEntity> getAllRoles(){ + return new ResponseEntity<>(roleService.getRoles(), FOUND); + } + + @PostMapping("/create-new-role") + public ResponseEntity createRole(@RequestBody Role theRole){ + try{ + roleService.createRole(theRole); + return ResponseEntity.ok("New role created successfully!"); + }catch(RoleAlreadyExistException re){ + return ResponseEntity.status(HttpStatus.CONFLICT).body(re.getMessage()); + + } + } + @DeleteMapping("/delete/{roleId}") + public void deleteRole(@PathVariable("roleId") Long roleId){ + roleService.deleteRole(roleId); + } + @PostMapping("/remove-all-users-from-role/{roleId}") + public Role removeAllUsersFromRole(@PathVariable("roleId") Long roleId){ + return roleService.removeAllUsersFromRole(roleId); + } + + @PostMapping("/remove-user-from-role") + public User removeUserFromRole( + @RequestParam("userId") Long userId, + @RequestParam("roleId") Long roleId){ + return roleService.removeUserFromRole(userId, roleId); + } + @PostMapping("/assign-user-to-role") + public User assignUserToRole( + @RequestParam("userId") Long userId, + @RequestParam("roleId") Long roleId){ + return roleService.assignRoleToUser(userId, roleId); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoomController.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoomController.java new file mode 100644 index 0000000..b989579 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/RoomController.java @@ -0,0 +1,156 @@ +package com.dailycodework.lakesidehotel.controller; + +import com.dailycodework.lakesidehotel.exception.PhotoRetrievalException; +import com.dailycodework.lakesidehotel.exception.ResourceNotFoundException; +import com.dailycodework.lakesidehotel.model.BookedRoom; +import com.dailycodework.lakesidehotel.model.Room; +import com.dailycodework.lakesidehotel.response.BookingResponse; +import com.dailycodework.lakesidehotel.response.RoomResponse; +import com.dailycodework.lakesidehotel.service.BookingService; +import com.dailycodework.lakesidehotel.service.IRoomService; +import lombok.RequiredArgsConstructor; +import org.apache.tomcat.util.codec.binary.Base64; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.sql.rowset.serial.SerialBlob; +import java.io.IOException; +import java.math.BigDecimal; +import java.sql.Blob; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +@RestController +@RequiredArgsConstructor +@RequestMapping("/rooms") +public class RoomController { + private final IRoomService roomService; + private final BookingService bookingService; + + @PostMapping("/add/new-room") + @PreAuthorize("hasRole('ROLE_ADMIN')") + public ResponseEntity addNewRoom( + @RequestParam("photo") MultipartFile photo, + @RequestParam("roomType") String roomType, + @RequestParam("roomPrice") BigDecimal roomPrice) throws SQLException, IOException { + Room savedRoom = roomService.addNewRoom(photo, roomType, roomPrice); + RoomResponse response = new RoomResponse(savedRoom.getId(), savedRoom.getRoomType(), + savedRoom.getRoomPrice()); + return ResponseEntity.ok(response); + } + + @GetMapping("/room/types") + public List getRoomTypes() { + return roomService.getAllRoomTypes(); + } + + @GetMapping("/all-rooms") + public ResponseEntity> getAllRooms() throws SQLException { + List rooms = roomService.getAllRooms(); + List roomResponses = new ArrayList<>(); + for (Room room : rooms) { + byte[] photoBytes = roomService.getRoomPhotoByRoomId(room.getId()); + if (photoBytes != null && photoBytes.length > 0) { + String base64Photo = Base64.encodeBase64String(photoBytes); + RoomResponse roomResponse = getRoomResponse(room); + roomResponse.setPhoto(base64Photo); + roomResponses.add(roomResponse); + } + } + return ResponseEntity.ok(roomResponses); + } + @DeleteMapping("/delete/room/{roomId}") + @PreAuthorize("hasRole('ROLE_ADMIN')") + public ResponseEntity deleteRoom(@PathVariable Long roomId){ + roomService.deleteRoom(roomId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @PutMapping("/update/{roomId}") + @PreAuthorize("hasRole('ROLE_ADMIN')") + public ResponseEntity updateRoom(@PathVariable Long roomId, + @RequestParam(required = false) String roomType, + @RequestParam(required = false) BigDecimal roomPrice, + @RequestParam(required = false) MultipartFile photo) throws SQLException, IOException { + byte[] photoBytes = photo != null && !photo.isEmpty() ? + photo.getBytes() : roomService.getRoomPhotoByRoomId(roomId); + Blob photoBlob = photoBytes != null && photoBytes.length >0 ? new SerialBlob(photoBytes): null; + Room theRoom = roomService.updateRoom(roomId, roomType, roomPrice, photoBytes); + theRoom.setPhoto(photoBlob); + RoomResponse roomResponse = getRoomResponse(theRoom); + return ResponseEntity.ok(roomResponse); + } + + @GetMapping("/room/{roomId}") + public ResponseEntity> getRoomById(@PathVariable Long roomId){ + Optional theRoom = roomService.getRoomById(roomId); + return theRoom.map(room -> { + RoomResponse roomResponse = getRoomResponse(room); + return ResponseEntity.ok(Optional.of(roomResponse)); + }).orElseThrow(() -> new ResourceNotFoundException("Room not found")); + } + + @GetMapping("/available-rooms") + public ResponseEntity> getAvailableRooms( + @RequestParam("checkInDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)LocalDate checkInDate, + @RequestParam("checkOutDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)LocalDate checkOutDate, + @RequestParam("roomType") String roomType) throws SQLException { + List availableRooms = roomService.getAvailableRooms(checkInDate, checkOutDate, roomType); + List roomResponses = new ArrayList<>(); + for (Room room : availableRooms){ + byte[] photoBytes = roomService.getRoomPhotoByRoomId(room.getId()); + if (photoBytes != null && photoBytes.length > 0){ + String photoBase64 = Base64.encodeBase64String(photoBytes); + RoomResponse roomResponse = getRoomResponse(room); + roomResponse.setPhoto(photoBase64); + roomResponses.add(roomResponse); + } + } + if(roomResponses.isEmpty()){ + return ResponseEntity.noContent().build(); + }else{ + return ResponseEntity.ok(roomResponses); + } + } + + + + + private RoomResponse getRoomResponse(Room room) { + List bookings = getAllBookingsByRoomId(room.getId()); + List bookingInfo = bookings + .stream() + .map(booking -> new BookingResponse(booking.getBookingId(), + booking.getCheckInDate(), + booking.getCheckOutDate(), booking.getBookingConfirmationCode())).toList(); + byte[] photoBytes = null; + Blob photoBlob = room.getPhoto(); + if (photoBlob != null) { + try { + photoBytes = photoBlob.getBytes(1, (int) photoBlob.length()); + } catch (SQLException e) { + throw new PhotoRetrievalException("Error retrieving photo"); + } + } + return new RoomResponse(room.getId(), + room.getRoomType(), room.getRoomPrice(), + room.isBooked(), photoBytes, bookingInfo); + } + + private List getAllBookingsByRoomId(Long roomId) { + return bookingService.getAllBookingsByRoomId(roomId); + + } + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/UserController.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/UserController.java new file mode 100644 index 0000000..241a663 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/controller/UserController.java @@ -0,0 +1,57 @@ +package com.dailycodework.lakesidehotel.controller; + +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.service.IUserService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * @author Simpson Alfred + */ + +@RestController +@RequestMapping("/users") +@RequiredArgsConstructor +public class UserController { + private final IUserService userService; + + @GetMapping("/all") + @PreAuthorize("hasRole('ROLE_ADMIN')") + public ResponseEntity> getUsers(){ + + return new ResponseEntity<>(userService.getUsers(), HttpStatus.FOUND); + } + + @GetMapping("/{email}") + @PreAuthorize("hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')") + public ResponseEntity getUserByEmail(@PathVariable("email") String email){ + try{ + User theUser = userService.getUser(email); + return ResponseEntity.ok(theUser); + }catch (UsernameNotFoundException e){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); + }catch (Exception e){ + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error fetching user"); + } + } + @DeleteMapping("/delete/{userId}") + @PreAuthorize("hasRole('ROLE_ADMIN') or (hasRole('ROLE_USER') and #email == principal.username)") + public ResponseEntity deleteUser(@PathVariable("userId") String email){ + try{ + userService.deleteUser(email); + return ResponseEntity.ok("User deleted successfully"); + }catch (UsernameNotFoundException e){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage()); + }catch (Exception e){ + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error deleting user: " + e.getMessage()); + } + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InternalServerException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InternalServerException.java new file mode 100644 index 0000000..6ebdb55 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InternalServerException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class InternalServerException extends RuntimeException { + public InternalServerException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InvalidBookingRequestException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InvalidBookingRequestException.java new file mode 100644 index 0000000..15c7a51 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/InvalidBookingRequestException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class InvalidBookingRequestException extends RuntimeException { + public InvalidBookingRequestException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/PhotoRetrievalException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/PhotoRetrievalException.java new file mode 100644 index 0000000..63ea34a --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/PhotoRetrievalException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class PhotoRetrievalException extends RuntimeException { + public PhotoRetrievalException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/ResourceNotFoundException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/ResourceNotFoundException.java new file mode 100644 index 0000000..4e73926 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/ResourceNotFoundException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/RoleAlreadyExistException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/RoleAlreadyExistException.java new file mode 100644 index 0000000..f78d7a8 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/RoleAlreadyExistException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class RoleAlreadyExistException extends RuntimeException { + public RoleAlreadyExistException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/UserAlreadyExistsException.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/UserAlreadyExistsException.java new file mode 100644 index 0000000..333730b --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/exception/UserAlreadyExistsException.java @@ -0,0 +1,11 @@ +package com.dailycodework.lakesidehotel.exception; + +/** + * @author Simpson Alfred + */ + +public class UserAlreadyExistsException extends RuntimeException{ + public UserAlreadyExistsException(String message) { + super(message); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/BookedRoom.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/BookedRoom.java new file mode 100644 index 0000000..a10c594 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/BookedRoom.java @@ -0,0 +1,69 @@ +package com.dailycodework.lakesidehotel.model; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDate; + +/** + * @author Simpson Alfred + */ +@Entity +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class BookedRoom { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long bookingId; + + @Column(name = "check_in") + private LocalDate checkInDate; + + @Column(name = "check_out") + private LocalDate checkOutDate; + + @Column(name = "guest_fullName") + private String guestFullName; + + @Column(name = "guest_email") + private String guestEmail; + + @Column(name = "adults") + private int NumOfAdults; + + @Column(name = "children") + private int NumOfChildren; + + @Column(name = "total_guest") + private int totalNumOfGuest; + + @Column(name = "confirmation_Code") + private String bookingConfirmationCode; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "room_id") + private Room room; + + public void calculateTotalNumberOfGuest(){ + this.totalNumOfGuest = this.NumOfAdults + NumOfChildren; + } + + public void setNumOfAdults(int numOfAdults) { + NumOfAdults = numOfAdults; + calculateTotalNumberOfGuest(); + } + + public void setNumOfChildren(int numOfChildren) { + NumOfChildren = numOfChildren; + calculateTotalNumberOfGuest(); + } + + public void setBookingConfirmationCode(String bookingConfirmationCode) { + this.bookingConfirmationCode = bookingConfirmationCode; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Role.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Role.java new file mode 100644 index 0000000..f4545ed --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Role.java @@ -0,0 +1,54 @@ +package com.dailycodework.lakesidehotel.model; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +/** + * @author Simpson Alfred + */ +@Entity +@Getter +@Setter +@NoArgsConstructor +public class Role { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; + + @JsonIgnore + @ManyToMany(mappedBy = "roles") + private Collection users = new HashSet<>(); + + public Role(String name) { + this.name = name; + } + + public void assignRoleToUser(User user){ + user.getRoles().add(this); + this.getUsers().add(user); + } + + public void removeUserFromRole(User user){ + user.getRoles().remove(this); + this.getUsers().remove(user); + + } + + public void removeAllUsersFromRole(){ + if (this.getUsers() != null){ + List roleUsers = this.getUsers().stream().toList(); + roleUsers.forEach(this :: removeUserFromRole); + } + } + public String getName(){ + return name != null? name : ""; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Room.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Room.java new file mode 100644 index 0000000..f134383 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/Room.java @@ -0,0 +1,47 @@ +package com.dailycodework.lakesidehotel.model; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.RandomStringUtils; + +import java.math.BigDecimal; +import java.sql.Blob; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Simpson Alfred + */ +@Entity +@Getter +@Setter +@AllArgsConstructor +public class Room { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String roomType; + private BigDecimal roomPrice; + private boolean isBooked = false; + @Lob + private Blob photo; + + @OneToMany(mappedBy="room", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + private List bookings; + + public Room() { + this.bookings = new ArrayList<>(); + } + public void addBooking(BookedRoom booking){ + if (bookings == null){ + bookings = new ArrayList<>(); + } + bookings.add(booking); + booking.setRoom(this); + isBooked = true; + String bookingCode = RandomStringUtils.randomNumeric(10); + booking.setBookingConfirmationCode(bookingCode); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/User.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/User.java new file mode 100644 index 0000000..1388518 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/model/User.java @@ -0,0 +1,38 @@ +package com.dailycodework.lakesidehotel.model; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.ManyToAny; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; + +/** + * @author Simpson Alfred + */ +@Entity +@Getter +@Setter +@NoArgsConstructor +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String firstName; + private String lastName; + private String email; + private String password; + @ManyToMany(fetch = FetchType.EAGER, + cascade = {CascadeType.PERSIST, + CascadeType.MERGE, CascadeType.DETACH}) + @JoinTable(name = "user_roles", + joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), + inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id")) + private Collection roles = new HashSet<>(); + + + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/BookingRepository.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/BookingRepository.java new file mode 100644 index 0000000..6676dff --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/BookingRepository.java @@ -0,0 +1,20 @@ +package com.dailycodework.lakesidehotel.repository; + +import com.dailycodework.lakesidehotel.model.BookedRoom; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +public interface BookingRepository extends JpaRepository { + + List findByRoomId(Long roomId); + + Optional findByBookingConfirmationCode(String confirmationCode); + + List findByGuestEmail(String email); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoleRepository.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoleRepository.java new file mode 100644 index 0000000..048d3e8 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoleRepository.java @@ -0,0 +1,18 @@ +package com.dailycodework.lakesidehotel.repository; + +import com.dailycodework.lakesidehotel.model.Role; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +public interface RoleRepository extends JpaRepository { + + Optional findByName(String role); + + + boolean existsByName(String role); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoomRepository.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoomRepository.java new file mode 100644 index 0000000..45beb7f --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/RoomRepository.java @@ -0,0 +1,28 @@ +package com.dailycodework.lakesidehotel.repository; + +import com.dailycodework.lakesidehotel.model.Room; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.time.LocalDate; +import java.util.List; + +/** + * @author Simpson Alfred + */ + +public interface RoomRepository extends JpaRepository { + + @Query("SELECT DISTINCT r.roomType FROM Room r") + List findDistinctRoomTypes(); + + @Query(" SELECT r FROM Room r " + + " WHERE r.roomType LIKE %:roomType% " + + " AND r.id NOT IN (" + + " SELECT br.room.id FROM BookedRoom br " + + " WHERE ((br.checkInDate <= :checkOutDate) AND (br.checkOutDate >= :checkInDate))" + + ")") + + List findAvailableRoomsByDatesAndType(LocalDate checkInDate, LocalDate checkOutDate, String roomType); +} + diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/UserRepository.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/UserRepository.java new file mode 100644 index 0000000..81d26fa --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/repository/UserRepository.java @@ -0,0 +1,18 @@ +package com.dailycodework.lakesidehotel.repository; + +import com.dailycodework.lakesidehotel.model.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +public interface UserRepository extends JpaRepository { + boolean existsByEmail(String email); + + void deleteByEmail(String email); + + Optional findByEmail(String email); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/request/LoginRequest.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/request/LoginRequest.java new file mode 100644 index 0000000..75c089a --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/request/LoginRequest.java @@ -0,0 +1,15 @@ +package com.dailycodework.lakesidehotel.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +/** + * @author Simpson Alfred + */ +@Data +public class LoginRequest { + @NotBlank + private String email; + @NotBlank + private String password; +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/BookingResponse.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/BookingResponse.java new file mode 100644 index 0000000..e0308dc --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/BookingResponse.java @@ -0,0 +1,45 @@ +package com.dailycodework.lakesidehotel.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +/** + * @author Simpson Alfred + */ + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BookingResponse { + + private Long id; + + private LocalDate checkInDate; + + private LocalDate checkOutDate; + + private String guestName; + + private String guestEmail; + + private int numOfAdults; + + private int numOfChildren; + + private int totalNumOfGuests; + + private String bookingConfirmationCode; + + private RoomResponse room; + + public BookingResponse(Long id, LocalDate checkInDate, LocalDate checkOutDate, + String bookingConfirmationCode) { + this.id = id; + this.checkInDate = checkInDate; + this.checkOutDate = checkOutDate; + this.bookingConfirmationCode = bookingConfirmationCode; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/JwtResponse.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/JwtResponse.java new file mode 100644 index 0000000..764866d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/JwtResponse.java @@ -0,0 +1,30 @@ +package com.dailycodework.lakesidehotel.response; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author Simpson Alfred + */ + +@Data + +@NoArgsConstructor +public class JwtResponse { + private Long id; + private String email; + private String token; + private String type = "Bearer"; + private List roles; + + public JwtResponse(Long id, String email, String token, List roles) { + this.id = id; + this.email = email; + this.token = token; + this.roles = roles; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/RoomResponse.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/RoomResponse.java new file mode 100644 index 0000000..d077d1a --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/response/RoomResponse.java @@ -0,0 +1,40 @@ +package com.dailycodework.lakesidehotel.response; + + +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.tomcat.util.codec.binary.Base64; + +import java.math.BigDecimal; +import java.util.List; + +/** + * @author Simpson Alfred + */ +@Data +@NoArgsConstructor +public class RoomResponse { + private Long id; + private String roomType; + private BigDecimal roomPrice; + private boolean isBooked; + private String photo; + private Listbookings; + + public RoomResponse(Long id, String roomType, BigDecimal roomPrice) { + this.id = id; + this.roomType = roomType; + this.roomPrice = roomPrice; + } + + public RoomResponse(Long id, String roomType, BigDecimal roomPrice, boolean isBooked, + byte[] photoBytes , List bookings) { + this.id = id; + this.roomType = roomType; + this.roomPrice = roomPrice; + this.isBooked = isBooked; + this.photo = photoBytes != null ? Base64.encodeBase64String(photoBytes) : null; + this.bookings = bookings; + } + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/CorsConfig.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/CorsConfig.java new file mode 100644 index 0000000..5b95f39 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/CorsConfig.java @@ -0,0 +1,47 @@ +package com.dailycodework.lakesidehotel.security; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import java.util.Arrays; + +/** + * @author Simpson Alfred + */ + +@Configuration +@EnableWebMvc +public class CorsConfig { + + private static final Long MAX_AGE = 3600L; + private static final int CORS_FILTER_ORDER = -102; + + @Bean + public FilterRegistrationBean corsFilter() { + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("http://localhost:5173"); + config.setAllowedHeaders(Arrays.asList( + HttpHeaders.AUTHORIZATION, + HttpHeaders.CONTENT_TYPE, + HttpHeaders.ACCEPT)); + config.setAllowedMethods(Arrays.asList( + HttpMethod.GET.name(), + HttpMethod.POST.name(), + HttpMethod.PUT.name(), + HttpMethod.DELETE.name())); + config.setMaxAge(MAX_AGE); + source.registerCorsConfiguration("/**", config); + FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); + bean.setOrder(CORS_FILTER_ORDER); + return bean; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/WebSecurityConfig.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/WebSecurityConfig.java new file mode 100644 index 0000000..d71fe90 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/WebSecurityConfig.java @@ -0,0 +1,75 @@ +package com.dailycodework.lakesidehotel.security; +import com.dailycodework.lakesidehotel.security.jwt.AuthTokenFilter; +import com.dailycodework.lakesidehotel.security.jwt.JwtAuthEntryPoint; +import com.dailycodework.lakesidehotel.security.user.HotelUserDetailsService; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + + +/** + * @author Simpson Alfred + */ +@Configuration +@RequiredArgsConstructor +@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true) +public class WebSecurityConfig { + private final HotelUserDetailsService userDetailsService; + private final JwtAuthEntryPoint jwtAuthEntryPoint; + + @Bean + public AuthTokenFilter authenticationTokenFilter(){ + return new AuthTokenFilter(); + } + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + var authProvider = new DaoAuthenticationProvider(); + authProvider.setUserDetailsService(userDetailsService); + authProvider.setPasswordEncoder(passwordEncoder()); + return authProvider; + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { + return authConfig.getAuthenticationManager(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http.csrf(AbstractHttpConfigurer :: disable) + .exceptionHandling( + exception -> exception.authenticationEntryPoint(jwtAuthEntryPoint)) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .authorizeHttpRequests(auth -> auth + .requestMatchers("/auth/**", "/rooms/**","/bookings/**") + .permitAll().requestMatchers("/roles/**").hasRole("ADMIN") + .anyRequest().authenticated()); + http.authenticationProvider(authenticationProvider()); + http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); + return http.build(); + } + + + + + + + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/AuthTokenFilter.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/AuthTokenFilter.java new file mode 100644 index 0000000..54cdd37 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/AuthTokenFilter.java @@ -0,0 +1,60 @@ +package com.dailycodework.lakesidehotel.security.jwt; + +import com.dailycodework.lakesidehotel.security.user.HotelUserDetailsService; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; +import org.springframework.util.StringUtils; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +/** + * @author Simpson Alfred + */ + +public class AuthTokenFilter extends OncePerRequestFilter { + + @Autowired + private JwtUtils jwtUtils; + + @Autowired + private HotelUserDetailsService userDetailsService; + private static final Logger logger = LoggerFactory.getLogger(AuthTokenFilter.class); + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) throws ServletException, IOException { + try{ + String jwt = parseJwt(request); + if (jwt != null && jwtUtils.validateToken(jwt)){ + String email = jwtUtils.getUserNameFromToken(jwt); + UserDetails userDetails = userDetailsService.loadUserByUsername(email); + var authentication = + new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); + authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + }catch (Exception e){ + logger.error("Cannot set user authentication : {} ", e.getMessage()); + } + filterChain.doFilter(request, response); + } + + private String parseJwt(HttpServletRequest request) { + String headerAuth = request.getHeader("Authorization"); + if (StringUtils.hasText(headerAuth) && headerAuth.startsWith("Bearer ")){ + return headerAuth.substring(7); + } + return null; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtAuthEntryPoint.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtAuthEntryPoint.java new file mode 100644 index 0000000..64641ac --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtAuthEntryPoint.java @@ -0,0 +1,46 @@ +package com.dailycodework.lakesidehotel.security.jwt; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +/** + * @author Simpson Alfred + */ + +@Component +public class JwtAuthEntryPoint implements AuthenticationEntryPoint { + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException, ServletException { + + response.setContentType(MediaType.APPLICATION_JSON_VALUE); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + + final Map body = new HashMap<>(); + body.put("status", HttpServletResponse.SC_UNAUTHORIZED); + body.put("error", "Unauthorized"); + body.put("message", authException.getMessage()); + body.put("path", request.getServletPath()); + + final ObjectMapper mapper = new ObjectMapper(); + mapper.writeValue(response.getOutputStream(), body); + } +} + + + + diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtUtils.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtUtils.java new file mode 100644 index 0000000..790b8be --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/jwt/JwtUtils.java @@ -0,0 +1,72 @@ +package com.dailycodework.lakesidehotel.security.jwt; + +import com.dailycodework.lakesidehotel.security.user.HotelUserDetails; +import io.jsonwebtoken.*; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Component; + +import java.security.Key; +import java.util.Date; +import java.util.List; + + +/** + * @author Simpson Alfred + */ + +@Component +public class JwtUtils { + private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class); + + @Value("${auth.token.jwtSecret}") + private String jwtSecret; + + @Value("${auth.token.expirationInMils}") + private int jwtExpirationMs; + + public String generateJwtTokenForUser(Authentication authentication){ + HotelUserDetails userPrincipal = (HotelUserDetails) authentication.getPrincipal(); + List roles = userPrincipal.getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority).toList(); + return Jwts.builder() + .setSubject(userPrincipal.getUsername()) + .claim("roles", roles) + .setIssuedAt(new Date()) + .setExpiration(new Date((new Date()).getTime()+jwtExpirationMs)) + .signWith(key(), SignatureAlgorithm.HS256).compact(); + } + + private Key key() { + return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret)); + } + public String getUserNameFromToken(String token){ + return Jwts.parserBuilder() + .setSigningKey(key()) + .build() + .parseClaimsJws(token).getBody().getSubject(); + } + public boolean validateToken(String token){ + try{ + Jwts.parserBuilder().setSigningKey(key()).build().parse(token); + return true; + }catch(MalformedJwtException e){ + logger.error("Invalid jwt token : {} ", e.getMessage()); + }catch (ExpiredJwtException e){ + logger.error("Expired token : {} ", e.getMessage()); + }catch (UnsupportedJwtException e){ + logger.error("This token is not supported : {} ", e.getMessage()); + }catch (IllegalArgumentException e){ + logger.error("No claims found : {} ", e.getMessage()); + } + return false; + } + + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetails.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetails.java new file mode 100644 index 0000000..e23dd0d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetails.java @@ -0,0 +1,79 @@ +package com.dailycodework.lakesidehotel.security.user; + +import com.dailycodework.lakesidehotel.model.User; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Simpson Alfred + */ + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class HotelUserDetails implements UserDetails { + private Long id; + private String email; + private String password; + private Collection authorities; + + public static HotelUserDetails buildUserDetails(User user){ + List authorities = user.getRoles() + .stream() + .map(role -> new SimpleGrantedAuthority(role.getName())) + .collect(Collectors.toList()); + return new HotelUserDetails( + user.getId(), + user.getEmail(), + user.getPassword(), + authorities); + + } + + + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return email; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetailsService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetailsService.java new file mode 100644 index 0000000..8dbc56e --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/security/user/HotelUserDetailsService.java @@ -0,0 +1,25 @@ +package com.dailycodework.lakesidehotel.security.user; + +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +/** + * @author Simpson Alfred + */ +@Service +@RequiredArgsConstructor +public class HotelUserDetailsService implements UserDetailsService { + private final UserRepository userRepository; + + @Override + public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { + User user = userRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + return HotelUserDetails.buildUserDetails(user); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/BookingService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/BookingService.java new file mode 100644 index 0000000..6d55d53 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/BookingService.java @@ -0,0 +1,94 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.exception.InvalidBookingRequestException; +import com.dailycodework.lakesidehotel.exception.ResourceNotFoundException; +import com.dailycodework.lakesidehotel.model.BookedRoom; +import com.dailycodework.lakesidehotel.model.Room; +import com.dailycodework.lakesidehotel.repository.BookingRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import java.util.List; + +/** + * @author Simpson Alfred + */ + +@Service +@RequiredArgsConstructor +public class BookingService implements IBookingService { + private final BookingRepository bookingRepository; + private final IRoomService roomService; + + + @Override + public List getAllBookings() { + return bookingRepository.findAll(); + } + + + @Override + public List getBookingsByUserEmail(String email) { + return bookingRepository.findByGuestEmail(email); + } + + @Override + public void cancelBooking(Long bookingId) { + bookingRepository.deleteById(bookingId); + } + + @Override + public List getAllBookingsByRoomId(Long roomId) { + return bookingRepository.findByRoomId(roomId); + } + + @Override + public String saveBooking(Long roomId, BookedRoom bookingRequest) { + if (bookingRequest.getCheckOutDate().isBefore(bookingRequest.getCheckInDate())){ + throw new InvalidBookingRequestException("Check-in date must come before check-out date"); + } + Room room = roomService.getRoomById(roomId).get(); + List existingBookings = room.getBookings(); + boolean roomIsAvailable = roomIsAvailable(bookingRequest,existingBookings); + if (roomIsAvailable){ + room.addBooking(bookingRequest); + bookingRepository.save(bookingRequest); + }else{ + throw new InvalidBookingRequestException("Sorry, This room is not available for the selected dates;"); + } + return bookingRequest.getBookingConfirmationCode(); + } + + @Override + public BookedRoom findByBookingConfirmationCode(String confirmationCode) { + return bookingRepository.findByBookingConfirmationCode(confirmationCode) + .orElseThrow(() -> new ResourceNotFoundException("No booking found with booking code :"+confirmationCode)); + + } + + + private boolean roomIsAvailable(BookedRoom bookingRequest, List existingBookings) { + return existingBookings.stream() + .noneMatch(existingBooking -> + bookingRequest.getCheckInDate().equals(existingBooking.getCheckInDate()) + || bookingRequest.getCheckOutDate().isBefore(existingBooking.getCheckOutDate()) + || (bookingRequest.getCheckInDate().isAfter(existingBooking.getCheckInDate()) + && bookingRequest.getCheckInDate().isBefore(existingBooking.getCheckOutDate())) + || (bookingRequest.getCheckInDate().isBefore(existingBooking.getCheckInDate()) + + && bookingRequest.getCheckOutDate().equals(existingBooking.getCheckOutDate())) + || (bookingRequest.getCheckInDate().isBefore(existingBooking.getCheckInDate()) + + && bookingRequest.getCheckOutDate().isAfter(existingBooking.getCheckOutDate())) + + || (bookingRequest.getCheckInDate().equals(existingBooking.getCheckOutDate()) + && bookingRequest.getCheckOutDate().equals(existingBooking.getCheckInDate())) + + || (bookingRequest.getCheckInDate().equals(existingBooking.getCheckOutDate()) + && bookingRequest.getCheckOutDate().equals(bookingRequest.getCheckInDate())) + ); + } + + + + +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IBookingService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IBookingService.java new file mode 100644 index 0000000..b6154fe --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IBookingService.java @@ -0,0 +1,23 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.model.BookedRoom; + +import java.util.List; + +/** + * @author Simpson Alfred + */ + +public interface IBookingService { + void cancelBooking(Long bookingId); + + List getAllBookingsByRoomId(Long roomId); + + String saveBooking(Long roomId, BookedRoom bookingRequest); + + BookedRoom findByBookingConfirmationCode(String confirmationCode); + + List getAllBookings(); + + List getBookingsByUserEmail(String email); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoleService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoleService.java new file mode 100644 index 0000000..36e8fcd --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoleService.java @@ -0,0 +1,22 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.model.Role; +import com.dailycodework.lakesidehotel.model.User; + +import java.util.List; + +/** + * @author Simpson Alfred + */ + +public interface IRoleService { + List getRoles(); + Role createRole(Role theRole); + + void deleteRole(Long id); + Role findByName(String name); + + User removeUserFromRole(Long userId, Long roleId); + User assignRoleToUser(Long userId, Long roleId); + Role removeAllUsersFromRole(Long roleId); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoomService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoomService.java new file mode 100644 index 0000000..9dbfc2c --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IRoomService.java @@ -0,0 +1,33 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.model.Room; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.math.BigDecimal; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +public interface IRoomService { + Room addNewRoom(MultipartFile photo, String roomType, BigDecimal roomPrice) throws SQLException, IOException; + + List getAllRoomTypes(); + + List getAllRooms(); + + byte[] getRoomPhotoByRoomId(Long roomId) throws SQLException; + + void deleteRoom(Long roomId); + + Room updateRoom(Long roomId, String roomType, BigDecimal roomPrice, byte[] photoBytes); + + Optional getRoomById(Long roomId); + + List getAvailableRooms(LocalDate checkInDate, LocalDate checkOutDate, String roomType); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IUserService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IUserService.java new file mode 100644 index 0000000..982a36d --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/IUserService.java @@ -0,0 +1,16 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.model.User; + +import java.util.List; + +/** + * @author Simpson Alfred + */ + +public interface IUserService { + User registerUser(User user); + List getUsers(); + void deleteUser(String email); + User getUser(String email); +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoleService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoleService.java new file mode 100644 index 0000000..aebac62 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoleService.java @@ -0,0 +1,85 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.exception.RoleAlreadyExistException; +import com.dailycodework.lakesidehotel.exception.UserAlreadyExistsException; +import com.dailycodework.lakesidehotel.model.Role; +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.repository.RoleRepository; +import com.dailycodework.lakesidehotel.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +@Service +@RequiredArgsConstructor +public class RoleService implements IRoleService { + private final RoleRepository roleRepository; + private final UserRepository userRepository; + + @Override + public List getRoles() { + return roleRepository.findAll(); + } + + @Override + public Role createRole(Role theRole) { + String roleName = "ROLE_"+theRole.getName().toUpperCase(); + Role role = new Role(roleName); + if (roleRepository.existsByName(roleName)){ + throw new RoleAlreadyExistException(theRole.getName()+" role already exists"); + } + return roleRepository.save(role); + } + + @Override + public void deleteRole(Long roleId) { + this.removeAllUsersFromRole(roleId); + roleRepository.deleteById(roleId); + } + + @Override + public Role findByName(String name) { + return roleRepository.findByName(name).get(); + } + + @Override + public User removeUserFromRole(Long userId, Long roleId) { + Optional user = userRepository.findById(userId); + Optional role = roleRepository.findById(roleId); + if (role.isPresent() && role.get().getUsers().contains(user.get())){ + role.get().removeUserFromRole(user.get()); + roleRepository.save(role.get()); + return user.get(); + } + throw new UsernameNotFoundException("User not found"); + } + + @Override + public User assignRoleToUser(Long userId, Long roleId) { + Optional user = userRepository.findById(userId); + Optional role = roleRepository.findById(roleId); + if (user.isPresent() && user.get().getRoles().contains(role.get())){ + throw new UserAlreadyExistsException( + user.get().getFirstName()+ " is already assigned to the" + role.get().getName()+ " role"); + } + if (role.isPresent()){ + role.get().assignRoleToUser(user.get()); + roleRepository.save(role.get()); + } + return user.get(); + } + + @Override + public Role removeAllUsersFromRole(Long roleId) { + Optional role = roleRepository.findById(roleId); + role.ifPresent(Role::removeAllUsersFromRole); + return roleRepository.save(role.get()); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoomService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoomService.java new file mode 100644 index 0000000..56458ab --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/RoomService.java @@ -0,0 +1,96 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.exception.InternalServerException; +import com.dailycodework.lakesidehotel.exception.ResourceNotFoundException; +import com.dailycodework.lakesidehotel.model.Room; +import com.dailycodework.lakesidehotel.repository.RoomRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.sql.rowset.serial.SerialBlob; +import java.io.IOException; +import java.math.BigDecimal; +import java.sql.Blob; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +/** + * @author Simpson Alfred + */ + +@Service +@RequiredArgsConstructor +public class RoomService implements IRoomService { + private final RoomRepository roomRepository; + @Override + public Room addNewRoom(MultipartFile file, String roomType, BigDecimal roomPrice) throws SQLException, IOException { + Room room = new Room(); + room.setRoomType(roomType); + room.setRoomPrice(roomPrice); + if (!file.isEmpty()){ + byte[] photoBytes = file.getBytes(); + Blob photoBlob = new SerialBlob(photoBytes); + room.setPhoto(photoBlob); + } + return roomRepository.save(room); + } + + @Override + public List getAllRoomTypes() { + return roomRepository.findDistinctRoomTypes(); + } + + @Override + public List getAllRooms() { + return roomRepository.findAll(); + } + + @Override + public byte[] getRoomPhotoByRoomId(Long roomId) throws SQLException { + Optional theRoom = roomRepository.findById(roomId); + if(theRoom.isEmpty()){ + throw new ResourceNotFoundException("Sorry, Room not found!"); + } + Blob photoBlob = theRoom.get().getPhoto(); + if(photoBlob != null){ + return photoBlob.getBytes(1, (int) photoBlob.length()); + } + return null; + } + + @Override + public void deleteRoom(Long roomId) { + Optional theRoom = roomRepository.findById(roomId); + if(theRoom.isPresent()){ + roomRepository.deleteById(roomId); + } + } + + @Override + public Room updateRoom(Long roomId, String roomType, BigDecimal roomPrice, byte[] photoBytes) { + Room room = roomRepository.findById(roomId).get(); + if (roomType != null) room.setRoomType(roomType); + if (roomPrice != null) room.setRoomPrice(roomPrice); + if (photoBytes != null && photoBytes.length > 0) { + try { + room.setPhoto(new SerialBlob(photoBytes)); + } catch (SQLException ex) { + throw new InternalServerException("Fail updating room"); + } + } + return roomRepository.save(room); + } + + @Override + public Optional getRoomById(Long roomId) { + return Optional.of(roomRepository.findById(roomId).get()); + } + + @Override + public List getAvailableRooms(LocalDate checkInDate, LocalDate checkOutDate, String roomType) { + return roomRepository.findAvailableRoomsByDatesAndType(checkInDate, checkOutDate, roomType); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/UserService.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/UserService.java new file mode 100644 index 0000000..135e547 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/java/com/dailycodework/lakesidehotel/service/UserService.java @@ -0,0 +1,60 @@ +package com.dailycodework.lakesidehotel.service; + +import com.dailycodework.lakesidehotel.exception.UserAlreadyExistsException; +import com.dailycodework.lakesidehotel.model.Role; +import com.dailycodework.lakesidehotel.model.User; +import com.dailycodework.lakesidehotel.repository.RoleRepository; +import com.dailycodework.lakesidehotel.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Collections; +import java.util.List; + +/** + * @author Simpson Alfred + */ + +@Service +@RequiredArgsConstructor +public class UserService implements IUserService { + private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; + private final RoleRepository roleRepository; + + @Override + public User registerUser(User user) { + if (userRepository.existsByEmail(user.getEmail())){ + throw new UserAlreadyExistsException(user.getEmail() + " already exists"); + } + user.setPassword(passwordEncoder.encode(user.getPassword())); + System.out.println(user.getPassword()); + Role userRole = roleRepository.findByName("ROLE_USER").get(); + user.setRoles(Collections.singletonList(userRole)); + return userRepository.save(user); + } + + @Override + public List getUsers() { + return userRepository.findAll(); + } + + @Transactional + @Override + public void deleteUser(String email) { + User theUser = getUser(email); + if (theUser != null){ + userRepository.deleteByEmail(email); + } + + } + + @Override + public User getUser(String email) { + return userRepository.findByEmail(email) + .orElseThrow(() -> new UsernameNotFoundException("User not found")); + } +} diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.properties b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.properties new file mode 100644 index 0000000..5085fb5 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.properties @@ -0,0 +1,25 @@ +server.port=9192 + +spring.datasource.url=jdbc:mysql://localhost:3306/lakeSide_hotel_db +spring.datasource.username=root +spring.datasource.password=admin + +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver +spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQLDialect + + +spring.servlet.multipart.max-file-size=500KB +spring.servlet.multipart.max-request-size=500KB + +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +spring.jpa.hibernate.ddl-auto=update + + +logging.level.org.hibernate.SQL=DEBUG +logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE + +# App Properties + +auth.token.expirationInMils=3600000 +auth.token.jwtSecret=36763979244226452948404D635166546A576D5A7134743777217A25432A462D diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.yml b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.yml new file mode 100644 index 0000000..5398c81 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/main/resources/application.yml @@ -0,0 +1,40 @@ +#server: +# port: 9192 +# +#spring: +# datasource: +# username: root +# password: admin +# url: jdbc:mysql://localhost:3306/lakeSide_hotel_db +# driver-class-name: com.mysql.cj.jdbc.Driver +# jpa: +# show-sql: true +# hibernate: +# ddl-auto: update +# format_sql: true +# servlet: +# multipart: +# max-file-size: 5MB +# max-request-size: 5MB +# file-size-threshold: 2KB +# +# security: +# jwt: +# secret-key: 36763979244226452948404D635166546A576D5A7134743777217A25432A462D +# expire-length: 3600000 +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# diff --git a/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/test/java/com/dailycodework/lakesidehotel/LakeSideHotelApplicationTests.java b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/test/java/com/dailycodework/lakesidehotel/LakeSideHotelApplicationTests.java new file mode 100644 index 0000000..7e64a96 --- /dev/null +++ b/XSampleCode/Hotel-DeLuna/server/flexycode-hotel-server-master/src/test/java/com/dailycodework/lakesidehotel/LakeSideHotelApplicationTests.java @@ -0,0 +1,13 @@ +package com.dailycodework.lakesidehotel; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class LakeSideHotelApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/week_1/introduction/intermediate_java/App,java b/week_1/introduction/intermediate_java/App,java new file mode 100644 index 0000000..bf7e2de --- /dev/null +++ b/week_1/introduction/intermediate_java/App,java @@ -0,0 +1,49 @@ +package IntermediateJava; + +public class IntermediateJava { + public static void main(String[] args) { + // Variables and Data Types + int age = 25; + double height = 1.75; + String name = "John"; + + // Conditional Statements + if (age >= 18) { + System.out.println(name + " is an adult."); + } else { + System.out.println(name + " is a minor."); + } + + // Loops + for (int i = 0; i < 5; i++) { + System.out.println("Loop iteration: " + i); + } + + // Arrays + String[] fruits = {"Apple", "Banana", "Orange"}; + System.out.println("First fruit: " + fruits[0]); + + // Classes and Objects + Person person = new Person("Alice", 30); + System.out.println("Person name: " + person.getName()); + System.out.println("Person age: " + person.getAge()); + } +} + +class Person { + private String name; + private int age; + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} \ No newline at end of file diff --git a/week_1/introduction/intro.txt b/week_1/introduction/intro.txt new file mode 100644 index 0000000..ca746be --- /dev/null +++ b/week_1/introduction/intro.txt @@ -0,0 +1,12 @@ +## [Introduction](#introduction) +This repository contains source code for a Java project that focuses on Intermediate concepts, codes and exercises. + +#### Course Description: +This course is a continuation of CCPRGG1L - Fundamentals of Programming. The course covers advanced topics in Java to train students in developing robust programs. Topics to be covered include recursion, regular expression, basic object-oriented principles, graphics, and multithreaded programming. + +#### Course outcomes: +At the end of the course, the studend must be able to: +1. Create a program that uses recursions and regular expressions +2. Implement Object-Oriented in program design +3. Create and document application that uses a modern graphical user interface (GUI) + diff --git a/week_2/accessing_array_elements/App.java b/week_2/accessing_array_elements/App.java new file mode 100644 index 0000000..815b961 --- /dev/null +++ b/week_2/accessing_array_elements/App.java @@ -0,0 +1,23 @@ +public class App { + public static void main(String[] args) { + + // Array of Strings + String[] myfavefastfood = { "KuyaJay", "AlingTising", "BurgerKing", "BonChon", + "KennyRogers" }; + + // Access first array element + System.out.println(myfavefastfood[0]); + + // Access second array element + System.out.println(myfavefastfood[1]); + + // Access third array element + System.out.println(myfavefastfood[2]); + + // Access fourth array element + System.out.println(myfavefastfood[3]); + + // Access last array element + System.out.println(myfavefastfood[4]); + } +} \ No newline at end of file diff --git a/week_2/array/App.java b/week_2/array/App.java new file mode 100644 index 0000000..1df40a6 --- /dev/null +++ b/week_2/array/App.java @@ -0,0 +1,13 @@ +public class App { + public static void main(String[] args) { + + // Array of Strings + String[] myfavefastfood = { "KuyaJay", "AlingTising", "BurgerKing", "BonChon", "Chowking" }; + + // Array of Integers + int[] primeNumbers = { 2, 3, 5, 7 }; + + // Array of Characters + char[] myName = { 'J', 'A', 'Y', 'A', 'R', 'R', 'E' }; + } +} \ No newline at end of file diff --git a/week_2/looping_through_a_multidimensional_array /App.java b/week_2/looping_through_a_multidimensional_array /App.java new file mode 100644 index 0000000..407d104 --- /dev/null +++ b/week_2/looping_through_a_multidimensional_array /App.java @@ -0,0 +1,21 @@ +public class App { + public static void main(String[] args) throws Exception { + + // 3x3 + String[][] seatingArrangement = { { "JayArre", "Gabriel", "CielleMae" }, + { "Vince", "Joshua", "Anilov" }, + { "Kristine", "Jezlyn", "Jamaine" } }; + + // outer loop + for (int row = 0; row < seatingArrangement.length; row++) { + + System.out.println(" "); + System.out.print("row " + row + ": "); + // inner loop + for (int column = 0; column < seatingArrangement.length; column++) { + + System.out.print(seatingArrangement[row][column] + " "); + } + } + } +} \ No newline at end of file diff --git a/week_2/looping_through_an_array/App.java b/week_2/looping_through_an_array/App.java new file mode 100644 index 0000000..1a65c50 --- /dev/null +++ b/week_2/looping_through_an_array/App.java @@ -0,0 +1,36 @@ +public class App { + public static void main(String[] args) throws Exception { + + String[] myfavefastfood = { "KennyRogers", "PizzaHut", "BurgerKing", "AlingTising", "Bulaluan" }; + + // Loop through an array of strings + for (int i = 0; i < myfavefastfood.length; i++) { + System.out.println(myfavefastfood[i]); + } + + int[] primeNumbers = { 2, 3, 5, 7 }; + + // Loop through an array of integers + for (int i = 0; i < primeNumbers.length; i++) { + System.out.println(primeNumbers[i]); + } + + char[] myName = { 'J', 'A', 'Y', 'A', 'R', 'R', 'E' }; + + // Loop through an array of characters + for (int i = 0; i < myName.length; i++) { + System.out.println(myName[i]); + } + + System.out.println(""); + // Print name in reverse + for (int i = myName.length - 1; i >= 0; i--) { + System.out.print(myName[i]); + } + + // Using foreach + for (char i : myName) { + System.out.print(i); + } + } +} \ No newline at end of file diff --git a/week_2/looping_through_an_array_with_conditions/App.java b/week_2/looping_through_an_array_with_conditions/App.java new file mode 100644 index 0000000..86cf837 --- /dev/null +++ b/week_2/looping_through_an_array_with_conditions/App.java @@ -0,0 +1,34 @@ +public class App { + public static void main(String[] args) { + + // Array of Characters + char[] myName = { 'J', 'A', 'Y', 'A', 'R', 'R', 'E' }; + + // Loop through all characters + for (int i = 0; i < myName.length; i++) { + System.out.println(myName[i]); + } + + // Loop through all characters in reverse order + for (int i = myName.length - 1 ; i >= 0; i--) { + System.out.println(myName[i]); + } + + + // // Only display vowels + for (int i = 0; i < myName.length; i++) { + + if (myName[i] == 'A' || myName[i] == 'E' || myName[i] == 'I' || myName[i] == 'O' || myName[i] == 'U') { + System.out.println(myName[i]); + } + } + + // Only display consonants + for (int i = 0; i < myName.length; i++) { + + if (!(myName[i] == 'A' || myName[i] == 'E' || myName[i] == 'I' || myName[i] == 'O' || myName[i] == 'U')) { + System.out.println(myName[i]); + } + } + } +} \ No newline at end of file diff --git a/week_2/multidimensional_array/App.java b/week_2/multidimensional_array/App.java new file mode 100644 index 0000000..59f99de --- /dev/null +++ b/week_2/multidimensional_array/App.java @@ -0,0 +1,32 @@ +public class App { + public static void main(String[] args) throws Exception { + + String[][] seatReservation = { + { "Available", "Available", "Available", "Available", "Available", "Available", "Available" }, + { "Booked", "Booked", "Booked", "Booked", "Booked", "Booked", "Booked" }, + { "Booked", "Booked", "Booked", "Booked", "Booked", "Booked", "Booked" }, + { "Booked", "Booked", "Booked", "Booked", "Booked", "Booked", "Booked" }, + { "Booked", "Booked", "Booked", "Booked", "Booked", "Booked", "Booked" }, + { "Booked", "Booked", "Booked", "Booked", "Booked", "Booked", "Booked" }, + { "Available", "Available", "Available", "Available", "Available", "Selected", "Selected" } + }; + + // Access element that is selected + System.out.println(seatReservation[6][5]); + + // Access element that is selected + System.out.println(seatReservation[6][6]); + + // 2x1 Array + String[][] array2x1 = { { "X" }, { "O" } }; + + // 2x2 Array + String[][] array2x2 = { { "X", "O" }, { "O", "X" } }; + + // 2x3 Array + String[][] array2x3 = { { "X", "O", "X" }, { "O", "X", "O" } }; + + // 3x3 Array + String[][] array3x3 = { { "X", "O", "X" }, { "O", "X", "O" }, { "X", "O", "X" } }; + } +} diff --git a/week_2/multidimensional_array_patterns/App.java b/week_2/multidimensional_array_patterns/App.java new file mode 100644 index 0000000..690e5a8 --- /dev/null +++ b/week_2/multidimensional_array_patterns/App.java @@ -0,0 +1,51 @@ +public class App { + public static void main(String[] args) throws Exception { + + char [][] array_3x3 = {{'A','B','C'},{'D','E','F'},{'G','H','I'}}; + + // // A TO L + for (int rows = 0; rows < array_3x3.length; rows++) { + + System.out.println(""); + for (int columns = 0; columns < array_3x3.length; columns++) { + System.out.print(array_3x3[rows][columns]); + } + } + + // L TO A + for (int rows = array_3x3.length - 1; rows >= 0; rows--) { + + System.out.println(""); + + for (int columns = 0 ; columns < array_3x3.length; columns++) { + + System.out.print(array_3x3[rows][columns]); + } + } + + // Pattern + // Print column 0 and column 2 if the row is even. + // Print column 1 if the row is odd. + + for (int rows = 0; rows < array_3x3.length; rows++) { + + System.out.println(""); + + for (int columns = 0; columns < array_3x3.length; columns++) { + + // EVEN ROWS + if (rows % 2 == 0 && (columns == 0 || columns == 2)) { + System.out.print(array_3x3[rows][columns]); + } + // ODD ROWS + else if (rows % 2 != 0 && columns == 1) { + System.out.print(array_3x3[rows][columns]); + } + else + { + System.out.print(" "); + } + } + } + } +} \ No newline at end of file diff --git a/week_3/excemption_handling/arithmetic_exception/App.java b/week_3/excemption_handling/arithmetic_exception/App.java new file mode 100644 index 0000000..868c1e2 --- /dev/null +++ b/week_3/excemption_handling/arithmetic_exception/App.java @@ -0,0 +1,12 @@ +public class App { + public static void main(String[] args) { + + try { + int a = 5; + int b = 0; + System.out.println(a / b); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_3/excemption_handling/arrayindexoutofbounds_exception/App.java b/week_3/excemption_handling/arrayindexoutofbounds_exception/App.java new file mode 100644 index 0000000..f0bd1d7 --- /dev/null +++ b/week_3/excemption_handling/arrayindexoutofbounds_exception/App.java @@ -0,0 +1,12 @@ +public class App { + public static void main(String[] args) { + + try { + char[] myName = { 'J', 'A', 'Y', 'A', 'R', 'R', 'E' }; + + System.out.println(myName[7]); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_3/excemption_handling/illegalargument_exception/App.java b/week_3/excemption_handling/illegalargument_exception/App.java new file mode 100644 index 0000000..68dbe85 --- /dev/null +++ b/week_3/excemption_handling/illegalargument_exception/App.java @@ -0,0 +1,19 @@ +public class App { + public static void main(String[] args) { + + try { + iDontWantZeros(0); + } catch (Exception e) { + e.printStackTrace(); + } + } + + static void iDontWantZeros(int num) { + + if (num == 0) { + throw new IllegalArgumentException("I said no zeros!"); + } + + System.out.println(num); + } +} \ No newline at end of file diff --git a/week_3/excemption_handling/nullpointer_exception/App.java b/week_3/excemption_handling/nullpointer_exception/App.java new file mode 100644 index 0000000..834d4fa --- /dev/null +++ b/week_3/excemption_handling/nullpointer_exception/App.java @@ -0,0 +1,12 @@ +public class App { + public static void main(String[] args) { + + try { + String myName = null; + + System.out.println(myName.length()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_3/excemption_handling/userdefined_exception/App.java b/week_3/excemption_handling/userdefined_exception/App.java new file mode 100644 index 0000000..b36876f --- /dev/null +++ b/week_3/excemption_handling/userdefined_exception/App.java @@ -0,0 +1,25 @@ +import java.util.Scanner; + +public class App { + public static void main(String[] args) throws Exception { + + Scanner scan = new Scanner(System.in); + + try { + System.out.println("Divide two numbers!"); + + System.out.print("Enter dividend: "); + int firstNumber = scan.nextInt(); + + System.out.print("Enter divisor: "); + int secondNumber = scan.nextInt(); + + int quotient = firstNumber / secondNumber; + + System.out.print("The quotient is: " + quotient); + } catch (Exception e) { + System.out.print("You cannot divide by zero"); + e.printStackTrace(); + } + } +} diff --git a/week_3/file_handling/create_file/App.java b/week_3/file_handling/create_file/App.java new file mode 100644 index 0000000..d6edfd5 --- /dev/null +++ b/week_3/file_handling/create_file/App.java @@ -0,0 +1,22 @@ +import java.io.File; + +public class App { + public static void main(String[] args) throws Exception { + + try { + // Create object from File class + File myFile = new File("C:\\Users\\flexycode\\Documents\\sample.txt"); + + // .createNewFile() method creates a new file if the file in the pathname does + // not exist + if (myFile.createNewFile()) { + System.out.println(myFile.getName() + " created!"); + } else { + System.out.println(myFile.getName() + " already exists!"); + } + } catch (Exception e) { + System.out.println("There is an error"); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_3/file_handling/delete_file/App.java b/week_3/file_handling/delete_file/App.java new file mode 100644 index 0000000..3ac1033 --- /dev/null +++ b/week_3/file_handling/delete_file/App.java @@ -0,0 +1,22 @@ +import java.io.File; + +public class App { + public static void main(String[] args) throws Exception { + + try { + // Create object from File class + File myFile = new File("C:\\Users\\SLY\\Documents\\sample.txt"); + + // .delete() method removes a file if the file exists in the pathname + if (myFile.delete()) { + System.out.println(myFile.getName() + " deleted successfully!"); + } else { + System.out.println("Failed to delete " + myFile.getName()); + } + } catch (Exception e) { + System.out.println("There is an error"); + e.printStackTrace(); + } + + } +} \ No newline at end of file diff --git a/week_3/file_handling/file_class/App.java b/week_3/file_handling/file_class/App.java new file mode 100644 index 0000000..9507a7c --- /dev/null +++ b/week_3/file_handling/file_class/App.java @@ -0,0 +1,22 @@ +import java.io.File; + +public class App { + public static void main(String[] args) throws Exception { + + try { + // Create object from File class + File myFile = new File("C:\\Users\\flexycode\\Documents\\sample.txt"); + + // .exists() method checks if a file exists in the pathname + if (myFile.exists()) { + System.out.println(myFile.getName() + "exists!"); + } else { + System.out.println(myFile.getName() + " does not exist!"); + } + } catch (Exception e) { + System.out.println("There is an error"); + e.printStackTrace(); + } + + } +} \ No newline at end of file diff --git a/week_3/file_handling/read_file/App.java b/week_3/file_handling/read_file/App.java new file mode 100644 index 0000000..3e14518 --- /dev/null +++ b/week_3/file_handling/read_file/App.java @@ -0,0 +1,28 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Scanner; + +public class App { + public static void main(String[] args) throws Exception { + + try { + // Create an object from the File class + File myFile = new File("C:\\Users\\flexycode\\Documents\\sample.txt"); + + // Create an object from the Scanner class + Scanner scan = new Scanner(myFile); + + // Read the content of the file + while (scan.hasNextLine()) { + String data = scan.nextLine(); + System.out.println(data); + } + + // Close scanner + scan.close(); + } catch (FileNotFoundException e) { + System.out.println("An error occurred"); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_3/file_handling/write_file/App.java b/week_3/file_handling/write_file/App.java new file mode 100644 index 0000000..cbb948c --- /dev/null +++ b/week_3/file_handling/write_file/App.java @@ -0,0 +1,23 @@ +import java.io.FileWriter; +import java.io.IOException; + +public class App { + public static void main(String[] args) throws Exception { + + try { + // Create object from FileWriter class + FileWriter myWriter = new FileWriter("C:\\Users\\flexycode\\Documents\\sample.txt"); + + // .write() methods adds content to the file + myWriter.write("Hello i am now taking intermediate programming in Java!"); + + // Close FileWriter + myWriter.close(); + + System.out.println("File Write successful!"); + } catch (IOException e) { + System.out.println("An error occurred."); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/week_4/RegexPattern/Password/App.java b/week_4/RegexPattern/Password/App.java new file mode 100644 index 0000000..b808431 --- /dev/null +++ b/week_4/RegexPattern/Password/App.java @@ -0,0 +1,28 @@ +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.Scanner; + +public class App { + public static void main(String[] args) { + + // At least one letter + // At least one number + // At least 8 chars + + // Java program to check if a password is valid + Scanner scan = new Scanner(System.in); + System.out.print("Enter password: "); + String password = scan.nextLine(); + + Pattern pattern = Pattern.compile("^(?=.*[A-Za-z])(?=.*\\d).{8,}$"); + Matcher matcher = pattern.matcher(password); + + boolean match = matcher.matches(); + + if (match) { + System.out.println("valid password "); + } else { + System.out.println("invalid password "); + } + } +} diff --git a/week_4/RegularExpression/Find/App.java b/week_4/RegularExpression/Find/App.java new file mode 100644 index 0000000..d317174 --- /dev/null +++ b/week_4/RegularExpression/Find/App.java @@ -0,0 +1,28 @@ +import java.util.regex.Pattern; +import java.util.Scanner; +import java.util.regex.Matcher; + +public class App { + public static void main(String[] args) { + + Scanner scan = new Scanner(System.in); + + while (true) { + System.out.println("Enter text:"); + + Pattern pattern = Pattern.compile("java"); + Matcher matcher = pattern.matcher(scan.nextLine()); + + boolean found = false; + + while (matcher.find()) { + System.out.println("I found the text " + matcher.group() + " starting at index " + + matcher.start() + " and ending at index " + matcher.end()); + found = true; + } + if (!found) { + System.out.println("No match found."); + } + } + } +} \ No newline at end of file diff --git a/week_4/RegularExpression/Match/App.java b/week_4/RegularExpression/Match/App.java new file mode 100644 index 0000000..39733ea --- /dev/null +++ b/week_4/RegularExpression/Match/App.java @@ -0,0 +1,45 @@ +package Intermediate + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.Scanner; + +public class App { + public static void main(String[] args) { + + // Java program to check if a student number is valid + Scanner scan = new Scanner(System.in); + System.out.print("Enter student number: "); + String studentNum = scan.nextLine(); + + // Long method + Pattern pattern = Pattern.compile("\\d{4}-\\d{6}"); + Matcher matcher = pattern.matcher(studentNum); + + boolean match = matcher.matches(); + + if (match) { + System.out.println("valid student number"); + } else { + System.out.println("invalid student number"); + } + + // Short method + match = Pattern.compile("\\d{4}-\\d{6}").matcher(studentNum).matches(); + + if (match) { + System.out.println("valid student number"); + } else { + System.out.println("invalid student number"); + } + + // Even shorter method + match = Pattern.matches("\\d{4}-\\d{6}", studentNum); + + if (match) { + System.out.println("valid student number"); + } else { + System.out.println("invalid student number"); + } + } +} diff --git a/week_4/StringBuilder/Append/App.java b/week_4/StringBuilder/Append/App.java new file mode 100644 index 0000000..acb85db --- /dev/null +++ b/week_4/StringBuilder/Append/App.java @@ -0,0 +1,20 @@ +package Intermediate; + +public class StringBuilderAppend { + + public static void main(String[] args) { + // Create a StringBuilder with some text + StringBuilder myStr = new StringBuilder("My Email Address is "); + + // Append different data types using append() + myStr.append("MagicMan "); + myStr.append(2024); + myStr.append("@"); + myStr.append("Google.com"); + + // Print the StringBuilder + System.out.println(myStr.toString()); + + } + +} diff --git a/week_4/StringBuilder/Delete/SBDelete.java b/week_4/StringBuilder/Delete/SBDelete.java new file mode 100644 index 0000000..32d824b --- /dev/null +++ b/week_4/StringBuilder/Delete/SBDelete.java @@ -0,0 +1,14 @@ +package Intermediate; + +public class SBDelete { + + public static void main(String[] args) { + StringBuilder sb = new StringBuilder("This is a deleted text"); + + // Remove "deleted" (starting at index 9, length 8) + sb.delete(9, 17); + + System.out.println(sb.toString()); // Output: This is a test + } + +} diff --git a/week_4/StringBuilder/Insert/App.java b/week_4/StringBuilder/Insert/App.java new file mode 100644 index 0000000..b6fe4e3 --- /dev/null +++ b/week_4/StringBuilder/Insert/App.java @@ -0,0 +1,14 @@ +package Intermediate; + +public class SBInsert { + + public static void main(String[] args) { + StringBuilder sb = new StringBuilder("Kamusta kabayan!"); + + sb.insert(8, "Mga Pogi at Gwapa kong "); + system.out.println(sb.toString()); + + + } + +} \ No newline at end of file diff --git a/week_4/StringBuilder/Replace/SBReplace.java b/week_4/StringBuilder/Replace/SBReplace.java new file mode 100644 index 0000000..8e959c7 --- /dev/null +++ b/week_4/StringBuilder/Replace/SBReplace.java @@ -0,0 +1,14 @@ +package Intermediate; + +public class SBReplace { + + public static void main(String[] args) { + StringBuilder sb = new StringBuilder("This is my favorite"); + + // Replace "is" with "at" (starting at index 2, length 2) + sb.replace(2, 4, "at"); + + System.out.prntln(sb.toString()); + } + +} diff --git a/week_4/StringBuilder/Reverse/SBReverse.java b/week_4/StringBuilder/Reverse/SBReverse.java new file mode 100644 index 0000000..e7275b0 --- /dev/null +++ b/week_4/StringBuilder/Reverse/SBReverse.java @@ -0,0 +1,15 @@ +package Intermediate; + +public class SBReverse { + + public static void main(String[] args) { + StringBuilder sb = new StringBuilder("Programmer Ako"); + + // Reverse the characters in the StringBuilder + sb.reverse(); + + System.out.println(sb.toString()); + + } + +} diff --git a/week_5/add_one_to_ten/App.java b/week_5/add_one_to_ten/App.java new file mode 100644 index 0000000..846bc72 --- /dev/null +++ b/week_5/add_one_to_ten/App.java @@ -0,0 +1,20 @@ +public class App { + public static void main(String[] args) { + int result = sum(10); + System.out.println(result); + } + + public static int sum(int k) { + if (k > 0) { + + System.out.print(k + " + sum(" + (k - 1) + ")"); + System.out.println(""); + + // Recursion + return k + sum(k - 1); + + } else { + return 0; + } + } +} \ No newline at end of file diff --git a/week_5/recursive_factorial/App.java b/week_5/recursive_factorial/App.java new file mode 100644 index 0000000..44fd54f --- /dev/null +++ b/week_5/recursive_factorial/App.java @@ -0,0 +1,15 @@ +public class RecursiveFactorial { + public static int factorial(int n) { + if (n == 0) { + return 1; + } else { + return n * factorial(n - 1); + } + } + + public static void main(String[] args) { + int number = 5; + int result = factorial(number); + System.out.println("The factorial of " + number + " is: " + result); + } +} \ No newline at end of file diff --git a/week_5/recursive_fibonacci/App.java b/week_5/recursive_fibonacci/App.java new file mode 100644 index 0000000..5c30e87 --- /dev/null +++ b/week_5/recursive_fibonacci/App.java @@ -0,0 +1,15 @@ +public class RecursiveFibonacci { + public static int fibonacci(int n) { + if (n <= 1) { + return n; + } else { + return fibonacci(n - 1) + fibonacci(n - 2); + } + } + + public static void main(String[] args) { + int number = 6; + int result = fibonacci(number); + System.out.println("The Fibonacci number at position " + number + " is: " + result); + } +} diff --git a/week_5/reverse_string/App.java b/week_5/reverse_string/App.java new file mode 100644 index 0000000..11127d8 --- /dev/null +++ b/week_5/reverse_string/App.java @@ -0,0 +1,18 @@ +public class App { + public static void main(String[] args) throws Exception { + + String input = "JAYARRE"; + System.out.print(reverseString(input)); + } + + static String reverseString(String inpuString) { + + // Define the base case/stopping condition + if (inpuString.equals("")) { + return ""; + } + + // Everytime the function calls itself, do something to reach the goal + return reverseString(inpuString.substring(1)) + inpuString.charAt(0); + } +} \ No newline at end of file diff --git a/week_6/aggregation/Fauna/App.java b/week_6/aggregation/Fauna/App.java new file mode 100644 index 0000000..0c43f54 --- /dev/null +++ b/week_6/aggregation/Fauna/App.java @@ -0,0 +1,27 @@ +import java.util.*; +//Country class + +class Main { + public static void main(String[] args) { + // Create two Fauna objects + + Fauna PhilippineEagle = new Fauna("Philippine Eagle"); + Fauna Tarsier = new Fauna("Tarsier"); + + // Create a country + Country Philippines = new Country("Philippines"); + + // Create a arraylist and add the fauna + List listOfFauna = new ArrayList(); + + listOfFauna.add(PhilippineEagle); + listOfFauna.add(Tarsier); + + // now add this list to Country Class + Philippines.setlistofFauna(listOfFauna); + + System.out + .println("The fauna found from the " + Philippines.getName() + " are " + Philippines.getSportPersons()); + + } +} \ No newline at end of file diff --git a/week_6/aggregation/Fauna/Country.java b/week_6/aggregation/Fauna/Country.java new file mode 100644 index 0000000..c4f1561 --- /dev/null +++ b/week_6/aggregation/Fauna/Country.java @@ -0,0 +1,29 @@ +import java.util.List; +import java.util.ArrayList; + +class Country { + private String name; + List fauna; + + public Country(String name) // to assign Country name + { + this.name = name; + } + + public void setlistofFauna(List fauna) { + this.fauna = fauna; + } + + public List getSportPersons() { + List listOfFauna = this.fauna; + List names = new ArrayList(); + for (Fauna fauna : fauna) { + names.add(fauna.getName()); + } + return names; + } + + public String getName() { + return this.name; + } +} \ No newline at end of file diff --git a/week_6/aggregation/Fauna/Fauna.java b/week_6/aggregation/Fauna/Fauna.java new file mode 100644 index 0000000..5c19993 --- /dev/null +++ b/week_6/aggregation/Fauna/Fauna.java @@ -0,0 +1,13 @@ +//Fauna class +class Fauna { + private String name; + + public Fauna(String name) // to assign Sportsperson name + { + this.name = name; + } + + public String getName() { + return this.name; + } +} \ No newline at end of file diff --git a/week_6/aggregation/University/App.java b/week_6/aggregation/University/App.java new file mode 100644 index 0000000..966a8dc --- /dev/null +++ b/week_6/aggregation/University/App.java @@ -0,0 +1,54 @@ +import java.util.ArrayList; +import java.util.List; + +class University { + private String name; + private List students; + + public University(String name) { + this.name = name; + this.students = new ArrayList<>(); + } + + public void addStudent(Student student) { + students.add(student); + } + + public List getStudentNames() { + List names = new ArrayList<>(); + for (Student student : students) { + names.add(student.getName()); + } + return names; + } + + public String getName() { + return name; + } +} + +class Student { + private String name; + + public Student(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} + +public class Main { + public static void main(String[] args) { + University university = new University("National University"); + + Student student1 = new Student("Jay"); + Student student2 = new Student("Jasmainelyn"); + + university.addStudent(student1); + university.addStudent(student2); + + System.out.println("Students in " + university.getName() + ": " + university.getStudentNames()); + } +} diff --git a/week_6/association/App.java b/week_6/association/App.java new file mode 100644 index 0000000..674d757 --- /dev/null +++ b/week_6/association/App.java @@ -0,0 +1,27 @@ +import java.util.List; +import java.util.ArrayList; + +public class App { + public static void main(String[] args) { + + // Create two professor objects + Professor EP = new Professor("Elizer Ponio Jr"); + Professor JA = new Professor("Jay Abaleta"); + + // Create a department object + Department CCIT = new Department("CCIT"); + + // Add the professors to a list and add this list to department + List CCIT_STAFF = new ArrayList(); + CCIT_STAFF.add(EP); + CCIT_STAFF.add(JA); + + // Add staff to cse department + CCIT.setStaff(CCIT_STAFF); + + // Output + + System.out.println("The staff of department " + CCIT.getName() + " is: " + CCIT.getStaff()); + + } +} \ No newline at end of file diff --git a/week_6/association/Department.java b/week_6/association/Department.java new file mode 100644 index 0000000..80dca26 --- /dev/null +++ b/week_6/association/Department.java @@ -0,0 +1,34 @@ +import java.util.List; +import java.util.ArrayList; + +//Department Class +class Department { + private String name; + List staff; + + // Constructor + // Assign department name + Department(String name) { + this.name = name; + } + + // Method to retrieve department name + public String getName() { + return this.name; + } + + // Method to assign list of department staff + public void setStaff(List staff) { + this.staff = staff; + } + + // Method to return the list of staff names + public List getStaff() { + + List professor_names = new ArrayList(); + for (Professor prof : this.staff) { + professor_names.add(prof.getName()); // add name of each professor to names list + } + return professor_names; // return names list + } +} \ No newline at end of file diff --git a/week_6/association/Professor.java b/week_6/association/Professor.java new file mode 100644 index 0000000..e85dfa4 --- /dev/null +++ b/week_6/association/Professor.java @@ -0,0 +1,16 @@ +//Professor Class +class Professor { + private String name; + + // Constructor + // Assign professor name + Professor(String name) { + this.name = name; + } + + // Method to retrieve name of professor + public String getName() { + return this.name; + } + +} \ No newline at end of file diff --git a/week_6/methods/App.java b/week_6/methods/App.java new file mode 100644 index 0000000..086673c --- /dev/null +++ b/week_6/methods/App.java @@ -0,0 +1,68 @@ +public class App { + public static void main(String[] args) throws Exception { + + App myApp = new App(); + + // Non-static method call + myApp.showHelloJava(); + + // Static method call + showHelloWorld(); + + // Non-static method call with parameter + myApp.showName("Jay"); + + // Static method call with parameter + showAge(20); + + // Static method call with two parameters + showNameAndAge("Jay", 20); + + // Non-static method call with two parameters that returns an int + int sum = myApp.add(1, 1); + System.out.println(sum); + + // Static method call with two parameters that returns an int + int difference = subtract(1, 1); + System.out.println(difference); + + } + + // Non-static method + void showHelloJava() { + System.out.println("Hello Java! This is a non-static method."); + } + + // Static method + static void showHelloWorld() { + System.out.println("Hello World! This is a static method."); + } + + // Non-static method with a parameter + void showName(String name) { + System.out.println("My name is " + name); + } + + // Static method with a parameter + static void showAge(int age) { + System.out.println("My age is " + age); + } + + // Static method with two parameters + static void showNameAndAge(String name, int age) { + System.out.println("Hello: " + name); + System.out.println("You are : " + age + " years old!"); + } + + // Non-static method with two parameters with a return type + int add(int x, int y) { + int z = x + y; + return z; + } + + // Static method with two parameters with a return type + static int subtract(int x, int y) { + int z = x - y; + return z; + } +} \ No newline at end of file diff --git a/week_6/regex_prof_jay_example/character_class/App.java b/week_6/regex_prof_jay_example/character_class/App.java new file mode 100644 index 0000000..c7033d4 --- /dev/null +++ b/week_6/regex_prof_jay_example/character_class/App.java @@ -0,0 +1,20 @@ +package Intermediate; +import java.util.regex.*; + +public class RegExCharClass { + + public static void main(String[] args) + { + + System.out.println(Pattern.matches("[abc]", "a"));//false (not a or b or c) + System.out.println(Pattern.matches("[abc]", "abc"));//false (among a or b or c) + System.out.println(Pattern.matches("[abc]", "abbbbc"));//false (a and a comes more than once) + + + System.out.println(Pattern.matches("[abc]?", "b"));//false (a comes more than one time) + System.out.println(Pattern.matches("[abcx]+", "abcabacaaxaa"));//true (a or b or c once or more times) + System.out.println(Pattern.matches("[abc]+", "aaabbbbbb"));//true (a comes more than one time) + + } + +} \ No newline at end of file diff --git a/week_6/regex_prof_jay_example/combination_regex/App.java b/week_6/regex_prof_jay_example/combination_regex/App.java new file mode 100644 index 0000000..32ddd22 --- /dev/null +++ b/week_6/regex_prof_jay_example/combination_regex/App.java @@ -0,0 +1,30 @@ +package JRegEx; +import java.util.Scanner; +import java.util.regex.*; +public class RegStudID { + public static void main(String[] args) + { + try + { + Scanner sc = new Scanner(System.in); + System.out.println("Please Enter your Student ID Number:"); + String StudNum = sc.nextLine(); + Pattern pat = Pattern.compile("^22-[0-9]{4}"); + Matcher mat = pat.matcher(StudNum); + if(mat.matches()==true) + { + System.out.println("Student Number is Accepted"); + } + else + { + System.out.println("Invalid student number"); + } + } + catch(Exception e) + { + System.out.println(e.getMessage()); + } + + } + +} \ No newline at end of file diff --git a/week_6/regex_prof_jay_example/regex_pattern/App.java b/week_6/regex_prof_jay_example/regex_pattern/App.java new file mode 100644 index 0000000..017fee2 --- /dev/null +++ b/week_6/regex_prof_jay_example/regex_pattern/App.java @@ -0,0 +1,21 @@ +package JRegEx; + +public class RegPattern { + + public static void main(String[] args) + { + String num1 = "^[0-9]+$"; + String num2 = "^2023+$"; + String word ="^a...e$"; + String word2 = "^J.r..n"; + + System.out.println("112434" .matches(num1)); + System.out.println("apples" .matches(word)); + System.out.println("2024" .matches(num2)); + System.out.println("Jarnan" .matches(word2)); + + + } + +} + \ No newline at end of file diff --git a/week_6/regex_prof_jay_example/string_pattern/App.java b/week_6/regex_prof_jay_example/string_pattern/App.java new file mode 100644 index 0000000..bd8bf85 --- /dev/null +++ b/week_6/regex_prof_jay_example/string_pattern/App.java @@ -0,0 +1,19 @@ +package Intermediate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +public class RegExMatcherText { + + public static void main(String[] args) + { + Pattern pat = Pattern.compile("NatioNAL UniverSity", Pattern.CASE_INSENSITIVE); + Matcher mat = pat.matcher("NationaL university"); + + boolean matchFound = mat.find(); + if(matchFound) { + System.out.println("Match found in the pattern"); + } else { + System.out.println("Match not found in the pattern"); + } + } + +} diff --git a/week_7/classes_and_objects/class_with_constructor/App.java b/week_7/classes_and_objects/class_with_constructor/App.java new file mode 100644 index 0000000..4e3b9d4 --- /dev/null +++ b/week_7/classes_and_objects/class_with_constructor/App.java @@ -0,0 +1,19 @@ +public class App { + public static void main(String[] args) { + + // Creates a new object named "Knight" from Character class + Character knight = new Character(10, 5, 0, "Chen"); + // Calls the sayMyName method + knight.sayMyName(); + + // Creates a new object named "mage" from Character class + Character mage = new Character(0, 5, 10, "Akasha"); + // Calls the sayMyName method + mage.sayMyName(); + + // Creates a new object named "mage" from Character class + Character thief = new Character(5, 10, 0, "Gondar"); + // Calls the sayMyName method + thief.sayMyName(); + } +} \ No newline at end of file diff --git a/week_7/classes_and_objects/class_with_constructor/Character.java b/week_7/classes_and_objects/class_with_constructor/Character.java new file mode 100644 index 0000000..138d011 --- /dev/null +++ b/week_7/classes_and_objects/class_with_constructor/Character.java @@ -0,0 +1,20 @@ +public class Character { + // Attributes + int strength; + int agility; + int intelligence; + String name; + + // Method + public void sayMyName() { + System.out.println("Hello I am " + name); + } + + // Constructor + public Character(int str, int agi, int intel, String characterName) { + strength = str; + agility = agi; + intelligence = intel; + name = characterName; + } +} \ No newline at end of file diff --git a/week_7/classes_and_objects/standard_class/App.java b/week_7/classes_and_objects/standard_class/App.java new file mode 100644 index 0000000..12eccde --- /dev/null +++ b/week_7/classes_and_objects/standard_class/App.java @@ -0,0 +1,28 @@ +public class App { + public static void main(String[] args) { + + Character knight = new Character(); + + knight.strength = 10; + knight.agility = 5; + knight.intelligence = 0; + knight.name = "Chen"; + knight.sayMyName(); + + Character mage = new Character(); + + mage.strength = 0; + mage.agility = 5; + mage.intelligence = 10; + mage.name = "Akasha"; + mage.sayMyName(); + + Character thief = new Character(); + + thief.strength = 5; + thief.agility = 10; + thief.intelligence = 0; + mage.name = "Gondar"; + thief.sayMyName(); + } +} \ No newline at end of file diff --git a/week_7/classes_and_objects/standard_class/Character.java b/week_7/classes_and_objects/standard_class/Character.java new file mode 100644 index 0000000..9f14317 --- /dev/null +++ b/week_7/classes_and_objects/standard_class/Character.java @@ -0,0 +1,14 @@ +public class Character { + int strength; + int agility; + int intelligence; + String name; + + public void sayMyName() { + System.out.println("Hello I am " + name); + } + + public void sayMyStrength() { + System.out.println("My strength is " + strength); + } +} \ No newline at end of file diff --git a/week_7/objectclasses_prof_jay_example/ObjectClasses/Courses.java b/week_7/objectclasses_prof_jay_example/ObjectClasses/Courses.java new file mode 100644 index 0000000..5967af7 --- /dev/null +++ b/week_7/objectclasses_prof_jay_example/ObjectClasses/Courses.java @@ -0,0 +1,8 @@ +package ObjectClasses; + +public class Courses +{ + int courseCode; + String CourseName; +} + \ No newline at end of file diff --git a/week_7/objectclasses_prof_jay_example/ObjectClasses/Degree.java b/week_7/objectclasses_prof_jay_example/ObjectClasses/Degree.java new file mode 100644 index 0000000..a7bc69c --- /dev/null +++ b/week_7/objectclasses_prof_jay_example/ObjectClasses/Degree.java @@ -0,0 +1,6 @@ +package ObjectClasses; + +public class Degree +{ + String Deg; +} \ No newline at end of file diff --git a/week_7/objectclasses_prof_jay_example/ObjectClasses/MainStudentRecord.java b/week_7/objectclasses_prof_jay_example/ObjectClasses/MainStudentRecord.java new file mode 100644 index 0000000..c0f1e1d --- /dev/null +++ b/week_7/objectclasses_prof_jay_example/ObjectClasses/MainStudentRecord.java @@ -0,0 +1,48 @@ +package ObjectClasses; + +public class MainStudentRecord { + + public static void main(String[] args) { + Student StudAObj = new Student(); + Student StudBObj = new Student(); + Degree D = new Degree(); + Degree D1 = new Degree(); + Courses C = new Courses(); + + + + StudAObj.StudentID = 202401; + D.Deg = "BSCS"; + C.courseCode = 202; + C.CourseName = "Intermediate Programming"; + StudAObj.FirstName = "Roland"; + StudAObj.MiddleName = "Tom"; + StudAObj.LastName = "Reyes"; + StudAObj.Age = 34; + + System.out.println(StudAObj.StudentID); + System.out.println(D.Deg); + System.out.println(C.courseCode); + System.out.println(C.CourseName); + System.out.println(StudAObj.FirstName); + System.out.println(StudAObj.MiddleName); + System.out.println(StudAObj.LastName); + System.out.println(StudAObj.Age); + + System.out.println("============="); + StudBObj.StudentID = 202402; + D1.Deg = "BSIT"; + StudBObj.FirstName = "Michael"; + StudBObj.MiddleName = "Santos"; + StudBObj.LastName = "Lopez"; + StudBObj.Age = 18; + System.out.println(StudBObj.StudentID); + System.out.println(D1.Deg); + System.out.println(StudBObj.FirstName); + System.out.println(StudBObj.MiddleName); + System.out.println(StudBObj.LastName); + System.out.println(StudBObj.Age); + + } + +} \ No newline at end of file diff --git a/week_7/objectclasses_prof_jay_example/ObjectClasses/Student.java b/week_7/objectclasses_prof_jay_example/ObjectClasses/Student.java new file mode 100644 index 0000000..36e7e92 --- /dev/null +++ b/week_7/objectclasses_prof_jay_example/ObjectClasses/Student.java @@ -0,0 +1,10 @@ +package ObjectClasses; + +public class Student +{ + int StudentID; + String FirstName; + String MiddleName; + String LastName; + int Age; +} \ No newline at end of file diff --git a/week_8/Abstraction/abstract_class/App.java b/week_8/Abstraction/abstract_class/App.java new file mode 100644 index 0000000..61badc7 --- /dev/null +++ b/week_8/Abstraction/abstract_class/App.java @@ -0,0 +1,10 @@ +public class App { + public static void main(String[] args) throws Exception { + + // Only objects from subclasses can be created. Creating objects from + // superclasses are not permitted. + Dog dalmatian = new Dog(); + + dalmatian.eat(); + } +} \ No newline at end of file diff --git a/week_8/Abstraction/abstract_class/Dog.java b/week_8/Abstraction/abstract_class/Dog.java new file mode 100644 index 0000000..5f43d4d --- /dev/null +++ b/week_8/Abstraction/abstract_class/Dog.java @@ -0,0 +1,8 @@ +public class Dog extends Pet { + + // Abstract method eat() is mandatory for all subclasses + public void eat() { + System.out.print("The dog is eating!"); + } + +} \ No newline at end of file diff --git a/week_8/Abstraction/abstract_class/Pet.java b/week_8/Abstraction/abstract_class/Pet.java new file mode 100644 index 0000000..151ec34 --- /dev/null +++ b/week_8/Abstraction/abstract_class/Pet.java @@ -0,0 +1,10 @@ +abstract class Pet { + + // abstract method + public abstract void eat(); + + // An abstract class can contain regular method + public void sleep() { + System.out.print("Zzzzzzzzzz"); + } +} \ No newline at end of file diff --git a/week_8/Abstraction/interface/App.java b/week_8/Abstraction/interface/App.java new file mode 100644 index 0000000..fc606b6 --- /dev/null +++ b/week_8/Abstraction/interface/App.java @@ -0,0 +1,10 @@ +public class App { + public static void main(String[] args) throws Exception { + + Cat myCat = new Cat(); + + myCat.eat(); + + myCat.sleep(); + } +} \ No newline at end of file diff --git a/week_8/Abstraction/interface/Cat.java b/week_8/Abstraction/interface/Cat.java new file mode 100644 index 0000000..a8bcec6 --- /dev/null +++ b/week_8/Abstraction/interface/Cat.java @@ -0,0 +1,12 @@ +public class Cat implements Pet { + + // The eat and sleep methods are mandatory in the Cat class + public void eat() { + + System.out.println("My cat is eating fish"); + } + + public void sleep() { + System.out.println("My cat is sleeping gently"); + } +} \ No newline at end of file diff --git a/week_8/Abstraction/interface/Pet.java b/week_8/Abstraction/interface/Pet.java new file mode 100644 index 0000000..afb8f17 --- /dev/null +++ b/week_8/Abstraction/interface/Pet.java @@ -0,0 +1,6 @@ +interface Pet { + + public void eat(); + + public void sleep(); +} \ No newline at end of file diff --git a/week_8/Encapsulation/App.java b/week_8/Encapsulation/App.java new file mode 100644 index 0000000..5849d53 --- /dev/null +++ b/week_8/Encapsulation/App.java @@ -0,0 +1,15 @@ +public class App { + public static void main(String[] args) throws Exception { + + Person Me = new Person(); + + // The name property cannot be accessed outside of the Person class. + // Me.name; + + Me.setName("Jay Arre"); + + String myName = Me.getName(); + + System.out.println("My name is " + myName); + } +} \ No newline at end of file diff --git a/week_8/Encapsulation/Person.java b/week_8/Encapsulation/Person.java new file mode 100644 index 0000000..9b71ed8 --- /dev/null +++ b/week_8/Encapsulation/Person.java @@ -0,0 +1,19 @@ +public class Person { + + // Private variable + // Private variables are only accessible within the class where they are + // declared. They are not accessible outside of this class. + private String name; + + // get() method + public String getName() { + + return this.name; + } + + // set() method + public void setName(String newName) { + + this.name = newName; + } +} \ No newline at end of file diff --git a/week_8/Explanation.txt b/week_8/Explanation.txt new file mode 100644 index 0000000..4fd834d --- /dev/null +++ b/week_8/Explanation.txt @@ -0,0 +1,19 @@ +Java Polymorphism - Explained with Examples +Unlock the versatility of Java polymorphism with practical examples. Master dynamic code behavior, enhancing your object-oriented programming skills seamlessly. + +Java Polymorphism +Polymorphism means "many forms", and it occurs when we have many classes that are related to each other by inheritance. + +Polymorphism uses those methods to perform different tasks. This allows us to perform a single action in different ways. + +For example, think of a superclass called Animal that has a method called animalSound(). Subclasses of Animals could be Pigs, Cats, Dogs, Birds - And they also have their own implementation of an animal sound (the pig oinks, and the cat meows, etc.): + +## See the code in Polymorphism_1 + +Now we can create Pig and Dog objects and call the animalSound() method on both of them: + +## See the code in Polymorphism_2 + +Why And When To Use "Inheritance" and "Polymorphism"? + +- It is useful for code reusability: reuse attributes and methods of an existing class when you create a new class. \ No newline at end of file diff --git a/week_8/Inheritance/App.java b/week_8/Inheritance/App.java new file mode 100644 index 0000000..b3a9894 --- /dev/null +++ b/week_8/Inheritance/App.java @@ -0,0 +1,23 @@ +public class App { + public static void main(String[] args) throws Exception { + + // Son object + Son me = new Son(); + me.name = "Jay"; + + // The Son class inherited the surname variable and the getSurname() method + String surname = me.getSurname(); + + System.out.println("My name is " + me.name + " and my surname is " + surname); + + // Daughter object + Daughter mySister = new Daughter(); + mySister.name = "Dianne"; + + // The Daughter class also inherited the surname variable and the getSurname() + // method + surname = mySister.getSurname(); + + System.out.println("My sister's name is " + mySister.name + " and her surname is also " + surname); + } +} \ No newline at end of file diff --git a/week_8/Inheritance/Daughter.java b/week_8/Inheritance/Daughter.java new file mode 100644 index 0000000..556f968 --- /dev/null +++ b/week_8/Inheritance/Daughter.java @@ -0,0 +1,5 @@ +public class Daughter extends Mommy { + + // Properties + String name; +} \ No newline at end of file diff --git a/week_8/Inheritance/Mommy.java b/week_8/Inheritance/Mommy.java new file mode 100644 index 0000000..ca01d8f --- /dev/null +++ b/week_8/Inheritance/Mommy.java @@ -0,0 +1,12 @@ +public class Mommy { + + // Properties + protected String surname = "Ponio"; + + // Methods + public String getSurname() { + + return this.surname; + } + +} \ No newline at end of file diff --git a/week_8/Inheritance/Son.java b/week_8/Inheritance/Son.java new file mode 100644 index 0000000..5eaed4e --- /dev/null +++ b/week_8/Inheritance/Son.java @@ -0,0 +1,5 @@ +public class Son extends Mommy { + + // Properties + String name; +} \ No newline at end of file diff --git a/week_8/Polymorphism/Grocery/App.java b/week_8/Polymorphism/Grocery/App.java new file mode 100644 index 0000000..337147e --- /dev/null +++ b/week_8/Polymorphism/Grocery/App.java @@ -0,0 +1,33 @@ +public class App { + public static void main(String[] args) throws Exception { + + // Polymorphic variable/object + GroceryItem item1 = new Junkfood(); + item1.name = "V-cut"; + + // Polymorphic variable/object + GroceryItem item2 = new Shampoo(); + item2.name = "Pantene"; + + // Polymorphic array + GroceryItem[] itemArray = new GroceryItem[2]; + itemArray[0] = item1; + itemArray[1] = item2; + + // Instead of calling the showItemName for each grocery item, we can loop + // through the polymorphic array + for (int i = 0; i < 2; i++) { + itemArray[i].showItemName(); + } + + // Cashier Object + Cashier c1 = new Cashier(); + + // Polymorphic Argument + c1.checkOut(item1); + + // Polymorphic Argument + c1.checkOut(item2); + + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Grocery/Cashier.java b/week_8/Polymorphism/Grocery/Cashier.java new file mode 100644 index 0000000..473265e --- /dev/null +++ b/week_8/Polymorphism/Grocery/Cashier.java @@ -0,0 +1,7 @@ +public class Cashier { + + public void checkOut(GroceryItem item) { + System.out.println("You have purchased " + item.name); + + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Grocery/GroceryItem.java b/week_8/Polymorphism/Grocery/GroceryItem.java new file mode 100644 index 0000000..eb2a5c1 --- /dev/null +++ b/week_8/Polymorphism/Grocery/GroceryItem.java @@ -0,0 +1,11 @@ +public class GroceryItem { + + String name; + + // Methods + public void showItemName() { + + System.out.println("This is a " + this.name); + } + +} \ No newline at end of file diff --git a/week_8/Polymorphism/Grocery/Junkfood.java b/week_8/Polymorphism/Grocery/Junkfood.java new file mode 100644 index 0000000..0af6daa --- /dev/null +++ b/week_8/Polymorphism/Grocery/Junkfood.java @@ -0,0 +1,8 @@ +public class Junkfood extends GroceryItem { + + // Method Override + public void showItemName() { + + System.out.println("The name of this junkfood is " + this.name); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Grocery/Shampoo.java b/week_8/Polymorphism/Grocery/Shampoo.java new file mode 100644 index 0000000..cacd0cc --- /dev/null +++ b/week_8/Polymorphism/Grocery/Shampoo.java @@ -0,0 +1,8 @@ +public class Shampoo extends GroceryItem { + + // Method Override + public void showItemName() { + + System.out.println("The name of this shampoo is " + this.name); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/App.java b/week_8/Polymorphism/Person/App.java new file mode 100644 index 0000000..1b0d16e --- /dev/null +++ b/week_8/Polymorphism/Person/App.java @@ -0,0 +1,26 @@ +public class App { + public static void main(String[] args) throws Exception { + + // Polymorphism + + Person me = new Person(); + me.name = "Elizer"; + me.aboutMe(); + + // Me in a form of a teacher + me = new Teacher(); + me.aboutMe(); + + // Me in a form of a student + me = new Student(); + me.aboutMe(); + + // Me in a form of a diver + me = new Diver(); + me.aboutMe(); + + // Me in a form of a gardener + me = new Gardener(); + me.aboutMe(); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/Diver.java b/week_8/Polymorphism/Person/Diver.java new file mode 100644 index 0000000..53655ca --- /dev/null +++ b/week_8/Polymorphism/Person/Diver.java @@ -0,0 +1,7 @@ +public class Diver extends Person { + + // Override method + public void aboutMe() { + System.out.println(name + " loves freediving"); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/Gardener.java b/week_8/Polymorphism/Person/Gardener.java new file mode 100644 index 0000000..04ada2c --- /dev/null +++ b/week_8/Polymorphism/Person/Gardener.java @@ -0,0 +1,8 @@ +public class Gardener extends Person { + + // Override method + public void aboutMe() { + System.out.println(name + " loves gardening"); + } + +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/Person.java b/week_8/Polymorphism/Person/Person.java new file mode 100644 index 0000000..5fbc0be --- /dev/null +++ b/week_8/Polymorphism/Person/Person.java @@ -0,0 +1,8 @@ +public class Person { + + static protected String name; + + public void aboutMe() { + System.out.println("My name is " + name); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/Student.java b/week_8/Polymorphism/Person/Student.java new file mode 100644 index 0000000..62f93bd --- /dev/null +++ b/week_8/Polymorphism/Person/Student.java @@ -0,0 +1,8 @@ +public class Student extends Person { + + // Override method + public void aboutMe() { + System.out.println(name + " is a student studying computer science"); + } + +} \ No newline at end of file diff --git a/week_8/Polymorphism/Person/Teacher.java b/week_8/Polymorphism/Person/Teacher.java new file mode 100644 index 0000000..c4867e7 --- /dev/null +++ b/week_8/Polymorphism/Person/Teacher.java @@ -0,0 +1,8 @@ +public class Teacher extends Person { + + // Override method + public void aboutMe() { + System.out.println(name + " is a teacher by profession"); + } + +} \ No newline at end of file diff --git a/week_8/Polymorphism_example/Polymorphism_1/App.java b/week_8/Polymorphism_example/Polymorphism_1/App.java new file mode 100644 index 0000000..5b5a88f --- /dev/null +++ b/week_8/Polymorphism_example/Polymorphism_1/App.java @@ -0,0 +1,17 @@ +class Animal { + public void animalSound() { + System.out.println("The animal makes a sound"); + } +} + +class Pig extends Animal { + public void animalSound() { + System.out.println("The pig says: wee wee"); + } +} + +class Dog extends Animal { + public void animalSound() { + System.out.println("The dog says: bow wow"); + } +} \ No newline at end of file diff --git a/week_8/Polymorphism_example/Polymorphism_2/App.java b/week_8/Polymorphism_example/Polymorphism_2/App.java new file mode 100644 index 0000000..6001193 --- /dev/null +++ b/week_8/Polymorphism_example/Polymorphism_2/App.java @@ -0,0 +1,28 @@ +class Animal { + public void animalSound() { + System.out.println("The animal makes a sound"); + } + } + + class Pig extends Animal { + public void animalSound() { + System.out.println("The pig says: wee wee"); + } + } + + class Dog extends Animal { + public void animalSound() { + System.out.println("The dog says: bow wow"); + } + } + + class Main { + public static void main(String[] args) { + Animal myAnimal = new Animal(); // Create a Animal object + Animal myPig = new Pig(); // Create a Pig object + Animal myDog = new Dog(); // Create a Dog object + myAnimal.animalSound(); + myPig.animalSound(); + myDog.animalSound(); + } + } \ No newline at end of file diff --git a/week_9/JButton/sample1/App.java b/week_9/JButton/sample1/App.java new file mode 100644 index 0000000..ce900cc --- /dev/null +++ b/week_9/JButton/sample1/App.java @@ -0,0 +1,15 @@ +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(400, 400); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JButton/sample1/Frame.java b/week_9/JButton/sample1/Frame.java new file mode 100644 index 0000000..ecb3d50 --- /dev/null +++ b/week_9/JButton/sample1/Frame.java @@ -0,0 +1,41 @@ +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JTextField; +import java.awt.FlowLayout; +import javax.swing.JOptionPane; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class Frame extends JFrame { + + Frame() { + + // Set the title of the window/frame + super("My title"); + + setLayout(new FlowLayout()); + + // JButton Component + JButton button = new JButton("Click Here"); + + // Set component size + button.setBounds(50, 100, 95, 30); + + // Add JButton Component to frame/window + add(button); + + // Add event + EventHandler handler = new EventHandler(); + button.addActionListener(handler); + } + + // Event Handler Class + private class EventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + JOptionPane.showMessageDialog(null, "Hello"); + } + } +} \ No newline at end of file diff --git a/week_9/JButton/sample2/App.java b/week_9/JButton/sample2/App.java new file mode 100644 index 0000000..269f36b --- /dev/null +++ b/week_9/JButton/sample2/App.java @@ -0,0 +1,15 @@ +public class App { + public static void main(String[] args) throws Exception { + + MyFrame frame = new MyFrame(); + + frame.setLayout(null); + // Makes frame visible + frame.setVisible(true); + // Sets frame size + frame.setSize(500, 500); + // Exit out of application + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + + } +} \ No newline at end of file diff --git a/week_9/JButton/sample2/Frame.java b/week_9/JButton/sample2/Frame.java new file mode 100644 index 0000000..59da272 --- /dev/null +++ b/week_9/JButton/sample2/Frame.java @@ -0,0 +1,68 @@ +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; + +import java.awt.event.ActionListener; +import java.awt.Color; +import java.awt.Font; +import java.awt.event.ActionEvent; + +public class MyFrame extends JFrame { + + JButton button; + JLabel label; + + MyFrame() { + + ImageIcon icon = new ImageIcon("pointing.png"); + ImageIcon icon2 = new ImageIcon("smile.png"); + + label = new JLabel(); + label.setIcon(icon2); + label.setBounds(150, 250, 150, 150); + label.setVisible(false); + + button = new JButton("Click me"); + button.setBounds(100, 100, 250, 100); + button.setIcon(icon); + button.setHorizontalTextPosition(JButton.CENTER); + button.setVerticalTextPosition(JButton.BOTTOM); + button.setFont(new Font("Comic Sans", Font.BOLD, 25)); + button.setIconTextGap(-5); + button.setForeground(Color.CYAN); + button.setBackground(Color.LIGHT_GRAY); + button.setBorder(BorderFactory.createEtchedBorder()); + // Disables a button + // button.setEnabled(false); + + // How to add button event + // 1. Create an EventHandler Object + EventHandler eventhandler = new EventHandler(); + // 2. Add a ActionListener + button.addActionListener(eventhandler); + + // OR + + // Use a lambda expression + // With lambda expressions, you do not need to create a EventHandler class + // button.addActionListener(e -> JOptionPane.showMessageDialog(null, "HELLOO")); + + button.setFocusable(false); + this.add(button); + this.add(label); + + }; + + // Event Handler Class + private class EventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + // Causes button to be clicked only once + button.setEnabled(false); + label.setVisible(true); + } + } +} \ No newline at end of file diff --git a/week_9/JButton/sample2/pointing.png b/week_9/JButton/sample2/pointing.png new file mode 100644 index 0000000..93f0cab Binary files /dev/null and b/week_9/JButton/sample2/pointing.png differ diff --git a/week_9/JButton/sample2/smile.png b/week_9/JButton/sample2/smile.png new file mode 100644 index 0000000..4668ab5 Binary files /dev/null and b/week_9/JButton/sample2/smile.png differ diff --git a/week_9/JCheckBox/App.java b/week_9/JCheckBox/App.java new file mode 100644 index 0000000..9e4db2c --- /dev/null +++ b/week_9/JCheckBox/App.java @@ -0,0 +1,16 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the frame/window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JCheckBox/Frame.java b/week_9/JCheckBox/Frame.java new file mode 100644 index 0000000..a7a2d1c --- /dev/null +++ b/week_9/JCheckBox/Frame.java @@ -0,0 +1,62 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class Frame extends JFrame { + + private JTextField textField; + private JCheckBox checkBox1; + private JCheckBox checkBox2; + + public Frame() { + // Set the title of the window/frame + super("The title"); + setLayout(new FlowLayout()); + + // JTextField Component + textField = new JTextField("This is a sentence", 20); + textField.setFont(new Font("Serif", Font.PLAIN, 14)); + + // Add JTextField Component to frame/window + add(textField); + + // JCheckBox Component + checkBox1 = new JCheckBox("bold"); + + // JCheckBox Component + checkBox2 = new JCheckBox("italic"); + + // Add JCheckBox Component to frame/window + add(checkBox1); + + // Add JCheckBox Component to frame/window + add(checkBox2); + + // Add event + EventHandler handler = new EventHandler(); + checkBox1.addItemListener(handler); + checkBox2.addItemListener(handler); + + } + + // Event Handler Class + private class EventHandler implements ItemListener { + + public void itemStateChanged(ItemEvent event) { + Font font = null; + + if (checkBox1.isSelected() && checkBox2.isSelected()) { + font = new Font("Serif", Font.BOLD + Font.ITALIC, 14); + } else if (checkBox1.isSelected()) { + font = new Font("Serif", Font.BOLD, 14); + } else if (checkBox2.isSelected()) { + font = new Font("Serif", Font.ITALIC, 14); + } else { + font = new Font("Serif", Font.PLAIN, 14); + } + + textField.setFont(font); + } + } + +} \ No newline at end of file diff --git a/week_9/JComboBox/App.java b/week_9/JComboBox/App.java new file mode 100644 index 0000000..28d5a6f --- /dev/null +++ b/week_9/JComboBox/App.java @@ -0,0 +1,17 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JComboBox/Frame.java b/week_9/JComboBox/Frame.java new file mode 100644 index 0000000..6d0c0c9 --- /dev/null +++ b/week_9/JComboBox/Frame.java @@ -0,0 +1,49 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class Frame extends JFrame { + + private JComboBox box; + private JLabel picture; + + // Declare filename array + private static String[] filename = { "icon1.png", "icon2.png" }; + + // Declare icon array + private Icon[] pics = { + new ImageIcon(getClass().getResource(filename[0])), + new ImageIcon(getClass().getResource(filename[1])) }; + + public Frame() { + // Set the title of the window/frame + super("The title"); + setLayout(new FlowLayout()); + + // JComboBox Component + box = new JComboBox(filename); + + // Add event + EventHandler handler = new EventHandler(); + box.addItemListener(handler); + + // Add JComboBox Component + add(box); + + // JLabel Component + picture = new JLabel(pics[0]); + + // Add JLabel Component + add(picture); + } + + // Event Handler Class + private class EventHandler implements ItemListener { + + public void itemStateChanged(ItemEvent event) { + if (event.getStateChange() == ItemEvent.SELECTED) { + picture.setIcon(pics[box.getSelectedIndex()]); + } + } + } +} \ No newline at end of file diff --git a/week_9/JComboBox/icon1.png b/week_9/JComboBox/icon1.png new file mode 100644 index 0000000..93d9d0e Binary files /dev/null and b/week_9/JComboBox/icon1.png differ diff --git a/week_9/JComboBox/icon2.png b/week_9/JComboBox/icon2.png new file mode 100644 index 0000000..dbc4061 Binary files /dev/null and b/week_9/JComboBox/icon2.png differ diff --git a/week_9/JFrame/App.java b/week_9/JFrame/App.java new file mode 100644 index 0000000..3e6c65e --- /dev/null +++ b/week_9/JFrame/App.java @@ -0,0 +1,10 @@ +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import java.awt.Color; + +public class App { + public static void main(String[] args) throws Exception { + + new MyFrame(); + } +} \ No newline at end of file diff --git a/week_9/JFrame/MyFrame.java b/week_9/JFrame/MyFrame.java new file mode 100644 index 0000000..d846cb6 --- /dev/null +++ b/week_9/JFrame/MyFrame.java @@ -0,0 +1,38 @@ +import javax.swing.JFrame; +import javax.swing.ImageIcon; +import java.awt.Color; + +public class MyFrame extends JFrame { + + MyFrame() { + // Makes frame visible + this.setVisible(true); + + // Sets frame size + this.setSize(420, 420); + + // Sets title of frame + this.setTitle("JFrame title"); + + // Exit out of application + this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); + + // Prevent frame from being resized + this.setResizable(false); + + // This will create an image icon + ImageIcon image = new ImageIcon("tiktok.png"); + + // Change icon of frame + this.setIconImage(image.getImage()); + + // Set background color + // frame.getContentPane().setBackground(Color.green); + + // Set background color using RGB + this.getContentPane().setBackground(new Color(123, 50, 250)); + + // Set background color using Hexadecimal + this.getContentPane().setBackground(new Color(0x123456)); + }; +} \ No newline at end of file diff --git a/week_9/JFrame/tiktok.png b/week_9/JFrame/tiktok.png new file mode 100644 index 0000000..7fe96be Binary files /dev/null and b/week_9/JFrame/tiktok.png differ diff --git a/week_9/JLabel/App,java b/week_9/JLabel/App,java new file mode 100644 index 0000000..b398c0d --- /dev/null +++ b/week_9/JLabel/App,java @@ -0,0 +1,33 @@ +import javax.swing.ImageIcon; + +public class App { + public static void main(String[] args) throws Exception { + + MyFrame frame = new MyFrame(); + + // frame.setLayout(null); + // Makes frame visible + frame.setVisible(true); + // Sets frame size + // frame.setSize(500, 500); + // Sets title of frame + frame.setTitle("JFrame title"); + // Exit out of application + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + // Prevent frame from being resized + frame.setResizable(true); + // This will create an image icon + ImageIcon image = new ImageIcon("tiktok.png"); + // Change icon of frame + frame.setIconImage(image.getImage()); + + // Set background color + // frame.getContentPane().setBackground(Color.green); + // Set background color using RGB + // frame.getContentPane().setBackground(new Color(123, 50, 250)); + // Set background color using Hexadecimal + // frame.getContentPane().setBackground(new Color(0x123456)); + + frame.pack(); + } +} \ No newline at end of file diff --git a/week_9/JLabel/Frame.java b/week_9/JLabel/Frame.java new file mode 100644 index 0000000..37830f2 --- /dev/null +++ b/week_9/JLabel/Frame.java @@ -0,0 +1,47 @@ +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.border.Border; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import java.awt.Color; +import java.awt.Font; + +public class MyFrame extends JFrame { + + MyFrame() { + + ImageIcon image = new ImageIcon("smile.png"); + + Border border = BorderFactory.createLineBorder(Color.green, 3); + + JLabel label = new JLabel(); + // Set text of label + label.setText("Do you even code?"); + this.add(label); + label.setIcon(image); + // Set text LEFT, CENTER, RIGHT of imageicon + label.setHorizontalTextPosition(JLabel.CENTER); + // Set text TOP,CENTER, BOTTOM of image + label.setVerticalTextPosition(JLabel.TOP); + // Set font color of text + label.setForeground(new Color(0x00FF00)); + // Set font of text + label.setFont(new Font("Consolas", Font.PLAIN, 20)); + // Set gap of text to image + label.setIconTextGap(-25); + // Set background color + label.setBackground(Color.BLACK); + // Display background color + label.setOpaque(true); + // Set border + label.setBorder(border); + // Set vertical position of icon and text within label + label.setVerticalAlignment(JLabel.CENTER); + // Set horizontal position of icon and text within label + label.setHorizontalAlignment(JLabel.CENTER); + + // This will set x,y position within frame as well as dimensions + // label.setBounds(100, 100, 250, 250); + + }; +} \ No newline at end of file diff --git a/week_9/JLabel/smile.png b/week_9/JLabel/smile.png new file mode 100644 index 0000000..4668ab5 Binary files /dev/null and b/week_9/JLabel/smile.png differ diff --git a/week_9/JList/Multiple Selection/App.java b/week_9/JList/Multiple Selection/App.java new file mode 100644 index 0000000..28d5a6f --- /dev/null +++ b/week_9/JList/Multiple Selection/App.java @@ -0,0 +1,17 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JList/Multiple Selection/Frame.java b/week_9/JList/Multiple Selection/Frame.java new file mode 100644 index 0000000..2467f4e --- /dev/null +++ b/week_9/JList/Multiple Selection/Frame.java @@ -0,0 +1,66 @@ +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; +import java.awt.*; + +public class Frame extends JFrame { + + private JList leftList; + private JList rightList; + private JButton moveButton; + private static String[] food = { "bacon", "wings", "ham", "beef", "chicken" }; + + Frame() { + + // Adds window title + super("Title"); + setLayout(new FlowLayout()); + + // JList component + leftList = new JList(food); + + // Sets number of visible rows in the JList + leftList.setVisibleRowCount(3); + + // Enables user to select multiple items in the list + leftList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + // Adds a scrollbar + add(new JScrollPane(leftList)); + + // Adds text in button + moveButton = new JButton("Move -->"); + + // Add event when button is clicked + moveButton.addActionListener(new EventHandler()); + + // Add button component in frame + add(moveButton); + + rightList = new JList(); + + // Set number of visible item lists + rightList.setVisibleRowCount(3); + + // Set width and height of list + rightList.setFixedCellWidth(100); + rightList.setFixedCellHeight(15); + + // Enables user to select multiple items in the list + rightList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + add(new JScrollPane(rightList)); + } + + // Event handler class + private class EventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + rightList.setListData(leftList.getSelectedValuesList().toArray()); + } + } +} \ No newline at end of file diff --git a/week_9/JList/Single Selection/App.java b/week_9/JList/Single Selection/App.java new file mode 100644 index 0000000..b0b9dde --- /dev/null +++ b/week_9/JList/Single Selection/App.java @@ -0,0 +1,16 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JList/Single Selection/Frame.java b/week_9/JList/Single Selection/Frame.java new file mode 100644 index 0000000..3b7041b --- /dev/null +++ b/week_9/JList/Single Selection/Frame.java @@ -0,0 +1,46 @@ +import java.awt.*; +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +public class Frame extends JFrame { + + // Declare JList + private JList list; + + // Declare array of color names in the selection + private static String[] colorNames = { "Black", "Blue", "Red", "White" }; + + // Declare array of colors from the Colr class + private static Color[] colors = { Color.BLACK, Color.BLUE, Color.RED, Color.WHITE }; + + // Constructor + Frame() { + super("title"); + setLayout(new FlowLayout()); + + // JList Component + list = new JList(colorNames); + + // Set number of visible item lists + list.setVisibleRowCount(4); + + // Sets JList to selection one option at a time + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // Add JList component frame + add(new JScrollPane(list)); + + // Add event handler + list.addListSelectionListener(new EventHandler()); + } + + // Event handler class + private class EventHandler implements ListSelectionListener { + + // Changes background color when an event occurs + public void valueChanged(ListSelectionEvent event) { + getContentPane().setBackground(colors[list.getSelectedIndex()]); + } + } +} \ No newline at end of file diff --git a/week_9/JPanel/App.java b/week_9/JPanel/App.java new file mode 100644 index 0000000..269f36b --- /dev/null +++ b/week_9/JPanel/App.java @@ -0,0 +1,15 @@ +public class App { + public static void main(String[] args) throws Exception { + + MyFrame frame = new MyFrame(); + + frame.setLayout(null); + // Makes frame visible + frame.setVisible(true); + // Sets frame size + frame.setSize(500, 500); + // Exit out of application + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + + } +} \ No newline at end of file diff --git a/week_9/JPanel/Frame.java b/week_9/JPanel/Frame.java new file mode 100644 index 0000000..f82d8af --- /dev/null +++ b/week_9/JPanel/Frame.java @@ -0,0 +1,41 @@ +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.Color; +import java.awt.Font; +import java.awt.BorderLayout; + +public class MyFrame extends JFrame { + + MyFrame() { + + JLabel label = new JLabel(); + label.setText("Hello"); + label.setFont(new Font("Consolas", Font.PLAIN, 20)); + label.setVerticalAlignment(JLabel.BOTTOM); + label.setHorizontalAlignment(JLabel.RIGHT); + label.setBounds(100, 100, 75, 75); + + JPanel redPanel = new JPanel(); + redPanel.setBackground(Color.RED); + redPanel.setBounds(0, 0, 250, 250); + redPanel.setLayout(null); + + JPanel bluePanel = new JPanel(); + bluePanel.setBackground(Color.BLUE); + bluePanel.setBounds(250, 0, 250, 250); + bluePanel.setLayout(null); + + JPanel greenPanel = new JPanel(); + greenPanel.setBackground(Color.GREEN); + greenPanel.setBounds(0, 250, 500, 250); + // greenPanel.setLayout(new BorderLayout()); + greenPanel.setLayout(null); + + greenPanel.add(label); + this.add(redPanel); + this.add(bluePanel); + this.add(greenPanel); + + }; +} \ No newline at end of file diff --git a/week_9/JRadioButton/App.java b/week_9/JRadioButton/App.java new file mode 100644 index 0000000..b0b9dde --- /dev/null +++ b/week_9/JRadioButton/App.java @@ -0,0 +1,16 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/JRadioButton/Frame.java b/week_9/JRadioButton/Frame.java new file mode 100644 index 0000000..b4d9634 --- /dev/null +++ b/week_9/JRadioButton/Frame.java @@ -0,0 +1,78 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class Frame extends JFrame { + + private JTextField textField; + + private Font font1; + private Font font2; + private Font font3; + private Font font4; + + private JRadioButton radioButton1; + private JRadioButton radioButton2; + private JRadioButton radioButton3; + private JRadioButton radioButton4; + + private ButtonGroup group; + + public Frame() { + // Set the title of the window/frame + super("The title"); + setLayout(new FlowLayout()); + + // JTextField component + textField = new JTextField("This is a sentence", 25); + + // Add JTextField component + add(textField); + + // JRadioButton components + radioButton1 = new JRadioButton("plain", true); + radioButton2 = new JRadioButton("bold", false); + radioButton3 = new JRadioButton("italic", false); + radioButton4 = new JRadioButton("bold and italic", false); + + // Add JRadioButton components + add(radioButton1); + add(radioButton2); + add(radioButton3); + add(radioButton4); + + group = new ButtonGroup(); + group.add(radioButton1); + group.add(radioButton2); + group.add(radioButton3); + group.add(radioButton4); + + font1 = new Font("Serif", Font.PLAIN, 14); + font2 = new Font("Serif", Font.BOLD, 14); + font3 = new Font("Serif", Font.ITALIC, 14); + font4 = new Font("Serif", Font.BOLD + Font.ITALIC, 14); + textField.setFont(font1); + + // Add Event + radioButton1.addItemListener(new EventHandler(font1)); + radioButton2.addItemListener(new EventHandler(font2)); + radioButton3.addItemListener(new EventHandler(font3)); + radioButton4.addItemListener(new EventHandler(font4)); + + } + + // Event handler class + private class EventHandler implements ItemListener { + + private Font font; + + public EventHandler(Font f) { + font = f; + } + + public void itemStateChanged(ItemEvent event) { + textField.setFont(font); + } + } + +} \ No newline at end of file diff --git a/week_9/Layout/BorderLayout/App.java b/week_9/Layout/BorderLayout/App.java new file mode 100644 index 0000000..fc73f2e --- /dev/null +++ b/week_9/Layout/BorderLayout/App.java @@ -0,0 +1,15 @@ +import java.awt.*; +import javax.swing.*; + +public class App { + public static void main(String[] args) throws Exception { + + Frame f = new Frame(); + + f.setDefaultCloseOperation(f.getDefaultCloseOperation()); + + // Frame size + f.setSize(500, 500); + f.setVisible(true); + } +} \ No newline at end of file diff --git a/week_9/Layout/BorderLayout/Frame.java b/week_9/Layout/BorderLayout/Frame.java new file mode 100644 index 0000000..f814921 --- /dev/null +++ b/week_9/Layout/BorderLayout/Frame.java @@ -0,0 +1,41 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class Frame extends JFrame { + + // Layout Manager = Defines the natural layout for components within a container + + // BorderLayout = A BorderLayout places components in five areas: NORTH, SOUTH, + // WEST, EAST, CENTER. All extra space is placed in the center area. + + Frame() { + + // JPAnel components + JPanel northPanel = new JPanel(); + northPanel.setBackground(Color.RED); + JPanel southPanel = new JPanel(); + southPanel.setBackground(Color.BLUE); + JPanel eastPanel = new JPanel(); + eastPanel.setBackground(Color.GREEN); + JPanel westPanel = new JPanel(); + westPanel.setBackground(Color.ORANGE); + JPanel centerPanel = new JPanel(); + centerPanel.setBackground(Color.MAGENTA); + + // Set JPanel component sizes + northPanel.setPreferredSize(new Dimension(100, 100)); + southPanel.setPreferredSize(new Dimension(100, 100)); + eastPanel.setPreferredSize(new Dimension(100, 100)); + westPanel.setPreferredSize(new Dimension(100, 100)); + centerPanel.setPreferredSize(new Dimension(100, 100)); + + // Add JPanel component sizes + add(northPanel, BorderLayout.NORTH); + add(southPanel, BorderLayout.SOUTH); + add(eastPanel, BorderLayout.EAST); + add(westPanel, BorderLayout.WEST); + add(centerPanel, BorderLayout.CENTER); + } +} + diff --git a/week_9/Layout/FlowLayout/App.java b/week_9/Layout/FlowLayout/App.java new file mode 100644 index 0000000..873e1ef --- /dev/null +++ b/week_9/Layout/FlowLayout/App.java @@ -0,0 +1,14 @@ +public class App { + public static void main(String[] args) throws Exception { + + MyFrame frame = new MyFrame(); + + // Makes frame visible + frame.setVisible(true); + // Sets frame size + frame.setSize(500, 500); + // Exit out of application + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + + } +} \ No newline at end of file diff --git a/week_9/Layout/FlowLayout/Frame.java b/week_9/Layout/FlowLayout/Frame.java new file mode 100644 index 0000000..be7ac53 --- /dev/null +++ b/week_9/Layout/FlowLayout/Frame.java @@ -0,0 +1,35 @@ +import java.awt.*; +import javax.swing.*; + +public class MyFrame extends JFrame { + + // Layout Manager = Defines the natural layout for components within a container + + // FlowLayout = places components in a row, sized at their preferred size. + // If the horizontal space in the container is too small, the FlowLayout class + // uses the next available row. + + MyFrame() { + // this.setLayout(new FlowLayout(FlowLayout.TRAILING)); + // this.setLayout(new FlowLayout(FlowLayout.LEADING)); + this.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); + + JPanel panel = new JPanel(); + panel.setPreferredSize(new Dimension(250, 250)); + panel.setBackground(Color.LIGHT_GRAY); + panel.setLayout(new FlowLayout()); + + // Adds nine buttons + panel.add(new JButton("1")); + panel.add(new JButton("2")); + panel.add(new JButton("4")); + panel.add(new JButton("5")); + panel.add(new JButton("6")); + panel.add(new JButton("7")); + panel.add(new JButton("8")); + panel.add(new JButton("9")); + + this.add(panel); + + } +} \ No newline at end of file diff --git a/week_9/Layout/GridLayout/App.java b/week_9/Layout/GridLayout/App.java new file mode 100644 index 0000000..873e1ef --- /dev/null +++ b/week_9/Layout/GridLayout/App.java @@ -0,0 +1,14 @@ +public class App { + public static void main(String[] args) throws Exception { + + MyFrame frame = new MyFrame(); + + // Makes frame visible + frame.setVisible(true); + // Sets frame size + frame.setSize(500, 500); + // Exit out of application + frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE); + + } +} \ No newline at end of file diff --git a/week_9/Layout/GridLayout/Frame.java b/week_9/Layout/GridLayout/Frame.java new file mode 100644 index 0000000..4228936 --- /dev/null +++ b/week_9/Layout/GridLayout/Frame.java @@ -0,0 +1,26 @@ +import java.awt.*; +import javax.swing.*; + +public class MyFrame extends JFrame { + + // Layout Manager = Defines the natural layout for components within a container + + // GridLayout = places components in a grid of cells. Each componentn takes all + // the available space within its cell, and each cell is the same size. + + MyFrame() { + + this.setLayout(new GridLayout(3, 3, 10, 10)); + + // Add ten buttons + this.add(new JButton("1")); + this.add(new JButton("2")); + this.add(new JButton("3")); + this.add(new JButton("4")); + this.add(new JButton("5")); + this.add(new JButton("6")); + this.add(new JButton("7")); + this.add(new JButton("8")); + this.add(new JButton("9")); + } +} \ No newline at end of file diff --git a/week_x10/Image_as_Background/App.java b/week_x10/Image_as_Background/App.java new file mode 100644 index 0000000..8430ecd --- /dev/null +++ b/week_x10/Image_as_Background/App.java @@ -0,0 +1,7 @@ +public class App { + + public static void main(String args[]) { + new MainMenu(); + + } +} \ No newline at end of file diff --git a/week_x10/Image_as_Background/MainMenu.java b/week_x10/Image_as_Background/MainMenu.java new file mode 100644 index 0000000..20316c1 --- /dev/null +++ b/week_x10/Image_as_Background/MainMenu.java @@ -0,0 +1,23 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +class MainMenu extends JFrame { + JButton b1; + JLabel l1; + + MainMenu() { + + setContentPane(new JLabel(new ImageIcon("snake.jpg"))); + setLayout(new FlowLayout()); + + b1 = new JButton("I am a button"); + + add(b1); + setSize(740, 420); + setTitle("Background Color for JFrame"); + setLocationRelativeTo(null); + setDefaultCloseOperation(EXIT_ON_CLOSE); + setVisible(true); + } +} \ No newline at end of file diff --git a/week_x10/MouseEvents/App.java b/week_x10/MouseEvents/App.java new file mode 100644 index 0000000..b0b9dde --- /dev/null +++ b/week_x10/MouseEvents/App.java @@ -0,0 +1,16 @@ +import javax.swing.JFrame; + +public class App { + public static void main(String[] args) throws Exception { + + Frame frame = new Frame(); + // Terminates the program when clicking the close button + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // Sets the size of the frame/window + frame.setSize(300, 200); + + // Makes the window appear + frame.setVisible(true); + } +} \ No newline at end of file diff --git a/week_x10/MouseEvents/Frame.java b/week_x10/MouseEvents/Frame.java new file mode 100644 index 0000000..c28ae14 --- /dev/null +++ b/week_x10/MouseEvents/Frame.java @@ -0,0 +1,67 @@ +import java.awt.*; +import java.awt.event.*; +import java.awt.event.MouseEvent; +import javax.swing.*; + +public class Frame extends JFrame { + + private JPanel mousePanel; + private JLabel statusBar; + + Frame() { + + // Set window title + super("Title"); + + // JPanel Component + mousePanel = new JPanel(); + mousePanel.setBackground(Color.WHITE); + + // Add JPanel Component + add(mousePanel, BorderLayout.CENTER); + + // Add JLabel Component + statusBar = new JLabel(); + + // Add JPanel Component + add(statusBar, BorderLayout.SOUTH); + + // Add Event + mousePanel.addMouseListener(new EventHandler()); + mousePanel.addMouseMotionListener(new EventHandler()); + } + + // Event handler class + private class EventHandler implements MouseListener, MouseMotionListener { + + public void mouseClicked(MouseEvent event) { + statusBar.setText(String.format("Clicked at %d, %d", event.getX(), event.getY())); + } + + public void mousePressed(MouseEvent event) { + statusBar.setText("You pressed down the mouse!"); + } + + public void mouseReleased(MouseEvent event) { + statusBar.setText("You released the button!"); + } + + public void mouseEntered(MouseEvent event) { + statusBar.setText("You entered the area!"); + mousePanel.setBackground(Color.RED); + } + + public void mouseExited(MouseEvent event) { + statusBar.setText("The mouse has left the window"); + mousePanel.setBackground(Color.WHITE); + } + + public void mouseDragged(MouseEvent event) { + statusBar.setText("You are dragging the mouse"); + } + + public void mouseMoved(MouseEvent event) { + statusBar.setText("You moved the mouse"); + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/App.java b/week_x10/Snake_with_menus/App.java new file mode 100644 index 0000000..f8fe4bd --- /dev/null +++ b/week_x10/Snake_with_menus/App.java @@ -0,0 +1,18 @@ +import java.awt.Color; + +public class App { + + public static void main(String[] args) { + + MainMenu mainMenu = new MainMenu(); + + mainMenu.setDefaultCloseOperation(mainMenu.EXIT_ON_CLOSE); + mainMenu.setSize(500, 500); + mainMenu.setVisible(true); + mainMenu.setLocationRelativeTo(null); + mainMenu.setResizable(false); + // background color of frame + mainMenu.getContentPane().setBackground(new Color(200, 20, 100)); + + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/ColorMenu.java b/week_x10/Snake_with_menus/ColorMenu.java new file mode 100644 index 0000000..802b4a1 --- /dev/null +++ b/week_x10/Snake_with_menus/ColorMenu.java @@ -0,0 +1,74 @@ +import java.awt.Color; +import java.awt.Font; +import java.awt.*; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +public class ColorMenu extends JFrame { + + JList list; + private String[] colorlist = { "BLUE", "WHITE", "MAGENTA", "YELLOW" }; + private Color[] colors = { Color.BLUE, Color.WHITE, Color.MAGENTA, Color.YELLOW }; + + ColorMenu() { + super("Snake Game"); + this.setLayout(new FlowLayout()); + + // JLabel component + JLabel label = new JLabel(); + label.setText("Choose your favorite color: "); + label.setFont(new Font("Arial", Font.BOLD, 30)); + + // Jlist component + list = new JList(colorlist); + list.setFont(new Font("Arial", Font.BOLD, 30)); + list.setVisibleRowCount(2); + + // Sets JList to selection one option at a time + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // Add event + EventHandler handler = new EventHandler(); + list.addListSelectionListener(handler); + + // JScrollPane + JScrollPane scrollPane = new JScrollPane(list); + + // ADd components to frame + this.add(label); + this.add(scrollPane); + + // Close java program when closing window + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + // dimension of frame + this.setSize(500, 500); + // makes frame appear + this.setVisible(true); + // set frame to center + this.setLocationRelativeTo(null); + // background color of frame + this.getContentPane().setBackground(new Color(200, 20, 100)); + } + + // Event handler + private class EventHandler implements ListSelectionListener { + + public void valueChanged(ListSelectionEvent event) { + + GamePanel gp = new GamePanel(); + gp.snakeColor = colors[list.getSelectedIndex()]; + + // goes to player menu + new PlayerMenu(); + + // closes color menu + dispose(); + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/DifficultyMenu.java b/week_x10/Snake_with_menus/DifficultyMenu.java new file mode 100644 index 0000000..fcaf71f --- /dev/null +++ b/week_x10/Snake_with_menus/DifficultyMenu.java @@ -0,0 +1,70 @@ +import javax.swing.JButton; +import javax.swing.JFrame; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class DifficultyMenu extends JFrame { + DifficultyMenu() { + super("Snake Game"); + this.setLayout(new FlowLayout()); + + JButton easyButton = new JButton(); + easyButton.setText("EASY"); + easyButton.setFont(new Font("Arial", Font.BOLD, 30)); + // Add event to easy button + EventHandler easyHandler = new EventHandler(200); + easyButton.addActionListener(easyHandler); + + JButton mediumButton = new JButton(); + mediumButton.setText("MEDIUM"); + mediumButton.setFont(new Font("Arial", Font.BOLD, 30)); + // Add event to easy button + EventHandler mediumHandler = new EventHandler(120); + mediumButton.addActionListener(mediumHandler); + + JButton hardButton = new JButton(); + hardButton.setText("HARD"); + hardButton.setFont(new Font("Arial", Font.BOLD, 30)); + // Add event to easy button + EventHandler hardHandler = new EventHandler(40); + hardButton.addActionListener(hardHandler); + + add(easyButton); + add(mediumButton); + add(hardButton); + + // Close java program when closing window + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + // dimension of frame + this.setSize(500, 500); + // makes frame appear + this.setVisible(true); + // set frame to center + this.setLocationRelativeTo(null); + // background color of frame + this.getContentPane().setBackground(new Color(200, 20, 100)); + } + + private class EventHandler implements ActionListener { + + int snakeSpeed; + + // Constructor + EventHandler(int speed) { + this.snakeSpeed = speed; + } + + public void actionPerformed(ActionEvent event) { + GamePanel gp = new GamePanel(); + gp.DELAY = snakeSpeed; + + // Goes to colormenu frame + new ColorMenu(); + + // Closes difficulty menu frame + dispose(); + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/GameFrame.java b/week_x10/Snake_with_menus/GameFrame.java new file mode 100644 index 0000000..a781abb --- /dev/null +++ b/week_x10/Snake_with_menus/GameFrame.java @@ -0,0 +1,16 @@ +import javax.swing.JFrame; + +public class GameFrame extends JFrame { + + GameFrame() { + + this.add(new GamePanel()); + this.setTitle("Snake"); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + this.setResizable(false); + this.pack(); + this.setVisible(true); + this.setLocationRelativeTo(null); + + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/GamePanel.java b/week_x10/Snake_with_menus/GamePanel.java new file mode 100644 index 0000000..34bc9a2 --- /dev/null +++ b/week_x10/Snake_with_menus/GamePanel.java @@ -0,0 +1,219 @@ +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import java.util.Random; + +public class GamePanel extends JPanel implements ActionListener { + + static final int SCREEN_WIDTH = 1300; + static final int SCREEN_HEIGHT = 750; + static final int UNIT_SIZE = 50; + static final int GAME_UNITS = (SCREEN_WIDTH * SCREEN_HEIGHT) / (UNIT_SIZE * UNIT_SIZE); + + static boolean gameEnd = false; + + // Snake Speed + static int DELAY; + + // Snake Color + static Color snakeColor; + + // Player name + static String playerName; + + final int x[] = new int[GAME_UNITS]; + final int y[] = new int[GAME_UNITS]; + int bodyParts = 6; + int applesEaten; + int appleX; + int appleY; + char direction = 'R'; + boolean running = false; + Timer timer; + Random random; + private Image apple; + + GamePanel() { + random = new Random(); + apple = new ImageIcon("apple.png").getImage(); + this.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT)); + this.setBackground(Color.black); + this.setFocusable(true); + this.addKeyListener(new MyKeyAdapter()); + startGame(); + } + + public void startGame() { + newApple(); + running = true; + timer = new Timer(DELAY, this); + timer.start(); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + draw(g); + } + + public void draw(Graphics g) { + + Graphics2D g2d = (Graphics2D) g; + + if (running) { + g2d.setColor(Color.red); + // g2d.fillOval(appleX, appleY, UNIT_SIZE, UNIT_SIZE); + drawApple(g2d, appleX, appleY); + + for (int i = 0; i < bodyParts; i++) { + if (i == 0) { + g2d.setColor(snakeColor); + g.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE); + } else { + g2d.setColor(snakeColor); + g2d.fillRect(x[i], y[i], UNIT_SIZE, UNIT_SIZE); + } + } + g2d.setColor(Color.red); + g2d.setFont(new Font("Ink Free", Font.BOLD, 40)); + FontMetrics metrics = getFontMetrics(g2d.getFont()); + + g2d.drawString("Player: " + playerName, 0, g2d.getFont().getSize()); + + g2d.drawString("Score: " + applesEaten, (SCREEN_WIDTH - metrics.stringWidth("Score: " + applesEaten)) / 2, + g2d.getFont().getSize()); + } else { + gameOver(g2d); + } + + } + + public void newApple() { + appleX = random.nextInt((int) (SCREEN_WIDTH / UNIT_SIZE)) * UNIT_SIZE; + appleY = random.nextInt((int) (SCREEN_HEIGHT / UNIT_SIZE)) * UNIT_SIZE; + } + + private void drawApple(Graphics2D g2d, int x, int y) { + + g2d.drawImage(apple, x, y, this); + } + + public void move() { + for (int i = bodyParts; i > 0; i--) { + x[i] = x[i - 1]; + y[i] = y[i - 1]; + } + + switch (direction) { + case 'U': + y[0] = y[0] - UNIT_SIZE; + break; + case 'D': + y[0] = y[0] + UNIT_SIZE; + break; + case 'L': + x[0] = x[0] - UNIT_SIZE; + break; + case 'R': + x[0] = x[0] + UNIT_SIZE; + break; + } + + } + + public void checkApple() { + if ((x[0] == appleX) && (y[0] == appleY)) { + bodyParts++; + applesEaten++; + newApple(); + } + } + + public void checkCollisions() { + // checks if head collides with body + for (int i = bodyParts; i > 0; i--) { + if ((x[0] == x[i]) && (y[0] == y[i])) { + running = false; + } + } + // check if head touches left border + if (x[0] < 0) { + running = false; + } + // check if head touches right border + if (x[0] > SCREEN_WIDTH) { + running = false; + } + // check if head touches top border + if (y[0] < 0) { + running = false; + } + // check if head touches bottom border + if (y[0] > SCREEN_HEIGHT) { + running = false; + } + + if (!running) { + timer.stop(); + } + } + + public void gameOver(Graphics2D g) { + // Score + g.setColor(Color.red); + g.setFont(new Font("Ink Free", Font.BOLD, 40)); + FontMetrics metrics1 = getFontMetrics(g.getFont()); + g.drawString("Score: " + applesEaten, (SCREEN_WIDTH - metrics1.stringWidth("Score: " + applesEaten)) / 2, + g.getFont().getSize()); + // Game Over text + g.setColor(Color.red); + g.setFont(new Font("Ink Free", Font.BOLD, 75)); + FontMetrics metrics2 = getFontMetrics(g.getFont()); + g.drawString("Game Over", (SCREEN_WIDTH - metrics2.stringWidth("Game Over")) / 2, SCREEN_HEIGHT / 2); + + // Create object that refers to GameFrame + JFrame parent = (JFrame) this.getTopLevelAncestor(); + parent.dispose(); + + // Go to try again frame + new TryAgain(); + } + + @Override + public void actionPerformed(ActionEvent e) { + + if (running) { + move(); + checkApple(); + checkCollisions(); + } + repaint(); + } + + public class MyKeyAdapter extends KeyAdapter { + @Override + public void keyPressed(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_LEFT: + if (direction != 'R') { + direction = 'L'; + } + break; + case KeyEvent.VK_RIGHT: + if (direction != 'L') { + direction = 'R'; + } + break; + case KeyEvent.VK_UP: + if (direction != 'D') { + direction = 'U'; + } + break; + case KeyEvent.VK_DOWN: + if (direction != 'U') { + direction = 'D'; + } + break; + } + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/MainMenu.java b/week_x10/Snake_with_menus/MainMenu.java new file mode 100644 index 0000000..a9898cd --- /dev/null +++ b/week_x10/Snake_with_menus/MainMenu.java @@ -0,0 +1,45 @@ +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; + +import java.awt.*; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class MainMenu extends JFrame { + MainMenu() { + super("Snake Game"); + this.setLayout(new FlowLayout()); + + ImageIcon snakeIcon = new ImageIcon("rainbowcat.gif"); + JLabel label = new JLabel(); + label.setIcon(snakeIcon); + + JButton button = new JButton(); + button.setText("START GAME"); + button.setFont(new Font("Consolas", Font.BOLD, 25)); + + EventHandler handler = new EventHandler(); + button.addActionListener(handler); + + this.add(label); + this.add(button); + } + + // Event handler class + private class EventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + // JOptionPane.showMessageDialog(null, "HELLO ELIZER PONIO JR"); + + // Switches to difficulty menu + new DifficultyMenu(); + + // Closes main menu + dispose(); + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/PlayerMenu.java b/week_x10/Snake_with_menus/PlayerMenu.java new file mode 100644 index 0000000..596c4e9 --- /dev/null +++ b/week_x10/Snake_with_menus/PlayerMenu.java @@ -0,0 +1,72 @@ +import java.awt.Color; +import java.awt.event.KeyListener; +import java.awt.event.KeyEvent; +import java.awt.*; + +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTextField; + +public class PlayerMenu extends JFrame { + + JTextField textField; + + PlayerMenu() { + super("Snake Game"); + this.setLayout(new FlowLayout()); + + // JLabel + JLabel label = new JLabel(); + label.setText("Enter player name: "); + label.setFont(new Font("Arial", Font.BOLD, 30)); + + // JTextField + textField = new JTextField(20); + // Adds event to textfield + EventHandler handler = new EventHandler(); + textField.addKeyListener(handler); + + // Add components to frame + this.add(label); + this.add(textField); + + // Close java program when closing window + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + // dimension of frame + this.setSize(500, 500); + // makes frame appear + this.setVisible(true); + // set frame to center + this.setLocationRelativeTo(null); + // background color of frame + this.getContentPane().setBackground(new Color(200, 20, 100)); + } + + private class EventHandler implements KeyListener { + + public void keyPressed(KeyEvent event) { + + GamePanel gp = new GamePanel(); + + // If ENTER button is pressed, do this + if (event.getKeyCode() == KeyEvent.VK_ENTER) { + + gp.playerName = textField.getText(); + + // Close playermenu frame + dispose(); + + // Go to game frame + new GameFrame(); + } + } + + public void keyTyped(KeyEvent event) { + // + } + + public void keyReleased(KeyEvent event) { + // + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/TryAgain.java b/week_x10/Snake_with_menus/TryAgain.java new file mode 100644 index 0000000..85f0291 --- /dev/null +++ b/week_x10/Snake_with_menus/TryAgain.java @@ -0,0 +1,57 @@ +import javax.swing.JButton; +import javax.swing.JFrame; + +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class TryAgain extends JFrame { + TryAgain() { + super("Snake Game"); + this.setLayout(new FlowLayout()); + + JButton tryAgainButton = new JButton(); + tryAgainButton.setText("TRY AGAIN"); + tryAgainButton.setFont(new Font("Arial", Font.BOLD, 30)); + // Add event to easy button + TryAgainEventHandler tryHandler = new TryAgainEventHandler(); + tryAgainButton.addActionListener(tryHandler); + + JButton exitButton = new JButton(); + exitButton.setText("EXIT"); + exitButton.setFont(new Font("Arial", Font.BOLD, 30)); + // Add event to easy button + ExitEventHandler exitHandler = new ExitEventHandler(); + exitButton.addActionListener(exitHandler); + + add(tryAgainButton); + add(exitButton); + + // Close java program when closing window + this.setDefaultCloseOperation(EXIT_ON_CLOSE); + // dimension of frame + this.setSize(500, 500); + // makes frame appear + this.setVisible(true); + // set frame to center + this.setLocationRelativeTo(null); + // background color of frame + this.getContentPane().setBackground(new Color(200, 20, 100)); + } + + private class TryAgainEventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + App myApp = new App(); + myApp.main(null); + dispose(); + } + } + + private class ExitEventHandler implements ActionListener { + + public void actionPerformed(ActionEvent event) { + dispose(); + } + } +} \ No newline at end of file diff --git a/week_x10/Snake_with_menus/apple.png b/week_x10/Snake_with_menus/apple.png new file mode 100644 index 0000000..b0e69ba Binary files /dev/null and b/week_x10/Snake_with_menus/apple.png differ diff --git a/week_x10/Snake_with_menus/rainbowcat.gif b/week_x10/Snake_with_menus/rainbowcat.gif new file mode 100644 index 0000000..54d698c Binary files /dev/null and b/week_x10/Snake_with_menus/rainbowcat.gif differ diff --git a/week_x10/Snake_with_menus/snake.jpg b/week_x10/Snake_with_menus/snake.jpg new file mode 100644 index 0000000..b0a03f4 Binary files /dev/null and b/week_x10/Snake_with_menus/snake.jpg differ diff --git a/week_y11/Multithreading/extends and implements/App.java b/week_y11/Multithreading/extends and implements/App.java new file mode 100644 index 0000000..af3f792 --- /dev/null +++ b/week_y11/Multithreading/extends and implements/App.java @@ -0,0 +1,26 @@ +public class App { + public static void main(String[] args) throws Exception { + + // Thread created using Thread class + MyThread thread1 = new MyThread(); + + // Thread created using Runnable Interface + MyRunnable runnable1 = new MyRunnable(); + Thread thread2 = new Thread(runnable1); + + // thread1.setDaemon(true); + // thread2.setDaemon(true); + + thread1.start(); + + // Will wait until thread1 dies + // thread1.join(); + + // Will wait until thread1 dies for a specified time in milliseconds + thread1.join(3000); + + thread2.start(); + + // System.out.println(1 / 0); + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/extends and implements/MyRunnable.java b/week_y11/Multithreading/extends and implements/MyRunnable.java new file mode 100644 index 0000000..046b20a --- /dev/null +++ b/week_y11/Multithreading/extends and implements/MyRunnable.java @@ -0,0 +1,20 @@ +public class MyRunnable implements Runnable { + + @Override + public void run() { + + for (int i = 0; i < 10; i++) { + System.out.println("Thread # 2: " + i); + + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + + // System.out.println(1 / 0); + } + + System.out.println("Thread # 2 is finished :)"); + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/extends and implements/MyThread.java b/week_y11/Multithreading/extends and implements/MyThread.java new file mode 100644 index 0000000..db2dfe3 --- /dev/null +++ b/week_y11/Multithreading/extends and implements/MyThread.java @@ -0,0 +1,18 @@ +public class MyThread extends Thread { + + @Override + public void run() { + + for (int i = 10; i > 0; i--) { + System.out.println("Thread # 1: " + i); + + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } + } + + System.out.println("Thread # 1 is finished :)"); + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/extends/App.java b/week_y11/Multithreading/extends/App.java new file mode 100644 index 0000000..1764a95 --- /dev/null +++ b/week_y11/Multithreading/extends/App.java @@ -0,0 +1,15 @@ +public class App { + public static void main(String[] args) throws Exception { + + MyThread thread1 = new MyThread("YouTube"); + MyThread thread2 = new MyThread("Facebook"); + MyThread thread3 = new MyThread("Instagram"); + MyThread thread4 = new MyThread("TikTok"); + + // Start all threads at once + thread1.start(); + thread2.start(); + thread3.start(); + thread4.start(); + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/extends/MyThread.java b/week_y11/Multithreading/extends/MyThread.java new file mode 100644 index 0000000..f162ef1 --- /dev/null +++ b/week_y11/Multithreading/extends/MyThread.java @@ -0,0 +1,22 @@ +import java.util.Random; + +public class MyThread extends Thread { + String name; + int time; + Random r = new Random(); + + public MyThread(String x) { + name = x; + time = r.nextInt(999); + } + + public void run() { + try { + System.out.printf("%s is loading for %d\n", name, time); + Thread.sleep(time); + System.out.printf("%s is done\n", name); + } catch (Exception e) { + // TODO: handle exception + } + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/implements/App.java b/week_y11/Multithreading/implements/App.java new file mode 100644 index 0000000..2627aa9 --- /dev/null +++ b/week_y11/Multithreading/implements/App.java @@ -0,0 +1,16 @@ +public class App { + public static void main(String[] args) throws Exception { + + Thread thread1 = new Thread(new MyThread("YouTube")); + Thread thread2 = new Thread(new MyThread("Facebook")); + Thread thread3 = new Thread(new MyThread("Instagram")); + Thread thread4 = new Thread(new MyThread("TikTok")); + + // Start all threads at once + thread1.start(); + thread2.start(); + thread3.start(); + thread4.start(); + + } +} \ No newline at end of file diff --git a/week_y11/Multithreading/implements/MyThread.java b/week_y11/Multithreading/implements/MyThread.java new file mode 100644 index 0000000..aa2f2d1 --- /dev/null +++ b/week_y11/Multithreading/implements/MyThread.java @@ -0,0 +1,25 @@ +import java.util.Random; + +import java.util.*; + +public class MyThread implements Runnable { + + String name; + int time; + Random r = new Random(); + + public MyThread(String x) { + name = x; + time = r.nextInt(999); + } + + public void run() { + try { + System.out.printf("%s is loading for %d\n", name, time); + Thread.sleep(time); + System.out.printf("%s is done\n", name); + } catch (Exception e) { + // TODO: handle exception + } + } +} \ No newline at end of file diff --git a/week_y11/Threads/App.java b/week_y11/Threads/App.java new file mode 100644 index 0000000..d9796ae --- /dev/null +++ b/week_y11/Threads/App.java @@ -0,0 +1,52 @@ +public class App { + public static void main(String[] args) throws InterruptedException { + + // Gets the active number of threads + System.out.println(Thread.activeCount()); + + // Change the name of the current thread + Thread.currentThread().setName("MAIN"); + + // Retrieve the name of the current thread + System.out.println(Thread.currentThread().getName()); + + // Set the priority level of a thread + Thread.currentThread().setPriority(10); + + // Get the priority level of a thread + System.out.println(Thread.currentThread().getPriority()); + + System.out.println(Thread.currentThread().isAlive()); + + for (int i = 1; i > 0; i--) { + if (i == 1) { + System.out.print("Loading"); + } + Thread.sleep(1000); + System.out.print("."); + } + + System.out.println(" Finished loading"); + + // Create new thread + MyThread thread2 = new MyThread(); + + thread2.setDaemon(true); + System.out.println(thread2.isDaemon()); + + // Starts the second thread + thread2.start(); + + System.out.println(thread2.isAlive()); + + thread2.setName("Second thread"); + + System.out.println(thread2.getName()); + + thread2.setPriority(1); + + System.out.println(thread2.getPriority()); + + System.out.println(Thread.activeCount()); + } +} \ No newline at end of file diff --git a/week_y11/Threads/MyThread.java b/week_y11/Threads/MyThread.java new file mode 100644 index 0000000..c4163e9 --- /dev/null +++ b/week_y11/Threads/MyThread.java @@ -0,0 +1,11 @@ +public class MyThread extends Thread { + + public void run() { + + if (this.isDaemon()) { + System.out.println("This daemon thread is running"); + } else { + System.out.println("This user thread is running"); + } + } +} \ No newline at end of file diff --git a/week_z12/locks/App.java b/week_z12/locks/App.java new file mode 100644 index 0000000..e62ff4c --- /dev/null +++ b/week_z12/locks/App.java @@ -0,0 +1,15 @@ +public class App { + + public static void main(String[] args) throws InterruptedException { + char[] myArray = new char[20]; + + Thread thread1 = new MyThread(myArray, "HELLO"); + thread1.start(); + + Thread thread2 = new MyThread(myArray, "WORLD"); + thread2.start(); + + thread1.join(); + thread2.join(); + } +} \ No newline at end of file diff --git a/week_z12/locks/MyThreads.java b/week_z12/locks/MyThreads.java new file mode 100644 index 0000000..05408b8 --- /dev/null +++ b/week_z12/locks/MyThreads.java @@ -0,0 +1,42 @@ +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.Lock; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class MyThread extends Thread { + + private char[] array; + private String message; + private static Lock lock = new ReentrantLock(true); + + public MyThread(char[] array, String message) { + this.array = array; + this.message = message; + } + + @Override + public void run() { + pleaseLock(); + try { + System.out.println("Lock is being used by " + Thread.currentThread().getName()); + for (int i = 0; i < message.length(); i++) { + try { + array[i] = message.charAt(i); + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + System.out.println(array); + } finally { + lock.unlock(); + System.out.println("Lock unlocked by " + Thread.currentThread().getName()); + } + + } + + private void pleaseLock() { + lock.lock(); + } + +} \ No newline at end of file diff --git a/week_z12/registration/App.java b/week_z12/registration/App.java new file mode 100644 index 0000000..a02e66d --- /dev/null +++ b/week_z12/registration/App.java @@ -0,0 +1,22 @@ +public class App { + + public static void main(String[] args) throws Exception { + + Registration reg = new Registration(); + + // Thread 1 + StudentThread student1 = new StudentThread(reg, "Jay"); + // Thread 2 + StudentThread student2 = new StudentThread(reg, "Gab"); + // Thread 2 + StudentThread student3 = new StudentThread(reg, "Ani"); + + // Start thread 1 + student1.start(); + // Start thread 2 + student2.start(); + // Start thread 3 + student3.start(); + } + +} \ No newline at end of file diff --git a/week_z12/registration/Registration.java b/week_z12/registration/Registration.java new file mode 100644 index 0000000..8924cec --- /dev/null +++ b/week_z12/registration/Registration.java @@ -0,0 +1,40 @@ +public class Registration implements Runnable { + + private int totalSlotsAvailable = 2; + + public void run() { + + // Type Casting + StudentThread st = (StudentThread) Thread.currentThread(); + + boolean slotsReserved = this.registerSection(st.getName()); + + if (slotsReserved) { + System.out.println("Congratulations " + Thread.currentThread().getName() + + ", you are now registered in this section"); + } else { + System.out + .println("Sorry " + Thread.currentThread().getName() + ", the section is already full!"); + } + } + + public synchronized boolean registerSection(String name) { + + System.out.println( + "Welcome to NUIS! " + Thread.currentThread().getName() + + ", the number of slots available for this section is : " + + this.getTotalSlotsAvailable()); + + if (totalSlotsAvailable <= 0) { + return false; + } else { + totalSlotsAvailable = totalSlotsAvailable - 1; + + return true; + } + } + + private int getTotalSlotsAvailable() { + return totalSlotsAvailable; + } +} \ No newline at end of file diff --git a/week_z12/registration/StudentThread.java b/week_z12/registration/StudentThread.java new file mode 100644 index 0000000..4d1d005 --- /dev/null +++ b/week_z12/registration/StudentThread.java @@ -0,0 +1,6 @@ +public class StudentThread extends Thread { + + public StudentThread(Runnable target, String name) { + super(target, name); + } +} \ No newline at end of file diff --git a/week_z12/reservation/App.java b/week_z12/reservation/App.java new file mode 100644 index 0000000..e8d8bf7 --- /dev/null +++ b/week_z12/reservation/App.java @@ -0,0 +1,14 @@ +public class App { + + public static void main(String[] args) throws Exception { + + BusReservation br = new BusReservation(); + + PassengerThread pt1 = new PassengerThread(2, br, "Sam"); + PassengerThread pt2 = new PassengerThread(2, br, "Jack"); + + pt1.start(); + pt2.start(); + } + +} \ No newline at end of file diff --git a/week_z12/reservation/BusReservation.java b/week_z12/reservation/BusReservation.java new file mode 100644 index 0000000..e9f56f2 --- /dev/null +++ b/week_z12/reservation/BusReservation.java @@ -0,0 +1,43 @@ +public class BusReservation implements Runnable { + + private int totalSeatsAvailable = 2; + + public void run() { + + PassengerThread pt = (PassengerThread) Thread.currentThread(); + + boolean ticketsBooked = this.bookTickets(pt.getSeatsNeeded(), pt.getName()); + + if (ticketsBooked) { + System.out + .println( + "Congratulations " + Thread.currentThread().getName() + + ", the number of seats you have requested: " + + pt.getSeatsNeeded() + " are booked!"); + } else { + System.out + .println("Sorry " + Thread.currentThread().getName() + ", the number of seats you have requested: " + + pt.getSeatsNeeded() + " are not available!"); + } + } + + public synchronized boolean bookTickets(int seats, String name) { + + System.out.println( + "Welcome to Bus Company! " + Thread.currentThread().getName() + + ", the number of tickets available are: " + + this.getTotalSeatsAvailable()); + + if (seats > this.getTotalSeatsAvailable()) { + return false; + } else { + totalSeatsAvailable = totalSeatsAvailable - seats; + + return true; + } + } + + private int getTotalSeatsAvailable() { + return totalSeatsAvailable; + } +} \ No newline at end of file diff --git a/week_z12/reservation/PassengerThread.java b/week_z12/reservation/PassengerThread.java new file mode 100644 index 0000000..b00c82c --- /dev/null +++ b/week_z12/reservation/PassengerThread.java @@ -0,0 +1,13 @@ +public class PassengerThread extends Thread { + + private int seatsNeeded; + + public PassengerThread(int seats, Runnable target, String name) { + super(target, name); + this.seatsNeeded = seats; + } + + public int getSeatsNeeded() { + return seatsNeeded; + } +} \ No newline at end of file diff --git a/week_z12/shared_array/App.java b/week_z12/shared_array/App.java new file mode 100644 index 0000000..1729f46 --- /dev/null +++ b/week_z12/shared_array/App.java @@ -0,0 +1,19 @@ +import java.util.ArrayList; +import java.util.List; + +public class App { + + public static void main(String[] args) throws InterruptedException { + char[] myArray = new char[20]; + + Thread thread1 = new MyThread(myArray, "HELLO"); + thread1.start(); + + Thread thread2 = new MyThread(myArray, "WORLD"); + thread2.start(); + + thread1.join(); + thread2.join(); + } +} + diff --git a/week_z12/shared_array/MyThread.java b/week_z12/shared_array/MyThread.java new file mode 100644 index 0000000..53dfae6 --- /dev/null +++ b/week_z12/shared_array/MyThread.java @@ -0,0 +1,30 @@ +import java.util.logging.Level; +import java.util.logging.Logger; + +public class MyThread extends Thread { + + private char[] array; + private String message; + + public MyThread(char[] array, String message) { + this.array = array; + this.message = message; + } + + @Override + public void run() { + synchronized (array) { + System.out.println("Array is being used by " + Thread.currentThread().getName()); + for (int i = 0; i < message.length(); i++) { + try { + array[i] = message.charAt(i); + Thread.sleep(50); + } catch (InterruptedException ex) { + Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex); + } + } + System.out.println(array); + } + } + +} \ No newline at end of file